相关疑难解决方法(0)

完全仿真与完全虚拟化

在完全仿真中,I/O设备,CPU,主存储器被虚拟化.客户操作系统将访问虚拟设备而不是物理设备.但究竟什么是完全虚拟化?是完全仿真还是完全不同的东西?

virtualization emulation

31
推荐指数
4
解决办法
1万
查看次数

如何为我的bootloader制作内核?

我正在尝试制作自己的自定义操作系统,我需要一些代码帮助.这是我的bootloader.asm:

[ORG 0x7c00]

start:
    cli
    xor ax, ax
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov [BOOT_DRIVE], dl
    mov bp, 0x8000
    mov sp, bp
    mov bx, 0x9000
    mov dh, 5
    mov dl, [BOOT_DRIVE]
    call load_kernel
    call enable_A20
    call graphics_mode
    lgdt [gdtr]
    mov eax, cr0
    or al, 1
    mov cr0, eax
    jmp CODE_SEG:init_pm

[bits 32]
init_pm:
    mov ax, DATA_SEG
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly kernel osdev bootloader

8
推荐指数
1
解决办法
1866
查看次数

近呼叫/跳转表并不总是在引导加载程序中工作

一般问题

我一直在开发一个简单的引导加载程序,并且在某些环境中偶然发现问题,这些环境中的指令不起作用:

mov si, call_tbl      ; SI=Call table pointer
call [call_tbl]       ; Call print_char using near indirect absolute call
                      ; via memory operand
call [ds:call_tbl]    ; Call print_char using near indirect absolute call
                      ; via memory operand w/segment override
call near [si]        ; Call print_char using near indirect absolute call
                      ; via register
Run Code Online (Sandbox Code Playgroud)

这些中的每一个碰巧涉及间接接近CALL到绝对存储器偏移.我发现如果我使用类似的JMP表,我会遇到问题.相对的呼叫和跳转似乎没有受到影响.像这样的代码有效:

call print_char 
Run Code Online (Sandbox Code Playgroud)

我已经通过海报讨论了Stackoverflow上提出的建议,讨论了编写引导加载程序的注意事项.特别是我看到这个Stackoverflow回答了一般的Bootloader技巧.第一个提示是:

  1. 当BIOS跳转到您的代码时,您不能依赖具有有效或预期值的CS,DS,ES,SS,SP寄存器.应在引导加载程序启动时正确设置它们.您只能保证将从物理地址0x07c00加载并运行引导加载程序,并将引导驱动器号加载到DL寄存器中. …

x86 assembly real-mode nasm bootloader

7
推荐指数
1
解决办法
584
查看次数

链接两个或多个程序集文件

我正在开发一个简单而小型的64位操作系统。到目前为止,我只使用一个文件,并使用NASM进行编译:

nasm -f bin os.asm -o os.bin
Run Code Online (Sandbox Code Playgroud)

然后.bin用qemu 测试文件。
现在,我需要在文件中使用多个os.bin文件。我插入了这一行:

extern helper_func
Run Code Online (Sandbox Code Playgroud)

然后在代码中调用它。在另一个.asm文件中,我创建了此函数或过程。问题是bin格式不支持extern,因此我尝试使用ELF格式创建.obj文件,然后将它们与gcc链接:

gcc -m32 -nostdlib -nodefaultlibs -lgcc os.obj helper.obj -t linker.ld
Run Code Online (Sandbox Code Playgroud)

与此链接文件:

ENTRY(_start)

SECTIONS
{
    . = 0x7C00;

    .text :
    {
        *(.text);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行.bin已创建的时,qemu无法识别该文件。我做错了什么?

(我使用过gcc是因为我计划将来使用C代码)

实际上,我什至不知道gcc中所有标志的作用。我已经从Internet XD复制了它们。

到目前为止,这是我所做的:

nasm -f elf os.asm -o os.obj
nasm -f elf helper.asm -o helper.obj
gcc -m32 -nostdlib -nodefaultlibs -lgcc os.obj helper.obj -t linker.ld -o myos.bin
objcopy --input-target=elf32-little --output-target=binary myos.bin myos.bin.new
qemu-system-x86_64 myos.bin.new …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm osdev bootloader

7
推荐指数
1
解决办法
134
查看次数

启用引导加载程序以加载USB的第二个扇区

我正在学习汇编语言.我写了一个简单的bootloader.测试后,它没有用.这是我的代码:

[bits 16]
[org 0x7c00]

jmp start

data:
wolf_wel_msg db 'Welcome to Bootloader!!!',0x0D,0x0A,0
wolf_kernel_load db 'Loading kernel....',0x0D,0x0A,0
wolf_error_msg db 'Kernel.bin not found!',0x0D,0x0A,0
wolf_error_msg1 db 'Press any key to restart..',0

start:
        mov si, wolf_wel_msg
    call wolf_print

    mov si, wolf_kernel_load
    call wolf_print

    pushf
    stc

    mov ah,00
    mov dl,00
    int 13h

    read_sector:
            mov ax, 0x0
        mov es, ax
        xor bx, bx
            mov ah, 02
        mov al, 01
        mov ch, 01
        mov cl, 02
        mov dh, 00
        mov dl, 00
        int 13h

    jc wolf_error …
Run Code Online (Sandbox Code Playgroud)

assembly osdev bootloader bochs x86-16

6
推荐指数
1
解决办法
1404
查看次数

通过USB驱动器启动的自定义引导加载程序在某些计算机上产生错误的输出

我对装配很新,但我正试图深入了解低级计算的世界.我正在尝试学习如何编写将作为引导加载程序代码运行的汇编代码; 所以独立于任何其他操作系统,如Linux或Windows.在阅读了本页和其他几个x86指令集列表之后,我想出了一些汇编代码,它应该在屏幕上打印10 A然后是1 B.

      BITS 16
start: 
    mov ax, 07C0h       ; Set up 4K stack space after this bootloader
    add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax

    mov cl, 10          ; Use this register as our loop counter
    mov ah, 0Eh         ; This register holds our BIOS instruction

.repeat:
    mov al, 41h         ; Put …
Run Code Online (Sandbox Code Playgroud)

x86 assembly usb-drive bios bootloader

6
推荐指数
2
解决办法
758
查看次数

为什么在尝试处理286而不是现代CPU或Bochs上的异常时出现三重错误?

我正在尝试通过AMD 286系统上的异常处理来初始化保护模式。我已经在Bochs上调试了以下代码,并且在这里可以正常工作。在奔腾4机器上运行时也是如此。但是在286上,当到达int3指令时,它只是三重故障。可以观察到的行为是:如果我注释掉了int3,则会无限期地在屏幕上显示“ OK”,而按原样使用代码,则系统将重新启动。

该代码将由FASM编译,并将二进制文件放入HDD或FDD的引导扇区中。我实际上是从1.4M软盘运行它。

 org 0x7c00
 use16

 CODE_SELECTOR     = code_descr - gdt
 DATA_SELECTOR     = data_descr - gdt

    ; print "OK" on the screen to see that we've actually started
    push     0xb800
    pop      es
    xor      di,di
    mov      ax, 0x0700+'O'
    stosw
    mov      ax, 0x0700+'K'
    stosw
    ; clear the rest of the screen
    mov      cx, 80*25*2-2
    mov      ax, 0x0720
    rep stosw

    lgdt     [cs:gdtr]
    cli
    smsw     ax
    or       al, 1
    lmsw     ax
    jmp      CODE_SELECTOR:enterPM
enterPM:
    lidt     [idtr]
    mov      cx, DATA_SELECTOR …
Run Code Online (Sandbox Code Playgroud)

x86 assembly protected-mode interrupt-handling 80286

6
推荐指数
1
解决办法
87
查看次数

引导加载程序在 qemu 中工作,但在 virtualbox 和硬件上失败

我的引导加载程序由两个 512 字节的阶段组成。阶段 1 由 bios 加载到 MBR 区域。stage1 然后继续从驱动器加载 stage2 并跳转到它。

我用十六进制编辑器确认最终二进制“program.bin”的大小正好是 1024 字节长,并且包含两个“签名”(每个阶段的最后两个字节,0xAA55 用于 stage1(MBR 签名)和 0xCC77 用于 stage2)。

预期产出是:

1 // stage1 started
0000 or 0080 // drive# in hex
CC77 // stage2 "signature" in hex
2 // stage2 started
Run Code Online (Sandbox Code Playgroud)

这在 QEMU 中工作正常,但在 virtualbox 和硬件上失败。在我看来,stage2 加载无声无息地失败(错误分支没有被调用),我希望解决这个问题两周,但没有成功。

QEMU 输出
QEMU 输出

硬件和 Virtual Box 输出
VBox 输出

stage1.asm:

global _start
extern _stage2
extern _stage2data

BITS 16

_start:
; init registers
    xor ax, ax
    mov es, ax
    mov gs, ax
    mov ss, ax …
Run Code Online (Sandbox Code Playgroud)

boot assembly mbr x86-64

6
推荐指数
1
解决办法
217
查看次数

为什么无法从 .data 节加载我的 HELLO_WORLD 字符串?

我正在制作引导加载程序,作为学习汇编的一种方式。我已经研究过使用部分来组织和优化我的代码,但是当我调用 printf 函数时,一件事不起作用。当我在 .data 部分中有 HELLO_WORLD 字符串时,它根本不想加载该字符串

; Set Code to run at 0x7c00
org 0x7c00
; Put into real mode
bits 16 

; Variables without values
section .bss

; Our constant values
section .data
    HELLO_WORLD: db 'Hello World!', 0

; Where our code runs
section .text
    _start:
        mov si, HELLO_WORLD ; Moves address for string into si register
        call printf ; Calls printf function
        jmp $ ; Jump forever
        
    printf:
        lodsb ; Load the next character
        cmp al, 0 …
Run Code Online (Sandbox Code Playgroud)

assembly nasm bootloader x86-16

6
推荐指数
1
解决办法
167
查看次数

在引导扇区中使用 INT 0x10 打印字符串

我想创建printl允许我在寄存器中打印字符串的函数ax。我处于 16 位实模式,找不到任何打印消息的方法。我用来int 0x10打印一封信。

我尝试在寄存器中传递参数(要打印的字符串)bx,然后在循环中逐个字母地打印,然后使用popaand返回ret。我的代码并没有真正起作用——要么它创建了一个无限循环,要么打印了一个奇怪的符号。

如果您知道更有效的方法,那么这不是问题。如果您提供任何评论,我还想询问您的代码

这是我的代码

启动.asm:

start:
    mov bx, welcome    ;put argument to bx
    call printl        ;call printl function in sysf.asm
    hlt                ;halt cpu

welcome db 'Hello', 0

include 'sysf.asm'
times 510 - ($-$$) db 0

db 0x55
db 0xAA
Run Code Online (Sandbox Code Playgroud)

sysf.asm:

;print function
; al is one letter argument (type Java:char)
;
print:
        pusha
        mov ah, 0x0e
        int 0x10
        popa
        ret              ; go back

;printl function …
Run Code Online (Sandbox Code Playgroud)

x86 assembly fasm

5
推荐指数
1
解决办法
4407
查看次数