我开始完全用汇编创建一个操作系统,我想完全在实模式下完成它,但是当我意识到我所拥有的限制时,我决定在实模式下创建引导加载程序,在保护模式下创建内核 我尝试在引导加载程序中设置 gdt,但似乎不起作用。你能告诉我为什么吗?
这是代码
bootloader.asm:
bits 16
section .boot
global _start
KERNEL_ADDRESS equ 0x7E00
_start:
cld
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 9000h
mov di, 5 ; Allow 5 tries
BOOT_TryNext:
mov dh, 0 ; CHS = (0,0,2), DL is drive number from BIOS
mov cx, 0002h
mov bx, 7E00h ; ES:BX is buffer
mov ax, 0201h ; BIOS.ReadDiskSector
int 13h ; -> AX CF
jnc BOOT_Loaded
mov ah, 00h ; BIOS.ResetDiskSystem
int 13h ; -> AH CF
dec di
jnz BOOT_TryNext
BOOT_Exit:
call BOOT_notLoaded
BOOT_Exit_Loop:
cli
hlt
jmp BOOT_Exit_Loop
BOOT_Loaded:
GDT_Start:
null_descriptor:
dd 0
dd 0
code_descriptor:
dw 0xffff
dw 0
db 0
db 10011010
db 11001111
db 0
data_descriptor:
dw 0xffff
dw 0
db 0
db 10010010
db 11001111
db 0
GDT_End:
GDT_Descriptor:
dw GDT_End - GDT_Start - 1
dd GDT_Start
CODE_SEG equ code_descriptor - GDT_Start
DATA_SEG equ code_descriptor - GDT_Start
cli
lgdt [GDT_Descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:boot_trampoline
boot_trampoline:
; Setup dei segmenti per il kernel
mov ax, DATA_SEG ; Carica il segmento dati del kernel
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Imposta lo stack pointer per il kernel
mov ax, KERNEL_STACK_SIZE
mov ss, ax
mov sp, KERNEL_STACK_START
; Salta al kernel
jmp KERNEL_ADDRESS
; Definisci le costanti per lo stack del kernel
KERNEL_STACK_SIZE equ 0x1000 ; Dimensione dello stack del kernel (4KB)
KERNEL_STACK_START equ 0x8000 - KERNEL_STACK_SIZE
BOOT_notLoaded:
pusha
mov ax, 0x0700 ; function 07, AL=0 means scroll whole window
mov bh, 0x07 ; character attribute = white on black
mov cx, 0x0000 ; row = 0, col = 0
mov dx, 0x184f ; row = 24 (0x18), col = 79 (0x4f)
int 10h ; call BIOS video interrupt
popa
mov ah, 0x02
xor bh, bh
xor dx, dx
int 10h
mov si, boot_err
mov ah, 0x0e
boot_characterLoop2:
lodsb
or al, al
jz BOOT_Exit_Loop
int 10h
jmp boot_characterLoop2
boot_msg: db "Il sistema operativo e' stato caricato correttamente!", 0
boot_err: db "Il sistema operativo non e' stato caricato correttamente!", 0
times 510-($-$$) db 0
dw 0xAA55
内核.asm:
bits 32
section .kernel
global _start_kernel
_start_kernel:
mov al, 'A'
mov ah, 0x0f
mov [0xb8000], ax
链接器.ld:
OUTPUT_FORMAT(binary)
ENTRY(_start)
SECTIONS
{
. = 0x7c00;
bootloader :
{
bootloader.bin(.boot)
}
kernel :
{
kernel.bin(.kernel)
}
/DISCARD/ :
{
*(.bss*);
*(COMMON*);
}
}
生成文件:
boot = bootloader.asm
kernel = kernel.asm
boot_o = bootloader.bin
kernel_o = kernel.bin
bin = myos.bin
asm_compiler = nasm
qemu = qemu-system-i386
compile:
$(asm_compiler) -f elf32 -g $(boot) -o $(boot_o)
$(asm_compiler) -f elf32 -g $(kernel) -o $(kernel_o)
ld -m elf_i386 -nmagic -T linker.ld -o $(bin) $(boot_o) $(kernel_o)
run:
$(qemu) -fda $(bin)
clean:
-rm $(boot_o)
-rm $(kernel_o)
-rm $(bin)