Linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解

前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式——在一个独立的文件夹通过makefile配合内核源码路径完成

那么如何将驱动直接编译进内核呢?

    在我们实际内核的移植配置过程中经常听说的内核裁剪又是怎么麽回事呢?

我们在进行linux内核配置的时候经常会执行make menuconfig这个命令,然后屏幕上会出现以下界面:

这个界面是怎么生成的呢?

跟我们经常说的内核配置与与编译又有什么关系呢?

下面我们借此来讲解一下linux内核的配置机制及其编译过程。

一、配置系统的基本结构

Linux内核的配置系统由三个部分组成,分别是:

 1、Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linux 内核的编译规则;

    2、配置文件(config.in(2.4内核,2.6内核)):给用户提供配置选择的功能;

    3、配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。

这些配置工具都是使用脚本语言,如 Tcl/TK、Perl 编写的(也包含一些用 C 编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需要知道如何编写 Makefile 和配置文件就可以。

二、makefile menuconfig过程讲解

当我们在执行make menuconfig这个命令时,系统到底帮我们做了哪些工作呢?

这里面一共涉及到了一下几个文件我们来一一讲解

Linux内核根目录下的scripts文件夹

arch/$ARCH/Kconfig文件、各层目录下的Kconfig文件

Linux内核根目录下的makefile文件、各层目录下的makefile文件

Linux内核根目录下的的.config文件、arm/$ARCH/下的config文件

Linux内核根目录下的 include/generated/autoconf.h文件

1)scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,我们作为使用者无需关心这个文件夹的内容

 

2)当我们执行make menuconfig命令出现上述蓝色配置界面以前,系统帮我们做了以下工作:

    首先系统会读取arch/$ARCH/目录下的Kconfig文件生成整个配置界面选项(Kconfig是整个linux配置机制的核心),那么ARCH环境变量的值等于多少呢?

它是由linux内核根目录下的makefile文件决定的,在makefile下有此环境变量的定义:

或者通过 make ARCH=arm menuconfig命令来生成配置界面,默认生成的界面是所有参数都是没有值的

比如教务处进行考试,考试科数可能有外语、语文、数学等科,这里相当于我们选择了arm科可进行考试,系统就会读取arm/arm/kconfig文件生成配置选项(选择了arm科的卷子),系统还提供了x86科、milps科等10几门功课的考试题

3)假设教务处比较“仁慈”,为了怕某些同学做不错试题,还给我们准备了一份参考答案(默认配置选项),存放在arch/$ARCH/configs下,对于arm科来说就是arch/arm/configs文件夹:

此文件夹中有许多选项,系统会读取哪个呢?内核默认会读取linux内核根目录下.config文件作为内核的默认选项(试题的参考答案),我们一般会根据开发板的类型从中选取一个与我们开发板最接近的系列到Linux内核根目录下(选择一个最接近的参考答案)

#cp arch/arm/configs/s3c2410_defconfig .config

4).config

    假设教务处留了一个心眼,他提供的参考答案并不完全正确(.config文件与我们的板子并不是完全匹配),这时我们可以选择直接修改.config文件然后执行make menuconfig命令读取新的选项

    但是一般我们不采取这个方案,我们选择在配置界面中通过空格、esc、回车选择某些选项选中或者不选中,最后保存退出的时候,Linux内核会把新的选项(正确的参��答案)更新到.config中,此时我们可以把.config重命名为其它文件保存起来(当你执行make distclean时系统会把.config文件删除),以后我们再配置内核时就不需要再去arch/arm/configs下考取相应的文件了,省去了重新配置的麻烦,直接将保存的.config文件复制为.config即可.

5)经过以上两步,我们可以正确的读取、配置我们需要的界面了

那么他们如何跟makefile文件建立编译关系呢?

当你保存make menuconfig选项时,系统会除了会自动更新.config外,还会将所有的选项以宏的形式保存在

Linux内核根目录下的 include/generated/autoconf.h文件下

内核中的源代码就都会包含以上.h文件,跟宏的定义情况进行条件编译。

当我们需要对一个文件整体选择如是否编译时,还需要修改对应的makefile文件,例如:

    我们选择是否要编译s3c2410_ts.c这个文件时,makefile会根据CONFIG_TOUCHSCREEN_S3C2410来决定是编译此文件,此宏是在Kconfig文件中定义,当我们配置完成后,会出现在.config及autconf中,至此,我们就完成了整个linux内核的编译过程。

    最后我们会发现,整个linux内核配置过程中,留给用户的接口其实只有各层Kconfig、makefile文件以及对应的源文件。

    比如我们如果想要给内核增加一个功能,并且通过make menuconfig控制其声称过程

    首先需要做的工作是:修改对应目录下的Kconfig文件,按照Kconfig语法增加对应的选项;

    其次执行make menuconfig选择编译进内核或者不编译进内核,或者编译为模块,.config文件和autoconf.h文件会自动生成;

    最后修改对应目录下的makefile文件完成编译选项的添加;

    最后的最后执行make zImage命令进行编译。

三、具体实例

下面我们以前面做过的模块实验为例,讲解如何通过make menuconfig机制将前面单独编译的模块编译进内核或编译为模块

假设我已经有了这么一个驱动:

modules.c

  1. #include <linux/module.h>       /*module_init()*/
  2. #include <linux/kernel.h> /* printk() */
  3. #include <linux/init.h>       /* __init __exit */
  4. #define DEBUG   //open debug message
  5. #ifdef DEBUG
  6. #define PRINTK(fmt, arg...)     printk(KERN_WARNING fmt, ##arg)
  7. #else
  8. #define PRINTK(fmt, arg...)     printk(KERN_DEBUG fmt, ##arg)
  9. #endif
  10. /* Module Init & Exit function */
  11. static int __init myModule_init(void)
  12. {
  13. /* Module init code */
  14. PRINTK("myModule_init\n");
  15. return 0;
  16. }
  17. static void __exit myModule_exit(void)
  18. {
  19. /* Module exit code */
  20. PRINTK("myModule_exit\n");
  21. return;
  22. }
  23. module_init(myModule_init);
  24. module_exit(myModule_exit);
  25. MODULE_AUTHOR("dengwei");                          /*模块作者,可选*/
  26. MODULE_LICENSE("GPL");                             /*模块许可证明,描述内核模块的许可权限,必须*/
  27. MODULE_DESCRIPTION("A simple Hello World Module"); /*模块说明,可选*/
Step1:将modules.c拷到drivers/char/目录下(这个文件夹一般存放常见的字符驱动)
 
Step2: vi driver/char/Kconfig,在
    config DEVKMEM后添加以下信息
 
config MODULES
tristate "modules device support"
default y
help
 Say Y here,the modules will be build in kernel.
 Say M here,the modules willbe build to modules.
 Say N here,there will be nothing to be do. 
 
Step3:make menuconfig 
     Device driver-character devices
           [*]modules device suppor
 
Step4:vi driver/char/Makefile,在js-rtc后添加
obj-$(CONFIG_MODULES)+= modules.o

CONFIG_MODULES 必须跟上面的Kconfig中保持一致,系统会自动添加CONFIG_前缀

modules.o必须跟你加入的.c文件名一致

最后执行:make zImage modules就会被编译进内核中

第三步:

Step3:make menuconfig
     Device driver-character devices
           [M]modules device suppor

把星号在配置界面通过空格改为M,最后执行make modules,在driver/char/目录下会生成一个modules.ko文件

跟我们前面讲的单独编译模块效果一样,也会生成一个模块,将它考入开发板执行insmod moudles.ko,即可将生成的模块插入内核使用。

最新文章

  1. 敏捷开发与jira之项目现状
  2. Spring.Net 初探之牛刀小试
  3. MetaHandler.js:移动端适配各种屏幕
  4. 盯盯拍Android App 3.0指导
  5. 6/19 sprint3 看板和燃尽图的更新
  6. CF 103E Buying Sets 最大权闭合子图,匹配 难度:4
  7. [HDOJ3974]Assign the task(建树胡搞)
  8. [ACM] 最短路算法整理(bellman_ford , SPFA , floyed , dijkstra 思想,步骤及模板)
  9. ASP.Net免费发送短信-阿里大鱼短信接口
  10. 14--物理引擎Box2D
  11. Flex 日志管理
  12. 使用MediatR重构单体应用中的事件发布/订阅
  13. FixedUpdate()使用
  14. EJB3.0之事务
  15. mysql替换字符串
  16. vue.js精讲02
  17. 【SQL】glob 和 like 的区别
  18. [SQL]用SQL语句断开某个数据库的所有活动连接
  19. 洛谷P4211 LCA
  20. Parallels Desktop与VirturalBox对比

热门文章

  1. InnoDB体系架构总结(二)
  2. Python基础:字典(dict)与集合(set)
  3. linux系统,python3.7环境安装talib过程
  4. Python从文件中读取数据
  5. Python9-反射-day27(大年初三)
  6. 记如何解决蓝桥杯中to_string和atoi等无法使用的问题
  7. SVM 支持向量机算法介绍
  8. python图像插值
  9. bootshiro---开源的后台管理框架--基于springboot2+ shiro+jwt的真正rest api资源无状态认证权限管理框架,开发人员无需关注权限问题,后端开发完api,前端页面配置即可
  10. xtu数据结构 H. City Horizon