Linux内核源代码在组织上有着非常清晰的目录结构,了解这些目录的存放位置和各自职责,是进行内核学习、驱动开发或系统调试的第一步。通常我们从内核官网或Git仓库获取到的源码压缩包,在解压之后会形成一棵以版本号命名的目录树,例如 linux-6.8。这棵目录树既可以放在当前用户的家目录下,也可以放在系统的公共源码路径中。

源码的常规存放路径
在Linux系统中,最常见的源码存放位置有两个。其一是用户主目录,比如 ~/linux-6.8,这种方式不需要root权限,适合个人阅读和编译测试。其二是传统的系统级目录 /usr/src,发行版过去常把内核源码放在 /usr/src/linux 符号链接指向的具体版本目录中,例如 /usr/src/linux-6.8。如今多数发行版不再默认提供完整源码,需要手动下载。
从社区获取源码的主要途径包括 kernel.org 的 tarball 压缩包,以及使用 git 克隆官方仓库。如果用 git,执行 git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 后,代码就会落在当前目录的 linux 文件夹里。无论放在哪里,目录内部的布局是完全一致的,区别只在于权限和路径长短。
有些嵌入式开发板厂商会提供修改过的内核,这时源码可能放在工程目录的 kernel/ 子目录中。但无论如何变化,顶层目录一定包含后面要介绍的那些核心文件夹。建议编译时通过 O= 参数指定输出目录,避免污染源码树,例如 make O=/build/linux-6.8。
顶层目录的核心组成
打开源码根目录,你会看到 arch、kernel、mm、fs、drivers 等文件夹。其中 arch 存放与体系结构相关的代码,比如 x86、arm64 各有一个子目录,里面包含启动汇编和架构特有实现。kernel 目录则是独立于硬件的通用内核子系统,如调度器、信号、定时器都在此。
mm 目录负责内存管理,包括页分配器、 slab 分配器和虚拟内存区域操作。fs 目录实现了各种文件系统,从 ext4 到 proc 都能在这里找到对应子目录。而 drivers 占据了源码最大的体量,所有设备驱动按类型分类,如 drivers/net、drivers/usb。这种划分让开发者能按功能快速定位。
除了上述目录,根目录下还有 include 存放头文件,scripts 提供构建辅助工具,Documentation 包含大量说明文本。阅读代码时,结合 Makefile 和 Kconfig 能理解模块如何被编译进内核。下面是一段简单遍历顶层目录的脚本示例:
#!/bin/bash
# 进入内核源码目录并打印主要子目录
cd ~/linux-6.8 || exit 1
for d in arch kernel mm fs drivers include; do
if [ -d "$d" ]; then
echo "目录 $d 存在,文件数: $(find $d -type f | wc -l)"
fi
done
如何基于目录结构高效阅读源码
面对庞大的代码量,盲目搜索效率极低。推荐从系统调用入口开始,用户态通过 syscall 触发,内核端在 kernel/sys.c 或各子系统文件中定义。例如打开文件最终走到 fs/open.c。利用 cscope 或 ctags 生成索引后,能直接在 arch 和 kernel 间跳转。
若想添加自定义驱动,应在 drivers 下建立新文件夹,并编写 Kconfig 与 Makefile 以便集成。编译时用 make menuconfig 勾选,源码树会自动处理依赖。这种基于目录约定俗成的分工,使全球数千名开发者能协同工作而不混乱。
最后要注意,不要直接修改 /usr/src 下的系统源码来试验,以免破坏包管理。最佳实践是复制一份到家目录,用普通用户权限编辑,只在安装模块时临时使用root。理解了源码放在什么文件下以及内部布局,后续的内核编程便有了一张可靠的地图。