在开发的过程中,一般都是将驱动编译成模块,然后将其发送到开发板加载驱动进行功能验证,驱动的功能验证没有问题后就可以将其编译进内核了。本文将介绍如何把上一篇文章Linux下设备树、pinctrl和gpio子系统、LED灯驱动实验中的LED驱动编译到内核。
首先在Linux内核的/drivers/目录下创建一个文件夹,用来存放自定义的驱动文件,我这里新建的文件夹是/mydrivers,其绝对路径是/…/…/drivers/,然后将要编译进内核的c代码(这里以uart_led.c为例)拷贝到/mydrivers文件夹下。
在/mydrivers文件夹下创建一个名为Kconfig的文件,在Kconfig文件中键入如下内容。
config UART_LEDtristate "uart_led" help
This module will be compiled into kernel and light the uart led.
UART_LED和Makefile中引用的要保持一致,Makefile中会在前面加上CONFIG_。
tristate可以把驱动编译成3种状态,即编译进内核、不编译进内核、编译成模块。如果是bool关键字,则不能编译成模块。
help是帮助信息,下面的一句话就是帮助信息的内容。
同样地,在/mydrivers文件夹下创建一个名为Makefile的文件,在Makefile文件中键入如下内容。
obj-$(CONFIG_UART_LED)+=uart_led.o
UART_LED要和Kconfig中的保持一致,uart_led.o这里的名字和.c文件的命名要一致。
接下来进入到上一级目录,也就是/drivers/目录下,打开Kconfig文件,在里面添加下面的代码。
source "drivers/mydrivers/Kconfig"
上面的代码表示把自己创建的Kconfig文件链接到内核中已经有的,指明了Kconfig的路径,这样内核就可以一层一层的编译到我们自己创建的。
打开/drivers/目录下的Makefile文件,在里面添加下面的代码。
obj-y += mydrivers/
这里添加的是自定义文件夹的名字,不要少了最后的“/”,表示把这个文件夹编译进内核。
当然也可以将.c文件拷贝到/drivers/下的某个文件夹中,比如字符文件夹/char目录下,然后就不用再新建Kconfig和Makefile文件,直接在/char下的Kconfig和Makefile文件中追加内容就可以了。
不过还是建议自己新建一个文件夹,将自行新建的文件放到里面,这样就能确保尽可能少的改动Linux内核的原有文件。
以上这些工作完成以后,在Linux内核第一级目录下使用make menuconfig命令打开图形化界面进行相关配置。
前面括号里是星号的表示要编译进内核,括号为空的表示不编译进内核,括号为M的表示编译为模块。
移动到“Device Drivers —>”选项后按回车,进入下面的界面。
新加的这个驱动就出现在第一个位置,选中uart_led这一项按“Y”键将其选中,前面括号里出现了星号,表示要编译进内核。
按“?”打开帮助,其描述如下,这些内容就是在Kconfig文件中描述的信息。
退出当前界面,移动到最下面一栏,选择Save保存,弹出下面的界面,选择OK。
在Linux内核第一级目录下使用ls -a命令就可以看到所有文件,包括隐藏文件,这里的.config文件就是隐藏文件,如下图所示。
打开该文件,使用下面的命令查找我们刚才添加的设备驱动有没有保存在该文件中。
/CONFIG_UART_LED
如下图,新添加的这个设备=y就说明成功将这个驱动添加到内核中了。
确定设备添加到内核中后就使用下面的命令编译出内核镜像文件zImage。
make zImage -j16
-j参数是为了加快编译的速度,zImage编译完成后如下图所示。
镜像编译完成后在新建的/drivers/目录下就多了下面的两个.o文件。
将/arch/arm/boot/zImage发送到tftp文件夹里,然后启动开发板,查看开机打印信息如下图所示。
这些信息和加载驱动模块时打印的消息是一样的,如下图所示。
/dev/目录下也有一个名为/gpioled的文件。
再看一下开发板的物理表现,在内核启动的过程中,这个LED就被点亮了,如下图所示。
这就说明驱动编译进内核成功了!LED的亮灭也可以通过文章Linux下设备树、pinctrl和gpio子系统、LED灯驱动实验中的测试代码编译出的文件控制。
本文参考文章:
通俗易懂:把驱动编译进内核