Linux内核模块的编译

最简单的kbuild Makefile可以仅包含

复制代码
obj-$(CONFIG_FOO) += foo.o

其中(CONFIG_FOO)可以等于y或m,它的值由.config文件给出。如果(CONFIG_FOO)既不是y也不是m,那么该文件不会被编译和链接。

  • 当$(CONFIG_FOO)等于y时,编译到内核,上面语句等价于obj-y += foo.o,它告诉kbuild在当前目录下,有一个叫做foo.o的目标文件,它将从foo.c或者foo.S编译得到。eg:IIC SPI 优先级比较高

  • 当$(CONFIG_FOO)等于m时,表示foo.o需要被编译成模块。eg:wifi 调试用的多 启动顺序最后

一、obj-y 生成 built-in.a


在内核构建系统中,每个目录下的 Makefile 文件定义了编译目标。在这些目标中,obj-y 表示应该被编译并链接到内核的目标文件(通常是 vmlinux)中的文件。

编译源文件 :在 Kbuild 文件中,obj-y 会列出需要编译的源文件。比如:

obj-y += foo.o bar.o

这表示 foo.cbar.c 文件将会被编译成 foo.obar.o

较新的kernel使用的是 built-in.a。

进入到SPI

搜索built-in.a

在 Linux 内核(以你当前正点原子 RK3568 SDK 的drivers/spi驱动目录为例)的编译流程中,built-in.a子目录源码编译后的静态库集合文件,是内核 "分目录构建" 机制里的关键中间产物,下面结合你的场景拆解它的核心作用:

1. 它是什么?

built-in.a当前子目录下所有源码编译后的目标文件(.o)的打包文件 (静态库格式)。以你所在的drivers/spi目录为例:这个文件里包含了该目录下 SPI 驱动源码(如spi-rockchip.c等)编译生成的.o目标文件,是 SPI 驱动代码的 "静态集合包"。

2. 它是怎么来的?

内核采用分目录编译策略

  • 当你执行make编译内核时,每个子目录(比如drivers/spi)会先将自身的.c源码编译为.o目标文件;
  • 再通过ar工具(静态库打包工具)将这些.o打包成built-in.a
  • 最终,所有子目录的built-in.a会被统一链接到内核根目录的vmlinux(最终内核镜像)中。

3. 它的核心作用:静态内置到内核

built-in.a里的代码,对应make menuconfig中被设为*(编译进内核)的配置项 ------ 这部分代码会直接静态链接到内核镜像,随内核启动自动加载(而非动态加载)。

以你的 SPI 驱动目录为例:若你在menuconfig中把 SPI 驱动设为*,对应的代码就会被编译进这个built-in.a,最终成为内核镜像的一部分;若设为M(动态模块),则会生成.ko文件(可手动insmod加载),而非进入built-in.a

4. 对开发的意义(以你的正点原子 RK3568 为例)

你在drivers/spi目录看到built-in.a,说明:

  • 该目录下的 SPI 驱动源码已被编译为内核内置组件(不是动态模块);
  • 这些 SPI 驱动会随 RK3568 开发板的内核启动而自动初始化,无需手动加载模块。

简单说:built-in.a是内核 "把子目录代码打包成内置组件" 的中间产物,决定了哪些功能会被静态嵌入内核镜像(而非动态加载)------ 这也是你当前 SPI 驱动能随开发板内核自动运行的关键原因之一。

SPI的Makefile

二、目标由多个源文件编译得到

如果某个目标由多个源文件编译得到,那么可以通过(\-objs)或(<module_name>-y)把这些源文件告诉kbuild。Kbuild能够识别后缀-objs和-y,例如

<module_name>-objs 和 <module_name>-y 都可以在要编译<module_name>的时候把-y -objs定义的文件也编译上

2.1、$(<module_name>-y)案例

案例:

2.2、$(<module_name>-objs)案例

net/wireless/intel/iwlwifi/dvm/Makefile

加入一行

Makefile 加东西 查看差异

显示出我加的test

避免重复 改宏名

进入到configs目录

打开defconfig加一个宏

相关推荐
想唱rap4 小时前
Linux下进程的控制
linux·运维·服务器·c++·算法
itas1094 小时前
windows共享网络给网线直连的linux上网
linux·网络·windows·共享网卡·无网主机上网
徐徐图之!4 小时前
三、【阶段一运维基础】
linux·运维
Xの哲學4 小时前
Linux ALSA音频架构: 从内核驱动到应用开发的全面解析
linux·服务器·算法·架构·边缘计算
初心_20244 小时前
11. 嵌入式Linux防火墙nftables的使用
linux·运维·服务器
脏脏a6 小时前
【Linux】进程调度算法、进程切换、环境变量
linux·运维·服务器
暴风游侠8 小时前
linux知识点-内核参数相关
linux·运维·服务器·笔记
CAFEBABE 3413 小时前
linux离线安装docker并启动
linux·docker·eureka
OnlyEasyCode14 小时前
快速上手!查看、拷贝、编辑、远程连接Linux命令
linux·运维·服务器