引言

设置根设备、硬盘

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
2
request[i].dev=-1; //请求项未对应哪个设备
request[i].next=NULL; //还未形成请求项队列

与人机交互界面相关外设中断服务程序挂接

对串行口、显示器、键盘、开机启动时间设置,以及与此相关的中断服务程序与IDT挂接。

初始化0进程(重要)

大致过程如下,都由sched_init()函数实现:

  1. 初始化进程0
    • 将进程0的task_struct中LDT、TSS与GDT挂接
    • 初始化GDT、task[64]以及与进程调度相关寄存器
  2. 时钟中断设置 —> 多进程轮转
  3. 系统调用:通过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 中断描述符表挂接。