从头写一个操作系统 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容