Linux驱动程序如何编译进内核

  很多刚接触Linux驱动的初学者,肯定有这样的疑问,如何把自己写的驱动程序编译进内核使之可以驱动我的设备呢? 

  1. 从make menuconfig 说起

  在接触开发板的过程中,肯定都用到make menuconfig,进入界面之后可以通过菜单选择把驱动模块编译进内核,或者只是编译成模块,然后可以通过insmod加载这个模块。其实这已经涉及到驱动的两种加载方法:静态加载和动态加载。静态加载就是通过在菜单项前选[y]把模块直接编译进内核;动态加载就是通过insmod命令加载已经编译好的模块。假设开发板上原来没有nand flash驱动,现在我们自己写了一个nand flash驱动,想使用它,那分别通过动态加载和静态加载来实现。

  2 . 动态加载实现

  动态加载实现的话,任意位置新建一个nand驱动文件夹,里面有自己写的nand驱动程序和Makefile文件,在Linux环境下通过交叉编译生成设备驱动nand_device.ko和平台驱动nand_driver.ko,通过insmod nand_device.ko ,insmod nand_driver.ko加载进去,nand flash的驱动就加载进去可以使用了。

  3.静态加载实现

  3.1 驱动程序编译进内核

  静态加载的话要达到两个目标,首先在make menuconfig 里面能找到我们想要添加的驱动的菜单项,以nand 驱动为例,我们写了nand的驱动程序omap2.c,最终想看到这样的画面,如图1所示。其次,驱动程序编译进内核后可以识别对应的设备并可以驱动它。

Linux驱动程序如何编译进内核_第1张图片

                                                                               图1 Nand 驱动模块编译

NAND DEVICE Support 选项里有我们自己的omap2.c对应的NAND FLASH device on OMAP2 and OMAP3。NAND FLASH device on OMAP2 and OMAP3这句是我们自己添加的,和omap2.c是对应起来的,可以任意修改,下面就会讲到。

  omap2.c不能像动态加载那样随便放了,必须遵照内核的文件目录规则,把它放到/drivers/mtd/nand目录下面,然后修改nand目录下的两个文件Kconfig和Makefile。在Kconfig文件下面添加:

config MTD_NAND_OMAP2

tristate "NAND Flash device on OMAP2 and OMAP3"

depends on ARM && (ARCH_OMAP2 ||  ARCH_OMAP3)

help

Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms


在Makefile里面添加下面一行:

obj-$(CONFIG_MTD_NAND_OMAP2) +=omap2.o

  config MTD_NAND_OMAP2最后的OMAP2就是对应的文件名omap2.c,在Makefile里可以看到把它编译成了omap2.o。如果你的驱动程序是mynand.c,则就是

 config MTD_NAND_MYNAND,前缀MTD_NAND代表的是目录/mtd/nand,在每个目录下仿照其它的,修改最后一个后缀就可以了。

  tristate :表示三态,可以选Y,N,M三种情况,bool的话只能是Y,N,不能选M编译成模块。

  depends on 是依赖,使用这个的前提

  help 说明

  添加完之后,再使用make  ARCH=arm CROSS_COMPILE=arm-linux- menuconfig的时候,就可以找到我们的驱动选项了,退出之后自动保存在根目录下的.config里。以上就完成了我们的驱动程序编译进内核。

  如果对Kconfig和Makefile不熟悉的话可能还有点困惑,到底是怎么找到omap2.c这个文件的呢?那我们稍作说明。假设我们用的是arm平台,那么/arch/arm下的Kconfig里面会有这样几句,如图2所示

Linux驱动程序如何编译进内核_第2张图片

        图 2 /arch/arm下的Kconfig包含的子目录下的Kconfig

图2表示的是所有上一层的Kconfig都包含了其子目录下的Kconfig。

真正能使他包包含整个内核根目录下所有的Kconfig的是图3这几行:

Linux驱动程序如何编译进内核_第3张图片

  图 3 /arch/arm下的Kconfig包含的根目录下文件的Kconfig

  图3包含了根目录下的所有目录的Kconfig,以source "drivers/Kconfig"为例,它又包含了drivers目录下的所有子目录的Kconfig,当然就包含了source "drivers/mtd/Kconfig",mtd目录下的Kconfig包含了source "drivers/mtd/nand/Kconfig",这个Kconfig就是刚才我们修改的Kconfig了。这下应该比较清楚了吧。

  3.2 驱动程序可以识别对应设备并驱动它

  通过以上分析,你的驱动程序已经添加进了内核,但是并不一定能真的驱动你的nand flash。如果是原来的平台有nand flash且有相应的驱动,你只是移植使其可以支持新的nand 芯片,那么通过以上应该没有问题了。但如果是原来的平台没有开发这个nand驱动,那么就相对复杂了,如果要想使驱动可以正常工作,必须在/arch/arm下找到对应的开发板文件,如arch/arm/mach-omap2/board-am335xevm.c(选择哪个开发板对应的哪个文件也是在config文件里配置的,在里面搜一下自己的开发板名即可知道),在里面初始化am335x的nand控制器,最重要的是必须注册这个设备platform_device_register(&nand_device),本质上就是添加一个nand device 设备,即platform_device_add(&nand_device)。这样的话,你的设备的name和之前我们说的驱动程序的name如果一样的话,两者就可以匹配起来了,驱动程序就可以驱动这个设备了,不然的话驱动程序不知道要驱动哪个设备。到这里再看看我动态加载的时候,加载了两个文件,分别就包含了platform_device_register和platform_driver_register这两个函数。这里如果不明白的话可以查下platform_device_register和platform_driver_register之间如何匹配就可以了,我可以先告诉你是通过设备结构体和驱动结构体中的name来匹配的,name相同则匹配,具体细节可以网上搜一下,有文章讲的很清楚。


 


你可能感兴趣的:(linux,驱动)