
从头写一个操作系统 12
你可能需要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!
Leave 从头写一个操作系统 12 to:
Read more #code posts
Best Posts From geyu
We have not curated any of geyu's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.