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加一个宏

相关推荐
青梅橘子皮2 小时前
Linux---基本指令
linux·运维·服务器
REDcker3 小时前
Linux信号机制详解 POSIX语义与内核要点 sigaction与备用栈实践
linux·运维·php
cui_ruicheng4 小时前
Linux进程间通信(三):System V IPC与共享内存
linux·运维·服务器
蚰蜒螟4 小时前
深入 Linux 内核同步机制:从 futex 到 spinlock 的完整旅程
linux·windows·microsoft
运维全栈笔记4 小时前
Linux安装配置Tomcat保姆级教程:从部署到性能调优
linux·服务器·中间件·tomcat·apache·web
dllmayday5 小时前
Linux 上用终端连接 WiFi
linux·服务器·windows
峥无6 小时前
Linux系统编程基石:静态库·动态库·ELF文件·进程地址空间全景图
linux·运维·服务器
用户2367829801686 小时前
从 chmod 755 说起:Unix 文件权限到底是怎么算的?
linux
Strugglingler7 小时前
【systemctl 学习总结】
linux·systemd·systemctl·journalctl·unit file
嵌入式×边缘AI:打怪升级日志8 小时前
100ASK-T113 Pro 开发板 Bootloader 完全开发指南
linux·ubuntu·bootloader