Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

项目架构与内核架构设计

项目总体架构

为了进行混合内核与宏内核的对比,本项目实现了混合内核与宏内核两种内核架构,项目总体结构如下图所示:

项目总体架构

项目总体采用层次化软件开发方法,自底向上分为驱动、硬件抽象层、内核对象层、系统调用层、装载器和上层标准库和应用程序。

硬件抽象层(Hardware Abstraction Layer,HAL)定义一套硬件操作 API,提供给上层的内核对象使用,HAL层内部的实现和依赖的环境,对于上层内核对象 来说是完全透明的,且上层内核对象只能通过 HAL 层的 API 来操作硬件。HAL 层只给出接口定义,具体的实现可以有多种硬件架构,如 x86_64、aarch64 等(目前只实现了x86_64架构),在编译时通过 Rust 语言的 feature 条件编译选项将 HAL 定义的硬件接口绑定到具体的硬件平台实现上去。这种做法一方面可以将底 层的 unsafe 代码进行独立封装与集中检查测试,限制上层对象只能通过 HAL 层的 API 操作硬件,从而最大限度地利用 Rust 语言提供的内存安全特性,另一方面屏 蔽了不同硬件架构的硬件细节,使上层内核对象的操作独立于硬件。

内核对象层(Kernel Objects)基于 HAL 层给出的硬件接口,实现内核数据结 构和他们的方法(如进程线程等)。由于混合内核与宏内核的内部实现有所不同,分别实现宏内核对象和混合内核对象两套对象。

系统调用层(Syscall Layer)根据内核对象的方法实现系统调用接口。为了直接支持musl-libc,我们直接实现了Linux系统调用。

加载器(Loader)位于系统调用层之上,其向下使用系统调用层给出的系统调用 API,完成内核对象初始化、系统调用入口设定、第一个用户程序加载和启动的工作。用户程序(App)层运行用户态应用程序,可以直接使用内核提供的系统调用,也可以运行在系统调用层之上的 c 标准库(musl-libc)上。

代码目录树

项目的代码目录树如下

.
├── boot                    // 启动内核
├── crates                  // 有修改的第三方库
├── executor                // 协程执行器
├── hal                     // 硬件抽象层
├── hybrid-objects          // 混合内核对象
├── hybrid-syscalls         // 混合内核系统调用
├── loader                  // 加载器
├── misc                    // 杂项
├── monolithic-objects      // 宏内核对象
├── monolithic-syscalls     // 宏内核系统调用
├── musl                    // musl源码
├── Ncore                   // 顶层内核
├── rcore-fs-use            // 构建文件系统
├── tutorial                // 文档
├── user-c                  // C语言用户程序
├── user-components         // 用户态组件
├── user-rs                 // Rust用户程序
└── Question.md             // 本题目简介

其中的boot、executor、hal、hybrid-objects、hybrid-syscalls、loader、monolithic-objects、monolithic-syscalls、Ncore、user-rs都被实现为单独的Rust crate。