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 一个操做系统的实现》第一章。