我正在使用https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf作为我的教科书从头开始编写基本内核。我已经编写了基本的16位引导加载程序,我只是根据本文编写了切换到保护模式的代码。它定义了一个基本的通用描述符表,加载它,并在cr0特殊寄存器中翻转一下。但是,当我尝试启动代码时,我会在屏幕底部反复出现光标。我无法理解,因为我还没有显示任何内容。当我试图显示一个字符串时,我只得到了屏幕底部的光标。这是我的一些代码。
BITS 16
; switch to 32 bit protected mode
switch_to_pm:
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 0x1
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
;mov esp, ebp
BEGIN_PM:
;mov ebx, 0xb8000
;mov ah, 0x0f
;mov al, '3'
;mov [ebx], ax
;add ebx, 2
;mov al, '2'
;mov [ebx], ax
jmp $
这是进行切换的部分。它从主boot_loader文件中调用。如果需要该代码,我可以编辑我的问题以包含它。感谢你们。我真的无法弄清楚问题,但这是我第一次编写32位启动加载程序。
boot_loader.asm:
BITS 16
[org 0x7c00]
start:
mov [BOOT_DRIVE], dl
mov bp, 0x9000 ; setup our stack
mov sp, bp
mov dl, [BOOT_DRIVE]
call disk_load
call switch_to_pm
jmp $
disk_load:
push dx
mov bx, 0x1000 ; adress to write to
mov dh, 15 ; # sectors to read
mov ah, 0x02 ; sector to start at ??
mov al, dh ; same # sectors
mov ch, 0x00 ; cylinder to read ?
mov dh, 0x00 ; head to read (switch?)
mov cl, 0x02 ; sector to start at ??
int 0x13
jc disk_error
pop dx
cmp dh, al
jne disk_error
ret
disk_error:
mov ah, 0x0e
mov bx, DISKERR
sub bx, 1
disk_error_print:
add bx, 1
cmp byte [bx], 0x0
je disk_error_done
mov al, [bx]
int 0x10
jmp disk_error_print
disk_error_done:
jmp $
%include "boot/gdt.asm"
%include "boot/switch_to_pm.asm"
; Global vars
BOOT_DRIVE: db 0
DISKERR:
db "error reading disk" , 0
; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55
db "hello"
gdt.asm:
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code: ; the code segment descriptor
dw 0xffff
dw 0x0
dw 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data: ; the data segment descriptor
dw 0xffff
dw 0x0
dw 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start