【Linux 0.12】初始化程序

初始化程序

源代码 init/ 目录下只有一个 main.c ,系统在执行完 boot/ 目录下的 head.s 程序之后就会将执行权限交给 main.c。该程序完成了内核初始化的所有操作。

功能描述

  1. 设置系统的根文件设备号,和一些内存全局变量

相关信息由 setup.s 程序提供。指明了主内存区的开始抵制,系统拥有的内存容量,以及作为高速缓冲区内存的末端地址。内存映像示意图如图。

系统中内存功能划分示意图

  1. 进行硬件初始化等

陷阱门,块/字符设备,tty,第一个任务 Task0(idle 进程)。

  1. 设置中断允许标志,开启中断
  2. 并切换到 Task0 运行(从内核态切换到用户态,此时 main.c 的主程序运行于任务0)
  3. 调用 fork() 函数创建一个用于运行 init() 的子进程(通常称为 init 进程

内核初始化程序流程示意图

创建新进程的过程是通过完全复制父进程代码段和数据段的方式实现的,因此在首次使用 fork 创建进程 init 时,为了确保新进程用户态栈中没有进程 0 的多余信息,要求进程 0 在创建进程 1 之前不要使用用户态栈(即不要使用函数调用)。

init 函数的功能可以分为四个部分:

  • 安装根文件系统:

调用系统调用 setup() 收集硬盘设备分区表信息并安装根文件系统,在安装根文件系统之前,系统会先判断是否需要建立虚拟盘,则内核就会首先尝试把根文件系统加载到内存的虚拟盘区中。

  • 显示系统信息

init() 打开一个终端设备 tty0,并复制其文件描述符以产生标准输入 stdin,标准输出 stdout,和错误输出 stderror 设备。内核随后利用这些描述符在终端上显示一些系统信息,例如高速缓冲区中缓冲块总数,主内存空间内存总字节数等。

  • 运行系统初始资源配置文件 rc 中的命令
  • 执行用户登录 shell 程序

由于首次从任务 0 fork 生成任务 1 时,数据段和代码段都是完全复制的,所以需要保证任务 0 没有任何多余信息,其中包括栈内容,所以任务 0 不能进行函数调用,而是使用内联函数来执行系统调用。

CMOS(Complementary Metal Oxide Semiconductor):它是指制造大规模集成电路芯片用的一种技术或用这种技术制造出来的芯片,是电脑主板上的一块可读写的RAM芯片。