我正在尝试开发一个操作系统.设计是这样的:我有一个加载在0x7c00的引导程序,它加载第二阶段并在0x7e00跳转到它.第二阶段也处于实模式并且执行许多操作,例如加载gdt,启用A20并切换到保护模式.它还在0x8000处加载一个非常简单的32位内核.现在的问题是我无法调用或jmp到0x8000,因为内核似乎没有加载(我在VirtualBox中进行了内存转储).我已经在第二阶段完成了FAR JMP来设置CS寄存器.我在VirtualBox中测试我的操作系统.
我的启动加载程序的代码:
org 0x7c00 bits 16 Start: jmp Reset bpbOEM DB "SKULLOS " bpbBytesPerSector: DW 512 bpbSectorsPerCluster: DB 1 bpbReservedSectors: DW 1 bpbNumberOfFATs: DB 2 bpbRootEntries: DW 224 bpbTotalSectors: DW 2880 bpbMedia: DB 0xF0 bpbSectorsPerFAT: DW 9 bpbSectorsPerTrack: DW 18 bpbHeadsPerCylinder: DW 2 bpbHiddenSectors: DD 0 bpbTotalSectorsBig: DD 0 bsDriveNumber: DB 0 bsUnused: DB 0 bsExtBootSignature: DB 0x29 bsSerialNumber: DD 0xa0a1a2a3 bsVolumeLabel: DB "MOS FLOPPY " bsFileSystem: DB "SKFS " Set: mov al , 02h mov ah , 00h int 10h jmp Print Print: mov al , 'A' mov bl , 0Fh mov cx , 01h mov ah , 09h int 10h jmp Reset Reset: ; mov dl , 0x00 mov [0x500] , dl mov ah , 0x00 int 0x13 jc Reset mov ax , 0x7E0 mov es , ax xor bx , bx mov ah , 0x02 mov al , 1 mov ch , 0 mov cl , 2 mov dh , 0 mov dl , [0x500] int 0x13 jmp 0x0000 :0x7e00 times 510-($-$$) db 0 db 0x55 db 0xAA
第二阶段代码:
org 0x7E00 bits 16 Start: jmp Setup ;;;;;;;;;;;;;stack;;;;;;;;;; Setup: cli xor ax , ax mov ds , ax mov es , ax mov ax , 0x9000 mov ss , ax mov sp , 0xFFFF sti jmp Set ;;;;;;;;;;;;;video;;;;;;;;;;; Set: mov al , 03h mov ah , 00h int 10h mov ah , 09h mov al , 'A' mov bh , 00h mov bl , 0x0F mov cx , 01h int 10h jmp loadgdt ;;;;;;;;;;;;gdt;;;;;;;;;;;;;;; gdt_start: null: dd 0 dd 0 code: dw 0FFFFh dw 0 db 0 db 10011010b db 11001111b db 0 data: dw 0FFFFh dw 0 db 0 db 10010010b db 11001111b db 0 end: load: dw end - gdt_start -1 dd null ;;;;;;;;;;;;;loadgdt;;;;;;;;;; loadgdt: lgdt [load] jmp A20 ;;;;;;;;;;;;A20;;;;;;;;;;;;;;; A20: mov ax , 0x2401 int 0x15 jc A20 jmp Reset ;;;;;;;;;;;;;floppy;;;;;;;;;;; Reset: mov ah , 00h mov dl , [0x500] int 13h jc Reset jmp Read Read: mov ah , 02h mov al , 01h mov ch , 00h mov cl , 03h mov dh , 00h mov dl , [0x500] mov ax , 0x800 mov es , ax xor bx , bx int 13h jc Read jmp Begin Begin: mov ah , 09h mov al , 'G' mov bh , 00h mov bl , 0x0F mov cx , 01h int 10h jmp protected ;;;;;;;;;;;switching to protected;;;; protected: mov ah , 09h mov al , 'P' mov bh , 00h mov bl , 0x0F mov cx , 01h int 10h xor ax, ax mov ds, ax cli mov eax, cr0 or eax , 1 mov cr0 , eax jmp (code-gdt_start):transfer_control ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bits 32 transfer_control: mov ax, (data-gdt_start) mov ds, ax mov ss, ax mov es, ax mov esp, 90000h mov [0xB8000], word 0x0F58 ; Print 'X' call 0x8000 hlt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; times 512-($-$$) db 0
内核代码:
org 0x8000 bits 32 jmp Start Start: mov ax , 0x10 mov ds , ax mov ss, ax mov es, ax mov esp, 90000h mov [0xB8002], word 0x0F58 ; Print 'X' ret times 512-($-$$) db 0
目前,只打印一个'X'.但是,应打印两个"X".用于创建软盘的命令:
dd seek=0 if=boot of=os.img dd seek=1 if=second_stage of=os.img dd seek=2 if=third_stage of=os.img