news 2026/9/9 22:17:31

Ventoy 如何按 DMPATCH 文档编译 dm_patch.ko 内核模块?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ventoy 如何按 DMPATCH 文档编译 dm_patch.ko 内核模块?

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.kodm_patch_64.kodm_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.symverslinux-source提供完整内核源码(readme 第 4、7 步的make oldconfigmake menuconfigmake modules_prepare都依赖一棵完整源码树)。

环境准备包含三件事,均需在已make menuconfig前的内核源码树根目录操作:

  1. 复制当前内核的模块版本信息:

    cp /lib/modules/5.15.0-25-generic/build/Module.symvers ./
  2. 用当前运行的内核配置初始化源码树:

    # 将 /boot/config-5.15.0-25-generic 作为源码树的 .config make oldconfig
  3. 执行make menuconfig,关闭以下四个选项(readme 第 5 步):

    • CONFIG_STACKPROTECTOR
    • CONFIG_RETPOLINE
    • CONFIG_UBSAN_BOUNDS
    • CONFIG_UBSAN_ENUM

这些配置修改是针对 Ventoy 构建环境的文档要求,不要在未确认影响的情况下改回。

修改 modpost.c

readme 第 6 步要求在修改后的内核源码树中修改scripts/mod/modpost.c,共三处:

  1. add_srcversion中跳过逻辑(函数入口直接return);
  2. 强制启用 retpoline 处理:把判断宏从#ifdef改为#ifndefforce add_retpoline);
  3. 强制加入intree_flagforce 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.cMakefile的目录,例如本仓库的DMPATCH目录。

成功后在源码目录生成dm_patch.ko,再按 readme 第 10 步去掉调试信息:

strip --strip-debug /home/dmpatch/dm_patch.ko

验证方式参照 ubuntu_build.sh:该脚本在完成两次构建后以产物文件是否存在判断成功(同时存在dm_patch.kodm_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_CETCET_ENDBR_EN位,这是该变体存在的源码依据。

使用方法与标准变体相同:将Makefile_IBT复制为源码目录的Makefile后重新执行make modules M=...,产物为dm_patch_ibt.ko

参考:ubuntu_build.sh 的完整流程

ubuntu_build.sh 是文档配套的一条自动化脚本,完整展示了上述流程:下载源码与 Makefile → 复制*.cMakefile到临时目录./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.1FTPUSR='a:a'以及/home/panda/linux-source-5.15.0都是作者环境的私有地址与路径,外部读者无法直接使用,本文仅作流程参考;rm -f dmpatch.c Makefile Makefile_IBTrm -rf ./aa等清理命令会删除对应文件,如需运行须先确认这些文件可再获取、目标目录无其他重要内容,并去掉末尾的curl -T ... ftp://...上传步骤。

模块运行时的适用范围

编译只是前提,产物是否能在目标机器生效取决于运行时。dmpatch.c 的dmpatch_process依据内核大版本号选择不同补丁路径(5.x 与 6.5+ 使用不同代码匹配逻辑),init 中若首次按当前内核版本打补丁失败,会依次回退尝试6.5.06.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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 22:17:12

AI学习路径四阶段:从大模型原理到Agent实战

这两年我周围问AI学习路径的人特别多&#xff0c;而且问法高度相似&#xff1a;我已经会用ChatGPT写周报了&#xff0c;也知道Midjourney能画图&#xff0c;但再往深处走就完全没方向了——大模型原理要不要学&#xff1f;Agent到底是什么&#xff1f;那些动辄几十万的AI应用是…

作者头像 李华
网站建设 2026/9/9 22:15:55

STM32L4内部FLASH读写实战:从擦除对齐到掉电安全

简介&#xff1a;面向STM32L4系列嵌入式开发者&#xff0c;这份代码包提供基于LL库的寄存器级内部FLASH读写实现&#xff0c;已在STM32L452RET6芯片上调通。作者将FLASH解锁、擦除、写入、读取等操作封装在独立的C源文件与头文件中&#xff0c;底层均为寄存器配置&#xff0c;因…

作者头像 李华
网站建设 2026/9/9 22:15:36

STM32 GPIO扩展实战:74HC595级联驱动原理与代码详解

简介&#xff1a;STM32驱动74HC595的可级联函数包&#xff0c;面向嵌入式系统开发人员&#xff0c;特别适合数码管动态扫描、LED点阵显示和多通道并行输出等应用&#xff0c;能够有效节省微控制器引脚资源。代码基于Keil MDK工程编写&#xff0c;使用普通GPIO模拟SPI时序&#…

作者头像 李华
网站建设 2026/9/9 22:15:11

libmodbus 3.1.6在QT上位机中的集成与Modbus通信实战

简介&#xff1a;libmodbus-3.1.6-master 是一套面向嵌入式开发者的 Modbus 通信协议库源码包&#xff0c;重点解决 libmodbus 在 ARM A7 架构 imx6ull 平台上的交叉编译与定制集成问题。资源共 158 个文件&#xff0c;以 C 源文件、头文件、configure 配置脚本和 Makefile 工程…

作者头像 李华
网站建设 2026/9/9 22:13:08

localStorage 与 sessionStorage 怎么存 JSON 数据?存储 API 完整用法

localStorage 与 sessionStorage 怎么存 JSON 数据&#xff1f;存储 API 完整用法 【免费下载链接】33-js-concepts &#x1f4dc; 33 JavaScript concepts every developer should know. 项目地址: https://gitcode.com/GitHub_Trending/33/33-js-concepts 在浏览器应用…

作者头像 李华