启动引导程序——linux 0.12
时间:2009-06-02 来源:walker_wu
bootsect.s完成如下功能:
一. bootsect.s将它“自己“从被ROM BIOS载入的绝对地址0x7C00处搬到0x9000处,然后利用一个jmpi(jump indirectly)的指令,跳到新位置的jmpi的下一行(go:)去执行。
二. 接着,将其他segment registers包括DS,ES,SS都指向0x9000这个位置,与CS看齐。另外将SP及DX指向一任意位移地址( offset ),这个地址等一下会用来存放磁盘参数表(disk para- meter table )。设置堆栈段,且开始处为0x4000-12。
三. 读入磁盘参数,并建立参数表。
四. 接着利用BIOS中断服务int 13h的第0号功能,重置磁盘控制器,使得刚才的设定发挥功能。
五. 完成重置磁盘控制器之后,bootsect就从磁盘上读入紧邻着bootsect的setup程序,也就是setup.S,此读入动作是利用BIOS中断服务int 13h的第2号功能。setup的image将会读入至程序所指定的内存绝对地址0x90200处,也就是在内存中紧邻着bootsect 所在的位置。待setup的image读入内存后,利用BIOS中断服务int 13h的第8号功能读取目前磁盘的参数。
六. 再来,就要读入真正linux的kernel了,也就是你可以在linux的根目录下看到的“vmlinuz“ 。在读入前,将会先呼叫BIOS中断服务int 10h 的第3号功能,读取游标位置,之后再呼叫BIOS 中断服务int 10h的第13h号功能,在萤幕上输出字串“Loading“,这个字串在boot linux时都会首先被看到。
七. 接下来做的事是检查root device,之后就仿照一开始的方法,利用indirectjump 跳至刚刚已读入的setup.s部份。
在程序bootsect.s执行完以后(setup.s的前4个扇区的内容已被读入),setup.s紧接着开始执行。它负责从BIOS中获取系统信息,并且将它们存放到内存中适当的地方。它完成如下一些主要功能:
一. 检测setup.s的代码是否已完全被读入,如果没有的话,则查找其余部分代码。并将它自己的其余部分移动到内存中紧邻着先前被读入的4个扇区的内容后面。
二. 检测键盘、显示适配器、PS/2设备、Micro Channel(mca) bus,获取内存长度(以kb计算)。
三. 检查系统是否已被移动到了正确的地方,假如代码没有被准确移动到0x90000这个地方,我们则需要把代码移动到那个地方。当然在这以前,首先得检验我们调用的是否是bing-kernel。 head.s程序在被编译生成目标文件后会与内核其他程序一起被链接成system模块。
一、加载各个数据段寄存器,重新设置中断描述表idt, 共256项,并使各个表项均指向一个只报错误的哑中断子程序 ignore_int。
二、重新设置全局段描述表gdt。
三、使用物理地址0与1MB开始处的字节内容相比较,检测A20地址线是否已真的开启。若没有开启,则在访问高于1MB物理内存地址时CPU实际只会循环访问(IP MOD 1MB)地址处的内容,即与访问从0地址开始对应字节的内容都相同。
四、设置管理内存的分页处理机制。
五、head.s程序利用返回指令将预先放置在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序。
一. bootsect.s将它“自己“从被ROM BIOS载入的绝对地址0x7C00处搬到0x9000处,然后利用一个jmpi(jump indirectly)的指令,跳到新位置的jmpi的下一行(go:)去执行。
二. 接着,将其他segment registers包括DS,ES,SS都指向0x9000这个位置,与CS看齐。另外将SP及DX指向一任意位移地址( offset ),这个地址等一下会用来存放磁盘参数表(disk para- meter table )。设置堆栈段,且开始处为0x4000-12。
三. 读入磁盘参数,并建立参数表。
四. 接着利用BIOS中断服务int 13h的第0号功能,重置磁盘控制器,使得刚才的设定发挥功能。
五. 完成重置磁盘控制器之后,bootsect就从磁盘上读入紧邻着bootsect的setup程序,也就是setup.S,此读入动作是利用BIOS中断服务int 13h的第2号功能。setup的image将会读入至程序所指定的内存绝对地址0x90200处,也就是在内存中紧邻着bootsect 所在的位置。待setup的image读入内存后,利用BIOS中断服务int 13h的第8号功能读取目前磁盘的参数。
六. 再来,就要读入真正linux的kernel了,也就是你可以在linux的根目录下看到的“vmlinuz“ 。在读入前,将会先呼叫BIOS中断服务int 10h 的第3号功能,读取游标位置,之后再呼叫BIOS 中断服务int 10h的第13h号功能,在萤幕上输出字串“Loading“,这个字串在boot linux时都会首先被看到。
七. 接下来做的事是检查root device,之后就仿照一开始的方法,利用indirectjump 跳至刚刚已读入的setup.s部份。
在程序bootsect.s执行完以后(setup.s的前4个扇区的内容已被读入),setup.s紧接着开始执行。它负责从BIOS中获取系统信息,并且将它们存放到内存中适当的地方。它完成如下一些主要功能:
一. 检测setup.s的代码是否已完全被读入,如果没有的话,则查找其余部分代码。并将它自己的其余部分移动到内存中紧邻着先前被读入的4个扇区的内容后面。
二. 检测键盘、显示适配器、PS/2设备、Micro Channel(mca) bus,获取内存长度(以kb计算)。
三. 检查系统是否已被移动到了正确的地方,假如代码没有被准确移动到0x90000这个地方,我们则需要把代码移动到那个地方。当然在这以前,首先得检验我们调用的是否是bing-kernel。 head.s程序在被编译生成目标文件后会与内核其他程序一起被链接成system模块。
一、加载各个数据段寄存器,重新设置中断描述表idt, 共256项,并使各个表项均指向一个只报错误的哑中断子程序 ignore_int。
二、重新设置全局段描述表gdt。
三、使用物理地址0与1MB开始处的字节内容相比较,检测A20地址线是否已真的开启。若没有开启,则在访问高于1MB物理内存地址时CPU实际只会循环访问(IP MOD 1MB)地址处的内容,即与访问从0地址开始对应字节的内容都相同。
四、设置管理内存的分页处理机制。
五、head.s程序利用返回指令将预先放置在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序。
相关阅读 更多 +