1 | make -C /home/linux/vscode/arceos A=/home/linux/vscode/my_arceos_app ARCH=aarch64 LOG=debug SMP=1 run |
U.1.0 HelloWorld
![![[Pasted image 20241111091146.png]]](<2024年开源操作系统训练营第三阶段总结-silent12rt/Pasted image 20241111091146.png>)
该图展示了一个应用程序(hello_world
)在系统中各个模块(如axruntime
、axhal
、axstd
、arceos
)之间的结构和交互关系。以下是各个部分的功能说明:
axhal(硬件抽象层):该层对硬件细节进行抽象,为更高层提供一个屏蔽底层硬件的基础,使上层不需要直接管理底层硬件。
axruntime(运行时环境):该层管理应用程序的运行时环境,包括内存分配、线程调度和其他运行时服务,是应用程序正常运行的基础。
ulib(axstd):这是一个标准库,为应用层提供通用功能和实用工具,可能包含基本的I/O操作、数据处理等辅助功能。
api(arceos):这是与底层操作系统(ArceOS)的应用编程接口,允许应用程序执行系统级操作,如文件管理、进程间通信等。
app(hello_world):这是用户的应用程序,利用
axstd
和arceos
提供的库和接口来执行特定任务。执行流程:
- 左侧的准备环境(蓝色箭头)表示系统的准备阶段,在此阶段,配置和初始化必要的资源和环境。
- 右侧的调用功能(橙色箭头)表示应用程序在运行时与
axstd
和arceos
进行的交互,通过这些库和API执行特定功能。
U.2.0 Collections
Buddy System(伙伴系统)
- 分配内存单元
设置最小分配单元(通常是 2 的幂次方大小),而不是按1字节来分配。这种划分可以提高分配效率,并且降低管理开销。例如,如果分配单元是 8 字节,最小分配的内存块将是 8 字节。在 Buddy System 中,不同大小的块按 2 的幂次划分(即 8、16、32、64 等),每个大小被称为一个 order。每个 order 是一种特定大小的块。 - 分配过程
- 寻找最小满足请求的块。当程序请求内存时,分配器首先确定需要分配的块的大小(例如 64 字节)。然后分配器会在内存池中找到最小的能满足此请求的 order 块(例如 128 字节的块,若没有 64 字节的块)。
- 二分切割。如果找到的 order 大于所需的大小,那么分配器将不断地对该块进行 二分切割,直到得到匹配所需大小的块。
- 返回分配的块:分配器返回一个与请求大小匹配的块,并将它从空闲列表中移除。此时,程序可以使用该块。
- 释放过程
- 检查是否有空闲的邻居块:当程序释放某块内存时,分配器会检查该块是否有“伙伴”块(即同一级的邻居块)也是空闲的。两个邻居块的地址通常具有某种关系,使分配器可以根据地址快速定位伙伴块。
- 合并到高 order:如果找到空闲的伙伴块,分配器会将两个相邻的空闲块合并成一个更大的块。这个合并过程会尽量继续进行,直到不能再合并为止。
- 挂到 Order List:如果无法进一步合并,最终的空闲块会挂到相应的空闲列表(Order List)中,以备后续分配使用。
内存分配算法-Slab
![![[Pasted image 20241111191653.png]]](<2024年开源操作系统训练营第三阶段总结-silent12rt/Pasted image 20241111191653 1.png>)
分配过程
- 找到合适的OrderList
根据请求的内存大小,找到合适的 OrderList。OrderList 会匹配内存大小,确保分配合适的 Slab。 - 从 Slab 的空闲块链表中获取 block
- 从空闲块链表 (Free Block List) 中弹出一个 block,完成分配。
- 如果空闲块链表中没有可用的 block,则进入下一步。
- 调用 BuddyAllocator 分配新块:
- 当空闲链表中没有足够的块时,向 Buddy Allocator 请求一个较大的内存块。
- 将分配到的较大内存块切分为符合 Slab 需求大小的 block,然后加入到该 Slab 的空闲块链表。
- 最终,分配请求从空闲块链表中取出一个 block 返回。
释放过程
- 释放 block 到空闲块链表
- 释放时,将 block 放回对应 Slab 的空闲块链表。
- 这样,当后续需要分配类似大小的块时,可以直接从该空闲块链表中分配,避免重复分配和释放较大块的开销。
- 管理内存回收
- 如果某个 Slab 变得完全空闲(即所有 block 都释放),可以选择将该 Slab 的内存归还给 Buddy Allocator,以释放更多内存供其他用途。
U.3.0 Collections
U.4.0 Collections
核心算法:context_switch
任务上下文Context: 保存任务状态的最小的寄存器状态集合。
![![[Pasted image 20241112144224.png]]](<2024年开源操作系统训练营第三阶段总结-silent12rt/Pasted image 20241112144224.png>)
ra: 函数返回地址寄存器,这个切换实现了任务执行指令流的切换。
sp: 任务即线程,这个是线程栈
s0~s11:按照riscv规范,callee不能改这组寄存器的信息,所以需要保存。
抢占式调度算法ROUND_ROBIN
在协作式调度FIFO的基础上,由定时器定时递减当前任务的时间片,耗尽时允许调度,一旦外部条件符合,边沿触发抢占,当前任务排到队尾,如此完成各个任务的循环排列。
![![[Pasted image 20241112151551.png]]](<2024年开源操作系统训练营第三阶段总结-silent12rt/Pasted image 20241112151551.png>)
抢占式调度算法CFS(Completely Fair Scheduler)
![![[Pasted image 20241112151735.png]]](<2024年开源操作系统训练营第三阶段总结-silent12rt/Pasted image 20241112151735.png>)