xv6-riscv_struct
File structure of xv6-riscv
1 |
|
逐文件详细解读它们的作用、重要性:
🧠 整体结构
目录/文件 | 作用 | 建议重点关注 |
---|---|---|
kernel/ |
xv6 核心实现,内核源码 | ✅ 必看 |
user/ |
用户态程序、测试程序、库 | ✅ 推荐 |
mkfs/ |
构建文件系统镜像工具 | ❗可选 |
顶层构建文件 | Makefile , README , LICENSE 等 |
🧩 熟悉结构用 |
📁 kernel/ — xv6 的心脏(重点模块)
xv6 主要模块可分为:
- 内核启动与内存管理:
entry.S
、start.c
、vm.c
、kalloc.c
- 中断、异常、系统调用:
trap.c
、syscall.c
、kernelvec.S
、trampoline.S
- 进程调度与管理:
proc.c
、swtch.S
- 文件系统与文件接口:
fs.c
、file.c
、bio.c
、log.c
- 设备驱动:
uart.c
、console.c
、virtio_disk.c
、plic.c
- 内核工具代码:
spinlock.c
、sleeplock.c
、printf.c
、string.c
🧾 文件级详细解释(按子系统分类)
🟩 一、内核启动与内存管理
文件 | 作用 | 说明 |
---|---|---|
entry.S |
核心启动汇编入口 | 设置页表、跳转到 start() |
start.c |
C 语言入口 | main() 前做环境初始化(页表、trapframe) |
main.c |
内核主函数 | 启动内核模块,如 userinit() |
kernel.ld |
内核链接脚本 | 指定内核段地址、符号导出顺序 |
vm.c |
虚拟内存系统 | 页表分配、拷贝、映射(基于 Sv39) |
kalloc.c |
物理页分配器 | 管理空闲页链表,用于 allocuvm |
memlayout.h |
内存布局宏 | 定义 KERNBASE、PHYSTOP 等常量 |
📌 建议从 entry.S → start.c → main.c → userinit()
跑一遍流程。
🟦 二、进程管理与调度
文件 | 作用 | 说明 |
---|---|---|
proc.c |
管理进程表、fork/wait | scheduler() 是调度器核心 |
proc.h |
进程结构体定义 | 结构体 struct proc 包含页表、状态、trapframe |
swtch.S |
上下文切换汇编 | 保存/恢复寄存器,调度必用 |
trap.c |
trap/中断入口 | 用户 → 内核的总入口;异常调度、syscall 都走它 |
sysproc.c |
与进程相关的系统调用 | sys_exit 、sys_fork 、sys_wait |
📌 强烈建议:给 fork()
、scheduler()
、yield()
加打印观察运行。
🟨 三、系统调用机制
文件 | 作用 | 说明 |
---|---|---|
syscall.c |
syscall 分发器 | 根据 syscall num 分发到 sys_* |
syscall.h |
syscall 编号 | 用 #define SYS_write 1 等映射 |
sysfile.c |
文件相关 syscall | open/close/read/write 的内核实现 |
usys.pl → usys.S |
用户态 syscall 包装 | 生成用户代码 mov a7, id; ecall |
📌 syscall 流程 = 用户态 ecall
→ trap → syscall.c → sys_*()
🟧 四、文件系统与 I/O 接口
文件 | 作用 | 说明 |
---|---|---|
fs.c |
inode 层 | ialloc , readi , writei ,文件核心结构 |
fs.h |
inode 定义 | struct inode ,块地址信息等 |
file.c |
文件描述符层 | struct file ,管理 open/close 等 |
file.h |
文件描述符定义 | 支持 pipe/dev/inode 等类型 |
bio.c |
缓存块读写 | 实现 block 级读写缓存 |
log.c |
日志机制 | crash-safe 写操作事务(write-ahead logging) |
pipe.c |
管道实现 | 内存中双向 FIFO |
fcntl.h , stat.h |
POSIX 相关头文件 | 用于 open flag、stat 结构体 |
📌 建议调试 fs.c
的 namei()
、dirlookup()
,看路径如何被解析。
🟥 五、设备驱动与中断控制
文件 | 作用 | 说明 |
---|---|---|
uart.c |
串口驱动 | 初始化串口,写入字符给终端 |
console.c |
控制台 I/O | 与 UART 配合实现 shell 输入输出 |
plic.c |
中断控制器 | Platform-Level Interrupt Controller |
virtio_disk.c |
虚拟磁盘驱动 | QEMU 虚拟磁盘硬件访问层 |
virtio.h |
virtio 设备定义 | 配套数据结构 |
📌 virtio_disk.c
调试方法:观察 virtio_rw()
实现的读写逻辑。
🟫 六、工具类 / 内核库函数
文件 | 作用 | 说明 |
---|---|---|
defs.h |
内核函数声明 | extern 所有模块函数,供全局使用 |
riscv.h |
RISC-V CSR 宏、寄存器定义 | 包含 rdtime , csrr , sstatus 等 |
spinlock.c/.h |
自旋锁实现 | 核心互斥机制,需关中断 |
sleeplock.c/.h |
睡眠锁实现 | 用于文件系统,sleep/wakeup 管理 |
string.c |
libc 实现 | memcpy , strlen 等内核自带函数 |
printf.c |
内核级 printf | 用于调试打印,无缓冲版 |
param.h |
系统参数宏 | 定义 NPROC , MAXPATH 等全局参数 |
types.h |
常用类型定义 | uchar , uint , sint 等简写 |
📌 常用 grep 命令:grep -rn "spin_lock" kernel/
追踪并发点
📁 user/ — 用户态程序与测试
文件 | 作用 | 说明 |
---|---|---|
*.c |
命令程序 | shell 命令如 ls , cat , echo , sh 等 |
init.c |
首个用户进程 | userinit() 启动的程序,运行 /init |
initcode.S |
最原始的用户态代码 | 由 userinit() 载入的程序(汇编) |
ulib.c |
libc 函数 | 用户态的 malloc , printf 等 |
umalloc.c |
malloc 实现 | 用户态堆分配 |
usertests.c |
用户态测试集 | 测试 syscall、进程、文件功能 |
user.ld |
用户态链接脚本 | 控制用户程序的段分布 |
user.h |
函数声明 | 供用户程序引用 printf , fork 等接口 |
📌 强烈推荐你从 init.c
开始 debug,第一个用户进程的运行关键路径!
📁 mkfs/ — 构建文件系统镜像工具
文件 | 说明 |
---|---|
mkfs.c |
构建 xv6 文件系统镜像(user/init 等文件压入) |
📌 不看也无妨,用于 make
阶段构建 fs.img
📄 顶层文件
文件 | 说明 |
---|---|
Makefile |
编译入口,构建 kernel , fs.img , qemu 等 |
README |
简要说明文档,讲解如何使用 |
LICENSE |
授权条款(MIT) |
✅ 总结
- 用 模块化思维 分阶段学,比如 “先把 trap 理清楚”,再看 syscall。
- 推荐搭配如下工具:
- tmux
- zsh
- grep…
xv6-riscv_struct