StarryNext源代码阅读
Starry Next 源代码阅读
run_user_app:
- 新建用户地址空间
- 把内核地址空间复制到应用地址空间高地址区域 (ArceOS 特性)
- 设置当前目录
set_current_dir设置当前目录 全局变量CURRENT_DIRload_user_app- 借助创建的用户地址空间和传入的参数
- 读取 ELF 数据, 加载
ld.so/libc.so - 在用户地址空间映射可执行文件的各个逻辑段
- 通过预先布局的汇编常量地址和大小映射用户栈到用户地址空间, 初始化用户栈内容
- 在用户地址空间映射堆区.
- 返回起始运行地址和用户栈栈指针
- 准备用户地址空间上下文(管理 Trap 上下文, 例如通用寄存器状态, CSRs)
- 新建用户任务, 传一个切进用户态的闭包进去
- 设置根页表位置, RISCV SV39 下就是
satp - 准备进程和线程相关数据,
FD_TABLECURRENT_DIRtid等 - 把主线程添加到全局线程表中, 把任务添加到待执行队列等待调度
main:
- 宏内核扩展, 相当于一个”应用程序的 main”
- 启动
init进程, 运行 testcases
handle_page_fault:
- 当前任务的地址空间执行
handle_page_fault, 失败则SIGSEGV信号退出
handle_syscall:
- 依赖
syscallscrate 的Sysno, 根据 id 匹配一下具体的 syscall 类型, 分发到对应处理函数, 返回执行结果
map_elf:
- 解析参数传来的 elf 数据, 对每个段进行映射
todo!("有关 ELFParser::new 中有关 Interpreter的问题")?
TaskExt:
- ArceOS 中的任务控制块扩展. 对于宏内核扩展就是需要线程相关的
tid等 axtask::def_task_ext!宏注册任务控制块扩展thread中的数据除了tid还有一个Data字段.ThreadDataclear_chlld_tid?
ProcessData:
- 可执行文件的路径
- 用户地址空间
- 堆内存的起始和终止地址
ProcessData中为什么没有线程相关/任务相关数据?AxNamespace?
#[percpu::def_percpu]?
access_user_memory ?
time 相关 ?
check_region: 检查一段地址是否对齐存在且可访问
check_null_terminated: 返回
[start, 第一个 T::default 的地址]
PtrWrapper Trait: 指针的基本操作, 以及各种
get_as
单独系统调用: uname, sys_times
sys_mmap sys_waitpid 和 ArceOS 一致
sys_mprotect 是干嘛的?
sys_arch_prctl: 用于设置 (架构相关的)
用户态线程局部存储寄存器, 例如 FS(TLS 结构体)
GS (per_CPU 数据, 如进程控制块)
cleaR_child_tid:用户态的
tidptr: *mut i32变量, 初始值指向线程栈上gettid()的返回值, 置 0 时表示线程退出内核栈上
clear_child_tid与tidptr指向相同的内存地址, 退出时将其指向的位置置 0 表示退出
sys_set_tid_address:
do_exit: 被
sys_exit/sys_exit_group 依赖,
exit_group 为 T/F 的差别
- 置 0
clear_child_tid - 退出主线程
信号量机制
直接开写 lab 吧, 整体了解没什么硬伤, 任务驱动学习好了