内核裁剪的方式有两种:
第一种:make menuconfig 进入图形界面的配置。
第二种:就是打开源码进行相应的裁剪。
这里我们先介绍一下第一种方式的裁剪方式:make menuconfig
首先介绍下make menuconfig 这个命令实际上是这样运行的:./scripts/kconfig/mconf arch/arm/Kconfig
mconf:这个是一个解析器,用来解析Kconfig文件
Kconfig:就是用来生成我们make menuconfig看到的所有选项,当然,Kconfig也是一层层调用的,和makefile类似。下面我们来写一个最简单的Kconfig文件。
首先在我们上一节课的目录下driver/mydriver下创建一个Kconfig的文件:并写入一下代码
1 config MY_DRIVER 2 bool "select mydriver" //这是一个选项,并没有与我们的mydirver.c关联 3 default n //默认情况下不选择 也就是make menuconfig 中[ ]空的情况 想要选择的话,default y 4 help //对应我们make menuconfig 中下面的 select exit help 中的help 5 IF yuo select this ,you will happy !!! //这个是help中的解释描述
然后保存退出./scripts/kconfig/mconf driver/mydriver/Kconfig文件:
可以看到我们的选项就长成这个样子;
上面我们说过Kconfig是一层层调用的,所以我们来打开上层的Kconfig,把我们写的Kconfig写入到上层Kconfig,这样就能够make menuconfig的时候直接在整体的选项里面看到我们的Kconfig所生成的选项;
vim ../Kconfig 照猫画虎:第三行就是我们添加的代码用source 命令。source一下我们的Kconfig
1 menu "Device Drivers" 2 3 source "drivers/mydriver/Kconfig" 4 5 source "drivers/base/Kconfig" 6 7 source "drivers/connector/Kconfig" 8 9 source "drivers/mtd/Kconfig"
最后,make menuconfig 就可以看到我们的选项了,这次我们用空格按键把它选上,exit 保存。
[liuye@LiuYe linux-3.5]$>make menuconfig scripts/kconfig/mconf Kconfig # # configuration written to .config # *** End of the configuration. *** Execute 'make' to start the build or try 'make help'.
可以看到配置被写入到.config文件下:
我们来打开这个文件搜索一下 :/MY_DRIVER
1096 # 1097 # Device Drivers 1098 # 1099 CONFIG_MY_DRIVER=y 1100 1101 # 1102 # Generic Driver Options 1103 #
可以看到:CONFIG_MY_DRIVER=y。 这就是我们把自己编写出来的选项选中了;如果不选中的话,则如下#CONFIG_MY_DRIVER is not set
1096 # 1097 # Device Drivers 1098 # 1099 # CONFIG_MY_DRIVER is not set 1100 1101 # 1102 # Generic Driver Options 1103 #
到这里添加一个最简单的make menuconfig选项就写完了,后面我们会再讲解如何编写其他类型的选项。
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
还记得我们前面说的Kconfig中只是创建了一个选项,并没有把我们的代码和选项关联在一起:下面我们就来讲解一下如何把我们的代码与刚刚编写的选项关联:
116 如果我们写的选项被选中,那么在编译之后(make 之后),最终都会体现在下面两个文件中;make之前我们的选项,是否被选中都会直接体现在.config中,忘记了的同学往上屡屡。 117 118 内核中所有的.C中都会包含下面这个文件: 119 [liuye@LiuYe linux-3.5]$>vim include/generated/autoconf.h //这里面存放的是关于我们的选项的宏定义; 120 内核中所有的makefile中都会包含下面这个文件: 121 [liuye@LiuYe linux-3.5]$>vim include/config/auto.conf //这里面存放的是关于我们的选项的CONFIG_MY_DRIVER=y的变量:根makefiel中定义变量的方式是一样一样的;
同学们自行打开上面的文件look look。
打开driver/mydriver/Makefile
1 #include/config/auto.conf 2 obj-$(CONFIG_MY_DRIVER) += my.o #这行也就把我们的选项关联上了我们的代码。 3 #如果没有选中我们的选项:CONFIG_MY_DRIVER就不存在,上面的代码也就相当于下面这行。相当于没有选中我们的代码。 4 #obj-n +=my.o 5 #obj-y +=my.o
然后我们再用make menuconfig就可以自由的配置内核,也就是裁剪我们的代码,同学们可以选中或者不选中,重新编译一下kernel,刷机然后启动过程中我们的代码执行与否就可以体现的淋漓尽致。建议小伙伴们都试试。
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
上面我们裁剪的是对一个文件整体的一个裁剪,那如果我们想对文件中部分代码进行裁剪该怎么办呢?
让楼主告诉你们吧;
我们来想一下:整个文件的裁剪是在Kconfig里面编写的一个选项(一个宏)决定的,那我们也同样可以在Kconfig中来再写一个选项(宏)来匹配我们文件中的部分代码啊。真聪明!!!然后在代码中利用这个选项(宏),进行条件判断,执行不同的代码。
第一步:改我们的程序 :vim my.c
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/sched.h> 4 //include/generated/autoconf.h 5 //在内核启动过程中执行,且在内核启动过程中执行的函数类型是固定的:int test_init(void) :返回值和行参是固定的。 6 //init 段:这个函数被放到init段,好处是代码执行完成之后,函数体就释放了,节省一部分内存。只能调用一次。后面不要调用了> 。 7 static __init int test_init(void) 8 { 9 int i; 10 //如果资源申请失败,要饭会相应的错误吗 11 // 12 //return -ENOMEM;内存申请失败 13 for(i=0;i<20;i++) 14 { 15 #ifdef CONFIG_MY_DRIVER_KERNEL 16 printk("hello kernel "); 17 #else 18 printk("hello arm "); 19 #endif 20 } 21 //printf("") //>> 1 22 return 0; 23 24 } 25 //把test_init函数放到内核启动过程中执行 26 module_init(test_init); 27 MODULE_LICENSE("GPL"); 28 //下面三行可有可无 29 MODULE_AUTHOR("LIUYE"); 30 MODULE_VERSION("V1.0"); 31 MODULE_DESCRIPTION("test for class");
第二步:在Kconfig中添加我们的另一个选项(宏):vim driver/mydriver/Kconfig
1 config MY_DRIVER 2 bool "select mydriver" 3 default n 4 help 5 IF yuo select this ,you will happy !!! 6 config MY_DRIVER_KERNEL 7 bool "select my_driver" 8 default n 9 help 10 If ....................
第三步:make menuconfig 来选中或者不选中,编译内核:make 刷机:看效果!!!
需要注意的是:在my.c 中用的宏定义:CONFIG_MY_DIRVER_KERNEL要与Kconfig定义的选项(宏):MY_DRIVER_KERNEL相差一个CONFIG前缀:
因为,Kconfig里面定义的选项(宏)MY_DRIVER_KERNEL:在编译之后会在include/generated/autoconf.h中自动添加CONFIG前缀,然而内核中每个.c程序都是默认包含这个头文件的,所以我们在.c文件中用的宏就可以直接与选项关联上了。