Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 系统与高性能 / Systems & Performance

xv6 源码学习 / xv6 Source Learning

1. xv6 源码学习专题 / xv6 Source Learning

2. xv6 学习路线:从 C 指针到操作系统源码 / xv6 Learning Roadmap

3. 读 xv6 必备的 C 语言和指针基础 / C And Pointers For xv6

4. 读 xv6 必备的 RISC-V 基础 / RISC-V Basics For xv6

5. 如何阅读 xv6 源码 / How To Read xv6 Source

6. xv6 启动与内核入口 / xv6 Boot And Kernel Entry

7. xv6 内存布局与页表 / xv6 Memory Layout And Page Tables

8. xv6 trap、中断与系统调用 / xv6 Traps Interrupts And System Calls

9. xv6 进程与 struct proc / xv6 Process And struct proc

10. xv6 上下文切换与调度器 / xv6 Context Switch And Scheduler

11. xv6 sleep/wakeup、wait 与 exit / xv6 Sleep Wakeup Wait And Exit

12. xv6 锁与并发 / xv6 Locks And Concurrency

13. xv6 文件描述符与 inode / xv6 File Descriptor And Inode

14. xv6 文件系统与日志 / xv6 File System And Log

15. xv6 设备驱动、console、UART 与磁盘 / xv6 Device Driver Console UART And Disk

16. xv6 用户程序与 shell / xv6 User Programs And Shell

17. 用 QEMU/GDB 调试 xv6 / Debugging xv6 With QEMU And GDB

18. 从 xv6 过渡到 Linux 0.11 / Bridge From xv6 To Linux 0.11

19. xv6 专题总结与实践项目 / xv6 Summary And Practice Projects

本页目录

从 xv6 过渡到 Linux 0.11 / Bridge From xv6 To Linux 0.11 ​

1. 这篇文章解决什么问题 ​

学完 xv6 后,很多人会转向 Linux 0.11。

这个过渡很自然。

xv6 小而清晰。

Linux 0.11 更接近真实 Unix 历史。

但直接读 Linux 0.11 容易迷路。

原因不是 Linux 0.11 太大。

原因是它的抽象更拥挤。

xv6 的 struct proc 很集中。

Linux 0.11 的 task_struct 包含更多体系结构细节。

xv6 的调度器直接扫描进程表。

Linux 0.11 的 schedule() 带有时间片和信号处理。

xv6 的系统调用路径基于 RISC-V ecall。

Linux 0.11 的系统调用路径基于 x86 int 0x80。

本篇的目标不是完整讲 Linux 0.11。

目标是搭桥。

桥的意思是:用 xv6 里已经理解的概念去定位 Linux 0.11 中的对应物。

1.1 本文基础词小注释 ​

Linux 0.11:早期 Linux 内核版本,代码量比现代 Linux 小得多,但比 xv6 更接近真实历史系统。学习它适合放在 xv6 之后。

task_struct:Linux 0.11 里的进程描述结构。你可以先把它粗略对照 xv6 的 struct proc,但它包含更多 x86 相关字段和调度字段。

schedule:Linux 0.11 的调度函数。它和 xv6 的 scheduler() 都负责选择下一个任务,但 Linux 0.11 的策略和历史包袱更多。

x86:Linux 0.11 面向的 CPU 架构。xv6-riscv 用 RISC-V。不同架构会影响 trap、系统调用、页表、特权级切换的具体代码。

text
xv6 concept             Linux 0.11 entry
-----------             ----------------
struct proc      --->   task_struct
scheduler        --->   schedule
ecall/trap       --->   int 0x80 / trap gate
Sv39 page table  --->   x86 segmentation + paging
1
2
3
4
5
6

对照学习:不是机械找“一模一样”。更好的方法是先找相似职责,再承认差异。例如二者都有进程结构,但字段布局、调度策略、硬件机制都不同。

桥接 bridge:本篇所谓桥接,是帮你从 xv6 的清晰模型迁移到 Linux 0.11 的复杂模型。它不是替代 Linux 0.11 源码阅读。

2. 最简单的对照图 ​

先看一张粗图:

text
+----------------------+        +--------------------------+
| xv6-riscv            |        | Linux 0.11               |
+----------------------+        +--------------------------+
| struct proc          | <----> | struct task_struct       |
| scheduler()          | <----> | schedule()               |
| ecall/usertrap       | <----> | int 0x80/system_call     |
| bio.c buffer cache   | <----> | buffer.c buffer cache    |
| fs.c inode/log       | <----> | inode/super/block logic  |
| RISC-V Sv39          | <----> | x86 segmentation+paging  |
+----------------------+        +--------------------------+
1
2
3
4
5
6
7
8
9
10

这张图不是说它们完全相同。

它只是建立入口。

学习迁移时,先找相似处。

再看差异处。

最后回到各自的设计约束。

3. 本篇涉及的 xv6 源码文件 ​

kernel/proc.h 定义 struct proc 和进程状态。

kernel/proc.c 定义进程创建、退出、等待、调度。

kernel/swtch.S 保存和恢复内核上下文。

kernel/trap.c 处理系统调用和中断。

kernel/trampoline.S 处理用户态和内核态切换。

kernel/syscall.c 分派系统调用。

kernel/sysproc.c、kernel/sysfile.c 提供具体系统调用入口。

kernel/bio.c 实现 buffer cache。

kernel/buf.h 定义 struct buf。

kernel/fs.c 实现 inode 和目录。

kernel/file.c 实现文件对象和引用计数。

kernel/virtio_disk.c 连接块设备。

kernel/vm.c 实现 RISC-V 页表。

本篇会提到 Linux 0.11 的典型文件。

例如 include/linux/sched.h。

例如 kernel/sched.c。

例如 kernel/system_call.s。

例如 fs/buffer.c。

例如 fs/inode.c。

具体路径可能随整理版本略有差异。

请以你手边 Linux 0.11 源码为准。

4. 从 proc 到 task_struct ​

xv6 的进程结构叫 struct proc。

Linux 0.11 的进程结构叫 task_struct。

两者都是进程控制块。

进程控制块保存内核管理进程所需的信息。

xv6 的 struct proc 包含状态。

它包含 pid。

它包含父进程。

它包含页表。

它包含 trapframe。

它包含内核上下文。

它包含打开文件。

它包含当前目录。

Linux 0.11 的 task_struct 也包含类似信息。

但它还明显包含 x86 相关内容。

例如 TSS。

TSS 是 Task State Segment。

它是 x86 架构用于任务状态和特权级栈切换的结构。

Linux 0.11 还包含 LDT。

LDT 是 Local Descriptor Table。

它是 x86 分段机制的一部分。

这就是从 xv6 到 Linux 0.11 的第一个差异。

xv6-riscv 的进程结构偏“操作系统概念”。

Linux 0.11 的进程结构同时暴露了更多 x86 机制。

5. 进程状态对照 ​

xv6 常见状态:

text
UNUSED
USED
SLEEPING
RUNNABLE
RUNNING
ZOMBIE
1
2
3
4
5
6

Linux 0.11 常见状态包括:

text
TASK_RUNNING
TASK_INTERRUPTIBLE
TASK_UNINTERRUPTIBLE
TASK_ZOMBIE
TASK_STOPPED
1
2
3
4
5

TASK_RUNNING 不完全等于“正在 CPU 上运行”。

它更接近“可以运行或正在运行”。

xv6 则把 RUNNABLE 和 RUNNING 分开。

这是阅读差异之一。

不要机械翻译状态名。

要问调度器如何解释这个状态。

状态含义由调度代码定义。

状态不是孤立枚举。

6. 进程表组织方式 ​

xv6 使用固定大小数组:

text
struct proc proc[NPROC]
1

调度器扫描这个数组。

Linux 0.11 也有任务数组的味道。

它使用 task[NR_TASKS] 这样的结构组织任务。

这与现代 Linux 的链表、红黑树、CFS 差别很大。

所以 Linux 0.11 对 xv6 学习者很友好。

它仍然能看见简单扫描。

但 Linux 0.11 已经加入时间片、优先级、信号等因素。

因此它不是 xv6 的简单放大版。

它是更真实的早期 Unix-like 内核。

7. 从 scheduler() 到 schedule() ​

xv6 的 scheduler() 是每个 CPU 的调度循环。

它不断扫描进程表。

找到 RUNNABLE 进程。

设置为 RUNNING。

通过 swtch 切换到进程上下文。

进程让出 CPU 后再切回来。

Linux 0.11 的 schedule() 更像一个被调用的调度函数。

它选择下一个可运行任务。

它考虑 counter。

counter 可以理解为剩余时间片。

时间片是进程本轮还能运行多久的预算。

Linux 0.11 还考虑 priority。

priority 是静态优先级或权重。

当所有 counter 都耗尽时,Linux 0.11 会重新计算 counter。

粗略图:

text
xv6:
scheduler loop -> find RUNNABLE -> swtch

Linux 0.11:
schedule -> scan task[] -> choose max counter runnable task -> switch_to
1
2
3
4
5

8. 调度策略的差异 ​

xv6 调度策略非常朴素。

它接近轮询式。

它主要用于教学。

Linux 0.11 已经体现时间片调度。

时间片让 CPU 分配更可控。

counter 大的任务更可能被选中。

counter 用完后会衰减并补充。

这带来两个学习点。

第一,调度器不是只处理“能不能运行”。

它还处理“谁更应该运行”。

第二,调度策略和进程状态不同。

状态回答资格。

策略回答选择。

9. 上下文切换对照 ​

xv6 的上下文结构在 kernel/proc.h。

它保存 ra、sp 和 callee-saved registers。

callee-saved registers 是调用约定要求被调用者保持的寄存器。

swtch.S 保存旧上下文并恢复新上下文。

Linux 0.11 在 x86 上使用 switch_to。

它涉及寄存器保存。

它也涉及 TSS/LDT 等 x86 机制。

x86 的历史包袱更多。

RISC-V 的路径更直。

对照思路:

text
What must survive a context switch?
  |
  +-- kernel stack position
  +-- return address or instruction point
  +-- callee-saved registers
  +-- address space related state
  +-- architecture-specific task state
1
2
3
4
5
6
7

用这个问题读两边,比逐行硬背更稳。

10. 系统调用路径对照 ​

xv6-riscv 使用 ecall。

Linux 0.11 on x86 使用 int 0x80。

两者都是从用户态进入内核的受控入口。

RISC-V 路径:

text
user stub
  |
  v
ecall
  |
  v
trampoline.S uservec
  |
  v
trap.c usertrap
  |
  v
syscall.c syscall
1
2
3
4
5
6
7
8
9
10
11
12
13

x86 Linux 0.11 路径:

text
user library
  |
  v
int 0x80
  |
  v
system_call.s
  |
  v
sys_call_table
  |
  v
sys_* function
1
2
3
4
5
6
7
8
9
10
11
12
13

共同点:

用户态不能直接调用内核 C 函数。

必须通过特权级入口。

系统调用号决定分派目标。

参数按 ABI 约定传递。

返回值再按 ABI 约定放回寄存器。

11. trapframe 与寄存器保存 ​

xv6 有显式 struct trapframe。

它保存用户寄存器。

系统调用参数保存在 a0 到 a5。

系统调用号保存在 a7。

Linux 0.11 的 x86 入口会在汇编中保存寄存器。

x86 传统上用 eax 放系统调用号。

参数可通过 ebx、ecx、edx 等寄存器传递。

不要死记某个寄存器。

要理解入口汇编保存了什么。

要理解 C 函数从哪里取参数。

要理解返回值写回哪里。

这是跨架构阅读系统调用的稳定方法。

12. x86 与 RISC-V 的大差异 ​

RISC-V 是相对现代、简洁的 RISC 架构。

x86 是历史很长、兼容负担较重的 CISC 架构。

CISC 表示复杂指令集计算机。

RISC 表示精简指令集计算机。

Linux 0.11 的 x86 代码会出现分段。

分段是 x86 早期内存保护和地址转换机制。

它使用段选择子和描述符。

xv6-riscv 基本不让你处理这种历史复杂性。

RISC-V xv6 主要围绕页表和特权级。

x86 Linux 0.11 则同时涉及分段和分页。

这会让新读者觉得“多出来很多奇怪结构”。

不要恐慌。

先把它们归类为架构适配层。

13. 地址空间对照 ​

xv6 每个进程有 pagetable。

exec 创建新用户页表。

fork 复制父进程地址空间。

Linux 0.11 也要管理进程地址空间。

但它受 x86 80386 分段分页模型影响。

你会看到基址、限长、页目录、页表等概念。

页目录是 x86 两级分页中的顶层结构。

页表是下一级结构。

xv6 RISC-V Sv39 是三级页表。

Linux 0.11 x86 是两级分页。

对照图:

text
xv6 RISC-V Sv39:
VA -> L2 -> L1 -> L0 -> PA

Linux 0.11 x86:
logical address -> segment translation -> linear address -> page directory -> page table -> physical address
1
2
3
4
5

这张图是过渡关键。

Linux 0.11 不是只多一级页表。

它还多了分段到线性地址的阶段。

14. fork 对照 ​

xv6 的 fork 做几件事。

分配 struct proc。

复制用户内存。

复制 trapframe。

复制打开文件引用。

复制当前目录引用。

设置父子关系。

让子进程 RUNNABLE。

Linux 0.11 的 fork 也要创建任务。

它会复制 task_struct。

它会设置 TSS/LDT。

它会复制或共享部分资源。

它会处理页表。

Linux 0.11 已经有写时复制的影子或实现。

写时复制叫 copy-on-write。

它表示 fork 时先共享物理页。

当某一方写入时再复制。

xv6 标准实现通常直接复制用户内存。

所以 xv6 更易懂。

Linux 0.11 更接近性能现实。

15. exec 对照 ​

xv6 的 exec 读取 ELF。

Linux 0.11 读取的是当时支持的可执行格式。

早期 Linux 有 a.out 相关历史。

现代读者熟悉 ELF,但 Linux 0.11 的历史格式不同。

不要因为格式不同就迷路。

exec 的核心语义不变。

它替换当前进程的用户程序。

它通常保留 pid。

它通常保留部分进程属性。

它重建用户地址空间。

它设置入口地址和用户栈。

所以读 Linux 0.11 exec 时,先问:

程序文件怎么验证?

代码和数据怎么装入?

栈怎么布置?

入口地址写到哪里?

旧地址空间怎么释放?

16. wait/exit 对照 ​

xv6 的 exit 把进程变成 ZOMBIE。

xv6 的 wait 回收 ZOMBIE 子进程。

Linux 0.11 也有退出和等待。

但它还涉及信号。

信号是内核通知进程事件的一种机制。

例如子进程退出可以通知父进程。

Linux 的父子关系和会话、进程组等概念更丰富。

xv6 只保留最核心模型。

过渡时要把基本模型抓牢:

text
child exits
  |
  v
exit status remains
  |
  v
parent waits
  |
  v
kernel releases task record
1
2
3
4
5
6
7
8
9
10

然后再加 Linux 的信号和作业控制细节。

17. buffer cache 对照 ​

xv6 的 buffer cache 在 kernel/bio.c。

它缓存磁盘块。

它保证同一块在缓存中只有一个有效 buffer。

它用引用计数和锁管理并发。

Linux 0.11 也有 buffer cache。

它同样缓存块设备数据。

但 Linux 0.11 的 buffer 管理更复杂。

它有 hash 队列。

它有 free list。

它有脏块。

脏块是内存中已修改但尚未写回磁盘的块。

xv6 的日志系统让写入路径更教学化。

Linux 0.11 的缓存更接近实际块设备性能需求。

对照问题:

如何按设备号和块号查找 buffer?

如何避免同一块出现两个缓存副本?

如何标记数据是否有效?

如何标记数据是否脏?

何时写回磁盘?

谁在等待 I/O 完成?

18. 文件系统对照 ​

xv6 文件系统包含 inode、目录、日志、buffer cache。

inode 是文件元数据对象。

它记录类型、大小、链接数和数据块地址。

目录是特殊文件。

目录内容是名字到 inode 号的映射。

Linux 0.11 文件系统也围绕 inode。

但它的 VFS 抽象还很早期。

现代 Linux 的 VFS 更复杂。

Linux 0.11 适合作为中间阶段。

它比 xv6 更真实。

但还没有现代 Linux 那么庞大。

对照图:

text
pathname
  |
  v
directory lookup
  |
  v
inode
  |
  v
block mapping
  |
  v
buffer cache
  |
  v
disk driver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

这条链在 xv6 和 Linux 0.11 中都成立。

不同的是结构层数和缓存策略。

19. 文件描述符对照 ​

xv6 进程有 ofile[NOFILE]。

每个元素指向 struct file。

struct file 再指向 inode、pipe 或 device。

Linux 0.11 也有进程打开文件表。

它会关联 file 结构和 inode。

核心思想一致:

文件描述符是进程局部的小整数。

file 对象是内核中的打开文件状态。

inode 是文件本体的元数据。

不要把 fd、file、inode 混成一个概念。

这三个层次在两个系统里都很重要。

20. 锁与并发对照 ​

xv6-riscv 明确展示 spinlock 和 sleeplock。

它是多核教学系统。

Linux 0.11 诞生于更早的单处理器时代背景。

很多并发问题表现不同。

早期 Linux 代码中常见的是关中断、睡眠队列、引用计数等机制。

不要用现代 SMP Linux 的锁模型套 Linux 0.11。

也不要用 xv6 的锁命名机械套过去。

过渡时问同一个问题:

共享对象是什么?

不变量是什么?

谁可能并发访问?

等待条件是什么?

谁负责唤醒?

这个问题框架比术语更稳定。

21. 中断与异常对照 ​

xv6 的 trap 统一处理系统调用、中断、异常。

scause 表明原因。

sepc 表明返回位置。

stval 提供异常相关地址或值。

Linux 0.11 x86 使用 IDT。

IDT 是 Interrupt Descriptor Table。

它保存中断和异常入口描述符。

系统调用通过 int 0x80 进入。

页错误通过 page fault 异常进入。

时钟中断通过中断入口进入。

概念桥:

text
RISC-V stvec      <-> x86 IDT entry
RISC-V scause     <-> x86 vector/error code
RISC-V sepc       <-> x86 saved EIP
RISC-V sret       <-> x86 iret
1
2
3
4

名字不同。

角色相似。

22. 为什么不能逐字对应 ​

桥不是翻译表。

桥只是帮助定位。

有些概念在一个系统中很显式。

在另一个系统中可能被架构机制隐藏。

有些概念在 xv6 中为了教学被简化。

在 Linux 0.11 中为了实际运行被扩展。

有些概念在 Linux 0.11 中存在历史限制。

现代系统已经换了实现。

所以读 Linux 0.11 时要避免两个极端。

不要觉得“这和 xv6 不一样,所以我全不懂”。

也不要觉得“这和 xv6 名字像,所以完全一样”。

正确姿势是相似定位,差异追问。

23. 建议阅读顺序 ​

先用 xv6 复习进程生命周期。

再打开 Linux 0.11 的 sched.h。

找到 task_struct。

只标注字段类别。

不要一开始背字段。

再读 sched.c 的 schedule()。

重点看任务选择条件。

然后读系统调用入口汇编。

找到系统调用号如何分派。

再读 buffer cache。

观察块号查找和引用计数。

最后读文件系统路径。

把 pathname、inode、buffer 连接起来。

每一步都拿 xv6 做参照。

24. 对照阅读表:进程 ​

问题:进程状态保存在哪里?

xv6:struct proc。

Linux 0.11:task_struct。

问题:当前进程如何表示?

xv6:每 CPU struct cpu 中的 proc。

Linux 0.11:有 current 相关机制。

问题:父子关系在哪里?

xv6:p->parent。

Linux 0.11:father 等字段。

问题:内核栈在哪里?

xv6:每进程 kernel stack。

Linux 0.11:与 task 结构和页布局关系紧密。

问题:地址空间在哪里?

xv6:pagetable。

Linux 0.11:页目录、LDT、内存管理字段共同参与。

25. 对照阅读表:调度 ​

问题:谁能被选中?

xv6:RUNNABLE。

Linux 0.11:TASK_RUNNING 且 counter 等条件合适。

问题:选择标准是什么?

xv6:简单扫描。

Linux 0.11:选择 counter 最大的任务。

问题:何时重新计算预算?

xv6:没有复杂时间片预算。

Linux 0.11:counter 用尽后按 priority 重新计算。

问题:切换动作在哪里?

xv6:swtch。

Linux 0.11:switch_to。

问题:体系结构状态在哪里暴露?

xv6:较少。

Linux 0.11:TSS/LDT 更显眼。

26. 对照阅读表:系统调用 ​

问题:用户态入口指令是什么?

xv6:ecall。

Linux 0.11:int 0x80。

问题:系统调用号在哪里?

xv6:a7。

Linux 0.11:通常在 eax。

问题:入口汇编做什么?

xv6:trampoline.S 保存寄存器并切页表。

Linux 0.11:system_call.s 保存寄存器并分派。

问题:分派表在哪里?

xv6:syscalls[]。

Linux 0.11:sys_call_table。

问题:返回值在哪里?

xv6:a0。

Linux 0.11:通常在 eax。

27. 对照阅读表:文件系统 ​

问题:路径名怎么解析?

xv6:namei、namex。

Linux 0.11:路径解析函数和 inode 查找。

问题:文件元数据在哪里?

xv6:struct inode。

Linux 0.11:struct m_inode 等。

问题:磁盘块怎么缓存?

xv6:struct buf 和 bcache。

Linux 0.11:buffer_head 和 buffer cache。

问题:写入如何保证一致性?

xv6:日志系统。

Linux 0.11:buffer 写回和文件系统自身规则。

问题:打开文件状态在哪里?

xv6:struct file。

Linux 0.11:file table / file structure。

28. 常见误解 ​

误解一:Linux 0.11 是 xv6 的复杂版。

不准确。

它们目标不同,架构不同,历史语境不同。

误解二:task_struct 字段都必须先背下来。

不需要。

先按职责分类。

误解三:TASK_RUNNING 等于正在 CPU 上运行。

不总是。

要看调度器如何使用。

误解四:x86 分段可以忽略。

不能完全忽略。

Linux 0.11 的很多初始化和进程切换会碰到它。

误解五:buffer cache 只是性能优化。

不只是。

它还维护块的一致视图和 I/O 同步边界。

误解六:文件描述符就是 inode。

不是。

fd、file、inode 是三层概念。

29. 小实验:画进程字段映射 ​

实验目标:建立 proc 到 task_struct 的地图。

先列 xv6 struct proc 字段。

给每个字段标注职责。

再列 Linux 0.11 task_struct 字段。

尝试归类:

text
identity
state
scheduling
parent-child
address space
open files
signal
architecture state
1
2
3
4
5
6
7
8

不要追求一一对应。

追求知道字段属于哪类问题。

30. 小实验:比较调度选择 ​

实验目标:理解 scheduler 和 schedule 的差异。

在 xv6 中阅读 scheduler()。

写出它选进程的条件。

在 Linux 0.11 中阅读 schedule()。

写出它选任务的条件。

比较:

是否考虑时间片。

是否考虑优先级。

是否处理信号。

是否扫描固定数组。

最后写一句总结:哪个系统更教学,哪个系统更实际。

31. 小实验:追踪系统调用号 ​

实验目标:跨架构比较系统调用入口。

在 xv6 中追踪 write。

确认 a7 是系统调用号。

在 Linux 0.11 中追踪一个系统调用宏或汇编入口。

确认 eax 或相应寄存器如何放调用号。

画出两条路径。

把共同点标为“机制”。

把寄存器和入口指令标为“架构细节”。

这能训练你区分本质和实现。

32. 小实验:比较 buffer cache ​

实验目标:理解缓存块的不变量。

先在 xv6 中找到 bget。

写下它如何查找已有 buffer。

写下它如何回收空闲 buffer。

再在 Linux 0.11 中找到 buffer 获取函数。

观察是否有 hash。

观察是否有 free list。

观察脏块如何表示。

核心问题:

同一磁盘块是否可能有两个内存副本?

如果不能,代码如何保证?

33. 小实验:文件系统路径追踪 ​

实验目标:从文件名走到磁盘块。

在 xv6 中追踪 open("x")。

路径大致经过 sys_open、namei、ilock、readi、bmap、bread。

在 Linux 0.11 中追踪打开文件路径。

找出路径解析。

找出 inode 获取。

找出 block read。

最后画图:

text
name -> inode -> block number -> buffer -> disk
1

如果能画出来,就说明桥搭起来了。

34. 学习迁移策略 ​

第一步,用 xv6 给概念命名。

第二步,在 Linux 0.11 找对应入口。

第三步,列出相似职责。

第四步,列出架构差异。

第五步,列出历史差异。

第六步,用小实验验证一个路径。

第七步,回到源码补细节。

不要试图一口气读完整个 Linux 0.11。

系统学习最怕“全部都重要”。

先选一条路径读穿。

再横向扩展。

35. 本篇总结 ​

xv6 给你的是清晰骨架。

Linux 0.11 给你的是更真实的早期 Unix-like 内核。

从 xv6 到 Linux 0.11 的桥不是名字映射。

它是问题映射。

进程问题映射到 task_struct。

调度问题映射到 schedule()。

系统调用问题映射到 system_call。

块 I/O 问题映射到 buffer cache。

文件名问题映射到 inode 和目录。

架构问题映射到 x86 分段、分页、TSS、LDT。

最终要记住:

text
same operating-system questions,
different historical and architectural answers.
1
2

带着这个心智模型读 Linux 0.11,会比从第一行硬啃轻松很多。

最后更新于:

Pager
上一篇17. 用 QEMU/GDB 调试 xv6 / Debugging xv6 With QEMU And GDB
下一篇19. xv6 专题总结与实践项目 / xv6 Summary And Practice Projects

持续记录,持续成长

Copyright © Tidenflow