设备环境初始化及激活进程0
引言
设置根设备、硬盘
用bootsect.s
中写入机器系统数据的信息设置软盘为根设备,并设置内核中的硬盘信息。
规划物理内存格局
设置内存中除内核代码和数据之外三部分的位置和大小:
- 主内存区:进程代码运行的空间;
- 缓冲区:主机与外设(块设备)交换数据的中转站;
- 虚拟盘区:可选,可将外设数据先复制至虚拟盘区,然后加以使用。
注:<<12或>>12相当于乘或除以4KB——页
设置虚拟盘空间并初始化
设定内存16MB,虚拟盘2MB(缓冲区末端2MB设为虚拟盘)。调用rd_init()
函数,对虚拟盘设置:
将虚拟盘请求项处理函数do_rd_request
与 请求项处理函数控制结构blk_dev[7]
第二项挂钩,意味着内核能通过调用do_rd_request
函数处理与虚拟盘相关的请求项操作。
内存管理结构 mem_map 初始化
调用mem_init()
函数,通过mem_map[]
对 1MB (内核所在区域)以上的内存分页进行管理,记录一个页面的使用次数
异常处理类中断服务程序挂接
trap_init()
函数将中断、异常处理的服务程序与IDT进行挂接,逐步重建中断服务体系。
其中,还需要拼接中断描述符:
初始化块设备请求项结构
linux外设分为块设备(硬盘、软盘)和字符设备(键盘、黑屏命令行显示器),进程想与块设备进行沟通,必须经过主机内存的缓冲区。
请求项管理结构request[32]
就是操作系统管理缓冲区与块设备逻辑块读写关系的数据结构。操作系统决定缓冲块与块设备间的读写操作,并把需要操作的缓冲块记录在请求项中,得到读写块设备操作指令后,只根据请求项中的记录决定要处理哪个设备的哪个逻辑块。
初始化:
1 | request[i].dev=-1; //请求项未对应哪个设备 |
与人机交互界面相关外设中断服务程序挂接
对串行口、显示器、键盘、开机启动时间设置,以及与此相关的中断服务程序与IDT挂接。
初始化0进程(重要)
大致过程如下,都由sched_init()
函数实现:
- 初始化进程0
- 将进程0的task_struct中LDT、TSS与GDT挂接
- 初始化GDT、task[64]以及与进程调度相关寄存器
- 时钟中断设置 —> 多进程轮转
- 系统调用:通过set_system_gate将system_call与IDT挂接(特权3,set_trap_gate为特权0)
初始化进程0
首先在GDT中初始化进程0所占的4、5项,即初始化TSS0(任务状态段)和LDT0(局部描述符)。
另外,需要拼接对应的段描述符:
然后还需要通过INIT_TASK指针初始化进程0的task_struct(内核栈)。每个进程都有自己的用户栈和内核栈(跑内核代码时用这个)。
设置时钟中断
时钟中断是进程0及其他由它创建的进程轮转的基础。
设置系统调用总入口
将系统调用函数 system_call 与 int 0x80 中断描述符表挂接。