kernel-devel_kernel-headers_libmodules

kernel-devel

  1. 定义
    全称 Kernel Development Package,是专门为编译 Linux 内核模块(.ko) 提供的完整构建套件,也是你开发驱动 / 内核模块必须安装的包。
  2. 包含内容(模块编译的核心依赖)
    模块编译专用的内核私有头文件(内核内部数据结构、API 定义);
    内核编译配置文件 .config(和当前运行内核完全一致);
    模块构建 Makefile 脚本、Kbuild 规则;
    Module.symvers 符号版本文件(含module_layout等符号的版本哈希,解决模块加载版本冲突);
    路径:/usr/src/kernels/(uname−r)/,并软链接到/lib/modules/(uname -r)/,并软链接到 /lib/modules/(uname−r)/,并软链接到/lib/modules/(uname -r)/build(模块 Makefile 的指向目录)。
  3. 核心用途
    唯一用途:编译内核模块(.ko)
    模块编译需要依赖内核内部的函数、结构体、符号版本校验;
    必须和当前运行的内核版本完全一致,否则就会出现你之前遇到的 module_layout 版本不匹配。
  4. 版本要求
    强制和uname -r输出的内核版本完全相同,一字不差

kernel-headers 里到底有什么头文件?(仅用户态用)

  • kernel-headers 的安装路径是 /usr/include/,核心目录是/usr/include/linux/、/usr/include/asm/,但这里的头文件有严格限制:仅包含内核向「用户态程序」暴露的公共接口定义,完全剔除了内核内部的私有头文件、子系统头文件。

    简单说,kernel-headers 的目录里根本没有 sound/ 这个文件夹,也没有drivers/、net/、fs/等内核驱动 / 子系统相关的目录,能找到的只是像linux/types.h、linux/errno.h、sys/socket.h这类用户态程序(比如 gcc、ls、cp 等命令)编译时需要的基础头文件

  • kernel-headers:用户态程序编译用,和内核模块无关;

  • kernel-devel:内核模块编译专属,含模块构建环境 + 符号版本校验信息,是驱动开发必装;

/lib/modules/

  • /lib/modules/ 是 Linux 内核模块运行时 + 编译链接的核心根目录 ,所有和内核模块(.ko相关的运行依赖、编译软链接、系统模块、依赖关系都存放在这里,按内核版本(uname -r)做完全隔离,目录结构和作用和你之前遇到的 模块编译、module_layout 校验、insmod/modprobe 加载强相关。

一、顶层结构

复制代码
/lib/modules/
└── [内核版本号]/      # 由 uname -r 得到,每个内核版本独立一套目录,互不干扰
    ├── build/        # 关键软链接 → 指向 kernel-devel 安装目录
    ├── source/       # 软链接 → 内核源码目录(一般和 build 同指向)
    ├── kernel/       # 系统原生内核模块存放目录
    ├── extra/        # 第三方/自定义编译安装的模块目录
    ├── modules.dep   # 模块依赖关系表
    ├── Module.symvers # 内核导出符号版本表(含 module_layout)
    └── 其他模块元数据文件(alias/symbols/devname等)

所有操作都针对当前运行内核的版本目录/lib/modules/$(uname -r)/


二、核心子项逐一分解(结合你的驱动/模块开发场景)

1. build/(最重要,模块编译的入口)

  • 本质 :指向**kernel-devel 安装目录**的软链接(一般到 /usr/src/kernels/$(uname -r)/

  • 作用
    编译内核模块时 Makefile 指向的 KERNELDIR 就是它,提供完整的模块编译环境
    内核 .config、内部头文件、Kbuild/Makefile 构建脚本、Module.symvers 符号版本表。

  • 你执行的模块编译命令本质就是跳转到这个目录执行构建:

    bash 复制代码
    make -C /lib/modules/$(uname -r)/build M=$PWD modules
  • 和之前报错的关联:build/ 指向的 kernel-devel 版本不匹配 → 模块编译用的 module_layout 和运行内核不一致 → 版本冲突。

2. source/

  • 软链接,通常和 build/ 指向同一个内核源码/开发目录,主要用于内核源码级编译,模块开发一般只用 build/

3. kernel/

  • 存放内核原生自带的模块 ,按功能子目录分类:

    复制代码
    kernel/drivers/  # 各类驱动模块(显卡/网卡/存储/USB)
    kernel/net/      # 网络协议模块
    kernel/fs/       # 文件系统模块
    kernel/lib/      # 内核库模块
  • 这些是内核发行版预装的标准模块,modprobe 加载系统模块时优先从这里查找。

4. extra/

  • 第三方/自定义内核模块 的默认安装目录:
    执行 make modules_install 安装自己编译的驱动、NVIDIA 显卡驱动、虚拟化驱动等,都会被安装到这里。
  • insmod/modprobe 加载第三方模块时,系统也会扫描该目录。

5. modules.dep & modules.dep.bin

  • 文本/二进制格式的模块依赖关系表 ,由 depmod 命令生成。
  • modprobe 加载模块时,靠这个文件自动加载依赖模块(比如加载 tun.ko 自动加载依赖的 ipv6.ko);
  • insmod 不会解析该文件,必须手动加载依赖。

6. Module.symvers(关键符号版本文件)

  • 记录内核所有导出符号的版本哈希值 (包括你遇到的 module_layout);
  • 模块加载时,内核用它和 .ko 里的符号版本做校验;
  • 该文件和 kernel-devel 里的 Module.symvers 完全一致,是模块版本兼容校验的核心依据

7. 其他元数据文件

  • modules.alias:硬件ID ↔ 内核模块的别名映射(热插拔/udev 用);
  • modules.symbols:内核导出符号 ↔ 所属模块的映射;
  • modules.devname:设备号/设备名 ↔ 模块的映射。

三、和 kernel-devel/kernel-headers 的关系

  1. /lib/modules/$(uname -r)/buildkernel-devel
    build 软链接就是 kernel-devel 的入口 ,没有安装 kernel-devel,该软链接指向无效,模块无法编译。
  2. kernel-headers 无关
    kernel-headers 安装在 /usr/include,供用户态程序使用,/lib/modules/ 目录无任何关联,模块编译也用不到它。

四、常用操作(和该目录相关)

bash 复制代码
# 1. 重新生成模块依赖与元数据(安装新模块后必执行)
sudo depmod -a

# 2. 查看模块的完整路径
modinfo -n xxx

# 3. 查看当前内核模块目录的软链接指向
ls -ld /lib/modules/$(uname -r)/build

# 4. 清理无效模块/重新生成依赖
sudo rm -f /lib/modules/$(uname -r)/modules.dep
sudo depmod

五、总结(一句话抓核心)

/lib/modules/$(uname -r)/内核模块的「运行仓库 + 编译入口」

  • build/ 软链接对接 kernel-devel,提供模块编译环境
  • kernel/extra/ 存放所有可加载的 .ko 模块;
  • 依赖/符号文件支撑 modprobe 加载和符号版本校验 (解决 module_layout 冲突)。
相关推荐
Web极客码2 小时前
CentOS 7.x如何快速升级到CentOS 7.9
linux·运维·centos
一位赵2 小时前
小练2 选择题
linux·运维·windows
代码游侠3 小时前
学习笔记——Linux字符设备驱动开发
linux·arm开发·驱动开发·单片机·嵌入式硬件·学习·算法
Lw老王要学习3 小时前
CentOS 7.9达梦数据库安装全流程解析
linux·运维·数据库·centos·达梦
CRUD酱3 小时前
CentOS的yum仓库失效问题解决(换镜像源)
linux·运维·服务器·centos
zly35004 小时前
VMware vCenter Converter Standalone 转换Linux系统,出现两个磁盘的处理
linux·运维·服务器
Albert Edison4 小时前
【Python】函数
java·linux·python·pip
General_G4 小时前
Linux中的信号
linux·运维·服务器
诸神缄默不语5 小时前
当无法直接用apt instll时,Linux如何离线安装软件包(以make为例)
linux·运维·服务器