切换到保护模式后,跳转到32位代码似乎没有生效

时间:2017-12-20 03:01:22

标签: x86 osdev real-mode protected-mode gdt

经过与我自己的争论,我终于决定将我的操作系统转移到保护模式。但是,我在执行保护模式代码时遇到了一些问题。 OSDev wiki的第一步是启用A20系列,因为快速门,我没有遇到什么麻烦。第二部分是加载全局描述符表。我按照BrokenThorn娱乐教程使用它作为我的GDT的粗略基础,并将一些长二进制值转换为漂亮和短的十六进制值。最后,我将cr0寄存器的最低位设置为1进入保护模式。然后我跳远到0x08:start32。但是,在执行我的代码并使用qemu的monitor -stdio标志监视寄存器时,我看到意外的结果。我的主要保护模式例程start32很简单。它将值0xDEADBABA移动到eax寄存器中。然而,这似乎没有生效,因为在QEMU上,值显示为00000100。 cr0寄存器是00000010,这似乎是正确的,但再次让我持怀疑态度,因为它不是最低位。到目前为止最糟糕的是GDT寄存器,它精确地等于00000000 00000000。这里有什么问题?我已经为我的bootsector和我的部分内核提供了代码,下面切换到保护模式。

P.S:bootsector清除屏幕并加载内核。这是它唯一的目的。

start.asm(bootsector):

bits 16

start:
    mov ax, 0x07C0
    add ax, 288
    mov ss, ax
    mov sp, 4096

    mov ax, 0x07C0
    mov ds, ax

    mov ah, 0x00
    mov al, 0x03
    int 0x10

    call load_kernel

load_kernel:
    mov ah, 0x02                ; call function 0x02 of int 13h (read sectors)
    mov al, 0x01                ; read one sector (512 bytes)
    mov ch, 0x00                ; track 0
    mov cl, 0x02                ; sector 2
    mov dh, 0x00                ; head 0
    mov dl, 0x00                ; drive 0, floppy 1
    mov bx, 0x2000              ; segment 0x2000
    mov es, bx                  ; segments must be loaded from non immediate data
    mov bx, 0x0000              ; start of segment -offset value
.readsector:
    int 13h                     ; call int 13h
    jc .readsector              ; error? try again

    mov ax, 0x2000              ; set the data segment register
    mov ds, ax                  ; as a pointer to the kernel's memory location

    jmp 0x2000:0x0000           ; jump to the kernel

times 510-($-$$) db 0
dw 0xAA55

kernel.asm(有问题的文件):

bits 16

section .text
start:
    mov ax, 0x2000
    add ax, 288
    mov ss, ax
    mov sp, 4096

    mov ax, 0x2000
    mov ds, ax

    cli    

    in al, 0x92
    or al, 2
    out 0x92, al

    lgdt[toc]

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x08:start32

section .rodata
gdt32:
    dd 0
    dd 0

    dw 0x0FFFF
    dw 0
    db 0
    db 0x9A
    db 0xCF
    db 0

    dw 0x0FFFF
    dw 0
    db 0
    db 0x92
    db 0xCF
    db 0
gdt_end:
toc:
    dw gdt_end - gdt32 - 1
    dd gdt32

bits 32
section .text
start32:
    mov eax, 0xDEADBABA

0 个答案:

没有答案