当前位置: 首页 > article >正文

【Linux内核模块】模块的编译:从代码到可加载模块的 “变身术“

一、内核模块编译的特殊性为什么不能直接用 gcc普通 C 程序编译很简单gcc hello.c -o hello就行但内核模块可不行。这就像做面包和做蛋糕的区别 —— 虽然都是面粉做的但烤箱温度、配料比例完全不同。1.1 内核模块的 特殊身份内核模块不是独立程序而是要嵌入到内核中的 插件意味着必须使用与内核完全一致的编译选项比如字节序、对齐方式不能依赖标准 C 库glibc只能用内核提供的函数如 printk必须与内核版本严格匹配不同内核版本的头文件差异很大1.2 举个直观的例子如果你用系统默认的 gcc 编译模块会得到类似这样的错误代码语言javascriptAI代码解释error: printk undeclared (first use in this function)这不是因为 printk 不存在而是因为没有正确引入内核头文件和编译选项。1.3 内核模块编译的三大要素二、编译前的准备搭建 工作台在开始编译前需要准备好必要的工具和环境就像做蛋糕前要准备好烤箱和原料。2.1 安装内核开发包最关键的是要安装与当前内核版本匹配的内核源码或开发包Ubuntu/Debian系统代码语言javascriptAI代码解释# 查看当前内核版本 uname -r # 安装对应版本的内核开发包 sudo apt-get install linux-headers-$(uname -r)CentOS/RHEL 系统代码语言javascriptAI代码解释sudo yum install kernel-devel-$(uname -r)这些包会安装编译模块所需的头文件和配置文件通常放在/lib/modules/$(uname -r)/build目录下。2.2 准备测试代码创建一个简单的测试模块hello.c代码语言javascriptAI代码解释#include linux/init.h #include linux/module.h static int __init hello_init(void) { printk(KERN_INFO Hello, 内核模块世界\n); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO Goodbye, 内核模块世界\n); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE(GPL); MODULE_DESCRIPTION(一个简单的测试模块);这个模块加载时会打印一句欢迎语卸载时打印告别语。三、核心工具Makefile 的写法内核模块的编译完全依赖 Makefile这是整个过程的 指挥中心。一个最简单的内核模块 Makefile 只有几行但每一行都有特殊含义。3.1 最基础的 Makefile创建文件Makefile注意首字母大写代码语言javascriptAI代码解释# 声明要编译的模块 obj-m hello.o # 内核源码树路径自动获取当前系统内核 KERNELDIR ? /lib/modules/$(shell uname -r)/build # 当前目录路径 PWD : $(shell pwd) # 默认编译目标 default: # 进入内核源码树执行编译 $(MAKE) -C $(KERNELDIR) M$(PWD) modules # 清理编译生成的文件 clean: $(MAKE) -C $(KERNELDIR) M$(PWD) cleanobj-m hello.o告诉内核构建系统要编译一个名为hello.ko的模块.o文件会被链接成.ko模块KERNELDIR指定内核源码树的位置/lib/modules/$(uname -r)/build是标准位置PWD记录当前目录路径让内核构建系统知道模块代码在哪里(MAKE)−C(KERNELDIR) M(PWD) modules这是核心命令意思是 -C (KERNELDIR)进入内核源码目录M(PWD)告诉内核构建系统模块源码在当前目录modules执行内核模块编译目标3.2 编译模块在终端执行make命令代码语言javascriptAI代码解释make如果一切顺利会看到类似这样的输出代码语言javascriptAI代码解释make -C /lib/modules/5.4.0-100-generic/build M/home/user/kernel-modules modules make[1]: Entering directory /usr/src/linux-headers-5.4.0-100-generic CC [M] /home/user/kernel-modules/hello.o Building modules, stage 2. MODPOST 1 modules CC [M] /home/user/kernel-modules/hello.mod.o LD [M] /home/user/kernel-modules/hello.ko make[1]: Leaving directory /usr/src/linux-headers-5.4.0-100-generic编译成功后目录下会生成几个文件hello.ko最终可加载的内核模块最重要的文件hello.o编译产生的目标文件hello.mod.c模块依赖信息自动生成hello.mod.o模块依赖目标文件modules.order和Module.symvers模块顺序和符号信息四、多文件模块编译如何编译多个源代码文件当模块代码复杂时通常会分成多个文件。比如我们有main.c和helper.c两个文件该如何编译呢4.1 多文件模块的 Makefile只需将多个文件合并成一个模块名代码语言javascriptAI代码解释# 将main.o和helper.o合并成一个demo.ko模块 obj-m demo.o demo-objs : main.o helper.o # 指定组成demo.ko的目标文件 KERNELDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M$(PWD) clean关键是demo-objs : main.o helper.o它告诉构建系统demo.ko由main.o和helper.o链接而成。4.2 多文件模块的代码结构main.c主文件代码语言javascriptAI代码解释#include linux/init.h #include linux/module.h #include helper.h // 包含辅助函数头文件 static int __init demo_init(void) { printk(KERN_INFO 主模块初始化\n); helper_function(); // 调用辅助函数 return 0; } static void __exit demo_exit(void) { printk(KERN_INFO 主模块退出\n); } module_init(demo_init); module_exit(demo_exit); MODULE_LICENSE(GPL);helper.c辅助文件代码语言javascriptAI代码解释#include linux/kernel.h #include helper.h void helper_function(void) { printk(KERN_INFO 这是辅助函数\n); }helper.h头文件代码语言javascriptAI代码解释#ifndef _HELPER_H_ #define _HELPER_H_ void helper_function(void); #endif执行make后会生成demo.ko模块包含了两个文件的功能。五、编译选项的高级配置自定义编译规则有时需要添加额外的编译选项比如警告级别、宏定义等这可以通过EXTRA_CFLAGS实现。5.1 添加编译警告选项让编译器更严格地检查代码代码语言javascriptAI代码解释obj-m hello.o EXTRA_CFLAGS -Wall -Wextra # 开启更多警告 KERNELDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M$(PWD) clean-Wall开启基本警告-Wextra开启额外警告帮助发现潜在问题。5.2 定义宏常量在编译时传递宏定义控制代码条件编译代码语言javascriptAI代码解释obj-m debug_module.o EXTRA_CFLAGS -DDEBUG1 # 定义DEBUG宏值为1 # 或者根据条件定义 ifdef DEBUG EXTRA_CFLAGS -DDEBUG1 endif在代码中可以这样使用代码语言javascriptAI代码解释#ifdef DEBUG printk(KERN_DEBUG 调试信息变量x的值为%d\n, x); #endif编译时如果定义了DEBUG1就会输出调试信息。5.3 包含额外头文件目录如果模块需要引用其他目录的头文件代码语言javascriptAI代码解释obj-m mymodule.o EXTRA_CFLAGS -I$(PWD)/include # 包含当前目录下的include子目录 KERNELDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M$(PWD) modules六、交叉编译为其他平台编译模块有时需要为嵌入式设备编译模块比如 ARM 架构这就需要交叉编译。1. 安装交叉编译工具链以 ARM 架构为例在 Ubuntu 上安装代码语言javascriptAI代码解释sudo apt-get install gcc-arm-linux-gnueabihf2. 交叉编译的 Makefile代码语言javascriptAI代码解释obj-m hello_arm.o # 目标架构的内核源码路径 KERNELDIR : /path/to/arm-linux-kernel # 交叉编译器前缀 CROSS_COMPILE : arm-linux-gnueabihf- # 当前目录 PWD : $(shell pwd) default: $(MAKE) -C $(KERNELDIR) ARCHarm CROSS_COMPILE$(CROSS_COMPILE) M$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) ARCHarm CROSS_COMPILE$(CROSS_COMPILE) M$(PWD) cleanARCHarm指定目标架构为 ARMCROSS_COMPILEarm-linux-gnueabihf-指定交叉编译器前缀执行make后会生成能在 ARM 设备上运行的hello_arm.ko模块。七、常见编译错误及解决方法即使最简单的模块也可能遇到编译错误。这里列举几个最常见的问题及解决办法。7.1 没有规则可制作目标 错误代码语言javascriptAI代码解释make: *** 没有规则可制作目标“modules”。 停止。原因内核源码树路径错误或未安装内核开发包。解决检查KERNELDIR是否指向正确的内核源码目录确保已安装linux-headers-$(uname -r)包7.2 隐式声明函数 错误代码语言javascriptAI代码解释error: implicit declaration of function ‘printk’ [-Werrorimplicit-function-declaration]原因忘记包含必要的头文件。解决在代码开头添加#include linux/kernel.hprintk 的声明在这个头文件中。

相关文章:

【Linux内核模块】模块的编译:从代码到可加载模块的 “变身术“

一、内核模块编译的特殊性:为什么不能直接用 gcc?普通 C 程序编译很简单,gcc hello.c -o hello就行,但内核模块可不行。这就像做面包和做蛋糕的区别 —— 虽然都是面粉做的,但烤箱温度、配料比例完全不同。1.1 内核模块…...

ElevenLabs波兰语语音突然失真?3类高频报错代码+实时调试日志解析(含波兰语IPA音素校验表)

更多请点击: https://codechina.net 第一章:ElevenLabs波兰语语音失真现象的系统性定位 ElevenLabs 的 TTS 服务在处理波兰语时,部分用户报告出现音素断裂、重音偏移及辅音簇(如 szcz、 żdź)发音模糊等失真现象。此…...

ElevenLabs越南文TTS落地全链路:从API密钥配置、SSML控制到本地化韵律校准(含实测MOS评分对比)

更多请点击: https://codechina.net 第一章:ElevenLabs越南文TTS落地全链路概览 ElevenLabs 作为当前高保真语音合成领域的领先平台,其对越南语(vi-VN)的支持已进入生产就绪阶段。尽管官方文档未单独设立越南语专区&a…...

【限时解密】Midjourney野兽派风格“原始态”生成协议:仅用/raw + 2个隐藏参数,绕过所有风格平滑化过滤(实测成功率提升67%)

更多请点击: https://codechina.net 第一章:Midjourney野兽派风格的美学本质与系统性失衡 野兽派(Fauvism)在视觉艺术中以高饱和色彩、粗犷笔触与主观情感压倒写实逻辑著称;当这一美学被Midjourney等扩散模型“转译”…...

告别繁琐点击:3大功能助你实现智能文档获取与自动化下载

告别繁琐点击:3大功能助你实现智能文档获取与自动化下载 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了…...

Python窗口美化终极指南:5分钟打造Windows 11风格界面

Python窗口美化终极指南:5分钟打造Windows 11风格界面 【免费下载链接】py-window-styles Customize your python UI window with awesome pre-built windows 11 themes. 项目地址: https://gitcode.com/gh_mirrors/py/py-window-styles 还在为Python应用程序…...

对比直接使用厂商API观察通过聚合平台调用的延迟差异

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接使用厂商API观察通过聚合平台调用的延迟差异 在将大模型集成到应用时,开发者通常会关注API调用的响应速度。聚…...

华为OD机试真题 新系统-等距二进制判断(C/C++/Py/Java/Js/Go)

等距二进制判断 华为OD机试新系统真题 华为OD上机考试新系统真题 5月20号 100分题型 华为OD机试新系统真题目录点击查看: 华为OD机试真题题库目录|机考题库 算法考点详解 题目内容 对于一个二进制数,我们定义相邻两个 111 之间 000 的数量为他们两个…...

新手入门指南,五分钟完成Taotoken账号注册与第一个API调用

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 新手入门指南,五分钟完成Taotoken账号注册与第一个API调用 对于初次接触大模型API的开发者来说,如何快速上…...

百考通AI:答辩PPT智能生成,覆盖从开题到终答的全流程,让毕业答辩更从容

毕业答辩是学术生涯的关键一战,一份逻辑清晰、专业美观的PPT是顺利通关的核心保障,却也让无数毕业生熬夜奋战:从提炼研究核心到规划答辩流程,从设计页面排版到打磨讲稿,繁琐的准备工作常常让人焦头烂额。百考通AI&…...

3分钟上手Bifrost:跨平台三星固件下载与解密终极指南

3分钟上手Bifrost:跨平台三星固件下载与解密终极指南 【免费下载链接】Bifrost Cross-platform tool for downloading Samsung mobile device firmware. 项目地址: https://gitcode.com/gh_mirrors/sa/Bifrost 还在为三星设备刷机找不到官方固件而烦恼吗&…...

智慧铁路列车车辆和人员检测数据集VOC+YOLO格式5059张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):5059标注数量(xml文件个数):5059标注数量(txt文件个数):5059标注类别…...

企业知识资产化的三步走路线

企业知识资产化的三步走路线品质工程师老张每周一最头疼的事,就是准备品质例会的周报。上周的例会上,生产总监随口问了一句:“B12产线上个月出现的表面缺陷,之前有没有类似的案例?处理结果怎么样?”老张当场…...

Markdown怎么转换成txt?5种方法+在线工具对比2026最全指南

在日常工作中,Markdown格式的文件越来越常见,但有时候我们需要将其转换为纯文本格式来适应不同的应用场景。本文将为你详细介绍md转txt的多种方法,包括本地转换、在线工具、编程方案等,帮助你快速找到最适合的解决方案。为什么需要…...

从B站视频到高品质音频:BilibiliDown音频提取全攻略

从B站视频到高品质音频:BilibiliDown音频提取全攻略 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/…...

Steam Deck Tools 终极指南:Windows 掌机的完美伴侣

Steam Deck Tools 终极指南:Windows 掌机的完美伴侣 【免费下载链接】steam-deck-tools (Windows) Steam Deck Tools - Fan, Overlay, Power Control and Steam Controller for Windows 项目地址: https://gitcode.com/gh_mirrors/st/steam-deck-tools 还在为…...

终极macOS Windows启动盘制作工具:WinDiskWriter完整指南

终极macOS Windows启动盘制作工具:WinDiskWriter完整指南 【免费下载链接】windiskwriter 🖥 Windows Bootable USB creator for macOS. 🛠 Patches Windows 11 to bypass TPM and Secure Boot requirements. 👾 UEFI & Legac…...

收藏!程序员转AI工程师的3条死路+3条真路(内含2026年最新就业方向)

本文揭示了2026年程序员转AI工程师的3条死路和3条真路。死路包括从零学ML训练想做研究员、靠Prompt工程当主修、装AI App做评测自媒体,这些路径因入门方向被误导而难以成功。真路则包括用现有领域跳板转AI应用工程、AI Infra/MLOps方向、AI Agent工程师方向&#xf…...

王晓玲越“激进”,长安马自达越尴尬:油改电没份,新能源没量

【文/深度评车&财经三剑客】当长安马自达执行副总裁王晓玲喊出"马自达电动化转型,合资中最激进"时,市场的反应却是一阵沉默——因为这句话,怎么听都像是一种自我安慰。 王晓玲的底气有二:一是长安马自达坚持不做油改…...

Vulhub 中的 Cacti-CVE-2025-24367

0x00 前言先看结果吧,复现是成功了,但是没拿到shell,和我想的不一样。漏洞原理:Cacti是一款利用RRDTool数据存储和图形化功能的完整网络图形化解决方案。在Cacti 1.2.28及以前版本中存在一个命令注入漏洞,该漏洞允许已…...

教育机构搭建ai编程辅导平台时如何通过taotoken管理多学生密钥

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 教育机构搭建AI编程辅导平台时如何通过Taotoken管理多学生密钥 在AI编程辅导平台的构建中,教育机构常常面临一个核心的…...

3种方法彻底解决Realtek RTL8125 2.5GbE网卡驱动兼容性问题

3种方法彻底解决Realtek RTL8125 2.5GbE网卡驱动兼容性问题 【免费下载链接】realtek-r8125-dkms A DKMS package for easy use of Realtek r8125 driver, which supports 2.5 GbE. 项目地址: https://gitcode.com/gh_mirrors/re/realtek-r8125-dkms 你是否正在为Linux系…...

【限时解密】Midjourney范戴克印相私藏LUT包+预设Prompt库(仅开放48小时):含ISO 200/400/800三档真实胶片响应曲线

更多请点击: https://kaifayun.com 第一章:Midjourney范戴克印相的美学溯源与数字复刻逻辑 范戴克印相(Van Dyke Brown process)诞生于19世纪末,是一种以硝酸银、柠檬酸铁铵与酒石酸钾钠配制感光液,经紫外…...

数环通iPaaS流程引擎中断恢复机制设计:快照 + 消息驱动实现无缝续跑

一个无法回避的问题 做iPaaS自动化引擎开发的同学迟早会遇到这个问题:流程跑到一半断了,怎么办? 不是那种代码bug导致的异常退出——那种靠异常处理就行。我说的是更真实、更棘手的场景: 服务发版需要滚动重启,机器上还…...

获 800 万美元融资,MAU 超 40 万!「shapes」AI 社交能否成下一代聊天应用?

《「shapes」获 800 万美元种子轮融资,AI 助力社交“入场”,能否成下一代聊天应用?》这几天,我在「shapes」随机进了个陌生群聊,发了句 "hello",三秒内就有 AI 角色接上,回了串热情有…...

深入WCH USB主机IP:对比CH58x与CH32系列寄存器差异及CherryUSB适配心得

深入解析WCH USB主机IP:寄存器差异与CherryUSB适配实战 1. WCH USB主机IP架构概览 沁恒微电子(WCH)的CH58x/CH57x与CH32V/CH32F系列微控制器虽然采用不同的USB主机IP设计,但在协议栈层面保持了高度兼容性。这种设计哲学体现了硬件…...

宝丽来胶片模拟不等于加噪点!深度拆解Polaroid SX-70光学特性与MJ v6渲染引擎的4层映射偏差,附12组可直接复用的--sref哈希值

更多请点击: https://intelliparadigm.com 第一章:宝丽来SX-70胶片的光学本质与历史语境 宝丽来SX-70胶片并非传统意义上的“静态感光材料”,而是一套高度集成的自显影光学化学系统。其核心在于多层涂布结构中嵌入的镜面反射层、碱性催化剂囊…...

Codex 适配国产信创环境完整部署指南(深度技术篇)

摘要随着国内信创产业全面落地推进,基于大代码模型的智能编码助手 Codex,在国产化服务器、操作系统、CPU 架构环境下的适配、编译、部署、调优成为企业数字化转型过程中的刚需技术痛点。本文从架构原理、国产硬件适配、操作系统兼容、依赖编译、容器化部…...

从CubeMX到AD:为你的STM32F4项目创建‘带注释’原理图符号的完整指南

从CubeMX到AD:打造STM32F4项目专属原理图符号的工程实践 在嵌入式硬件开发中,原理图符号的清晰度直接影响着团队协作效率和后期维护成本。许多工程师都曾遇到过这样的困境:面对一个标准STM32芯片符号,需要反复查阅数据手册才能确认…...

为Claude Code配置Taotoken聚合API密钥与Base地址避免封号风险

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为Claude Code配置Taotoken聚合API密钥与Base地址避免封号风险 在使用Claude Code这类编程助手工具时,开发者有时会遇到…...