Linux内核启动:main函数设置根设备并规划内存
目录
教学视频
1. 楔子
从现在开始执行 main()函数! 目的就是让用户程序能够以“进程”的方式正常运行。能够实现这一目的的标准包括三方面的内容:
-
用户程序能够在主机上进行运算,
-
能够与外设进行交互
-
能够让用户以它为媒介进行人机交互。
所以main函数需要完成对设备环境进行初始化,并激活第一个进程——进程 0。
用户进程运行应该互不干扰,需要要靠系统给进程设计一套“边界” 来对其进行保护。 这套“边界”就是系统为进程提供的进程管理信息数据结构,该结构包括: 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. 设置根设备和硬盘
内核首先初始化根设备和硬盘,用bootsect中写入机器系统数据0x901FC的根设备为软盘/硬盘的信息,设置软盘/硬盘为根设备,并用起始自0x90080的32字节的机器系统数据的硬盘参数表设置内核中的硬盘 信息drive_info。
这里用到了系统开始存储的机器系统数据,我们看一下内存,回忆一下
实现代码如下
存储机器信息如下
3. 规划物理内存
main函数接下来设置缓冲区、虚拟盘、主内存,具体规划如下:除内核代码和数据所占的内存空间之外,其余物理内存主要分为三部分,分别是 主内存区、缓冲区和虚拟盘。
- 主内存区是进程代码运行的空间,也包括内核管理进程的数据结构;
- 缓冲区主要作为主机与外设进行数据交互的中转站;
- “虚拟盘区”是一个可选的区域,如果选择使用虚拟盘,就可以将外设上的数据先复制进虚拟盘区,然后加以使用。由于从内存中操作数据的速度远高于外设,因此这样可以提高系统执行效率。
系统main函数要对主内存中的这三种不同性质的区域,在大小、位置以及管理方式方面进行规划。先 根据内存大小对缓冲区和主内存区的位置和大小进行初步设置。
实现代码如下
<<20 或 >>20 相当于乘或除以1MB
<<12 或 >>12 相当于乘或除以4KB(联想到页)
<<10 或 >>10 相当于乘或除以1KB。
1 << 20 就是 1 MB, EXT_MEM_K << 10 就是 EXT_MEM_K(扩展内存的KB数)的字节数。