1.概述
在内核源码的顶层目录下,输入命令make menuconfig。(无论什么linux源代码,还是安卓源代码)
这个图像化界面可以配置将驱动编译进内核,也可以配置不将这个驱动编译进内核。
打开图形化配置界面前,先设置环境变量,确定平台的类型。
export ARCH=arm642.打不开menuconfig的常见问题
常见打不来图形界面的问题:
1.没有安装ncurses
2.终端的窗口太小
3.没有在内核顶层源码路径下输入make menuconfig
3.界面操作
驱动状态:
将驱动编译成模块 ,用M表示
将驱动编译到内核中,用*表示
不编译
使用空格切换
搜索:/
跟rtthread的menuconfig操作一样。其实linux驱动开发和单片机的驱动开发方式,跟硬件相关的,一模一样。
4.容易困扰的一个问题
如果要将驱动编译到内核中,源码的位置一定在驱动文件夹中
而如果只是将驱动编译成模块,源码位置可以自己修改
准确结论
驱动编译到内核中(内置编译,
y选项)- 源码建议 / 通常放在内核源码树的驱动文件夹中(如
drivers/char/、drivers/misc/等),而非 “必须”—— 本质是内核的Kconfig和Makefile要能找到源码,只要配置文件路径正确,源码也可放在内核树内其他目录,但行业惯例是按驱动类型归类到对应drivers/子目录(比如字符驱动放drivers/char/,SPI 驱动放drivers/spi/)。 - 核心要求:必须修改内核源码树中的
Kconfig(添加驱动配置项)和Makefile(添加obj-y += 驱动文件名.o),否则内核编译时无法识别该驱动。
- 源码建议 / 通常放在内核源码树的驱动文件夹中(如
驱动编译成模块(模块编译,
m选项)- 源码位置完全可以自定义(比如你放在
/home/workspace/driver/下),无需放入内核源码树 —— 这也是嵌入式开发中最常见的方式(避免修改内核源码树)。 - 核心要求:只需在驱动的独立
Makefile中指定内核源码路径(KERNELDIR)、架构(ARCH)、交叉编译器(CROSS_COMPILE),即可独立编译出.ko模块,无需修改内核的Kconfig/Makefile。
- 源码位置完全可以自定义(比如你放在
补充关键细节(避免踩坑)
1. 内置编译(编译到内核)的实操要点
如果你要把驱动编译进内核,步骤是:
- 将驱动源码(如
hello_drv.c)复制到内核源码树的对应驱动目录(如drivers/char/); - 修改该目录下的
Kconfig,添加驱动配置项:config
config HELLO_DRV tristate "Hello World Driver" help A simple char driver for test. - 修改该目录下的
Makefile,添加:makefile
obj-$(CONFIG_HELLO_DRV) += hello_drv.o - 执行
make menuconfig,找到HELLO_DRV选项并设为y(内置),再编译整个内核; - 编译后的内核镜像(
zImage/Image)会包含该驱动,启动后无需手动加载。
2. 模块编译的核心优势(为什么更常用)
- 无需修改内核源码树,驱动源码可放在任意目录(如你的
/home/workspace/driver/); - 编译速度快(仅编译驱动,无需编译整个内核);
- 可动态加载 / 卸载(
insmod/rmmod),调试方便; - 适合驱动开发阶段,迭代效率远高于内置编译。
总结
- 驱动内置编译到内核:源码 “惯例上” 放在内核
drivers/子目录(便于管理),核心是Kconfig/Makefile要能找到源码,路径可自定义但不推荐; - 驱动编译为模块:源码位置完全可自定义,只需在驱动的
Makefile中指定内核源码路径即可; - 嵌入式开发中(如 RK356X),驱动开发阶段优先用 “模块编译”,调试完成后若需随内核启动加载,再改为 “内置编译”。