一個操做系統的實現-筆記

開發環境

操做系統:32位ubuntu 彙編編譯器:nasm 虛擬機: bochsubuntu

版本0.1

代碼以下

; kernel.asm
; nasm -f elf kernel.asm -o kernel.o
; ld -s -Ttext 0x10000 kernel.o -o kernel.bin
; dd if=kernel.bin of=a.img bs=512 seek=1 conv=notrunc

[bits 32]
[section .text]

global _start

_start:
    mov ax, 24
    mov gs, ax

    mov edi, (80 * 11 + 79) * 2
    mov ah, 0x0c
    mov al, 'K'
    mov [gs:edi], ax

end:
    hlt
    jmp end

經過readelf -a kernel.bin命令,能夠獲得代碼在文件kernel.bin中的偏移量。 本例編譯後爲0x1000, 將它除以扇區大小(512),獲得8,由於kernel.bin在引導扇區後面,還要加一。 因此代碼在第十個扇區。 bootsec.asm 文件編譯後,做爲軟盤的引導扇區。ide

; nasm bootsec.asm -o bootsec.bin
; dd if=bootsec.bin of=a.img bs=512 count=1 conv=notrunc

org 0x7c00

jmp start

gdt:
    dw 0
    dw 0
    dw 0
    dw 0
gdt_code:
    dw 0xffff
    dw 0x0000
    dw 0x9a00
    dw 0x00cf
gdt_data:
    dw 0xffff
    dw 0x0000
    dw 0x92c0
    dw 0x00cf
gdt_video:
    dw 0xffff
    dw 0x8000
    dw 0x920b
    dw 0x0000

gdtlen equ $ - gdt
gdtptr dw gdtlen -1
       dd 0
; 使用0x13中斷,將軟盤的第十個扇區讀入內存0x10000處。
start:
    mov ax, 0x1000
    mov es, ax
    mov bx, 0

    mov ax, 0x0201
    mov cx, 0x000a
    mov dx, 0

    int 0x13

into_kernel:
    xor eax, eax
    mov ax, cs
    shl eax, 4
    add eax, gdt
    mov dword [gdtptr + 2], eax

    lgdt [gdtptr]

    cli

    in al, 0x92
    or al, 00000010b
    out 0x92, al

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

    jmp dword 0x8:0x10000

fill:
   times 510-($ - $$) db 0
   dw 0xaa55

下面代碼中,9200寫成92c0,結果在加載IDT的時候,死活加載不上,坑了兩天。操作系統

gdt_data:
    dw 0xffff
    dw 0x0000
    dw 0x92c0
    dw 0x00cf
相關文章
相關標籤/搜索