1.bootsect.s程序的主要功能:将setup.s和system模块加载到内存中,并且将自身移动到0x90000处,然后控制权交给setup.s程序
2.setup程序:利用BIOS获取硬件参数并保存(main.c会用到的);将system移动到0x00000;描述符表寄存器设置;硬件中断设置;设置CR0进入32位保护模式,控制权交给head.s
3.head.s程序:初步初始化中断描述符表项(哑中断);检查A20;测试是否有协处理器;初始化内存页目录表;跳转到main.c执行内核初始化
系统执行完boot/head.s程序就会将执行权交给main.c
main.c首先利用setup.s取得的系统参数设置系统的根文件设备号以及一些内存全局变量,这些变量指明了主内存的开始地址,系统所拥有的内存容量和作为高速缓存区的末端地址。若定义了虚拟盘,则主内存将适当减少
如同系统功能
高速缓冲区还要扣除被显存和ROM BIOS占用的部分。
高速缓存区是用于磁盘等块设备临时存放数据的地方,以1k字节为数据块单位。
主内存区的内存由内存管理模块mm通过分页机制进行管理分配,以4k字节为一个内存页单位
内核程序可以自由访问高速缓冲区的数据,但需要通过mm才能使用分配到的内存页面
内核进行所有的方面的硬件初始化工作。包括陷阱门,块设备,字符设备,tty,还包括人工设置的第一个任务(task 0).
所有的初始化工作完成后程序就设置中断允许标志以开启中断,并切换到任务0中允许。
在整个内核初始化完成后,内核将执行权切换到用户模式(任务0),
CPU从0特权级切换到了第3个特权级,然后此时main函数工作就在任务0中,最后系统第一次调用 进程创建函数fork(),创建出一个用于运行init()
的子进程(init进程)
内核初始化流程
1.main.c程序首先确定如何分配使用系统物理内存,然后调用内核各部分的初始化函数分别对内存管理、中断处理、块设备和字符设备、进程管理以及硬盘和软盘硬件进行初始化处理。在完成了这些操作之后,系统各部分已经处于可运行状态。此后程序把自己“手工”移动到任务0(进程0)中运行,并使用fork/调用首次创建出进程1(inti进程),并在其中调用min()函数。在该函数中程序将继续进行应用环境的初始化并执行shell登录程序。而原进程0则会在系统空闲时被调度执行,因此进程0通常也被称为idle进程。此时进程0仅执行pause()系统调用,并又会调用调度函数。
2.init 函数的功能可分为4个部分:①安装根文件系统:@显示系统信息;@运行系统初始资源配置文件re中的命令;④执行用户登录shell程序。
3.代码首先调用系统调用setup(),用来收集硬盘设备分区表信息并安装根文件系统。在安装根文件系统之前,系统会先判断是否需要先建立虚拟盘。若编译内核时设置了虚拟盘的大小,并在前面内核初始化过程中已经开辟了一块内存用作虚拟盘,则内核就会首先尝试把根文件系统加载到内存的虚拟盘区中。
4.然后inii打开一个终端设备tty0,并复制其文件描述符以产生标准输入stdin.标准输出stdout和错误输出water设备。内核随后利用这些描述符在终端上显示一些系统信息,例如高速缓冲区中缓冲块总数、主内存区空闲内存总字节数等。
5.接着init又新建了一个进程(进程2),并在其中为建立用户交互使用环境而执行一些初始配置操作,即在用户可以使用shelt命令行环境之前,内核调用/bin/sh程序运行了配置文件et心/c中设置的命令。文件的作用与DOS系统根目录上的AUTOEXEC.BAT文件类似。这段代码首先通过关闭文件描述符D,并立刻打开文件/te陵rù,从而把标准输入stdm定向到etc/re文件上。这样,所有的标准输入数据都将从该文件中读取。然后内核以非交互形式执行/sin/sh,从而实现执行/etc. re文件中的命令。当该文件中的命令执行完毕后,/bin/sh就会立刻退出。因此进程2也就随之结束。
6.init函数的最后一部份用于在新建进程中为用户建立一个新的会话,并运行用户登录shell程序,/bin/sh。在系统执行进程2中的程序时,父进程(mit进程)一直等待着它的结束。随着进程2的退出,父进程就进入到一个无限循环中。在该循环中,父进程会再次生成一个新进程,然后在该进程中创建一个新的会话,并以登录shell方式再次执行程序Dim/sh,以创建用户交互shell环境。然后父进程继续等待该子进程。登录shell虽然与前面的非交互式shell是同一个程序/bin/sh,但是所使用的命令行参数( argV[])不同。登录shelL的第0个命令行参数的第1个字符一定是一个减号比。这个特定的标志会在/bn/h执行时通知它这不是一次普通的运行,而是作为登录sh出l运行Jim/sh的。从这时开始,用户就可以正常使用Linux命令行环境了,而父进程随之又进入等待状态。此后若用户在命令行上执行了exit或Ilogount命令,那么在显示一条当前登录sheel退出的信息后,系统就会在这个无限循环中再次重复以上创建登录shelf进程的过程。
7.任务1中运行的init()函数的后两部分实际上应该是独立的环境初始化程序mit等的功能。
3.内联函数