linux0.11内核代码之bootsect.s

由前面的文章可知,BIOS一个很重要的功能就是读操作系统内核到内存中,然后将控制权交给内核。下面就是具体分析内存最先运行的代码bootsect.s。

1)  bootsect.s代码存储于磁盘的0柱面,0磁道,1扇区中,大小就是1个扇区,即512B。至于为什么bootsect.s位于此扇区,我猜是因为BIOS写死固定从磁盘的第1个扇区读数据。那是怎么把bootsect.s写到此扇区的呢,这其实是build.c函数制作image文件时写入的(具体过程等到分析build.c时再详细介绍,现在只要知道就行)。

2)  BIOS把第1个扇区加载到内存固定的0x7C00处,然后将CPU执行权交给bootsect.s。可能你会问为什么是0x7C00呢,而不是其他地址呢?这个值不是x86 CPU决定的,而是由BIOS决定的。具体原因可以参考http://www.glamenv-septzen.net/en/view/6

3)  正是由于历史原因才把bootsect.s加载到0x7C00处,所以当执行bootsect.s程序第一件事就是将其自己搬移到0x90000处。现在问题来了,代码已经被搬移到了0x90000处,既然已经搬移了,是不是应该到这里执行了呢?是的!对于汇编语言通过jmp家族的指令集可以轻松搞定。可是bootsect.s已经执行了一部分,怎么能让它跳转到应该执行的那一语句继续执行呢?内核代码用于下面非常精妙的语句:表示从段0x7C00处跳转到段0x90000处的偏移地址go处继续执行。即,jmpi是在段0x7C00段执行,而mov ax, cs就是在段0x90000处执行了。

Jmpi go, 0x9000  !jmpi表示段间跳转,go表示段内偏移地址,ox9000表示段基址

Go: mov ax, cs

4)  因为跳到不同的段了,所以还要设置堆栈,因为要把setup.s 2K的代码读到0x90200后,所以栈底指针要设的比这个值大一些。在内核代码将其设置为0x9ff00.

5)  通过BIOS的0x13中断(对于调用格式参考前面BIOS中断大全)来读4个扇区=2kB的setup.s程序到0x90200起始处。

6)  调用BIOS的0x13来读取单个磁道的扇区数。

7)  下面将要读内核代码,由于内核代码相对比较大,需要比较长的时间,为了不让用户误认为死机,调用BIOS的0x10中断去显示“loading system…”

8)  从第5个扇区读内核代码到内存0x10000处,为了缩短读取的时间,采用每次加载一整条磁道的数据。这段代码还是比较复杂的,后面用一篇文章详细介绍。

9)  关闭电机,具体不知道有什么作用。

10)  设置根文件系统设备。将其设置到508,509两个字节。第510,511两个字节设置为硬盘的有效标识0Xaa55.

11)  利用jmpi 0, 0x9020跳转到0x90200处执行

 

从网上收集的关于文件系统和根文件系统的解释

文件系统:是数据保存在设备上所使用的一种组织结构或格式,也可以说是操作系统访问外部设备数据所约定的一种通用访问接口格式

根文件系统:是linux/unix操作系统运行时所需要的特有文件系统。该文件系统不仅具有普通文件系统的存储数据文件的功能,还被操作系统用来存储运行时所需要的一些特殊文件。包括操作系统运行时的配置文件和设备文件。设备文件实际上保存着对就设备的一些接口,并与设备进行交互。因此把根文件系统是linux运行时所必须的

感觉上,先把内核映像文件bootimage加载到内存,注意bootimage是存放在启动软盘上的,由BIOS把bootsect.s读入内存,然后将CPU控制权交给bootsect.s,由其将内核映像文件从启动盘读入内存,等到CPU执行main.c文件时,才加载系统文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值