系统初始化 —— 上电

读内核源代码是一件很有意思的事。它像一条线,把操作系统,编译原理,汇编语言,计算机组成原理,C 语言,数据结构与算法,计算机系统结构等等计算机的基础课程串起来。而分析linux的启动很重要,因为牵涉到硬件的初始化和内核各模块初始化环境的搭建,所以我们就针对linux/arch/x86下的代码,对从打开PC电源到屏幕上出现shell环境,来对整个Linux的初始化过程进行一个全方位的分析,希望能有帮助,不足之处,还请各位网友不吝赐教。

 

1 引子

目前,市面上的大多数计算机系统的内存都是“随机性”的:一旦关机断电,存储在内存中的信息、连同操作系统本身都会丢失。所以,必须把操作系统(内核)的程序存储在某种永久性的介质中,使得开机加电时有一个从不挥发介质装入操作系统、并转入运行的过程,这个过程就叫做“引导”(bootload,或boot),也称为“自举”。

 

1.1 上电

我们只关注x86体系的这个过程,CPU所在的主板会有一个特殊的硬件电路在CPURESET引脚上产生一个电平。这时,CPU处于实地址模式中,并开始自检,自检的最后一个步骤是把一些寄存器(如cseip)设置成固定值。我们知道,实模式下的寻址方法是16位段寄存器左移4位加上16位偏移构成具有能寻址1MB能力的20位地址。所以,刚开始时,复位输入提供一种初始化的硬件手段:标志寄存器设为0xuuuu0002(u代表未定义,实模式下9位标志可用,这里是奇偶标志为1);指令指针eip设为0x0000fff0CS寄存器设为0xf000DSSSESFSGS寄存器都设为0x0000,指令队列清空。

 

CPU在识别出Reset信号后把数据总线设在高阻状态,地址线强行设为1。由于清空中断标志是初始化的一部分,外部中断被禁止。因为代码段寄存器为0xf000,指令指针为0x0000fff0,地址线A20-A31全部是1,从而复位后实模式程序从地址0xfffffff0开始(注意,只用于实模式高地址位忽略,从地址0xffff0开始)。该地址处可以包含一条转移指令跳到启动程序处。

 

那么,这段程序要有多大呢?这就要看具体的设计了。在早期的计算机中这段程序般都很小,例如2K字节或者史小,甚至于只有几条指令(我们的胡希明老同志回忆起70年代中美建交后进入中国的NOVA机,由此而来的国产机名为DJS-130,操作系统为RTOS,引导程序只有13条指令,当时称初始引导13条,亦称手拨13条。13条指令执行结果是通过光电读入机把存放在穿孔纸带上的RTOS执行码装入内存)。这是因为早期的PROMEPROM的容量都很小,并且其目的和功能也很单一。

 

我们在“PC存储器”一篇博文中讲到,ROMRAM扩展成一个整体的内存系统,这个ROM的地址是32位的,况且开机时CPU只运行在实模式下,高12位全被置1那么线性地址0xffff0对应的物理地址就是0xfffffff0,定位到这个ROMROM中所存放的程序集在80x86体系中通常叫做基本输入/输出系统(Basic Input/Output System, BIOS),因为它包括几个中断驱动的低级过程。比如,执行INT 10H,就是显示服务,10H是中断类型号,在运行以下流程:

(SP)(SP) - 2                SP - 2

((SP+1),(SP))(PSW)  ;标志位寄存器内容进栈

IF0, TF0          ;清除中断和陷阱标志

(SP)(SP) - 2                SP - 2

((SP+1),(SP))(CS)    CS入栈

(SP)(SP) – 2        SP - 2

((SP+1),(SP))(IP)      IP入栈

(IP)(TYPE*4)        ;取中断服务程序偏移地址,这里的TYPE10H

(CS)(TYPE*4 + 2)     ;取中断服务程序段地址,这里的TYPE10H

……                ;开始执行位于ROMBIOS中断服务程序

(SP)(SP) + 2          SP + 2

(IP)((SP-1),(SP))    IP出栈

(SP)(SP) + 2          SP + 2

(CS)((SP-1),(SP))    CS出栈

IF1, TF1         ;设置中断和陷阱标志

(SP)(SP) + 2          SP + 2

(PSW)((SP-1),(SP))  ;标志位寄存器内容出栈

 

不管LinuxMS-DOS还是Windows,在启动时,都要通过这些过程对计算机硬件设备初始化。Linux一旦进入了保护模式,就不再使用BIOS,而是为计算机上的每个硬件设备提供各自的设备驱动程序。

你可能感兴趣的:(疯狂内核之系统初始化)