05 操作系统的第一个c函数 init_hal()
hal_start 函数:执行板级初始化,
初始化hal层:
就是硬件抽象层,分离硬件特性,向上提供接口,让内核不在关注硬件相关的细节,也能方便以后的 移植和扩展;Cosmos是x86平台下 的,其他平台替换hal层即可;
init_hal函数,初始化平台、初始化内存、初始化中断;
- 初始化平台:init_halplatform
两个任务:一是把二级引导器建立的机器信息结构体复制到hal层的一个全局变量中,方便内核使用里面的信息,之后二级引导器建立的数据所占用的内存都会释放;init_machbstart函数;
复制machbstart_t 结构体,同时因为进入长模式,需要转化为虚拟地址;
二是初始化图形显示驱动,内核在运行过程需要向屏幕输出信息;init_bdvideo函数
初始化图形数据结构,包括分辨率,图形模式,图形驱动指针,结构体实现dftgraph_t,其中包括了图形驱动操作函数指针结构体 dftghops_t ;
初始化bga图形显卡的函数指针; 初始化vbe图形显卡的函数指针; 清空屏幕; 显示背景图片;
这儿就可以做一个显示背景的实验了;
- 初始化内存:init_halmm
halmm.c文件,向内存管理器提供内存布局信息;之前在二级引导器中获取的内存布局信息位基础 ,e820map_t结构体数组,设计一个新的结构体 phymmarge_t;包括内核要保留的一部分内存空间;
- 初始化中断:
x86CPU最多支持256个中断,需要有256个中断门描述符和中断处理程序入口;中断表 gate_t 结构体,IDTR寄存器指向它;set_idt_desc函数实现填充结构体; 中断处理程序只需要负责:保护CPU寄存器,调用中断处理器,恢复CPU寄存器;这三部分用汇编写 kernel.asm文件;
有的CPU异常,会有一个异常码压入栈中,而有的CPU异常没有,为了统一,手动压入一个常数维持栈平衡;
有了中断处理程序的入口地址,就可以在halsgdidit.c文件中写出函数设置中断门描述符,一开始把所有中断的处理程序设置为保留的通用处理程序,避免未知中断异常发生CPU无处可去;然后对已知的中断和异常进一步设置,这会覆盖之前的通用处理程序;随后让上层调用者调用;
COSMOS的CPU中断流程框架:CPU -> 中断门描述符 -> 中断、异常处理入口程序 -> 异常、中断分发器 -> 中断、异常描述符 ;
其中,intfltdsc_t 结构体是用来记录 中断描述符表; intserdsc_t 结构体是记录中断函数的地址;内核 或 设备驱动程序 若要安装一个中断处理函数,就要先申请一个intserdsc_t结构体,把中断函数地址写入其中,最后挂载到 intfltdsc_t结构体的 i_serlist 链表中;这么做的原因是:考虑到计算机中可能有很多设备,每个设备都可以产生中断,但是中断控制器的信号线是有限的,中断控制器最多产生几十号中断号,无法容纳所有设备,就会造成多个设备共享一根中断信号线,此时无法识别是哪一个设备产生中断,所以就让设备的驱动程序来决定,它是最了解设备的;
这里让这个 intfltdsc_t 结构体所有的中断处理函数依次执行,查看是否是自己的设备的中断,若是就处理,不是则略过;
中断处理函数:hal_do_hwint,根据中断号获取中断异常描述符地址,对异常描述符加锁并中断,运行中断处理的回调函数hal_run_intflthandle,解锁并恢复中断状态;
异常分发器:hal_fault_allocator 函数,异常处回调理函数 也是放在 中断异常描述符中,
中断分发器:同上;
回调函数hal_run_intflthandle:根据中断号获取异常描述符地址,遍历intfltdsc_t 结构体中的 i_serlist链表,将挂载的intserdsc_t 结构体,然后调用jintserdsc_t 结构中的中断处理回调函数;
- 初始化中断控制器:
设备端的中断交给设备驱动程序;这儿使用了8259A控制器,(之后是IOAPIC,MSI_X),在init_halintupt函数最后,调用8259初始化函数,并且屏蔽了所有中断;
初始化内核层:
内核层是hal层进入的,init_krl函数,目前什么也不做,是空函数,让hal_start函数调用它;
本节实验更新 4.24:
虚拟机上进行执行编译得到hd.img文件,这儿我直接用现成打包好的命令了:具体细节我再琢磨琢磨;
make vboxtest;
主机执行如下命令:
.\VBoxManage convertfromraw E:\Abianyi\make_OS\lesson13\test\hd.img --format VDI E:\Abianyi\make_OS\lesson13\test\hd.vdi
.\VBoxManage storagectl HelloOS --name "SATA" --remove
.\VBoxManage storagectl HelloOS --name "SATA" --add sata --controller IntelAhci --portcount 1
.\VBoxManage closemedium disk E:\Abianyi\make_OS\lesson13\test\hd.vdi
.\VBoxManage storageattach HelloOS --storagectl "SATA" --port 1 --device 0 --type hdd --medium E:\Abianyi\make_OS\lesson13\test\hd.vdi

启动HelloOS: .\VBoxManage.exe startvm HelloOS
得到如下界面:这儿没做修改底层的代码;
----------后续更新换图片 和 显示的 之后的代码

浙公网安备 33010602011771号