从头写一个操作系统 12

By @geyu4/17/2019code

你可能需要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

现在我们分别由两个文件,bootsectokernel
可以直接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!

THE ORIGIN ARTICALE IN GITHUB:[^1]

8

comments