StarryNext源代码阅读
Starry Next 源代码阅读
run_user_app
:
- 新建用户地址空间
- 把内核地址空间复制到应用地址空间高地址区域 (ArceOS 特性)
- 设置当前目录
set_current_dir
设置当前目录 全局变量CURRENT_DIR
load_user_app
- 借助创建的用户地址空间和传入的参数
- 读取 ELF 数据, 加载
ld.so
/libc.so
- 在用户地址空间映射可执行文件的各个逻辑段
- 通过预先布局的汇编常量地址和大小映射用户栈到用户地址空间, 初始化用户栈内容
- 在用户地址空间映射堆区.
- 返回起始运行地址和用户栈栈指针
- 准备用户地址空间上下文(管理 Trap 上下文, 例如通用寄存器状态, CSRs)
- 新建用户任务, 传一个切进用户态的闭包进去
- 设置根页表位置, RISCV SV39 下就是
satp
- 准备进程和线程相关数据,
FD_TABLE
CURRENT_DIR
tid
等 - 把主线程添加到全局线程表中, 把任务添加到待执行队列等待调度
main
:
- 宏内核扩展, 相当于一个”应用程序的 main”
- 启动
init
进程, 运行 testcases
handle_page_fault
:
- 当前任务的地址空间执行
handle_page_fault
, 失败则SIGSEGV
信号退出
handle_syscall
:
- 依赖
syscalls
crate 的Sysno
, 根据 id 匹配一下具体的 syscall 类型, 分发到对应处理函数, 返回执行结果
map_elf
:
- 解析参数传来的 elf 数据, 对每个段进行映射
todo!("有关 ELFParser::new 中有关 Interpreter的问题")
?
TaskExt
:
- ArceOS 中的任务控制块扩展. 对于宏内核扩展就是需要线程相关的
tid
等 axtask::def_task_ext!
宏注册任务控制块扩展thread
中的数据除了tid
还有一个Data
字段.ThreadData
clear_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 吧, 整体了解没什么硬伤, 任务驱动学习好了