关于bootsect.S Linux开机过程的分析

发信人:;huzq;(你快乐所以我快乐),;信区:;LINUX;
标 题:;[转载]Linux开机过程的分析;
发信站:;武汉白云黄鹤站;(Sat;Feb;10;14:37:30;2001),;站内信件;

这篇文章的目的,在将linuxkernel的boot部份做一个介绍,因为笔者觉得很少有这样的;
文章介绍一个作业系统最最开始的一步--把kernel本身载入至内存中,同时进行一些机;
器相关(machinedependent)的初始化工作,由于linux刚好使用的是大家最熟悉的386,;
486系列PC,所以在说明其程序流程时,也刚好可以对其相关的PC硬体架构做探讨,可以;
说是一举两得,不过,我必须假设读者对于组合语言及PC最基础的架构,如寄存器,分;
段,分页,中断服务等有大概的认识 。;
读者可在linuxsourcecode的/boot子目录下找到几个以.S作为副档名的组合语言档;
,本文要说明的即是其中的bootsect.S及setup.S两个档案,及尽量简单的说明其所牵涉;
的相关硬体部份 。;
bootsect.S;
这个程序是linuxkernel的第一个程序,包括了linux自己的bootstrap程序,但是在;
说明这个程序前,必须先说明一般IBMPC开机时的动作(此处的开机是指"打开PC的电源";
):;
一般PC在电源一开时,是由内存中地址FFFF:0000开始执行(这个地址一定在ROMBIO;
S中,ROMBIOS一般是在FEOOOh到FFFFFh中),而此处的内容则是一个jump指令,jump到另;
一个位于ROMBIOS中的位置,开始执行一系列的动作,包括了检查RAM,keyboard,显示;
器,软硬磁盘等等,这些动作是由系统测试码(systemtestcode)来执行的,随着制作BI;
OS厂商的不同而会有些许差异,但都是大同小异,读者可自行观察自家机器开机时,萤;
幕上所显示的检查讯息 。;
紧接着系统测试码之后,控制权会转移给ROM中的启动程序(ROMbootstraproutine);
,这个程序会将磁盘上的零道零扇区读入内存中(这就是一般所谓的bootsector,如果你;
曾接触过电脑病毒,就大概听过它的大名),至于被读到内存的哪里呢?--绝对位置07C0;
:0000(即07C00h处),这是IBM系列PC的特性 。而位在linux开机磁盘的bootsector上的正;
是linux的bootsect程序,也就是说,bootsect是第一个被读入内存中并执行的程序 。现;
在,我们可以开始来看看到底bootsect做了什么 。;
第一步;
首先,bootsect将它"自己"从被ROMBIOS载入的绝对地址0x7C00处搬到0x90000处,;
然后利用一个jmpi(jumpindirectly)的指令,跳到新位置的jmpi的下一行去执行,关键;
的assemblycode如下:;
.;
(搬移bootsect本身);
.;
.;
jmpigo,INITSEC;
go:;
.;
.;
.;
表示将跳到CS为0x9000,IP为offset"go"的位置(CS:IP=0x9000:offsetgo),其中I;
NITSEC=0x9000定义于程序开头的部份,而go这个label则恰好是下一行指令所在的位置;
。;
第二步;
接着,将其它segmentregisters包括DS,ES,SS都指向0x9000这个位置,与CS看齐;
。另外将SP及DX指向一任意位移地址(offset),这个地址等一下会用来存放磁盘参数表;
(diskpara-metertable);
提到磁盘参数表,就必须提到BIOS中断1Eh 。先简单的介绍一下BIOS的中断服务:80;
x86将内存最低的256*4byte保留给256个中断向量(每个interruptvector大小为4byte,;
所以一共有256*4=1024byte),而其中的第1Eh个向量指向"磁盘参数表",这个表会告诉;
电脑如何去读取磁盘机,而我们所要做的事是搬移磁盘参数表到刚才所设定的任意地址;
。;
接着,改变搬移来的参数表的参数,以符合我们的需要 。再将中断向量1Eh指向我们;
所修改过的磁盘参数表,然后呼叫BIOSinterrupt的int13h(function0,即AH=0)重置磁;
盘控制卡及磁盘驱动器,之后磁盘机就会照我们的意思动作了 。如果你曾trace过DOS的;

推荐阅读