Linux 内核入门地图:架构、源码目录与五大子系统

面向应用开发与嵌入式工程师。不堆概念,只讲「内核做什么、代码在哪、模块怎么串起来」。


1. 内核在系统中的位置

Linux 内核是运行在最高特权级的核心程序,位于用户态程序与硬件之间:向上提供系统调用,向下管理 CPU、内存、块设备、网络与中断。

text 复制代码
┌─────────────────────────────────────┐
│  用户空间:Shell / 应用 / 库(glibc)   │
├─────────────────────────────────────┤  系统调用 syscall
│  内核空间:Linux Kernel               │
│    进程调度 / 内存 / VFS / 网络 / 驱动  │
├─────────────────────────────────────┤
│  硬件:CPU / MMU / 存储 / 网卡 / 外设    │
└─────────────────────────────────────┘

三个层次(自顶向下)

层次 内容 典型目录
系统调用接口 open/read/write/fork 等 SCI arch/*/kernel/kernel/
架构无关代码 调度、内存、VFS、网络协议 kernel/ mm/ fs/ net/
架构相关代码 中断、MMU、平台启动 arch/arm64/ arch/x86/

glibc 通过系统调用进入内核;用户进程各自拥有虚拟地址空间,内核独占独立地址空间。这与微内核「仅保留最小核心、服务外置」不同------Linux 选择宏内核,基础能力集成在内核态,换取更低的跨边界开销。


2. 一条命令背后的内核链路

执行 ./app 时,内核侧大致经历:
#mermaid-svg-03vYL02aXnp7YaZK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-03vYL02aXnp7YaZK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-03vYL02aXnp7YaZK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-03vYL02aXnp7YaZK .error-icon{fill:#552222;}#mermaid-svg-03vYL02aXnp7YaZK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-03vYL02aXnp7YaZK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-03vYL02aXnp7YaZK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-03vYL02aXnp7YaZK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-03vYL02aXnp7YaZK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-03vYL02aXnp7YaZK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-03vYL02aXnp7YaZK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-03vYL02aXnp7YaZK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-03vYL02aXnp7YaZK .marker.cross{stroke:#333333;}#mermaid-svg-03vYL02aXnp7YaZK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-03vYL02aXnp7YaZK p{margin:0;}#mermaid-svg-03vYL02aXnp7YaZK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-03vYL02aXnp7YaZK .cluster-label text{fill:#333;}#mermaid-svg-03vYL02aXnp7YaZK .cluster-label span{color:#333;}#mermaid-svg-03vYL02aXnp7YaZK .cluster-label span p{background-color:transparent;}#mermaid-svg-03vYL02aXnp7YaZK .label text,#mermaid-svg-03vYL02aXnp7YaZK span{fill:#333;color:#333;}#mermaid-svg-03vYL02aXnp7YaZK .node rect,#mermaid-svg-03vYL02aXnp7YaZK .node circle,#mermaid-svg-03vYL02aXnp7YaZK .node ellipse,#mermaid-svg-03vYL02aXnp7YaZK .node polygon,#mermaid-svg-03vYL02aXnp7YaZK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-03vYL02aXnp7YaZK .rough-node .label text,#mermaid-svg-03vYL02aXnp7YaZK .node .label text,#mermaid-svg-03vYL02aXnp7YaZK .image-shape .label,#mermaid-svg-03vYL02aXnp7YaZK .icon-shape .label{text-anchor:middle;}#mermaid-svg-03vYL02aXnp7YaZK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-03vYL02aXnp7YaZK .rough-node .label,#mermaid-svg-03vYL02aXnp7YaZK .node .label,#mermaid-svg-03vYL02aXnp7YaZK .image-shape .label,#mermaid-svg-03vYL02aXnp7YaZK .icon-shape .label{text-align:center;}#mermaid-svg-03vYL02aXnp7YaZK .node.clickable{cursor:pointer;}#mermaid-svg-03vYL02aXnp7YaZK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-03vYL02aXnp7YaZK .arrowheadPath{fill:#333333;}#mermaid-svg-03vYL02aXnp7YaZK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-03vYL02aXnp7YaZK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-03vYL02aXnp7YaZK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-03vYL02aXnp7YaZK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-03vYL02aXnp7YaZK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-03vYL02aXnp7YaZK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-03vYL02aXnp7YaZK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-03vYL02aXnp7YaZK .cluster text{fill:#333;}#mermaid-svg-03vYL02aXnp7YaZK .cluster span{color:#333;}#mermaid-svg-03vYL02aXnp7YaZK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-03vYL02aXnp7YaZK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-03vYL02aXnp7YaZK rect.text{fill:none;stroke-width:0;}#mermaid-svg-03vYL02aXnp7YaZK .icon-shape,#mermaid-svg-03vYL02aXnp7YaZK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-03vYL02aXnp7YaZK .icon-shape p,#mermaid-svg-03vYL02aXnp7YaZK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-03vYL02aXnp7YaZK .icon-shape .label rect,#mermaid-svg-03vYL02aXnp7YaZK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-03vYL02aXnp7YaZK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-03vYL02aXnp7YaZK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-03vYL02aXnp7YaZK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} shell fork/exec
分配 task_struct
建立页表与 VMA
VFS open 可执行文件
页缓存 / 块 I/O 读入
加载 ELF 映射到用户空间
跳转用户态 _start

步骤 子系统 关键点
fork/exec 进程管理 copy_processload_elf_binary
内存映射 内存管理 mmap、VMA、页表
读文件 VFS + 块层 dentry/inode → bio → 驱动
调度运行 调度器 CFS、schedule()

理解这条链,排障时能快速判断:崩溃在内存、文件还是 I/O。


3. 源码顶层目录速查

克隆主线内核后,优先熟悉这些目录:

目录 职责
arch/ 体系结构相关:启动、MMU、中断、平台 DTS
kernel/ 调度、信号、锁、时间、power
mm/ 物理页、虚拟内存、slab、swap
fs/ VFS 及 ext4/xfs 等具体 FS
net/ 协议栈(TCP/IP、socket)
ipc/ 信号量、消息队列、共享内存
drivers/ 字符/块/网络设备驱动
block/ 块层、I/O 调度
init/ start_kernel 启动路径
include/ 内核头文件
lib/ 内核内工具库(CRC、radix tree 等)
security/ SELinux 等
virt/kvm/ 虚拟化
scripts/ Kconfig 构建与配置

阅读建议 :先抓 init/main.csched/core.cmm/slub.cfs/namei.c 的调用关系,再按问题深入驱动或协议栈。


4. 五大子系统

4.1 进程管理与调度

  • 进程描述task_struct(PID、状态、内存描述符、文件表、调度实体)
  • 创建fork()copy_process()exec() 替换映像
  • 线程:Linux 用轻量进程实现,内核视角均为可调度的 task
  • 调度 :现代内核默认 CFS(完全公平调度),基于红黑树与虚拟运行时间;实时类用 FIFO/RR
c 复制代码
/* 概念:每个 task 在 runqueue 中竞争 CPU */
schedule();  /* 内核主动/被动让出 CPU 的入口 */

源码入口:kernel/fork.ckernel/sched/core.c

4.2 内存管理

  • 分页:主流 4KB 页;MMU 完成虚拟→物理翻译
  • 分配器层级:memblock(启动)→ 伙伴系统(页)→ slab/slub(小对象)→ vmalloc(大块虚拟连续)
  • 换出:内存紧张时 page 换到 swap
  • 用户视角malloc 走 glibc 堆;大块用 mmap;与内核页 fault 联动

源码入口:mm/page_alloc.cmm/slub.cmm/memory.c(缺页异常)。

4.3 虚拟文件系统(VFS)

一切皆文件:普通文件、目录、设备、socket 都经 VFS 统一接口。

text 复制代码
open("/path/file")
  → path_lookup → dentry 缓存
  → inode(元数据 + 数据块指针)
  → 具体 FS 操作表 (ext4/xfs/...)
  → 返回 fd
结构 作用
super_block 文件系统实例
inode 文件元数据
dentry 路径名缓存
file 打开实例(fd 对应)

常见 FS:ext4(通用)、xfs(大文件/高并发)、squashfs(嵌入式只读)、procfs/sysfs(内核接口)。

4.4 网络协议栈

自顶向下:应用 → socket → TCP/UDP → IP → 链路层 → 驱动。

  • 用户态通过 Berkeley socket 与内核交互
  • Netlink 用于路由、udev 等与内核双向通信
  • 驱动在 drivers/net/;协议在 net/ipv4/net/ipv6/

4.5 设备驱动

类型 特点 例子
字符设备 字节流、无缓冲seek 串口、GPIO
块设备 按块、有请求队列 eMMC、NVMe
网络设备 数据包收发 以太网 MAC

Linux 3.x 后主流为 设备树(DT)+ platform/driver 模型compatible 匹配 → probe() 初始化硬件。


5. 内核模块(.ko)动态扩展

模块是可加载/卸载的内核代码,无需重编整内核。

bash 复制代码
lsmod                 # 已加载模块
sudo insmod xxx.ko    # 加载(需手动处理依赖)
sudo modprobe xxx     # 加载(自动解析依赖)
sudo rmmod xxx        # 卸载
modinfo xxx.ko        # 模块元信息

最小模块模板

c 复制代码
#include <linux/module.h>
#include <linux/init.h>

static int __init demo_init(void)
{
    pr_info("demo: loaded\n");
    return 0;
}

static void __exit demo_exit(void)
{
    pr_info("demo: unloaded\n");
}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Demo kernel module");

编译为 .koinsmod 即可;dmesg 查看 pr_info 输出。


6. 调试与观测手段

工具/方法 用途
printk / pr_info 最基础内核日志
/proc /sys 运行时参数与设备信息
ftrace / perf 性能与调用链
kprobe / ftrace function_graph 函数级跟踪
kgdb 源码级断点调试(需额外配置)
KASAN 内存越界检测
oops / panic 日志 崩溃栈分析

应用层问题用 strace 看系统调用;内核/driver 问题从 dmesg 与对应子系统 proc 节点入手。


7. 学习路径建议

  1. 先建立地图:用户态 → syscall → 五大子系统 → 驱动/硬件
  2. 再读启动链head.Sstart_kernelrest_init(与嵌入式启动衔接)
  3. 用工具验证strace/proc/pid/mapslsmodmount
  4. 小步读源码 :跟一条 open()fork() 进内核,不要一上来通读 drivers/

不必一开始就写驱动;能把「进程---内存---文件---块 I/O」串起来,就已经超过大多数「只会用命令」的层次。


8. 小结

模块 一句话
进程调度 管理 task 与 CPU 时间片
内存 虚拟地址、页表、分配与回收
VFS 统一文件接口,衔接具体 FS 与块层
网络 协议栈与 socket
驱动 把硬件接入内核子系统

内核学习的本质是:在特权级代码里,看清资源如何被抽象、分配、回收。掌握本文地图,再按需深入各子系统源码,效率远高于漫无目的翻目录。

相关推荐
智购科技无人售货机厂家19 分钟前
2026自动售货机制冷系统维护指南:从散热器清洁到压缩机换油的工程实践~YH
运维·redis·物联网·缓存·架构
剑客的茶馆26 分钟前
开发者,运维怎样转行FDE?
运维·ai·开发·fde
Julien200431 分钟前
控制 SELinux 文件上下文
linux·运维·服务器
wangruofeng40 分钟前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
sulikey40 分钟前
Linux Core Dump 完全指南:从原理到实战的崩溃调试手册。什么是core dump?程序报错core dumped怎么办?
linux·服务器·操作系统·调试·coredump
众壹新能源科技1 小时前
功率预测误差考核怎么降?从气象源到上报口径的排查清单
运维·人工智能·自动化
wangruofeng1 小时前
AI 画架构图总差点意思,archify 给它加了一条验收流水线
架构·github·aigc
DevLoom_2 小时前
SD卡插电脑提示:驱动器中的磁盘未被格式化?恢复数据正确处理步骤
运维·服务器·电脑
叶落方知秋2 小时前
大模型学习笔记:排序怎么帮公司赚钱、多方怎么博弈
架构