在Linux内核里,编译内核文件时,先要配置.config文件,然后Makefile在编译时通过读取.config文件的配置来选择要编译的文件,选择驱动的加载方式。.config文件的生成可通过make menuconfig ARCH=arm 或make defconfig 方式生成,这两种方式看上去虽然不同,但是两者的原理是一样的,都是通过Kconfig文件的配置来的。
1.make menuconfig ARCH=arm
使用这种方式的来配置.config文件,主要通过配置图形化界面来选择要加载的文件,而图形化界面是通过读取每个目录下的Kconfig文件来的,每一个目录基本都一个Kconfig文件,所有Kconfig的入口是在arch/Kconfig文件,
2.make defconfig
使用这种方式去配置.config文件相对第一种方式比较可靠,因为选项不容易丢失,在使用第一种方式去配置,这样配置的可能不全面,而且Linux kernel源码中也有一些开发板的defconfig文件给我们参考,当你使用这一款开发板是=时,可以去参考去配置,然后加入你所需要的其他文件,可以直接在文件里面写入所要编译的模块配置即可。一般deconfig文件存放在arch/arm/configs/目录下。
二、Kconfig 文件语法
Kconfig的基本语法其实几大类,我把它们分为几大类:
1.模块类型:bool,tristate,string,int,hex五类,基本使用的有bool,tristate,string三大类。bool 类型的变量只有两种选择Y和N,
tristate类型的变量有三种选择Y、N和M,string类型的变量是输入字符串,其中Y表示该模块要编进kernel,N表示该模块部编入kernel,M表示该模块以模块的方式编入kernel,生成的.ko驱动,需要使用insmod和rmmod命令安装、卸载驱动。
2.依赖关系:depend on 和 select,depend on 和 select后面跟其他模块,其中depend on 表示在选择要加载当前模块的时候,前提必须要加载depend on 后面的模块,否则该模块无法被加载, 而select 却是相反的,它表示如果当前模块被选择加载了,该模块就会被默认的加载到内核中,故其它叫反向依赖。
3.help:在help后面我们都会看到一些的语句,而这些语句都是为这个模块解释,解释这个模块是用来干什么的用,在这里我们可以把它理解为起解释作用。
4.菜单架构:menu和menuconfig,其中menu经常与endmenu搭配使用,这两者中间的为这个菜单的子菜单。同时子菜单都会继承父菜单的依赖关系。而menuconfig其实大体和menu没有多大的区别,他最大的不同点在于menuconfig的菜单栏时候编辑选择的,带有模块选择的功能,而menu只是显示作用,说明这下面的子菜单是属于哪个模块的。
5.if...endif 和 choice....endchoice:在if.....endif之间中的模块有一个依赖关系,只有当if后面的模块被选中了,它们两之间的模块才能被选择,作用其实就跟if判断条件一样作用。而choice.....endchoice之间的模块只能是bool类型和tristate两种类型。
6.source和commit:在一个Kconfig中经常可以看到该文件中会source 其他的Kconfig文件,它的主要作用是读取另一个Kconfig文件,有点想include。commit 后面经常跟一些字符串,它主要用来注释说明这个下面模块的作用。
三、Makefile 语法
关于Makefile语法这边如果细讲的比较多,在这里我就简单的讲解一下Makefile是如何把驱动源文件编译到内核镜像中去的。在编译内核驱动文件的时候,Makefile分为三种编译方式去编译这个驱动源文件,分别:直接编译,模块编译,条件编译。
1.直接编译:例:obj-y += foo.o;
2.模块编译:例:obj-m += foo.o;
3.条件编译:例:obj-$(CONFIG_INPUT) += input.o; 这个config变量的值有Y,N,M三种,它在.config文件中配置的,是对驱动的加载方式的悬着。
四、Kconfig、.config示例
4.1 Kconfig 例子:
config LYD
bool "lyd is Small white"
depend on Manito
select Debug
help
Small white should solve the problem with the help of the Manito.
这个配置项的意思是:选择LYD这个模必须要选择Mantio这个模块,同时选中LYD这个模块也会把Debug这个模块选上,但是这个模块只能有两种选择,yes 或者No, 通过Help可以明白这个模块的作用是,小白在解决问题的时候应该有大神的指导。
4.2 .config 例子:
1. CONFIG_INPUT_MOUSE=y ----->这种写法表示内核在编译的时候要把这个模块加载到镜像中;
2. # CONFIG_MOUSE_PS2 is not set ----->这种写法表示内核在编译的时候不要把这个模块加载到镜像中;
3.CONFIG_INPUT_MOUSE=m ----->这种写法表示内核在编译的时候以模块化形式把模块加载到镜像中;需要手动去加载.口文件,
注:在.config文件中,有时候没有写这个模块为yes,但是在编译的时候还是被编译出来的,这种一种默认的情况,默认情况是什么,在编译的时候就是什么,所以在编译的时候不要觉得奇怪。
-- by lyd