Ventoy 如何按 DMPATCH 文档编译 dm_patch.ko 内核模块?
【免费下载链接】VentoyA new bootable USB solution.项目地址: https://gitcode.com/GitHub_Trending/ve/Ventoy
本文解决的任务是:按照 Ventoy 仓库DMPATCH目录中的 readme.txt 文档,从零开始编译出dm_patch.ko内核模块。DMPATCH目录包含补丁模块源码 dmpatch.c(文件头注释为 "patch for device-mapper",即对 device-mapper 的运行时补丁)、Makefile 以及 IBT 变体用的 Makefile_IBT。该模块在 Ventoy 运行时环境中由 ventoy-hook-lib.sh 按架构选择dm_patch_32.ko、dm_patch_64.ko或dm_patch_ibt_64.ko加载,因此按文档重新编译出的产物可以直接替换这些运行时依赖。文档明确的前提环境是 Ubuntu 22.04、内核 5.15.0-25。
编译环境与准备条件
readme 给出的环境与依赖安装命令如下:
apt-get install build-essential flex libncurses-dev linux-headers-generic linux-source libssl-dev bison yacc vim libelf-dev其中linux-headers-generic提供头文件与Module.symvers,linux-source提供完整内核源码(readme 第 4、7 步的make oldconfig、make menuconfig、make modules_prepare都依赖一棵完整源码树)。
环境准备包含三件事,均需在已make menuconfig前的内核源码树根目录操作:
复制当前内核的模块版本信息:
cp /lib/modules/5.15.0-25-generic/build/Module.symvers ./用当前运行的内核配置初始化源码树:
# 将 /boot/config-5.15.0-25-generic 作为源码树的 .config make oldconfig执行
make menuconfig,关闭以下四个选项(readme 第 5 步):CONFIG_STACKPROTECTORCONFIG_RETPOLINECONFIG_UBSAN_BOUNDSCONFIG_UBSAN_ENUM
这些配置修改是针对 Ventoy 构建环境的文档要求,不要在未确认影响的情况下改回。
修改 modpost.c
readme 第 6 步要求在修改后的内核源码树中修改scripts/mod/modpost.c,共三处:
- 在
add_srcversion中跳过逻辑(函数入口直接return); - 强制启用 retpoline 处理:把判断宏从
#ifdef改为#ifndef(force add_retpoline); - 强制加入
intree_flag(force add_intree_flag)。
文档没有给出具体行号,因为该文件随内核源码版本不同而有差异,需要在 5.15.0-25 对应的源码中按上述三处语义定位修改。
执行 modules_prepare 与 module.h 修改
接下来执行 readme 第 7 步,在源码树中准备模块编译环境。LOCALVERSION使用 readme 原文给出的长-x串(文档中为 52 个x,复制时保持完整):
make modules_prepare LOCALVERSION=-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx然后按 readme 第 8 步,在<include/linux/module.h>的struct module结构体末尾追加 1024 字节的 padding:
struct module { enum module_state state; /* Member of list of modules */ struct list_head list; /* Unique handle for this module */ char name[MODULE_NAME_LEN]; .... char padding[1024]; };readme 对这一步给出的原因是:struct module的大小在不同内核版本、不同 CONFIG 组合下不一致,追加固定 padding 是为了规避该差异。
编译并 strip 出 dm_patch.ko
源码目录(DMPATCH,含 dmpatch.c 与 Makefile)的内容如下:
obj-m += dm_patch.o EXTRA_CFLAGS := -Wall dm_patch-objs := dmpatch.o即产物为dm_patch.ko,由dmpatch.o组成。在修改好的内核源码树目录中,以M=参数指向 dmpatch 源码目录执行(readme 第 9 步):
make modules M=/home/dmpatch其中/home/dmpatch是文档示例路径,替换为实际存放dmpatch.c、Makefile的目录,例如本仓库的DMPATCH目录。
成功后在源码目录生成dm_patch.ko,再按 readme 第 10 步去掉调试信息:
strip --strip-debug /home/dmpatch/dm_patch.ko验证方式参照 ubuntu_build.sh:该脚本在完成两次构建后以产物文件是否存在判断成功(同时存在dm_patch.ko与dm_patch_ibt.ko时输出=============== SUCCESS =============,否则输出=============== FAILED ==============)。因此编译完成的判定条件就是目标目录下存在可被strip --strip-debug处理的dm_patch.ko。
可选:编译 IBT 变体 dm_patch_ibt.ko
仓库还提供 Makefile_IBT:
obj-m += dm_patch_ibt.o EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register dm_patch_ibt-objs := dmpatch.o它与标准 Makefile 的差异:产物名为dm_patch_ibt.ko,额外定义VTOY_IBT并开启-fcf-protection=branch -mindirect-branch-register。dmpatch.c 中#ifdef VTOY_IBT段落会在模块 init/exit 时保存与恢复MSR_IA32_S_CET的CET_ENDBR_EN位,这是该变体存在的源码依据。
使用方法与标准变体相同:将Makefile_IBT复制为源码目录的Makefile后重新执行make modules M=...,产物为dm_patch_ibt.ko。
参考:ubuntu_build.sh 的完整流程
ubuntu_build.sh 是文档配套的一条自动化脚本,完整展示了上述流程:下载源码与 Makefile → 复制*.c与Makefile到临时目录./aa→ 在内核源码树(脚本中为/home/panda/linux-source-5.15.0)执行make modules M=/home/panda/build/aa/→strip --strip-debug→ 将.ko拷回 → 重复一遍 IBT 构建 → 上传到内网 FTP → 检查两个.ko是否存在并打印 SUCCESS/FAILED。
需要注意:脚本中的FTPIP=192.168.44.1、FTPUSR='a:a'以及/home/panda/linux-source-5.15.0都是作者环境的私有地址与路径,外部读者无法直接使用,本文仅作流程参考;rm -f dmpatch.c Makefile Makefile_IBT、rm -rf ./aa等清理命令会删除对应文件,如需运行须先确认这些文件可再获取、目标目录无其他重要内容,并去掉末尾的curl -T ... ftp://...上传步骤。
模块运行时的适用范围
编译只是前提,产物是否能在目标机器生效取决于运行时。dmpatch.c 的dmpatch_process依据内核大版本号选择不同补丁路径(5.x 与 6.5+ 使用不同代码匹配逻辑),init 中若首次按当前内核版本打补丁失败,会依次回退尝试6.5.0与6.7.0路径;dmpatch_exit会恢复被修改的内核指令,保证卸载时内核回到原状态。这说明模块自身对内核版本差异做了适配,但适配范围以dmpatch.c中已实现的匹配模式为限,超出范围时 init 会返回-EFAULT,属于文档未承诺支持的版本,不应以改代码方式强行扩展。
结论与限制
按 readme.txt 完成上述步骤后,你会得到dm_patch.ko(及可选的dm_patch_ibt.ko),即可作为 Ventoy 运行时中dm_patch_64.ko/dm_patch_ibt_64.ko的替换产物。需要留意的限制:
- 文档指定环境为 Ubuntu 22.04 + 5.15.0-25,其他内核版本需自行按第 4–8 步适配源码树;
scripts/mod/modpost.c的三处修改是 readme 强制要求,不可跳过;struct module追加 padding 是 readme 强制要求,改动会影响整个内核源码树,不要直接用于系统内核;- IBT 变体由 Makefile_IBT 区分,与标准变体不能混用产物名。
【免费下载链接】VentoyA new bootable USB solution.项目地址: https://gitcode.com/GitHub_Trending/ve/Ventoy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考