第2章 设备环境初始化及激活进程0
从现在开始执行main()函数!
系统达到怠速状态前所做的一切准备工作的核心目的就是让用户程序能够以“进程”的方式正常运行。能够实现这一目的的标准包括三方面的内容:用户程序能够在主机上进行运算,能够与外设进行交互,以及能够让用户以它为媒介进行人机交互。本章讲解的内容就是为了实现这个目标,对设备环境进行初始化,并激活第一个进程——进程0。
Linux 0.11是一个支持多进程的现代操作系统。这就意味着,各个用户进程在运行过程中,彼此不能相互干扰,这样才能保证进程在主机中正常地运算。然而,进程自身并没有一个天然的“边界”来对其进行保护,要靠系统“人为”地给它设计一套“边界”来对其进行保护。这套“边界”就是系统为进程提供的进程管理信息数据结构。进程管理信息数据结构包括:task_struct、task[64]、GDT等。task_struct是每个进程所独有的结构。它标识了进程的各项属性值,包括剩余时间片、进程执行状态、局部数据描述符表(LDT)和任务状态描述符表(TSS)等。task[64]和GDT是为管理多进程提供的数据结构。task[64]结构中存储着系统中所有进程的task_struct指针。如果操作系统需要对多个进程加以比较并选择,就可以通过遍历task[64]结构来实现。GDT中存储着一套针对所有进程的索引结构。通过索引项,操作系统可以间接地与每个进程中的LDT和TSS建立关系。
本章还将讲解操作系统是如何对内存、CPU、串行口、显示器、键盘、硬盘、软盘等硬件进行设置,并将这些硬件所对应的中断服务程序与IDT相挂接,为进程0及其直接、间接创建的所有后续进程与外设沟通构建环境。
2.1 设置根设备、硬盘
内核首先初始化根设备和硬盘,用bootsect中写入机器系统数据0x901FC (见1.2.3节)的根设备为软盘的信息,设置软盘为根设备,并用起始自0x90080 的32字节的机器系统数据的硬盘参数表设置内核中的硬盘信息drive_info。
具体执行代码如下:
- //代码路径:init/main.c:
- …
- #define DRIVE_INFO (*(struct drive_info *)0x90080)//硬盘参数表,参看机器系统数据
- #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)//根设备号
- …
- struct drive_info { char dummy[32]; } drive_info;//存放硬盘参数表的数据结构
- void main(void)
- {
- ROOT_DEV= ORIG_ROOT_DEV; //根据bootsect中写入机器系统数据的信息设置根设备为软盘
- drive_info= DRIVE_INFO; //的信息,设置为根设备
- …
- }
设置根设备为软盘以及设置硬盘参数表完成后的数据在内存中的位置如图2-1所示。