从头写一个操作系统 12 (create an OS from scratch 12)

你可能需要google: kernel, ELF format, makefile

目标: 写一个简单的kernel,让bootsect启动它

The kernel

我们用C语言写的内核只能做一点点事,就是在屏幕左上角打印一个'X',打开这个kernel.c

你会发现第一个函数中什么都没写,这个函数创建了指向main函数的内核入口。

添加-g的原因是在调试中需要用到这些信息,最后链接器链接kernel.o 与kernel_entry.o时会用到这些信息生成.elf,而这个.elf最终会用在gdb remote 到qemu中调试时用到。

i386-elf-gcc -g -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文件,并且解析标签,运行:

注意:这里的kernel_entry.o kernle.o两个文件的顺序不能颠倒,否则程序找不到入口!

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!

用qemu运行!

注意,如果你遇到硬盘载入错误之类的情况,可能需要调整硬盘的编号或者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]

Concepts you may want to Google beforehand: kernel, ELF format, makefile

Goal: Create a simple kernel and a bootsector capable of booting it

The kernel

Our C kernel will just print an 'X' on the top left corner of the screen. Go ahead and open kernel.c.

You will notice a dummy function that does nothing. That function will force us to create a kernel entry routine which does not point to byte 0x0 in our kernel, but to an actual label which we know that launches it. In our case, function main().

i386-elf-gcc -ffreestanding -c kernel.c -o kernel.o

That routine is coded on kernel_entry.asm. Read it and you will learn how to use [extern] declarations in assembly. To compile this file, instead of generating a binary, we will generate an elf format file which will be linked with kernel.o

nasm kernel_entry.asm -f elf -o kernel_entry.o

The linker

A linker is a very powerful tool and we only started to benefit from it.

To link both object files into a single binary kernel and resolve label references, run:

i386-elf-ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary

Notice how our kernel will be placed not at 0x0 in memory, but at 0x1000. The bootsector will need to know this address too.

The bootsector

It is very similar to the one in lesson 10. Open bootsect.asm and examine the code. Actually, if you remove all the lines used to print messages on the screen, it accounts to a couple dozen lines.

Compile it with nasm bootsect.asm -f bin -o bootsect.bin

Putting it all together

Now what? We have two separate files for the bootsector and the kernel?

Can't we just "link" them together into a single file? Yes, we can, and it's easy, just concatenate them:

cat bootsect.bin kernel.bin > os-image.bin

Run!

You can now run os-image.bin with 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

You will see four messages:

  • "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!

Makefile

As a last step, we will tidy up the compilation process with a Makefile. Open the Makefile script and examine its contents. If you don't know what a Makefile is, now is a good time to Google and learn it, as this will save us a lot of time in the future.


参考资料:
[1]:https://github.com/cfenollosa/os-tutorial/blob/master/12-kernel-c

版权注明:本文所有涉及到:https://github.com/cfenollosa/os-tutorial/ git仓库的内容,全部对应以下开源协议声明:
BSD 3-Clause License
Copyright (c) 2018,
Carlos Fenollosa

你可能感兴趣的:(从头写一个操作系统 12 (create an OS from scratch 12))