Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024-秋冬季开源操作系统训练营第三阶段总结-曹展豪 #649

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
title: 2024 秋冬季开源操作系统训练营第三阶段总结-曹展豪
date: 2024-12-01 22:45:53
tags:
- author: caozhanhao
---

# 🤔 第三阶段 - 组件化操作系统
这一阶段正好学校里有考试,ddl也比较多,学习的时间稍微少了一些,效果感觉差了一些。希望在第四阶段补全短板,增进对技术的理解。

<!-- more -->

完整的博客在[这里](https://mkfs.tech/index.php/archives/30/)。

## 内核模式
![1.png](https://mkfs.tech/usr/uploads/2024/12/14276843.png)
其中 Unikernel 的应用与内核处于同一特权级,且共享同一地址空间,最终编译形成一个Image,一体运行。
而其他的内核大多应用与内核隔离特权级运行,具有独立的地址空间,最终是不同的Image,独立运行。

## PFlash
Qemu的PFlash模拟闪存磁盘,启动时自动从文件加载内容到固定的MMIO区域,而且对读操作不需要驱动,可以直接访问。
![2.png](https://mkfs.tech/usr/uploads/2024/12/290153810.png)

## TLSF (Two-Level Segregated Fit)
![3.png](https://mkfs.tech/usr/uploads/2024/12/2778956413.png)
- First Level: 每一位对应一个范围的内存块,示例中分别对应24 ~ 231。1表示空闲。图中两个1。
- Second Level: 有几位就表示几等分。例如, 26表示64~127,然后进行4等分就是64~79, 80~95, 96~107, 108~127,每一位对应一个范围,同样1表示空闲。

[TLSF——一种简单高效的内存池实现](https://zhuanlan.zhihu.com/p/658922989)

## Buddy

![5.png](https://mkfs.tech/usr/uploads/2024/12/279611250.png)
![4.jpg](https://mkfs.tech/usr/uploads/2024/12/1916612972.jpg)

分配时寻找匹配alloc需要(order)的最小块。如果order大于目标,则二分切割,直至相等,每级剩余的部分挂到对应的Order List
释放时查看是否有邻居空闲块,有则尽可能向高Oder合并,直至无法合并,挂到OrderList。

[内存分配\[二\] - Buddy系统的原理](https://www.zhihu.com/column/p/73562347)

## Slab

![6.png](https://mkfs.tech/usr/uploads/2024/12/1942286885.png)

分配时从 block 空闲链表中弹出一个 block。
依靠 Buddy 分配器提供内存分配支持,初始时以及 block 不足时,从 BuddyAllocator 申请,分割 block 后加入 block 空闲链表。

Slab 分配器分配内存以字节为单位,基于 Buddy 分配器的大内存进一步细分成小内存分配。换句话说,Slab 分配器仍然从 Buddy 分配器中申请内存,之后自己对申请来的内存细分管理。

[Linux 内核 | 内存管理——slab 分配器](https://zhuanlan.zhihu.com/p/358891862)

## 基于 Unikernel 的最小化宏内核

![7.png](https://mkfs.tech/usr/uploads/2024/12/4058348040.png)

需要的增量工作:
1. 用户地址空间的创建和区域映射
2. 在异常中断响应的基础上增加系统调用
3. 复用 Unikernel 原来的调度机制,针对宏内核扩展 Task 属性
4. 在内核与用户两个特权级之间的切换机制

## 兼容 Linux 应用
![9.png](https://mkfs.tech/usr/uploads/2024/12/3505897926.png)

在应用和内核交互界面上实现兼容。
兼容界面包含三类:
1) syscall
2) procfs & sysfs等伪文件系统
3) 应用、编译器和libc对地址空间的假定,涉及某些参数定义或某些特殊地址的引用

## 应用的用户栈初始化
Linux应用基于glibc/musl-libc等库编译,libc在调用应用的main之前,检查用户栈上的参数等内容。
而应用启动之后,也可能会调用这些参数。内核需要在切换到首应用前,为应用准备栈上内容。
![8.png](https://mkfs.tech/usr/uploads/2024/12/3876172031.png)

## Hypervisor
Hypervisor与模拟器Emulator的区别:
![10.png](https://mkfs.tech/usr/uploads/2024/12/2548801357.png)
根据1974年,Popek和Goldberg对虚拟机的定义, 虚拟机可以看作是物理机的一种高效隔离的复制,蕴含三层含义:同质、高效和资源受控。同质要求ISA的同构,高效要求虚拟化消耗可忽略,资源受控要求中间层对物理资源的完全控制。Hypervisor必须符合上述要求,而模拟器更侧重的是仿真效果,对性能效率通常没有硬性要求。其根本区别是虚拟运行环境和支撑它的物理运行环境的体系结构即ISA是否一致。

两种类型的虚拟化:
![2024-12-01T11:20:17.png](https://mkfs.tech/usr/uploads/2024/12/2647307308.png)

## Riscv64在特权级模式的H扩展

![2024-12-01T11:22:58.png](https://mkfs.tech/usr/uploads/2024/12/4036930211.png)
![2024-12-01T11:23:02.png](https://mkfs.tech/usr/uploads/2024/12/384826824.png)

特权级从三个扩展到五个,新增了与Host平行的Guest域

- 原来的S增强了对虚拟化支持的特性后,称它为HS。
- M/HS/U形成Host域,用来运行I型Hypervisor或者II型的HostOS,三个特权级的作用不变。
- VS/VU形成Guest域,用来运行GuestOS,这两个特权级分别对应内核态和用户态。
- HS是关键,作为联通真实世界和虚拟世界的通道。体系结构设计了双向变迁机制。

H扩展后,S模式发送明显变化:原有s[xxx]寄存器组作用不变,新增hs[xxx]和vs[xxx]
hs[xxx]寄存器组的作用:面向Guest进行路径控制,例如异常/中断委托等
vs[xxx]寄存器组的作用:直接操纵Guest域中的VS,为其准备或设置状态
![2024-12-01T11:23:51.png](https://mkfs.tech/usr/uploads/2024/12/2915643031.png)

## Guest与Host的地址空间关系
Guest是指虚拟机所在的执行环境;Host指Hypervisor所处的执行环境。
Hypervisor负责基于HPA面向Guest映射GPA,基本寄存器是hgatp;
Guest认为看到的GPA是“实际”的物理空间,它基于satp映射内部的GVA虚拟空间。
![2024-12-01T11:26:25.png](https://mkfs.tech/usr/uploads/2024/12/3804255383.png)
![2024-12-01T11:26:54.png](https://mkfs.tech/usr/uploads/2024/12/1144908403.png)

## 虚拟机的时间中断
物理环境或者qemu模拟器中,时钟中断触发时,能够正常通过stvec寄存器找到异常中断向量表,然后
进入事先注册的响应函数。但是在虚拟机环境下,宿主环境下的原始路径失效了。有两种解决方案:
1. 启用 RISC-V AIA 机制,把特定的中断委托到虚拟机 Guest 环境下。要求平台支持,且比较复杂。
2. 通过中断注入的方式来实现。如下例

![2024-12-01T11:40:43.png](https://mkfs.tech/usr/uploads/2024/12/2020345139.png)

需要实现两部分的内容:
1. 响应虚拟机发出的SBI-Call功能调用SetTimer
2. 响应宿主机时钟中断导致的VM退出,注入到虚拟机内部
![2024-12-01T11:45:03.png](https://mkfs.tech/usr/uploads/2024/12/1158020441.png)