《Linux内核源码全景解读:从上电到用户态》之 目录

《Linux内核源码全景解读:从上电到用户态》

    • 一、全书结构
    • [二、上篇目录:按 x86_64 启动阶段划分](#二、上篇目录:按 x86_64 启动阶段划分)
      • [第 1 章 上电、固件与 x86_64 启动契约](#第 1 章 上电、固件与 x86_64 启动契约)
      • [第 2 章 实模式 setup:从 boot sector 到 protected mode](#第 2 章 实模式 setup:从 boot sector 到 protected mode)
      • [第 3 章 压缩内核入口:临时页表与解压执行环境](#第 3 章 压缩内核入口:临时页表与解压执行环境)
      • [第 4 章 跳入解压后的内核:`startup_64` 与初始身份映射](#第 4 章 跳入解压后的内核:startup_64 与初始身份映射)
      • [第 5 章 `x86_64_start_kernel()`:进入通用内核前的架构收口](#第 5 章 x86_64_start_kernel():进入通用内核前的架构收口)
      • [第 6 章 `start_kernel()` 总览:内核生命线的主函数](#第 6 章 start_kernel() 总览:内核生命线的主函数)
      • [第 7 章 `setup_arch()`:x86_64 拓扑、内存图与平台发现](#第 7 章 setup_arch():x86_64 拓扑、内存图与平台发现)
      • [第 8 章 早期内存管理:memblock、页表与伙伴系统前夜](#第 8 章 早期内存管理:memblock、页表与伙伴系统前夜)
      • [第 9 章 异常、IRQ 与时间:内核获得外部世界的节拍](#第 9 章 异常、IRQ 与时间:内核获得外部世界的节拍)
      • [第 10 章 调度器、RCU 与并发基础设施](#第 10 章 调度器、RCU 与并发基础设施)
      • [第 11 章 控制台、printk 与可观测启动](#第 11 章 控制台、printk 与可观测启动)
      • [第 12 章 进程模型成形:fork、pid、cred 与 `rest_init()`](#第 12 章 进程模型成形:fork、pid、cred 与 rest_init())
      • [第 13 章 VFS 与根文件系统前置:从 dcache 到 initramfs](#第 13 章 VFS 与根文件系统前置:从 dcache 到 initramfs)
      • [第 14 章 安全与命名空间:用户态边界的形成](#第 14 章 安全与命名空间:用户态边界的形成)
      • [第 15 章 initcall 机制:驱动、总线、文件系统与网络的批量唤醒](#第 15 章 initcall 机制:驱动、总线、文件系统与网络的批量唤醒)
      • [第 16 章 挂载根文件系统与执行 `/sbin/init`](#第 16 章 挂载根文件系统与执行 /sbin/init)
    • 三、下篇目录:核心子系统深度剖析
      • [第 17 章 调度子系统:从 `rq` 到 EEVDF](#第 17 章 调度子系统:从 rq 到 EEVDF)
      • [第 18 章 内存管理:从 memblock 到 folio/Maple Tree](#第 18 章 内存管理:从 memblock 到 folio/Maple Tree)
      • [第 19 章 VFS 与文件系统:路径、对象与页缓存](#第 19 章 VFS 与文件系统:路径、对象与页缓存)
      • [第 20 章 网络子系统:从 `sk_buff` 到 `net_device`](#第 20 章 网络子系统:从 sk_buff 到 net_device)
      • [第 21 章 进程间通信(IPC):信号量、消息队列与共享内存](#第 21 章 进程间通信(IPC):信号量、消息队列与共享内存)
      • [第 22 章 RCU 与同步原语:读多写少世界的基础设施](#第 22 章 RCU 与同步原语:读多写少世界的基础设施)
      • [第 23 章 块层与 I/O:bio、request 与 blk-mq](#第 23 章 块层与 I/O:bio、request 与 blk-mq)
      • [第 24 章 设备模型、驱动核心与电源管理](#第 24 章 设备模型、驱动核心与电源管理)
      • [第 25 章 安全子系统:LSM、凭据与系统调用边界](#第 25 章 安全子系统:LSM、凭据与系统调用边界)
      • [第 26 章 cgroup、namespace 与容器基础设施](#第 26 章 cgroup、namespace 与容器基础设施)
      • [第 27 章 eBPF、 tracing 与可观测性](#第 27 章 eBPF、 tracing 与可观测性)
      • [第 28 章 模块、符号与内核扩展边界](#第 28 章 模块、符号与内核扩展边界)
    • [四、时序全景图描述:从 `start_kernel()` 到 `do_initcalls()`](#四、时序全景图描述:从 start_kernel() 到 do_initcalls())

版本口径:本目录基于本地源码树 linux-7.1.3,架构范围限定为 x86_64。本文档按实际源码 Linux 7.1.3 组织路径与章节。

核心叙事:全书以 "上电 -> BIOS/UEFI -> 引导协议 -> 解压内核 -> x86_64 早期入口 -> start_kernel() -> initcall -> rootfs/init -> 用户态" 为主线。上篇按启动时序唤醒子系统,下篇再把这些子系统拆开深挖。

一、全书结构

上篇:启动时序篇

目标是按时间顺序回答 "内核怎样从一段不可调度、不可分页、不可中断的早期代码,逐步成长为能创建进程、挂载根文件系统、加载驱动并进入用户态的系统"。每章都绑定一个启动阶段,并说明该阶段首次引出的子系统。

下篇:子系统深度篇

目标是把上篇中被依次唤醒的核心子系统独立展开:数据结构、关键算法、热路径、初始化入口、调试观察点,以及从 Linux 5.12 到本源码 7.1.3 的主要演进线索。

二、上篇目录:按 x86_64 启动阶段划分

第 1 章 上电、固件与 x86_64 启动契约

  • 启动阶段:CPU reset vector、BIOS/UEFI 固件、bootloader 交接。
  • 引入子系统:x86 boot protocol、boot params、命令行、E820/EFI 内存图。
  • 核心源码路径:Documentation/arch/x86/boot.rst、arch/x86/include/uapi/asm/bootparam.h、arch/x86/include/asm/e820/types.h、arch/x86/platform/efi/efi.c。
  • 叙事重点:内核并不是从 C 语言 main() 开始,而是从固件和引导器约定的数据结构开始。

第 2 章 实模式 setup:从 boot sector 到 protected mode

  • 启动阶段:x86 setup code 接管 bootloader 传入的参数。
  • 引入子系统:早期控制台、A20、CPU 特性探测、视频模式、命令行解析。
  • 核心源码路径:arch/x86/boot/header.S、arch/x86/boot/main.c、arch/x86/boot/boot.h、arch/x86/boot/cmdline.c、arch/x86/boot/cpu.c、arch/x86/boot/pm.c。
  • 叙事重点:为什么早期代码有自己的 tiny libc、printf、BIOS 调用封装,以及它如何准备进入保护模式。

第 3 章 压缩内核入口:临时页表与解压执行环境

  • 启动阶段:进入 arch/x86/boot/compressed/,建立解压用的最小运行时。
  • 引入子系统:KASLR、早期页表、早期异常处理、早期串口/控制台。
  • 核心源码路径:arch/x86/boot/compressed/head_64.S、arch/x86/boot/compressed/misc.c、arch/x86/boot/compressed/kaslr.c、arch/x86/boot/compressed/pgtable_64.c、arch/x86/boot/compressed/error.c。
  • 叙事重点:startup_32/startup_64 如何调用 extract_kernel(),并返回真正内核映像入口。

第 4 章 跳入解压后的内核:startup_64 与初始身份映射

  • 启动阶段:解压后的 vmlinux 从汇编入口建立 long mode 所需状态。
  • 引入子系统:GDT/IDT、early page table、内核虚拟地址、SME/SEV 内存加密准备。
  • 核心源码路径:arch/x86/kernel/head_64.S、arch/x86/kernel/head64.c、arch/x86/boot/startup/map_kernel.c、arch/x86/boot/startup/gdt_idt.c、arch/x86/mm/mem_encrypt.c。
  • 叙事重点:startup_64 -> common_startup_64 -> x86_64_start_kernel() 如何把执行权移交给 C 层。

第 5 章 x86_64_start_kernel():进入通用内核前的架构收口

  • 启动阶段:x86_64 C 入口完成 early IDT、清 BSS、CPU 基础状态和命令行承接。
  • 引入子系统:early IDT、ORC/unwind 准备、early fixmap、静态分支基础。
  • 核心源码路径:arch/x86/kernel/head64.c、arch/x86/kernel/head_64.S、arch/x86/kernel/cpu/common.c、arch/x86/include/asm/setup.h。
  • 叙事重点:为何 start_kernel() 是通用内核入口,但它不是机器真正执行的第一段内核代码。

第 6 章 start_kernel() 总览:内核生命线的主函数

  • 启动阶段:进入 init/main.c:start_kernel()。
  • 引入子系统:lockdep、boot CPU、静态 key、cgroup 早期初始化、调试对象、栈随机化。
  • 核心源码路径:init/main.c、include/linux/start_kernel.h、kernel/locking/lockdep.c、kernel/cgroup/cgroup.c、lib/debugobjects.c。
  • 叙事重点:把 start_kernel() 拆成 "架构感知、内存可用、调度可用、中断可用、VFS 可用、用户态可用" 六段。

第 7 章 setup_arch():x86_64 拓扑、内存图与平台发现

  • 启动阶段:start_kernel() 调用 setup_arch(&command_line)。
  • 引入子系统:E820/memblock、NUMA、ACPI、EFI、CPU feature、KASLR 结果固化、early ioremap。
  • 核心源码路径:arch/x86/kernel/setup.c、arch/x86/kernel/e820.c、arch/x86/mm/init.c、arch/x86/mm/init_64.c、arch/x86/mm/numa.c、arch/x86/kernel/acpi/boot.c、arch/x86/platform/efi/efi.c。
  • 叙事重点:所有后续内存管理、设备枚举和 SMP 初始化都依赖 setup_arch() 建立的平台事实。

第 8 章 早期内存管理:memblock、页表与伙伴系统前夜

  • 启动阶段:setup_arch() 后到 mm_core_init() 前后。
  • 引入子系统:memblock、sparsemem、page allocator、SLUB、vmalloc、percpu allocator。
  • 核心源码路径:mm/mm_init.c、mm/memblock.c、mm/page_alloc.c、mm/sparse.c、mm/slub.c、mm/vmalloc.c、mm/percpu.c、include/linux/mmzone.h。
  • 叙事重点:从固件内存图到 struct page,再到早期分配器被正式页分配器接管。

第 9 章 异常、IRQ 与时间:内核获得外部世界的节拍

  • 启动阶段:trap_init()、init_IRQ()、tick_init()、timekeeping_init()。
  • 引入子系统:IDT、异常处理、irqdesc、APIC/IO-APIC、clocksource、tick、timer wheel/hrtimer。
  • 核心源码路径:arch/x86/kernel/traps.c、arch/x86/kernel/idt.c、arch/x86/kernel/irqinit.c、kernel/irq/irqdesc.c、kernel/time/tick-common.c、kernel/time/timekeeping.c、kernel/time/hrtimer.c。
  • 叙事重点:没有中断和时钟,调度器只能初始化,无法成为真正的多任务系统。

第 10 章 调度器、RCU 与并发基础设施

  • 启动阶段:sched_init()、rcu_init()、srcu_init()、softirq/tasklet/workqueue 准备。
  • 引入子系统:CFS/EEVDF、RT/DL、sched class、RCU tree、SRCU、softirq、workqueue。
  • 核心源码路径:kernel/sched/core.c、kernel/sched/fair.c、kernel/sched/rt.c、kernel/sched/deadline.c、kernel/rcu/tree.c、kernel/rcu/srcutree.c、kernel/softirq.c、kernel/workqueue.c。
  • 叙事重点:调度器和 RCU 是大量后续子系统的隐形前置条件。

第 11 章 控制台、printk 与可观测启动

  • 启动阶段:console_init() 前后的 early console 到正式 console 切换。
  • 引入子系统:printk ring buffer、console driver、earlycon、fbcon/tty console。
  • 核心源码路径:kernel/printk/printk.c、include/linux/console.h、drivers/tty/tty_io.c、drivers/video/fbdev/core/fbcon.c、arch/x86/boot/early_serial_console.c。
  • 叙事重点:日志可见性本身也是一个逐步初始化的子系统。

第 12 章 进程模型成形:fork、pid、cred 与 rest_init()

  • 启动阶段:fork_init()、proc_caches_init()、rest_init() 创建 kernel_init 和 kthreadd。
  • 引入子系统:task_struct、pid、cred、signal、kthread、init_task。
  • 核心源码路径:kernel/fork.c、init/init_task.c、kernel/pid.c、kernel/cred.c、kernel/kthread.c、include/linux/sched.h、include/linux/pid.h。
  • 叙事重点:0 号进程如何分裂出 1 号内核线程路径和 2 号 kthreadd。

第 13 章 VFS 与根文件系统前置:从 dcache 到 initramfs

  • 启动阶段:vfs_caches_init()、mnt_init()、init_rootfs()、initramfs 解包。
  • 引入子系统:VFS、dcache、inode cache、mount namespace、rootfs、initramfs。
  • 核心源码路径:fs/dcache.c、fs/inode.c、fs/file_table.c、fs/namespace.c、fs/filesystems.c、init/initramfs.c、init/do_mounts.c。
  • 叙事重点:进入用户态前,内核必须先有 "路径、文件、挂载点、根" 的抽象。

第 14 章 安全与命名空间:用户态边界的形成

  • 启动阶段:early_security_init()、security_init()、namespace 与 keyring 等初始化。
  • 引入子系统:LSM、capability、cred、user namespace、pid/mount/net namespace、audit。
  • 核心源码路径:security/security.c、security/commoncap.c、security/lsm_init.c、kernel/user_namespace.c、kernel/nsproxy.c、kernel/audit.c。
  • 叙事重点:用户态不是 "自然可信" 的目标,而是受凭据、命名空间和 LSM 策略约束的执行环境。

第 15 章 initcall 机制:驱动、总线、文件系统与网络的批量唤醒

  • 启动阶段:kernel_init_freeable() 调用 do_basic_setup(),随后 do_initcalls()。
  • 引入子系统:initcall 分层、driver core、bus/class/device、PCI/ACPI、网络协议栈、块层、文件系统注册。
  • 核心源码路径:init/main.c、include/linux/init.h、drivers/base/init.c、drivers/pci/pci.c、net/core/dev.c、net/ipv4/af_inet.c、block/blk-core.c、fs/filesystems.c。
  • 叙事重点:pure -> core -> postcore -> arch -> subsys -> fs -> rootfs -> device -> late 不是简单列表,而是依赖排序协议。

第 16 章 挂载根文件系统与执行 /sbin/init

  • 启动阶段:prepare_namespace()、init_mount_tree()、run_init_process()。
  • 引入子系统:root device、block layer、filesystem probing、execve、binfmt_elf、动态链接器入口。
  • 核心源码路径:init/do_mounts.c、init/do_mounts_initrd.c、init/do_mounts_rd.c、fs/exec.c、fs/binfmt_elf.c、fs/open.c、block/blk-core.c。
  • 叙事重点:内核启动主线的终点不是 shell,而是成功把 PID 1 的控制权交给用户态 init。

三、下篇目录:核心子系统深度剖析

第 17 章 调度子系统:从 rq 到 EEVDF

  • 核心数据结构:struct task_struct、struct rq、struct cfs_rq、struct sched_entity、struct sched_class、struct sched_dl_entity、struct rt_rq。
  • 核心源码路径:include/linux/sched.h、kernel/sched/sched.h、kernel/sched/core.c、kernel/sched/fair.c、kernel/sched/rt.c、kernel/sched/deadline.c、kernel/sched/ext.c。
  • 核心算法:调度类链、唤醒抢占、负载均衡、CFS/EEVDF 虚拟截止时间、RT 优先级队列、deadline CBS、CPU affinity、NUMA balancing。
  • 5.12 到 7.1.3 演进关键点:CFS 从 vruntime 红黑树模型演进到 EEVDF 语义;调度扩展 sched_ext 进入源码;PREEMPT_DYNAMIC/PREEMPT_RT 相关路径更完整;utilization clamping、energy-aware scheduling 和 PSI 观测继续深化。

第 18 章 内存管理:从 memblock 到 folio/Maple Tree

  • 核心数据结构:struct page、struct folio、struct zone、struct pglist_data、struct mm_struct、struct vm_area_struct、struct maple_tree、struct address_space。
  • 核心源码路径:mm/mm_init.c、mm/page_alloc.c、mm/memory.c、mm/mmap.c、mm/vmscan.c、mm/huge_memory.c、mm/slub.c、include/linux/mm_types.h、include/linux/maple_tree.h。
  • 核心算法:伙伴系统、per-cpu page list、SLUB 分配、页表缺页处理、匿名/文件页回收、LRU/MGLRU、THP、NUMA policy、GUP、COW。
  • 5.12 到 7.1.3 演进关键点:folio 成为页缓存和复合页处理的中心抽象;VMA 管理从红黑树迁移到 Maple Tree;MGLRU、DAMON、mseal、large folio/mTHP 相关路径显著扩展;内存热插拔、memcg、KASAN/KMSAN 支撑增强。

第 19 章 VFS 与文件系统:路径、对象与页缓存

  • 核心数据结构:struct inode、struct dentry、struct super_block、struct file、struct mount、struct file_system_type、struct address_space。
  • 核心源码路径:fs/dcache.c、fs/inode.c、fs/namei.c、fs/namespace.c、fs/super.c、fs/file_table.c、fs/read_write.c、mm/filemap.c。
  • 核心算法:路径解析、dcache lookup、RCU-walk/ref-walk、挂载传播、page cache read/write、writeback、文件锁、splice/direct I/O。
  • 5.12 到 7.1.3 演进关键点:mount API 和 fs_context 更成熟;pidfs 等新型伪文件系统进入主线;folio 化深入页缓存和网络文件系统;io_uring 与文件/块设备路径耦合更深;idmapped mounts 与命名空间边界继续扩展。

第 20 章 网络子系统:从 sk_buff 到 net_device

  • 核心数据结构:struct sk_buff、struct net_device、struct sock、struct socket、struct proto、struct napi_struct、struct net、struct dst_entry。
  • 核心源码路径:net/core/dev.c、net/core/skbuff.c、net/socket.c、net/ipv4/af_inet.c、net/ipv4/ip_input.c、net/ipv4/tcp*.c、net/ipv6/、include/linux/netdevice.h、include/linux/skbuff.h。
  • 核心算法:NAPI poll、GRO/GSO、qdisc、routing lookup、TCP 拥塞控制、socket receive/send buffer、net namespace、XDP/eBPF hook。
  • 5.12 到 7.1.3 演进关键点:XDP、BPF、AF_XDP 和 tc hook 生态继续扩大;MPTCP 更成熟;netmem/page_pool、GRO 和零拷贝路径强化;网络命名空间、nftables、TLS offload 等路径继续增长。

第 21 章 进程间通信(IPC):信号量、消息队列与共享内存

  • 核心数据结构:struct sem_array、struct msg_queue、struct shmid_kernel、struct ipc_ids、struct kern_ipc_perm。
  • 核心源码路径:ipc/sem.c、ipc/msg.c、ipc/shm.c、ipc/util.c、ipc/mqueue.c、include/linux/ipc.h、include/uapi/linux/sem.h、include/uapi/linux/msg.h、include/uapi/linux/shm.h。
  • 核心算法:System V 信号量原子操作与 undo、消息队列类型匹配和阻塞唤醒、共享内存 shmget -> shmat 映射、IPC_RMID 延迟删除、POSIX mqueue 通知。
  • 5.12 到 7.1.3 演进关键点:IPC namespace 与 nsfs 视角继续完善;共享内存和 tmpfs、memcg、页表管理联系更紧;权限检查、LSM hook 和容器边界持续强化。

第 22 章 RCU 与同步原语:读多写少世界的基础设施

  • 核心数据结构:struct rcu_head、struct rcu_state、struct rcu_node、struct rcu_data、struct srcu_struct、struct lock_class_key。
  • 核心源码路径:kernel/rcu/tree.c、kernel/rcu/srcutree.c、kernel/rcu/tasks.h、include/linux/rcupdate.h、include/linux/srcu.h、kernel/locking/。
  • 核心算法:grace period 检测、quiescent state、callback offload、RCU Tasks、SRCU per-domain grace period、lockdep 验证、seqlock、percpu rwsem。
  • 5.12 到 7.1.3 演进关键点:Tasks RCU、Lazy RCU callback、nocb/offload 与能耗优化持续演进;SRCU 和 sleepable RCU 使用面扩大;PREEMPT_RT 迫使更多同步原语明确区分 raw spinlock、spinlock 和睡眠锁。

第 23 章 块层与 I/O:bio、request 与 blk-mq

  • 核心数据结构:struct bio、struct request、struct request_queue、struct gendisk、struct blk_mq_hw_ctx、struct blk_mq_tag_set、struct elevator_queue。
  • 核心源码路径:block/blk-core.c、block/blk-mq.c、block/blk-mq-sched.c、block/bio.c、block/genhd.c、block/elevator.c、include/linux/blk_types.h、include/linux/blk-mq.h。
  • 核心算法:bio 合并、request 分发、tag 分配、multi-queue 映射、I/O scheduler、writeback throttling、blk-cgroup、flush/FUA。
  • 5.12 到 7.1.3 演进关键点:blk-mq 已成为中心路径;io_uring command 与块设备接口结合更紧;BFQ、mq-deadline、wbt、blk-cgroup 延迟控制持续调整;folio 化影响文件系统到 bio 的页提交路径。

第 24 章 设备模型、驱动核心与电源管理

  • 核心数据结构:struct device、struct device_driver、struct bus_type、struct class、struct kobject、struct kset、struct dev_pm_ops。
  • 核心源码路径:drivers/base/core.c、drivers/base/bus.c、drivers/base/dd.c、drivers/base/class.c、drivers/base/power/、lib/kobject.c、include/linux/device.h。
  • 核心算法:device/driver match、probe/remove、deferred probe、sysfs/kobject 生命周期、runtime PM、system suspend/resume、device links。
  • 5.12 到 7.1.3 演进关键点:fw_devlink、deferred probe、device links 和 runtime PM 关系更紧;CXL、PCIe、ACPI/DT 平台发现规模扩大;sysfs 属性生命周期和 Rust/auxiliary bus 等新驱动组织方式影响驱动模型边界。

第 25 章 安全子系统:LSM、凭据与系统调用边界

  • 核心数据结构:struct cred、struct user_namespace、struct linux_binprm、struct lsm_blob_sizes、struct security_hook_list、kernel_cap_t。
  • 核心源码路径:security/security.c、security/lsm_init.c、security/commoncap.c、kernel/cred.c、kernel/user_namespace.c、fs/exec.c、include/linux/lsm_hooks.h、include/linux/cred.h。
  • 核心算法:cred copy-on-write、capability 检查、LSM hook 分发、exec 凭据提交、seccomp 过滤、keyring、audit。
  • 5.12 到 7.1.3 演进关键点:LSM stacking 与 blob 管理继续强化;Landlock、IMA/EVM、BPF LSM 等可组合安全机制扩展;用户命名空间和 idmapped mount 使权限判断更依赖上下文。

第 26 章 cgroup、namespace 与容器基础设施

  • 核心数据结构:struct cgroup、struct cgroup_subsys_state、struct css_set、struct nsproxy、struct pid_namespace、struct mnt_namespace、struct net。
  • 核心源码路径:kernel/cgroup/cgroup.c、kernel/cgroup/、kernel/nsproxy.c、kernel/pid_namespace.c、fs/namespace.c、net/core/net_namespace.c、include/linux/cgroup.h。
  • 核心算法:css 生命周期、rstat 刷新、cgroup v2 层级控制、cpu/memory/io controller、namespace clone/unshare/setns、pidfd。
  • 5.12 到 7.1.3 演进关键点:cgroup v2 成为事实主线;rstat、pressure stall information 和 BPF-cgroup hook 更重要;pidfd/pidfs 让进程引用模型更文件描述符化;容器边界越来越多由 VFS、LSM、namespace 协同表达。

第 27 章 eBPF、 tracing 与可观测性

  • 核心数据结构:struct bpf_prog、struct bpf_map、struct bpf_verifier_env、struct trace_event_call、struct ftrace_ops、struct perf_event。
  • 核心源码路径:kernel/bpf/、kernel/trace/、kernel/events/core.c、include/linux/bpf.h、include/linux/trace_events.h、arch/x86/net/bpf_jit_comp.c。
  • 核心算法:BPF verifier、JIT、map 生命周期、kprobe/uprobe、ftrace 动态改写、perf ring buffer、tracepoint、BTF/CO-RE。
  • 5.12 到 7.1.3 演进关键点:BPF 子系统从观测工具扩展为网络、安全、调度、cgroup 的可编程平面;BTF、kfunc、struct_ops、sleepable BPF、token/delegation 等机制扩大了受控扩展能力。

第 28 章 模块、符号与内核扩展边界

  • 核心数据结构:struct module、struct kernel_symbol、struct modversion_info、struct jump_entry、struct static_key。
  • 核心源码路径:kernel/module/、kernel/kallsyms.c、kernel/jump_label.c、include/linux/module.h、include/linux/jump_label.h。
  • 核心算法:ELF section 装载、重定位、符号解析、module init/exit、livepatch 约束、static branch patching。
  • 5.12 到 7.1.3 演进关键点:模块代码拆分到 kernel/module/ 更清晰;签名、BTF、livepatch、static call/static key 与可观测性工具耦合更强;Rust 模块支持改变了扩展边界的语言假设。

四、时序全景图描述:从 start_kernel() 到 do_initcalls()

这幅图建议画成一条横向时间轴,左侧是 x86_64_start_kernel(),中间是 start_kernel(),右侧是 kernel_init_freeable() 和 do_initcalls()。时间轴下方用分层泳道表示子系统依赖。

  1. 第一段是 "架构事实层"。x86_64_start_kernel() 将汇编早期状态收口后进入 start_kernel();setup_arch() 读取 boot params、E820/EFI、ACPI、CPU feature、NUMA 拓扑,并用 memblock 描述可用物理内存。图上应把它标成所有后续子系统的底座。

  2. 第二段是 "内存可分配层"。mm_core_init() 之后,struct page、zone、伙伴系统、SLUB、vmalloc、percpu allocator 逐步可用。依赖箭头从这里指向调度器、VFS、网络、驱动核心,因为这些子系统都需要稳定的动态内存分配。

  3. 第三段是 "执行与同步层"。sched_init() 初始化 runqueue、调度类和 idle 任务语义;rcu_init()、srcu_init() 让读多写少同步机制可用;softirq/workqueue 等异步执行基础随后具备条件。图上应把 RCU 画成横贯 VFS、网络、设备模型、文件描述符表的共享依赖。

  4. 第四段是 "外部事件层"。trap_init()、init_IRQ()、tick_init()、timekeeping_init() 让异常、中断和时间源进入工作状态。箭头应从 IRQ/time 指向调度抢占、timer、hrtimer、网络 NAPI、块层超时、RCU grace period 推进。

  5. 第五段是 "对象模型层"。fork_init()、proc_caches_init() 让 task_struct、pid、cred 等进程对象可规模化分配;vfs_caches_init() 让 dentry、inode、file、mount 等 VFS 对象可用;security_init() 把 LSM hook 接入执行、文件和网络路径。图上应把进程、VFS、安全三者画成进入用户态前的三角门槛。

  6. 第六段是 "第一个并发分叉"。rest_init() 创建 kernel_init 和 kthreadd。原始 boot CPU 进入 idle 路径,kernel_init 继续完成可释放初始化,kthreadd 成为后续内核线程的父进程。图上这里应画出主线从 start_kernel() 分叉:一支到 idle,一支到 PID 1 的内核态准备,一支到 PID 2 的内核线程服务。

  7. 第七段是 "批量唤醒层"。kernel_init_freeable() 调用 do_basic_setup(),再调用 do_initcalls()。initcall 层级从 pure、core、postcore、arch、subsys、fs、rootfs、device 到 late,依次唤醒驱动核心、总线、文件系统、网络协议、块设备、平台设备和 late init 任务。图上应把 initcall 画成阶梯,而不是并列队列。

  8. 第八段是 "用户态交接层"。initcall 完成后,prepare_namespace() 挂载根文件系统,run_init_process() 尝试 /sbin/init、/etc/init、/bin/init、/bin/sh 等路径。箭头从 VFS、块层、文件系统、LSM、exec/binfmt 汇聚到 PID 1 的 execve,表示内核启动叙事在这里切换到用户态启动叙事。

整体依赖关系可以概括为:架构发现决定内存边界;内存分配支撑一切对象;调度、RCU、中断和时间让对象能并发运行;VFS、安全和进程模型定义用户态入口;initcall 机制按依赖层级批量唤醒可插拔子系统;最后根文件系统和 execve 把 PID 1 送入用户态。

相关推荐
律宏阔38 分钟前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔39 分钟前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴39 分钟前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千1 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei371 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei371 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei371 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
GeW1 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
GeW1 小时前
工业场景中的Linux与数据库选型:高端化转型的技术底座
linux
yunwei371 小时前
eBPF 开发者教程: 简单的 XDP 负载均衡器
linux·后端·性能优化