板级初始化即 hal 层(硬件抽象层)初始化,其中执行了平台初始化,hal层的内存初始化,中断初始化,最后是内核层初始化。
1 hal_start.c
该文件中只有这一个函数,调用函数用于初始化hal层和内核层:
2 hal 层初始化
为了分离硬件的特性,设计了hal层,把硬件相关的操作集中在这个层,并向上提供接口,目的是让内核上层不用关注硬件相关的细节,也方便移植和扩展。
3 init_hal
该文件中也只有这一个函数,调用函数用于初始化hal层的初始化:
3.1 初始化平台
主要负责两个任务:
1) 把二级引导器建立的机器信息结构复制到hal层中的一个全局变量中,方便内核中其他代码使用里面的信息,之后二级引导器建立的数据占用的内存都会被释放。
2) 初始化图形显示驱动,内核在运行过程中要在屏幕上输出信息。
3.1.1 halplatform.c
这个文件的代码负责平台初始化,平台初始化分两步走,先初始化机器信息结构,再初始化图形显示驱动:
初始化机器信息结构体主要有两个步骤:
1) 清零虚拟地址处的机器信息结构体
2) 将物理地址处的机器信息结构拷贝到虚拟地址处,即将物理地址转换成虚拟地址。
其中,kmachbsp是一个hal层的全局变量,结构体类型同kmbsp,是用来存储虚拟地址处机器信息结构。
3.1.2 bdvideo.c
这个文件中有init_bdvideo函数,用于初始化图形显示驱动。即初始化kdftgh这个全局变量。
3.2 初始化内存
hal的内存初始化只需要向内存管理器提供内存空间布局信息。之前在二级引导器中已经获取了内存布局信息(遗憾的是我没看懂),但Cosmos的内存管理器需要保存更多的信息,最好是顺序的内存布局信息,这样可以增加额外的功能属性,同时降低代码复杂度(没懂为啥)。
综上所述,hal的内存初始化就是以BIOS提供的结构为基础,设计一套新的数据结构(牛哇)
3.2.1 halmm.c
init_phtmmarge函数负责初始化 phymmarge_t 结构体,这个函数所做的事情主要是以 mbsp 机构图中的机器信息结构为基础,对 phymmarge_t 结构体进行了初始化。初始化代码如下图所示:
3.3 初始化中断
中断分为两种,一种是异常,是同步的,产生原因是错误或故障,有时也会是 CPU 通过陷阱指令主动发起异常。另一种是由外部事件产生的中断,是异步的,因为不确定何种设备何时发出中断信号。
在 x86 CPU 上,最多支持 256 个中断,这意味着我们要准备 256 个中断门描述符和 256 个中断处理程序的入口。
中断表其实是个 gate_t 结构的数组,由 CPU 的 IDTR 寄存器指向,IDTMAX 为 256。
光有数组还不行,还需要设置其中的数据, init_halintupt函数通过调用一些函数实现了中断的初始化:
4 实践篇
这个实验就很简单,在上一课的基础上,make release十三课的代码,把release文件夹下的eki文件拷到之前建立的虚拟硬盘目录下的boot目录下即可。如果没有变成这张图,试试改一下Makefile文件,把logo.bmp删掉:
我一开始图没变,后面又莫名其妙的变了,就很奇怪。
成功: