StarryOS 内部机制
本文档面向准备修改 StarryOS 内核、补充 Linux 兼容语义、分析 syscall 路径或调整 rootfs 验证流程的开发者,重点 阐述 StarryOS 的内部结构与执行机制。
若尚未运行过 StarryOS,建议先阅读 quick-start.md。
1. 系统定位与设计目标
StarryOS 是建立在 ArceOS 基础能力之上的组件化宏内核系统,继承了 ArceOS 的模块化、跨平台和 Rust 安全性,同时引入了更接近 Linux 的进程、线程、syscall、文件系统和 rootfs 语义。
核心设计目标:
| 目标 | 含义 | 典型落点 |
|---|---|---|
| Linux 兼容语义 | 提供更接近 Linux 的用户态程序运行环境 | kernel/src/syscall/*、kernel/src/task/*、kernel/src/file/* |
| 复用 ArceOS 基础能力 | 不重复实现 HAL、调度、部分文件与网络基础设施 | os/arceos/modules/* |
| 组件化宏内核 | 在一个内核映像中组织多种子系统,但继续按组件边界拆分职责 | components/starry-*、kernel/* |
| 用户态验证闭环 | 通过 rootfs 和 init shell 验证系统行为,而不仅仅是跑单个内核函数 | os/StarryOS/starryos、rootfs 镜像、test-suit/starryos |
StarryOS 介于"ArceOS 单内核应用运行时"与"完整 Linux 宏内核"之间:它并非简单地为 ArceOS 增加一个 shell,而是将进程、地址空间、syscall 分发、伪文件系统、信号、资源限制等内核机制系统化地组合起来。
2. 架构概览
StarryOS 的核心特征在于多个层次共同组成最终可运行的系统,而非仅有一个 kernel/ 目录。
理解此图需注意以下三点:
rootfsUsers是 StarryOS 验证 Linux 兼容行为的核心载体。kernelCore并非从零实现全部底层能力,而是将 ArceOS 模块和 Starry 专用组件拼接成宏内核语义。- 修改
arceosModules时,不仅 ArceOS 受影响,StarryOS 也会被波及。
2.1 主要分层职责
| 层次 | 目录 | 职责 |
|---|---|---|
| 用户态层 | rootfs 中的 shell、busybox、测试程序 | 触发 syscall、文件系统、进程管理等行为 |
| 启动包层 | os/StarryOS/starryos | 构造命令行与环境变量,进入内核入口 |
| 内核核心层 | os/StarryOS/kernel | entry、syscall、task、mm、file、pseudofs、time |
| Starry 专用组件层 | components/starry-* | 进程、信号、虚拟内存、网络兼容等抽象 |
| ArceOS 基础模块层 | os/arceos/modules/* | HAL、任务调度、同步、基础 I/O、文件与网络能力 |
| 平台层 | platform/*、axplat-* | 架构与板级支持 |
2.2 支持架构
当前 StarryOS 的架构支持状态:
riscv64:可用loongarch64:可用aarch64:可用x86_64:仍在进行中
稳定验证内核语义时,建议优先使用 riscv64。
3. 核心设计机制
3.1 基于 ArceOS 的组件化宏内核
StarryOS 与传统"从零写起"的宏内核不同,将大量底层职责交由 ArceOS 处理:
- 任务与调度的基本运行时建立在
ax-task之上。 - 地址空间与页表能力复用
ax-mm系列基础设施。 - 文件系统、网络、HAL、日志等依赖
ax-fs、ax-net、ax-hal、ax-log等模块。
StarryOS 自身重点补齐"多进程、多线程、Linux syscall 语义、rootfs 用户态验证"这几部分。
3.2 进程与线程分离
StarryOS 在 task 子系统中把“进程共享状态”和“线程私有状态”明确分离:
| 对象 | 主要内容 | 语义 |
|---|---|---|
ProcessData | proc、exe_path、cmdline、aspace、scope、rlim、signal、futex_table、umask | 进程级共享状态 |
Thread | proc_data、线程级 signal、time、clear_child_tid、robust_list_head、退出标志 | 线程级运行状态 |
这种分离使得:
clone()可根据 flags 决定共享进程级资源或复制新的进程上下文。支持CLONE_VM(共享地址空间)、CLONE_THREAD(同线程组)、CLONE_VFORK(挂起父进程直到 execve/exit)等标志位组合。execve()可在保持进程身份的前提下重装用户地址空间与程序映像,同时关闭CLOEXEC标志的文件描述符并重置信号处理器。fork()等价于带默认 flags 的clone(),使用 COW(写时复制)后端复制地址空间。- 线程切换时只需切换线程级上下文,资源、地址空间、信号行为仍按进程或线程粒度维护。
3.3 syscall 分发机制
kernel/src/syscall/mod.rs 中的 handle_syscall() 是 StarryOS 的核心控制中枢。其处理流程:
- 从
UserContext读取 syscall 编号与 参数。 - 将编号转换为
Sysno。 - 按功能域分发到
fs、mm、task、signal、ipc、net等实现。 - 将返回值转换为 Linux 风格错误码写回
UserContext。
StarryOS 的 Linux 兼容行为明确定义在 syscall 分发与各子模块实现中。当前支持的 syscall 覆盖以下主要类别:
| 类别 | 典型 syscall | 实现位置 |
|---|---|---|
| 进程管理 | clone、clone3、fork、execve、exit、wait4 | syscall/task/ |
| 文件操作 | open、read、write、close、lseek、stat | syscall/fs/ |
| 目录操作 | mkdir、getdents64、chdir、getcwd、symlink | syscall/fs/ |
| I/O 多路复用 | poll、select、epoll_create1、epoll_ctl、epoll_pwait | syscall/io_mpx/ |
| 内存管理 | brk、mmap、munmap、mprotect、mremap | syscall/mm/ |
| 信号处理 | rt_sigaction、rt_sigprocmask、kill、futex、sigaltstack | syscall/signal.rs、task/signal.rs |
| 网络 | socket、bind、listen、accept、connect、send、recv | syscall/net/ |
| IPC | msgget、msgsnd、msgrcv、shmget、shmat、shmdt | syscall/ipc/ |
| 时间 | clock_gettime、nanosleep、gettimeofday | syscall/time.rs |
| 管道与事件 | pipe2、eventfd2、signalfd4、pidfd_open | file/pipe.rs、file/event.rs |
3.4 用户程序加载机制
用户程序加载围绕 mm::load_user_app() 展开,执行以下操作:
- 解析路径或首个参数。
- 处理 shell 脚本与 shebang 解释器路径。
- 调用 ELF loader 解析二进制。
- 映射用户栈、写入
argv/envp/auxv。 - 建立用户堆区。
- 返回入口地址与用户栈顶。
execve() 不只是"替换当前进程路径字符串",而是会重建当前线程恢复用户态时看到的整个地址空间布局。
4. 功能组件与模块
本节介绍 StarryOS 的内核子系统总览、Starry 专用组件层及启动包与内核入口的关系。