我是一个学习操作系统开发的新手。从我所读的书中得知,引导加载程序将把第一个MBR复制到0x7c00,并在实模式下从那里启动。
而且,示例开始于16位汇编代码。 但是,当我看今天的Linux内核时,arch/x86/boot有 'header.S' 和 'boot.h' 文件,但实际代码是在'main.c'文件中实现。
这似乎通过“不写汇编”很有用。
但是,Linux是如何做到这一点的呢?
我大致能想象出可能有特殊的gcc
选项和链接策略,但我看不到细节。
我是一个学习操作系统开发的新手。从我所读的书中得知,引导加载程序将把第一个MBR复制到0x7c00,并在实模式下从那里启动。
而且,示例开始于16位汇编代码。 但是,当我看今天的Linux内核时,arch/x86/boot有 'header.S' 和 'boot.h' 文件,但实际代码是在'main.c'文件中实现。
这似乎通过“不写汇编”很有用。
但是,Linux是如何做到这一点的呢?
我大致能想象出可能有特殊的gcc
选项和链接策略,但我看不到细节。
.ld
扩展名。这驱动了将所有目标文件组合在一起的过程,并以与传统的BIOS引导过程(在0x07c00处以实模式运行的代码)兼容的方式进行。
这样做有很多陷阱,我建议不要这样做。如果您打算编写32位或64位内核,则建议不要编写自己的引导加载程序,而是使用现有的引导加载程序,例如GRUB。在20世纪90年代的Linux版本中,它有自己的引导加载程序,可以从软盘执行。现代Linux依赖于第三方引导加载程序来完成大部分工作。特别是它支持符合Multiboot规范的引导加载程序。
互联网上有许多使用GRUB作为引导程序的教程。OS Dev Wiki是一个非常宝贵的资源。他们有一个Bare Bones教程,使用原始的Multiboot规范(由GRUB支持)来引导基本内核。Multiboot规范可以很容易地使用最少的汇编语言代码进行开发。与Multiboot兼容的引导程序将自动将CPU置于保护模式,启用A20线路,可用于获取内存映射,并可在启动时告诉它将您放置在特定的视频模式中。
.S
文件是汇编文件(你将看到相当数量的汇编代码来调用C语言中的main
函数)。header.S
可以在编译期间用作实模式引导程序。真正的魔法在于创建一个链接器文件,在你的情况下是setup.ld
,它可以正确地构建带有代码和数据的对象,并将它们放在特定的位置。所有的C语言代码都必须使用BIOS例程或直接硬件访问来完成。 - Michael Petchboot.h
文件中。 - Michael Petch