前言
笔者为练习时长两年半的大学牲一枚,在历经Unity、ACM、Swift、Vulkan、CV和微服务框架的自我蹂躏之旅后,打算开个新坑:重做大二下全程划水的ucore(操作系统实验,C语言实现)。
作为笔者博客处女作,初衷还是深入贯彻“做中学”理念,为同样想自己扎扎实实了解一遍OS内核实现的同学提供微不足道的帮助,个人的兴趣和理想是向自行实现从逻辑门电路到图形化界面app的全链路大佬们看齐!
准备
- 具备C语言、汇编语言(AT&T格式)、操作系统基础,掌握一点点Linux命令
- 实验教程:《uCore OS实验指导书lab0-8》
- 虚拟机软件:VirtualBox或VMware(笔者用的是VMware WorkStation 17Pro,破解码可以自行百度)
- Linux虚拟机版本:Ubuntu 14.04 amd64
- ucore:在虚拟机的终端执行命令:
git clone http://github.com/kiukotsu/ucore.git
也可以在自己主机上使用该命令下载完成后,再拖拽到Ubuntu的桌面上
初始化环境
- 进入Ubuntu系统后,打开Terminal
- Ubuntu自带gcc,只需安装gcc编译环境
sudo apt-get install build-essential - 安装硬件模拟器qemu,用于模拟intel x86-32平台,搭载运行ucore,类似工具还有BOCHS、SkyEye等
sudo apt install qemu
使用到的数据结构
- 基于C语言的ucore使用函数指针来实现面向对象的接口和继承功能;
- 借鉴Linux使用双向循环链表,在libs/list.h中实现,维护空闲列表、进程列表等;该链表没有data域,而是在节点的数据结构中定义前后指针,目的是避免在每种数据结构中重新定义链表操作,减少代码冗余;链表操作采用inline内敛函数。
- 例如下面是空闲列表的实现方式:
struct list_entry {
struct list_entry *prev, *next;
};
/* free_area_t - 维护空闲列表的双向循环链表(作为头节点) */
typedef struct {
list_entry_t free_list; // 头节点的前后节点
unsigned int nr_free; // 空闲列表中节点个数
} free_area_t;
struct Page {
atomic_t ref; // 页帧引用计数器
……
list_entry_t page_link; // 链表前后节点
};
- 由于链表节点没有维护数据域,因此ucore仿照Linux使用le2XXX的宏来实现链表节点向XXX类型数据域的转换,该宏利用gcc编译器得到链表节点在宿主数据结构偏移量,再根据成员变量地址反推宿主数据结构变量地址。