0%

从ucore来总结操作系统(9)----仿照ucore来实现一个自己的操作系统

仿照ucore来实现一个自己的内核

硬件无关的内核

之前已经完成了ucore的所有lab,但是很多代码都是实现好的,且有很多细节没有去了解。所以做的时候就想着能不能一边做lab,一边按照自己的想法去实现(抄)一个更简单的玩具级操作系统内核呢?

操作系统本身模块很多,且软件硬件相互依赖,而且还需要对硬件实现各种驱动,还需要对CPU寄存器、架构有比较多的了解。

由于写一个内核本就是一时兴起,且扎入硬件中也非我本意,所以打算直接实现一个与硬件无关的内核。

实现硬件无关的最简单方式就是基于硬件抽象层,把内核扔在这上面运行。单片机厂商是会提供硬件抽象层的,所以这个内核可以直接实现在单片机上。且单片机有中断、定时器等丰富的外设,实现一个内核是绰绰有余。

因此,我打算基于stm32f103c8t6来实现一个操作系统内核,它有64KB的FLash和20KB的RAM。

顺便一提,单片机上有freerots等实时操作系统内核,是可以借鉴的好资源

内核的结构与实现手段

内核的结构与实现手段与ucore类似,但是由于是硬件无关的,所以不需要考虑硬件的细节。内核主要由以下几部分组成:

  • 中断系统

硬件抽象层会提供中断服务函数,因为要仿照ucore,我们把所有的中断都发送到一个trap函数上处理。

同时需要有时间片中断,这个可以用一个定时器来实现。

还可以实现一个伪中断,用于系统调用。这个我是使用一个外部引脚的中断来实现的(先把系统调用编号放入一个环境变量中,然后触发外部中断来实现)。

  • 内存管理

由于单片机会把外设的寄存器映射到存储器上,这取决于单片机的存储器映像图,且单片机的内存管理都是访问物理地址,没有虚拟地址这一说。

上图就是存储器映像,可以看到SRAM的地址是0x20000000开始的一段连续的地址,大小为20KB。由于总内存比较小,所以物理页面选择256B,这样就有80个物理页面。但是因为硬件上不支持虚拟内存的功能,所以虚拟内存这一块只能阉割一下了。

但是按照页来管理物理内存的颗粒度太大,很浪费,所以需要实现一个更加精细的内存管理方案。

因为没有虚拟内存,缺页中断、页表、页面置换、页面权限控制都不存在了,这里阉割其实还是挺大的,好在这些也不是很困难,缺就缺吧

  • 线程管理

类似ucore,这个内核也没有进程,只存在线程。需要为每个线程提供描述结构,同时还需要支持上下文切换等等(涉及到一部分汇编)。

线程可以将自己挂起,或者是因为时间片用完而被挂起。时间片中断则是通过定时器来实现的。

  • 同步量、互斥

有了线程的管理的内容,这部分还是比较好实现的。

  • 文件系统

为了实现一个文件系统,决定把20KB的内存,分为16KB+4KB。其中4KB伪装成磁盘,内容将是在内核启动后固定动态生成。同时可以串口读取这部分内容,以检查文件写入读取创建是否正确。

但是由于不支持虚拟内存,所以文件系统的实现也是阉割的,只能实现一个简单的文件系统,只支持文件的读写,不支持动态加载程序。

当然这个文件系统比较简单,没有虚拟文件系统那一坨。

其实我现在基本上写完了,但是跑起来的时候似乎存在非常诡异的bug,还在调试中....