bootasm.asm使用了nasm格式代碼,做用是切換到vga顯示模式,開啓A20地址線,設置GDT,進入保護模式,跳入32位彙編代碼段,調用C語言編寫的函數。shell
代碼以下:ubuntu
extern bootmain [bits 16] global start start: ; 切換顯示模式,320*200*8位彩色模式 ; 來自於《30天自制操做系統》 mov al, 0x13 mov ah, 0x00 int 0x10 ; 下面代碼來自於XV6 cli xor ax, ax mov ds, ax mov es, ax mov ss, ax ; 我的感受這段開啓A20的代碼比網上的使用CALL的代碼清晰、易懂 seta20.1: in al, 0x64 test al, 0x2 jnz seta20.1 mov al, 0xd1 out 0x64, al seta20.2: in al, 0x64 test al, 0x2 jnz seta20.2 mov al, 0xdf out 0x60, al ; 加載GDT lgdt [gdtdesc] ; 開啓保護模式 mov eax, cr0 or eax, 1 mov cr0, eax ; 進入保護模式 jmp dword 8:start32 [bits 32] start32: ; 初始化非代碼段寄存器 mov ax, 0x10 mov ds, ax mov es, ax mov ss, ax mov ax, 0 mov fs, ax mov gs, ax ; 設置棧頂 mov esp, start ; 調用C語言中的函數 call bootmain spin: jmp spin gdt: dw 0x0000, 0x0000, 0x0000, 0x0000 dw 0xffff, 0x0000, 0x9a00, 0x00cf ; 代碼段 dw 0xffff, 0x0000, 0x9200, 0x00cf ; 數據段 gdtdesc: dw (gdtdesc - gdt - 1) dd gdt
來至於《30天自制操做系統》第四章的生成條紋圖案的代碼以下:函數
void bootmain(void) { int i; char *p; p = (char *) 0xa0000; for (i = 0; i <= 0xffff; i++) { *(p + i) = i & 0x0f; } }
環境是:工具
ubuntu 14.04 32位版,64位的生成32位的代碼比較麻煩,其餘工具都是apt-get安裝的。
ui
編譯鏈接方法以下:操作系統
nasm -f elf bootasm.asm -o bootasm.o gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -O -nostdinc -I. -c bootmain.c ld -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o objcopy -S -O binary -j .text bootblock.o bootblock ./sign.pl bootblock ; 這個使用了XV6的一個腳本,截取文件開始的512個字節,並將截取後文件的最後兩個字節設置成0xAA55。 dd if=bootblock of=a.img bs=512 count=1 conv=notrunc ; 參照於淵老師的《Orange's 一個操做系統的實現》第一章。