1). 内核源码的配置项 在linux内核源码目录下,进行配置时:
make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 上面命令执行,它又会调用: scripts/kconfig/mconf Kconfig //其中"scripts/kconfig/mconf"是一个专门在终端上显示界面的程序 // "Kconfig"是在源码目录下的文件,传递给mconf程序,让mconf根据"Kconfig"里面的内容产生相应的配置项. //也就是说如要在linux内核里增加自己驱动的配置项时,只需要修改Kconfig文件里的内容即可. //配置完成后,最终的内核配置结果存放在linux内核源码目录下的".config"里2). Kconfig语法
基础语法1: config 关键字A 类型 "提示字符" if 关键字B // if表示依赖关键字B项, 如果B项不选中,则A项不会显示出来 default y/m/n //默认值 y编进内核 m编为模块 n不编译 help 帮助信息 基础语法2: config 关键字C depends on 关键字D && 关键字E && 关键字F 类型 "提示字符" 类型有: bool tristate hex string int // 增加菜单项: menu "菜单名" //增加一个菜单 config ... config ... endmenu / 必须选择一项的配置项: choice prompt "选项名" default 关键字 //默认选中的项 config 关键字 bool/tristate "提示" config ... config ... endchoice /// menuconfig 与config用法一样 区别在: menuconfig如有子项依赖的话, 则子项在下级菜单里 config不管依赖关系怎样, 都是在并列的菜单项里3). 增加我们自己的驱动配置项, 通常应是在设备驱动里 Kconfig里面可通过”source xxx/xxx/Kconfig”调用其它目录的Kconfig
在内核源码的drivers/目录下创建一个"0mydrvs"子目录, 里面存放我们自己的驱动源码. 把前面符号导出的源码放进0mydrvs目录里: myfunc子目录装着myfunc.c 用于提供全局函数"myfunc" usage子目录装着test.c,调用"myfunc"的测试代码 在linux内核里应用两个配置项来表示这两个驱动模块, 而且它们有依赖关系. 在linux内核里几乎每个目录里都有Kconfig, Kconfig文件由它的上一级目录的Kconfig里"source"调用. ////////////// 在0mydrvs目录里的Kconfig内容: source "drivers/0mydrvs/myfunc/Kconfig" source "drivers/0mydrvs/usage/Kconfig" 在0mydrvs目录下的myfunc子目录里的Kconfig内容: config MYFUNC tristate "configuration of myfunc" default y help help of myfunc 在0mydrvs目录下的usage子目录里的Kconfig内容: config USAGE tristate "test of myfunc" depends on MYFUNC help this is a test of myfunc 最后,不要忘了在内核源码drivers目录里的Kconfig增加调用0mydrvs里的Kconfig. 在drivers目录里的Kconfig增加语句: source "drivers/0mydrvs/Kconfig" / 通过"make menuconfig ..."选上这两个配置项后,在.config文件里可查看到: ... 995 CONFIG_MYFUNC=m 996 CONFIG_USAGE=m4). 驱动源码的编译. 前面加Kconfig仅仅多了两个配置项,最终也就是在”.config”文件里多两项内容. 编译还是需要用Makefile来指定编译的, 但是Makefile里应当由.config里的相应的关键字内容来决定是否编译,及是编进内核还是编成模块.
在linux内核里又是每个目录里都有Makefile文件, 由它的上一级目录里的Makefile文件里调用. 在0mydrvs目录里的Makefile内容: obj-y += myfunc/ obj-y += usage/ 在0mydrvs目录里的myfunc子目录的Makefile内容: obj-$(CONFIG_MYFUNC) += myfunc.o 在0mydrvs目录里的usage子目录的Makefile内容: obj-$(CONFIG_USAGE) += test.o 最后在内核源码的drivers目录的Makefile增加调用0mydrvs里的Makefile. 在drivers目录里的Makefile增加语句 : obj-y += 0mydrvs/5). 编译的操作:
如果配置项是编进内核镜像的话, 只要做下面这步就可以了: make uImage ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- // 编译好后,更换uImage后启动系统时,就会看到相应的打印输出 如果配置项是编成模块的话,除了做上面步骤外,还需要: make modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 如果编译出的模块很多的话,还可以: make modules_install INSTALL_MOD_PATH=板文件系统根目录/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-// 驱动模块在内核里的编译的好处: 在查看到驱动模块间的依赖关系。如:
modinfo drivers/0mydrvs/usage/test.ko filename: /disk3/myown/h3/orangepi_sdk/source/linux-3.4.112/drivers/0mydrvs/usage/test.ko license: GPL depends: myfunc intree: Y vermagic: 3.4.112 SMP preempt mod_unload ARMv7 p2v8 可以看出test.ko是依赖myfunc.ko的,当用"modprobe test"加载test.ko时会自动把依赖的驱动模块也加载上. //注意,用modprobe加载驱动模块必须是用"make modules_install ...."生成的.