你可能需要google: kernel, ELF format, makefile
目标: 写一个简单的kernel,让bootsect启动它
The kernel
我们用C语言写的内核只能做一点点事,就是在屏幕左上角打印一个'X',打开这个kernel.c。
你会发现第一个函数中什么都没写,这个函数创建了指向main函数的内核入口。
i386-elf-gcc -ffreestanding -c kernel.c -o kernel.o
调用main的程序是 kernel_entry.asm。打开学习学习汇编中[extern]声明的用法。编译这个文件的elf格式生成kernel.o,注意,这次的最终文件不是.bin的机器码文件。
nasm kernel_entry.asm -f elf -o kernel_entry.o
The linker
链接器是非常有用的工具,我们刚才只使用到它一点点能力。
要链接两个.obj文件,并且解析标签,运行:
i386-elf-ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary
注意,内核代码可不是被放在内存的0x0位置上,而是放在了0x1000,(译注:进入保护模式后会跳转到这个地址执行内核代码,指定地址后,链接器会将所有跳转(段内)指令的目标地址加上0x1000)。引导程序需要知道这个地址。这和lesson10中bootsect.asm很像。
The bootsector
编译它:
nasm bootsect.asm -f bin -o bootsect.bin
Putting it all together
现在我们分别由两个文件,bootsecto 和 kernel。
可以直接link它们吗?哈哈,当然,把他们接在一起就可以:
cat bootsect.bin kernel.bin > os-image.bin
Run!
You can now run os-image.bin with qemu.
用qemu运行!
Remember that if you find disk load errors you may need to play with the disk numbers or qemu parameters (floppy = 0x0, hdd = 0x80). I usually use qemu-system-i386 -fda os-image.bin
注意,如果你遇到硬盘载入错误之类的情况,可能需要调整硬盘的编号或者qemu的参数,我通常这么做:
qemu-system-i386 -fda os-image.bin
如果成功,会看到如下信息:
- "Started in 16-bit Real Mode"
- "Loading kernel into memory"
- (Top left) "Landed in 32-bit Protected Mode"
- (Top left, overwriting previous message) "X"
Congratulations!