Linux内核Makefile obj-y & obj-m

嘿嘿,说起Linux内核下的Makefile,真是内核构建过程中的一个宝藏。
我在问答论坛上呆了很多年,我看到很多人在这里感到头疼。
归根结底,它就像一块错综复杂的乐高积木。
您需要知道如何堆叠它们以获得您想要的核心。

我记得有一次,我帮助一位初学者阅读他的Makefile。
那家伙研究了一下午,但他不知道如何使用 obj-y 和 obj-m。
我告诉他,这两个东西就像你的零件盒,obj-y是必须塞进核心的部分,obj-m是可以做成单独模块的部分。
您需要先编译它,然后才能安装它。

当时我拿了一个小笔记本,写下了obj-y和obj-m的区别。
Obj-y 定义了连接成大块的文件,就像大的构建块一样,必须编译到内核中; obj-m 定义了可以独立的小构建块,它们将被编译成模块。

还有subdir-y和subdir-m,和你的workbench一样,专门用来处理子目录的。
我教他如何使用这个变量,比如“obj-$(CONFIG_BINFMT_ELF)+=binfmt_elf.o”。
这就像在工作台上放置新的积木一样。
满足条件时会自动添加。

然后是Rule.make文件,它是总管理器,负责连接各个子目录下的Makefile。
记得有一次,一位朋友说他不明白Rule.make是如何工作的,所以我给他展示了实际的项目,让他看看make命令是如何调用子目录中的Makefile的。

顶层目录下的Makefile和Makefile.build就像是项目的大概轮廓,定义了全局的构建参数,比如工具链、编译参数等。
我记得我参与过一个项目,我在这里设置了一个工具链,告诉编译器使用什么版本的gcc。

构建过程相当复杂,要经过几个步骤。
例如,您需要创建Makefile和Makefile.build,然后修改obj-y和相关变量,调整编译和链接选项,设置工具链,命名最终程序,最后进行构建和清理。

我之前遇到过一些问题,比如某些变量设置不正确,导致构建失败。
当时我必须一步步解决问题,有时要好几个小时。
因此,在构建 Linux 内核时,耐心至关重要。

这就是本文的内容。
在下一期中,我将更深入地探讨 obj-m 的使用,特别是与 file_operations 结构相关的部分。
希望读者能够通过本文得到内核构建过程的基本概念,也希望大家讨论更多关于内核的知识。

linux内核模块编译makefile

Linux内核模块编译,Easy是关键。
此项必须遵循 kbuild 规范。

让我们从一个简单的例子开始,因此:
obj-m += 你好.o 全部:制作模块-C/lib/模块/$ 干净:使 M=$(PWD) 干净
这意味着:编译模块 hello 并执行相同的清理操作。

按键命令说明:
do -C / lib/modules/$(con test uname -r)/construct M=$(PWD) 模块
这行代码切换到内核源码目录,指定当前模块路径,然后编译该模块。

多源文件编译,例如hi参数依赖于a.c和b.c,所以可以这样写:
obj-m += 你好.o 你好-y := a.o b.o
条件编译,比如判断是否在内核编译环境:
ifneq ($(KERNELRELEASE)) obj-m := 你好.o 别的东西 KDIR?=/lib/modules/$(crust-r) 全部:$(FAC) -C $(KDIR) M=$(PWD) 模块 干净:$(干净)-C $(KDIR)M = $(PWD)干净 结束
文件管理头,如自定义头文件添加路径:
ccflags-y += -I$(DIR)/include
对于常见问题,例如目标文件和源文件名称不同,需要显式指定客户端: 你好-y := 自定义名称.o
调试信息,如添加DEBUG编译选项:
CFLAGS_hello.o:=-DDEBUG
模块安装路径,如自定义安装目录:
INSTALL_MOD_PATH=/自定义/路径
综上所述,核心变量是obi-m、obi-y和ccflags-y。
运行递归编译的关键命令是通过 -C 和 M=。
灵活支持多个模块、多个源文件和自定义头文件路径。
递归逻辑是通过KERNELRELEASE来区分第一次调用与内核环境的区别。
掌握了这些之后,核心的Makefile模块就不再是问题了。