FreeNOS-kernel目录下boot.S、链接脚本kernel.ld文件分析(四)

上节提到过引导程序在将控制权交给内核时,相关寄存器状态已确定,并且程序入口地址为boot.S文件中的_start,下个面就来看看boot.S文件。

kernel目录下文件如下:在这里插入图片描述
其中Sconscript内容如下:
在这里插入图片描述
可以看到,最终生成的可执行文件的名字为kernel,它的生成依赖很多文件,可以去查看关于scons的语法,其中需要关注的是’ -T kernel/X86/kernel.ld’,ld连接器使用了链接脚本kernel.ld,在上图中:
ENTRY(_start)——ENTRY 接收一个参数_start,它指定了可执行文件的入口符号,_start在boot.S文件中。
SECTIONS 对我们来讲是最重要的。在这里,我们定义即将生成的可执行文件的布局。我们可以定义各个段链接融合的方式以及放置的位置,可以看到,SECTIONS块的起始地址是0x0010000(1MB),结束地址是0x0040000(4MB),其中的关键符号
kernelStart/kernelEnd 、CTOR_LIST/CTOR_END(C++构造函数所在地址段)、DTOR_LIST/DTOR_END(C++析构函数所在地址段)、initStart/initEnd等,都可以在相关的cpp文件中找到定义或者被引用的地方,后续结合源码分析。

既然知道了程序入后地址_start, 那么先来看看boot.S文件:
在这里插入图片描述
结合注释不难看懂此段代码的含义,需要注意的是以下比较指令:
cmpl $ MULTIBOOT_BOOTLOADER_MAGIC, %eax
eax=0x2BADB002,而宏定义MULTIBOOT_BOOTLOADER_MAGIC也为 0x2BADB002,即二者的值相等。
在上一节曾提到过进入_start前的寄存器状态:在这里插入图片描述
然后需要将ebx所指向的Multiboot信息结构体复制到multibootInfo所指内存区,大小为52byte:
在这里插入图片描述
mulitbootInfo是一个struct MultibootInfo:
在这里插入图片描述
现在需要知道的是mulitbootInfo已经被初始化了,给定了从grub传递过来的值。
后面设置GDT、IDT、segments、页目录以及开启页面保护模式,这些知识要找相关书籍了解一下,比较复杂,基本上与linux内核中是一致的,有少部分变动。最后跳转到kmain,也就是最后终于脱离汇编语言,进入到高级语言C++源码部分:
在这里插入图片描述
在这里插入图片描述
看到initStart、initEnd是不是很熟悉,它们在kernel.ld文件中出现过:
在这里插入图片描述
所有被连接器放在__attribute__((section(".init*")))的函数按顺序排列在initStart与initEnd之间,也就是说,
在这里插入图片描述
在这里插入图片描述
调用执行按顺序排列在initStart与initEnd之间函数。
那么函数怎样才能放到initStart与initEnd之间,具体举一个例子说明:在这里插入图片描述
INITACLASS是一个宏,其中Memory是一个类——class Memory, initialize是一个函数——void Memory::initialize(),PMEORY是宏——#define PMEMORY “0”。我们来层层展开宏:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
出现字眼".init" 以及 attribute((section(s))),基本上将宏完整展开就可以发现与以下部分的联系。
initStart = .;
KEEP ((SORT(.init)))
initEnd = .;
基本上其他函数初始化被调用都是使用同样的方法完成的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值