你在 AWS Lambda 上跑一段 Python。请求来了,函数执行,返回。整个过程里你没装 systemd、没调 /proc、没 apt install。看起来,“操作系统”这件事好像消失了。
但你稍微往下挖一点就会发现:Lambda 把你的函数跑在 Firecracker microVM 里;Firecracker 里是一个裁剪过的 Linux 内核,启动时间 125ms;这个 Linux 上跑着一个 Python runtime,由一个极简的 init(不是 systemd,是 Firecracker 自己写的一个 /sbin/init)拉起来。你的”一行函数”下面,仍然压着一整套 OS。
这就是 2025 年的 OS 景象:向上,OS 被越来越厚的 runtime / 容器 / serverless / AI framework 遮住;向下,OS 要面对 CXL、DPU、机密计算、异构加速器等越来越多样的硬件。 它不仅没消失,反而在”被隐藏”和”变复杂”这两个相反方向上同时加速。
这篇文章不是教材式的定义,而是要回答一个工程问题:OS 到底在做什么? 我们会拆出五件它不得不做的事情,然后拿这五件事去丈量宏内核、微内核、VMM、unikernel、serverless 各种形态,看谁做了哪些、代价是什么、边界在哪里。这既是本系列的开篇,也是一把后续几乎每一章都要反复用到的尺子。
一、先破除两个常见定义
打开任何一本教科书,“操作系统”一般被定义成两件事之一:
定义 A(资源管理视角):操作系统是管理计算机硬件资源、为应用程序提供服务的系统软件。
定义 B(抽象机器视角):操作系统在裸机之上构造一台”抽象机器”,让应用程序以更方便的方式使用硬件。
这两种定义在教学里没错,但在工程里都容易误导。
1.1 “资源管理” 掩盖了隔离和安全
“管理资源”听起来像是一个纯粹的调度 / 分配问题。但 Linux 内核源码里,与”资源管理”直接相关的代码(调度器、内存分配、I/O 调度)加起来不过几十万行,而整个内核是 3000 万行量级(Linux 6.6 统计约 3400 万行)。剩下的代码在干什么?大部分在做驱动、安全、隔离、可观测、协议栈——这些都不是狭义的”资源管理”。
如果你以”资源管理”为视角,会很容易忽略一个事实:现代 OS 的绝大部分复杂度,来自于”在不信任的用户空间之间隔离资源”,而不是”分配资源”本身。分配一页内存是简单的;在多个 cgroup、多个 namespace、多个用户之间把这页内存准确地归属、计费、限流、回收,才是真正的难题。
1.2 “抽象机器”掩盖了透明度
“提供抽象机器”是一种美化。实际上,OS 提供的抽象经常在 漏。mmap 的性能取决于页缓存脏页比例;read() 的延迟依赖于块层的队列深度;accept() 的尾延迟来自于 softirq 的堆积;fork 的成本主要在页表复制。
一个好的 OS 不是提供”完美的抽象机器”,而是在抽象之下 留出足够多的观察孔和调节旋钮,让工程师可以在需要时看透抽象,调整行为。Linux 上散落在 /proc、/sys、tracefs 里的数万个可调参数,就是这种透明度的体现。OS 的职责之一,是管理自己的抽象漏点。
1.3 回到工程视角
如果把上面两条教科书定义合起来再加上工程补丁,我们会得到一个更贴近现实的表述:
操作系统是一段常驻的、具备特权的软件,它在硬件之上为多个互不信任的工作负载构造可以复用、可观测、可治理的执行环境。
关键词是五个:特权、多个、互不信任、复用、可治理。少掉任何一个,就不是一个完整意义上的 OS——而是某种退化形态(下文会展开)。
下面这张图把本系列反复会用的”五件事”摆出来,便于下面章节对照。
flowchart LR
App[应用进程] --> K{OS 内核}
K --> A1[抽象<br/>fd / 虚地址 / task]
K --> A2[复用<br/>多路调度 / 分时]
K --> A3[隔离<br/>ns / cgroup / MMU]
K --> A4[策略<br/>调度器 / 回收 / 限流]
K --> A5[可观测<br/>proc / tracefs / eBPF]
A1 --> HW[(硬件)]
A2 --> HW
A3 --> HW
A4 --> HW
A5 --> HW
图中五个分支是下文评估所有 OS 形态的五把尺子:任何一个 OS(宏内核、微内核、unikernel、serverless)最终都要解释清楚它把这五件事各自做到了什么程度、以什么方式做。
二、OS 的五件事
我把现代 OS 必须做的工作抽象成五件事。顺序是有意义的:后一件通常依赖前一件。
2.1 资源抽象(Abstraction)
CPU 是一组寄存器与 ISA;磁盘是带坏块、带 ECC、带通道的一堆 NAND;网卡是一个带收发队列的 PCIe 设备。应用程序不应该直接面对这些东西。OS 把它们抽象成:
- 进程 / 线程:CPU 的时间切片 + 寄存器状态 + 地址空间
- 文件:字节流 + inode 元数据
- Socket:双向字节流(或数据报)+ 协议状态机
- 页:固定大小的物理内存块 + 翻译映射
这些抽象之所以有用,是因为它们 稳定且可组合:无论底层是 HDD 还是 NVMe,read(fd, buf, n) 的语义不变;无论底层是 Ethernet 还是 InfiniBand,send/recv 的语义不变。稳定的 ABI 是 OS 的产品接口。这条我们会在后面章节(A-05 syscall ABI、J-86 稳定 ABI)展开。
注意:抽象不是免费午餐。read(2) 与 io_uring 对同一块磁盘 I/O 的性能差可以到 3-5 倍。抽象选得不好就会卡住上层性能。这也是为什么 io_uring、XDP、DPDK 这些”旁路 OS 抽象”的机制会出现。
2.2 资源复用(Multiplexing)
一台机器上有 100 个进程,它们共享 16 个 CPU 核、64GB 内存、2 张网卡。复用是 OS 的日常:
- 时间复用:调度器在线程之间切换(C 系列)
- 空间复用:页表把物理内存切片给多个地址空间(D 系列)
- 设备复用:同一块网卡被多个 socket 共享(网络百科)
复用的核心挑战是 切换开销。一次完整的进程上下文切换在 x86_64 上大约 1-3μs,包含寄存器保存、TLB 刷新(部分)、调度器决策。在高频切换场景(比如每秒百万级请求的网络服务),切换开销本身可能成为瓶颈。这是为什么出现了协程 / 用户态调度、ktls、io_uring SQPOLL 等减少切换的机制。
切换开销不是 OS 设计的”浪费”,而是”复用”的税。你可以通过少让 OS 参与来降低这个税(unikernel、kernel-bypass),但你也就放弃了复用带来的好处。
2.3 资源隔离(Isolation)
如果只有一个工作负载,OS 大部分代码都不需要写。OS 的存在感 80% 来自”隔离”。
隔离有多种层次:
- 地址空间隔离(MMU + 页表,D-30)
- 权限隔离(ring0/ring3、EL0-3,A-04)
- 资源配额隔离(cgroup v2,B-18)
- 命名空间隔离(namespaces,B-17)
- 强制访问控制(SELinux / AppArmor,L-97)
- 硬件辅助隔离(VMX/SVM、SEV-SNP、TDX,L-101、M-108)
每一层隔离都对应一种”攻击面”或”故障传播面”。实际部署中往往是多层叠加:Kubernetes pod 就同时依赖 cgroup、namespace、seccomp、SELinux、AppArmor 至少五种机制。隔离做不好的代价有三种:
- 安全崩塌:A 进程偷到 B 进程的内存 / 秘密 / 权限(典型如 Meltdown/Spectre)
- 噪声邻居:A 进程抢光 CPU / IO 配额,B 进程变慢
- 故障传播:A 进程耗尽 inode / fd / PID,整机不可用
这三种是本系列反复出现的受害者。一个好 OS 的标志,是能把”隔离失败”限定在一个有限的范围并快速恢复。
2.4 公平与策略(Policy)
隔离保证”互不干扰”,但资源总量有限。OS 必须在用户之间做取舍。调度、内存、I/O、网络四个维度都有自己的公平策略:
- CPU:CFS 的 vruntime / EEVDF 的 eligible-virtual-deadline(C-20、C-21)
- 内存:cgroup v2 memory.low/min、PSI 驱动的 oomd(D-38)
- I/O:io.weight / io.max、blk-cgroup(F/G 系列 + 存储百科)
- 网络:tc qdisc(fq、fq_codel、cake)
“公平” 不是唯一可能的策略。实时系统里更常见是 优先级 或 预算保证(C-23 SCHED_DEADLINE)。多租户系统里是 配额。OS 的价值不在于选某一种策略,而在于把 策略 与 机制 分开:机制是如何切换、如何计量、如何限流;策略是”谁得多少、谁优先”。这种分离(由 Mach 和 L4 这一脉微内核推向极致)让同一套机制可以服务不同的策略。
2.5 可观测性(Observability)
第五件事在教科书里常常缺席,但在工程里比前四件都重要:如果
OS
不可观测,前四件事都无法验证。你说调度是公平的?拿出数据。你说内存足够?给我
MemAvailable 的定义。你说 I/O 队列深度?打开
/sys/block/
现代 Linux 把可观测性做成了几个子系统:
- /proc(进程 / 全局状态的文本视图)
- /sys(内核对象模型的树状视图)
- tracefs / debugfs(事件流)
- perf_event_open(硬件 PMU)
- eBPF(可编程观察点)
- netlink taskstats(内核 → 用户态流式推送)
这些机制加起来构成了 Linux 的可观测性平面。FreeBSD 的 DTrace、Solaris 的 kstat/mdb、macOS 的 os_signpost 是同一个职责的不同实现。一个不可观测的 OS 等于一个不可调试的 OS,在生产里是不可接受的——这是为什么许多实时/嵌入式 OS 在走向产品化时都在补可观测性。
三、五件事的”组合学”
五件事之间不是并列关系,而是 依赖 + 权衡 的关系。拿一些实际的 OS 形态来丈量:
┌───────────────────────────────────────────────────────────────────────┐
│ 抽象 复用 隔离 策略 可观测 │
├───────────────────────────────────────────────────────────────────────┤
│ 裸机 monitor (1950s) ● ◐ ○ ○ ○ │
│ 单用户 DOS ● ○ ○ ○ ◐ │
│ Unix V7 ● ● ◐ ◐ ◐ │
│ 宏内核 Linux 6.x ● ● ● ● ● │
│ 微内核 (Mach/L4) ● ● ● ● ◐ │
│ VMM + Guest OS ● ● ● ● ● │
│ Unikernel ● ○ ○ ◐ ○ │
│ Serverless (Lambda) ● ● ●(VM)●(配额)●(平台侧) │
└───────────────────────────────────────────────────────────────────────┘
● 一等公民 ◐ 有限实现 ○ 基本没有
读这张表的关键在于 注意空缺:
- Unikernel(MirageOS、Unikraft)放弃了”复用”和”隔离”——一个 unikernel 里只跑一个应用。它靠下面的 VMM 把这两件事外包给虚机监控程序。
- DOS 没有隔离,也没有复用。它就是个加载器。今天把它归为 OS 只是历史惯性。
- Serverless 在用户视角看几乎丢失了全部五件事,但从平台视角看,它把这五件事整体上移了一个抽象层(用 microVM + 控制面做)。
这张表的结论:OS 的五件事可以被”外包”给其他层次做(虚机、容器、平台),但它们不会凭空消失。这是为什么 unikernel / 轻量容器 / serverless 的成功,恰恰依赖一个健壮的 guest OS 或 host OS。
四、“一切皆文件”和它的暗面
Unix 的口号”一切皆文件”(everything is a file)是 OS 抽象设计的一个经典范式。进程通过 fd 操作文件、管道、socket、字符设备、甚至 Linux 上的 /proc/self/mem、signalfd、timerfd、eventfd、pidfd。
这种抽象的好处是显而易见的:
- 统一 API:read / write / close / poll 一套接口应对一切
- 可组合性:管道、重定向、fd-passing 构成了 Unix shell 生态
- 可观测性:lsof 一条命令看所有进程持有什么
但这个抽象 漏。下面列四个最大的漏点。
4.1 “文件”抽象不含生命周期信号
read(fd) 只能返回”已到的字节数”。它告诉不了你”对端主动关闭”与”对端超时”、“对端 OOM 被杀”的区别。Unix 需要一个带外的 errno、SIGPIPE、epoll EPOLLRDHUP 等补丁才能表达这些语义。这是 Unix 抽象最大的失败之一,它导致几乎所有网络服务都要手写一套”心跳、超时、重连”的上层协议。
4.2 “文件”抽象不含事务语义
write(fd, buf, n) 不保证原子性,除非 n <= PIPE_BUF(通常 4096)。对一个普通磁盘文件,write(2) 甚至可能部分写入。fsync、fdatasync、O_SYNC、O_DIRECT 四种机制叠加才勉强表达”写落到稳定存储”这个事务语义——这在存储百科 11-linux-async-io、12-data-integrity 里有完整讨论。
4.3 “文件”抽象不含类型系统
Unix 里,open(“/dev/kvm”) 和 open(“/etc/passwd”) 返回同一种 fd。类型信息隐式地附加在 ioctl 的命令号里。这种”弱类型”让 Unix 系统编程既灵活又危险——errno=ENOTTY 的根因几乎一定是这种类型混淆。Plan 9 的 9P 协议试图修正这个问题,把类型与操作绑定;NT 的 handle + object type 也走了类型化路线;但 Linux 没有采用。
4.4 “文件”抽象不含命名空间
open(“/etc/passwd”) 解析到哪个 inode,取决于进程的 mount namespace、pid namespace、user namespace、cgroup namespace、time namespace 的组合(B-17)。这在容器时代是特性,但在 shell 脚本时代是陷阱——许多古老的 sysadmin 脚本假设路径是全局的。namespace 的引入是把”一切皆文件”这个口号从哲学信仰降级到工程事实。
五、内核架构谱系概览
这一节只做地图级介绍,后续 A-03 会把每一种架构详细拆开。
5.1 宏内核(Monolithic)
代表:Linux、FreeBSD、AIX、Solaris 内核本体。所有内核功能(文件系统、网络栈、驱动、调度、内存、IPC)运行在同一地址空间,同一特权级。
优点:最简单、性能最高。子系统之间直接函数调用,没有 IPC 开销。 缺点:爆炸半径最大。一个驱动 bug 可以 panic 整机。
Linux 通过内核模块、命名空间、eBPF 等机制把”宏内核”变得越来越接近”可组合的宏内核”,但本质没变。
5.2 微内核(Microkernel)
代表:Mach、L4 家族(seL4、Fiasco、OKL4)、QNX、Minix 3。内核只保留 IPC、调度、基本内存管理;文件系统、网络、驱动运行在用户态。
优点:隔离性强、可验证(seL4 是第一个代码级证明正确性的 OS 内核)。 缺点:IPC 开销 → 性能代价。L4 第一代 IPC 开销高得让微内核在 90 年代几乎出局;L4 后续家族把 IPC 优化到与系统调用同一数量级,才在嵌入式与安全市场站稳。
5.3 混合内核(Hybrid)
代表:XNU(macOS/iOS)、Windows NT。架构上保留微内核思路(Mach、NT Executive),但把高性能路径直接放在内核地址空间,逻辑上用”object + message”组织。实际是宏内核的性能 + 微内核的组织。
优点:平衡。 缺点:两种哲学的夹缝里,代码复杂度高。
5.4 Exokernel
代表:MIT Exokernel、Nemesis。内核只”保护”资源,不”抽象”资源;抽象留给用户态的 libOS。unikernel 是 Exokernel 思想的现代继承者。
5.5 Unikernel
代表:MirageOS、IncludeOS、Unikraft、OSv。一个应用 + 它需要的 OS 原语编译成单一二进制,直接跑在 VMM 上。没有多进程、没有用户态/内核态区分。
优点:启动快(< 10ms)、攻击面小、内存占用小。 缺点:失去了”多工作负载复用”的能力。
5.6 VMM / Hypervisor
代表:Xen、KVM、Hyper-V、ESXi、Firecracker、Cloud Hypervisor。它不是传统 OS,但承担了 OS 的五件事中的前三件(抽象 / 复用 / 隔离),只不过把单位从”进程”换成”虚机”。
趋势:VMM + 精简 guest OS(例如 Firecracker + 轻 Linux)正在”吃掉” OS 的部分传统职责。这是 M-109 disaggregated-os 的伏笔。
六、“操作系统”的边界在哪里?
一个常被问起但没人能精确回答的问题:到底哪些代码算操作系统,哪些不算?
我的工作定义是:
在一台机器上,从加电开始到允许不受信任代码运行之前,所有常驻运行、具有特权访问物理资源能力、并且为后续工作负载提供抽象/复用/隔离/策略/可观测这五件事的软件,都是操作系统。
这个定义包含以下内容:
- BIOS/UEFI 固件?部分。UEFI 的 DXE、BDS 阶段算 pre-OS;runtime services 是 OS 与固件的灰色地带。
- Bootloader?是。GRUB、systemd-boot 属于启动期 OS。
- 内核本体?是。
- initramfs + init 系统(systemd)?是。它完成了”第一个不受信任进程启动前”的所有准备。
- glibc / libc?不是(是用户库,但部分职责如 malloc、dlopen 历史上也和 OS 边界有纠缠)。
- systemd-networkd / NetworkManager?边界。它们在用户态,但做的事情很像传统 OS 的职责。
这个定义的好处是它强调”职责”而不是”代码归属”。按它看,Docker daemon / kubelet / CRI-O 中有一部分代码就是”OS 的延伸”——它们承担了容器运行时的抽象、复用、隔离、策略和可观测。同理,AWS Nitro Hypervisor + Firecracker + init 加起来构成了”Lambda 的 OS”。
这种视角对你的意义:当你在设计一个大型系统(比如分布式数据库、AI 训练平台)时,你会反复问自己”这五件事谁来做?“——如果都推给内核,你会被调度和文件系统拖累;如果都自己做,你会重新发明一个 OS。大型基础软件的本质就是在”复用 OS”与”绕开 OS”之间做权衡。
七、OS 怎么启动自己?一个顺序回放
在正式进入后续主题前,把一台 x86_64 Linux 机器从加电到 PID 1 的过程过一遍,可以让这五件事落到具体时刻。细节在 J-81 会展开;这里只画骨架。
0ms 加电 → CPU 从 RESET 向量 0xFFFFFFF0 取指,进入 UEFI 固件
50ms UEFI 初始化 DRAM、PCI、存储控制器;加载 Boot Manager
200ms shim/GRUB/systemd-boot 加载 Linux kernel + initramfs(含签名校验)
300ms decompress、start_kernel() 开始执行
setup_arch() —— 建立早期页表、解析 CPU 特性
build_all_zonelists() —— 注册内存区域(Zone)
trap_init() / init_IRQ() —— 建立 IDT、中断向量
mm_init() / sched_init() —— 伙伴系统、SLUB、调度器就绪
rcu_init()、hrtimer_init()、workqueue_init()
smp_init() —— 其他 CPU 上线
rest_init() —— 创建 kernel_init 内核线程(未来的 PID 1)
1200ms kernel_init 跑完内核 initcall,挂载 rootfs 或 initramfs
1300ms execve("/sbin/init", ...) —— PID 1 变成 systemd
1800ms systemd 跑完 default.target,系统就绪,允许外部登录 / 接受请求
每一毫秒里 OS
都在积累职责:先有”抽象”(建立
CPU/内存的内核表示),再有”复用”(调度器、软中断),接着”隔离”(SELinux
policy、namespace 基座),最后”可观测”(sysfs/procfs
可用)。当你看到
systemd[1]: Reached target Multi-User System.
时,OS 的五件事才真正齐备。
这个时间线会在 J-81 用更细的 trace 重新走一遍;这里提前画出来,是为了让你对”OS 初始化”这件事有一个量级感——大多数机器的前 2 秒钟都在做 OS 的自举。serverless 把这个时间砍到 < 200ms 的办法,不是”更快地启动 OS”,而是”复用已经启动好的 OS 快照”(snapshot / fork-based cold start),这是 M 系列会讨论的前沿话题。
八、六十年简史速览
本节压到最短。把 OS 六十年的演化切成四段:
8.1 1950s–1960s:批处理与 OS-360
最早的”OS”是 IBM 7090 上的 FORTRAN Monitor System。它做的只有 job queue 管理。IBM OS/360(1964)第一次把 multiprogramming、spooling、中断驱动 I/O 做进一套系统。Fred Brooks 在《人月神话》里讲的就是这个 OS 的开发教训。
8.2 1970s:Unix 与分时系统
Multics 雄心太大,1965–1969 年 MIT/Bell/GE 联合开发,最终没能产品化但留下大量思想。Unix(1970,Bell Labs)是 Multics 的精神继承者 + 极度简化版。V6(1975)公开源码后,BSD 分叉,进入高校。VAX/VMS 是同期的商业代表。
8.3 1980s–1990s:个人计算与微内核浪潮
DOS(1981)把 OS 带到每一个家庭,但它不是真正的 OS。Windows NT(1993)带来了 NT 内核,Mach 风格的混合设计。Mach(CMU,1985)点燃微内核运动;L4(Jochen Liedtke,1995)把微内核从”慢”的标签里救回来。Linux(1991)在这个时代以宏内核姿态出场,反而一路赢。
8.4 2000s–2020s:隔离的军备竞赛
虚拟化复兴(VMware ESX 2001、Xen 2003、KVM 2007)把隔离单位从进程升格到虚机。容器(LXC 2008 → Docker 2013 → runc / containerd 2015)把隔离单位压回到用户态进程 + namespace + cgroup。Firecracker / Kata / gVisor(2018–)重新拉回虚机级别以抗逃逸。机密计算(SEV 2017、TDX 2022、CCA 2022)把不信任扩展到 hypervisor 与云运营者。Rust for Linux(2021 起)试图在内核层面削减内存安全漏洞。
这条主线在 A-02 os-history 会详细展开。但提前点题:过去二十年 OS 的演化,基本都绕着”隔离”这一件事。
九、给读者的读法建议
写到这里,“什么是操作系统”应该从一个模糊的概念变成一组可以丈量的职责。本系列接下来的路径:
- 子系列 A(本系列 A-02~A-08):把上面点到为止的几个话题展开——历史、内核架构、特权级、syscall ABI、边界契约、POSIX 的神话与事实、关于 OS 的常见错觉。
- 子系列 B 起,我们开始潜入内核具体子系统:进程 / 线程、调度器、虚拟内存、分配器、VFS、I/O、并发、中断、启动、可观测、安全,最后是前沿。
对这本系列的使用方式:
- 顺读:如果你是系统工程师但没系统读过 OS,建议顺序读 A → M,每读完一个子系列做一个小实验(后续每篇末尾给实验建议)。
- 问题驱动读:如果你碰到具体问题(比如”为什么我的服务延迟抖动”),跳到 C-26 调度延迟 + K-88 perf + K-89 eBPF,交叉读。
- 源码配读:每篇都会给具体 Linux 源码位置与 commit。建议 clone 一份 Linux 6.6(或以上),用 ctags/clangd 同步读。
如何高效读内核源码:别试图通读;从一个 syscall 入口(例如
SYSCALL_DEFINE3(read, ...)在fs/read_write.c)出发,沿调用链往下;每到一个子系统边界(VFS → 块层 → 驱动)就停下来读对应 Documentation/*.rst。这个方法在 A-06 内核与用户态边界中会有具体示范。
十、小结:OS 的五件事,一把尺子
我们提炼出的五件事:抽象、复用、隔离、策略、可观测。它们不是教科书定义的替代品,而是一把工程尺子。你可以拿它去丈量:
- 一个新的 runtime(比如 WasmEdge、Fly Machines)——它承担了五件事中的哪几件?
- 一个新的硬件特性(比如 CXL 内存池)——它会重塑哪几件?
- 一个新的语言抽象(比如 Go 的 goroutine)——它把哪件从 OS 手里拿走了?
- 一个生产事故——根因归到哪一件的失败?
这把尺子我们会一直用到 M-110 系列结语。OS 不是一个会消失的层;它是一个在每一次架构变迁中被重塑职责分工的层。看清这五件事的流动,才能看清 OS 的未来。
从下一篇起,我们回到历史——Unix 谱系、Plan 9、Linux 的设计遗产——看这五件事是如何一步步被今天的形状构造出来的。
参考文献
论文与书籍
- Dijkstra, E. W. “The Structure of the ‘THE’-Multiprogramming System.” Communications of the ACM, 11(5):341-346, 1968.
- Ritchie, D. M., Thompson, K. “The UNIX Time-Sharing System.” Communications of the ACM, 17(7):365-375, 1974.
- Tanenbaum, A. S., Woodhull, A. S. Operating Systems: Design and Implementation. 3rd Edition, Prentice Hall, 2006.(Minix 与 Linus 论战的起点书)
- Bovet, D. P., Cesati, M. Understanding the Linux Kernel. 3rd Edition, O’Reilly, 2005.(仍然是最清晰的 Linux 内核结构导论,版本旧但骨架未变)
- Love, R. Linux Kernel Development. 3rd Edition, Addison-Wesley, 2010.
- Mauerer, W. Professional Linux Kernel Architecture. Wiley, 2008.
- Liedtke, J. “On Micro-Kernel Construction.” SOSP, 1995.(微内核救赎)
- Klein, G., et al. “seL4: Formal Verification of an OS Kernel.” SOSP, 2009.
- Engler, D. R., Kaashoek, M. F., O’Toole, J. “Exokernel: An Operating System Architecture for Application-Level Resource Management.” SOSP, 1995.
- Madhavapeddy, A., et al. “Unikernels: Library Operating Systems for the Cloud.” ASPLOS, 2013.
- Agache, A., et al. “Firecracker: Lightweight Virtualization for Serverless Applications.” NSDI, 2020.
源码 / 工程文档
- Linux kernel: https://git.kernel.org/ (本系列基准版本:v6.6 LTS 及以上;重要差异标注版本)
- FreeBSD: https://cgit.freebsd.org/src/
- seL4: https://github.com/seL4/seL4
- Firecracker: https://github.com/firecracker-microvm/firecracker
- Unikraft: https://github.com/unikraft/unikraft
在线资源
- LWN.net 的 “Kernel index” 与 “Weekly Edition” 是跟踪 Linux 内核演化最好的来源。
- Brendan Gregg 的博客(brendangregg.com)和书《Systems Performance》、《BPF Performance Tools》几乎是本系列可观测性章节的第二脚本。
- The TUHS 项目(www.tuhs.org)收藏了完整的 Unix 早期源码与邮件档案。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】Unikernel
Unikernel 在云上为什么没成主流?MirageOS、IncludeOS、Unikraft、OSv 的设计取舍——库操作系统、启动时间、工具链、调试困难、POSIX 兼容。
【操作系统百科】宏内核 vs 微内核 vs 混合内核:Tanenbaum-Torvalds 三十年后
微内核是理论正义但工程失败?Linux 宏内核赢了只是因为先上车?三十年前的那场论战,在 seL4 形式化正确、L4 家族把 IPC 做到单 syscall、Fuchsia 真正商用的 2020s,我们应该怎么重新看?本文用四个可量化的维度——性能、可维护性、隔离性、可验证性——把四种内核架构(宏、微、混合、Exokernel/Unikernel)摆到同一张尺子上对齐。
操作系统百科
110 篇长文,从操作系统的基础抽象到调度、虚拟内存、文件系统、并发、安全、前沿方向。以 Linux 6.x 主线为实现参照,辅以 FreeBSD、XNU、Windows NT、实时 OS 的对照。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。