Kconfig和Makefile文件的学习总结

来源:互联网 发布:设置apache端口 编辑:程序博客网 时间:2024/06/06 04:25

      开始接触Kconfig 文件是在内核编译时,所以首先回顾一下内核编译的过程:
      我们可以从网上下载内核源码包或者从 /usr/src 中将内核文件夹复制出来,这样做以妨直接对内核操作从而造成不可知的结果。
      接下来我们就是来配置内核,配置内核可以采用字符界面配置( make config )、或用菜单界面配置( make menuconfig ) , 另外两种由于有别的依赖条件我们暂时不讲,而我们平常用的比较多的就是菜单界面了。 进入内核目录有时直接使用 make menuconfig 命令却无法显示配置菜单,这是因为它的依赖关系还不完整,需要先用 sudo apt-get install libncurses5-dev 命令来安装它的依赖包。内核的配置菜单大致有 General setup( 大众化的设置 ) 、 File system( 文件系统 ) 、 processor type and features( 处理器类型和特征 ) 、 Device drivers( 设备驱动 ) 等等。
    再下面就是编译内核了,对于内核编译的整个过程我还是不太清楚,所以我只回顾一些涉及到的命令:
      make bzImage 这个命令的功能是生成使用 gzip 压缩的内核
      make modules modules_install 这个命令是完成内核模块的编译并安装到 /lib/modules/ 相应内核版本目录中
    编译过程还会涉及到内核的符号表文件 System.map-version 的导出。
    在使用 make config/menuconfig 时还会相应的生成 .config 配置文件,这个文件用来记录哪些部分 被编译入内核、哪些部分被编译为内核模块。

Kconfig 和 Makefile
    首先我们要明确在内核中增加程序需要完成的步骤,可归结为如下三项工作:
      将源代码文件复制到内核源代码相应目录。
      在目录的 Kconfig 文件中增加新源代码对应项目的编译配置选项。
      在目录的 Makefile 文件中增加对新源代码的编译条目,也就是书写编译规则。

关于 Makefile 文件的知识:
      首先 Makefile 它的作用是什么,通俗点讲它就是一系列编译规则的集合。
      其文件构成:显式规则、隐含规则、使用变量、文件指示、注释。

显式规则:
      一条指明了目标文件、目标文件的依赖文件、生成或更新目标文件所使用的命令。如:
       module1.o:module1.c head1.h
       gcc -c module.c -o module.o
      需要注意的是当递归编译到此时发现目标文件比依赖文件旧时会重新生成目标文件。

隐含规则:

      由 make 根据目标文件而自动推导出的规则,以及自动产生目标的依赖文件和生成目标的命令。

使用变量:
      变量的赋值符主要有 4 个: =、:=、+=、?=。值得注意的是引用变量时要注意其用法,其含义分别是递归展开、直接展开、追加赋值、条件赋值。如 obj-m += hello.o 便是用来记录编译目标的变量,其值为 .o 文件的列表,因为 obj 变量之前已经定义过了,此处采用追加赋值,将目标文件编译成模块,这些会在 .config 文件里有所记录。
      引用变量的一般方法是 $( 变量 ) ,如: CURRENT_PATH:=$(shell pwd),这里直接展开后便是 CURRENT_PATH=shell pwd ,而 shell pwd 是一条脚本命令,此时会直接执行命令得 到当前路径。
      还有一种变量是 Makefile 的预定义变量,这些变量有其特别的含义,如 CC 、 CFLAGS 、 PWD 、 AR 等。

文件指示:
      包含三部分:一是在一个 Makefile 中包含另一个 Makefile ,二是根据某些情况指定 Makefile 中的有效 部分,三是定义一个多行的命令。

注释:
      以#字符开头的行被当作注释。
伪目标的含义:
      目标文件分为实目标文件和伪目标文件,伪目标的目的不是要生成实际文件,而是为了让 make 执 行一些辅助命令,如打印信息和删除无用的中间文件等。 如:
      clean:
            -rm -f *.o
        all:
            ………

搜索目录:
      当文件所在目录发生改变后,可以不用更改 Makefile 中的规则,而只改变依赖文件的搜索目录。命令如下: vpath 模式 路径,其中模式可以表示要搜索的文件集类型,如% .h 、% .c 等。在前一次的模块编译中就使用了 make -C /usr/... M=$(...)modules 来搜索所需要的头文件目录和源文件目录。

条件语句:
    在使用 Makefile 时还可以使用条件语句,如 ifeq ( 变量 1 ,变量 2) 、或 ifneq 、以及还有 ifdef 变量名、 ifndef 。

使用库:
      在链接时如果是一般的 .o 文件则直接插入可执行文件中,如果是库文件的话则从库中找到所需的变量或函数,我们还可以定制自己的库文件,如: mylib:mylib( 成员名 )

关于 Kconfig 文件的知识:

    菜单入口:
     config 关键字字义新的配置选项,配置选项的属性包括类型、数据范围、输入提示、依赖关系 ( 或反向依赖 ) 、帮助信息和默认值。
      类型包括: bool 、 tristate 、 string 、 hex 、 int 。
      输入提示: prompt “...”
      依赖关系: depends on … 、 select … 。
      数值范围: range symbol symbol
      帮助信息:以 help (--help--) 开始

说明:
      menuconfig 关键字的作用与 config 类似,但它在 config 的基础上要求所有子选项作为独立的行显示。

菜单结构:
      有两各方式来确定菜单结构,一是以如下方式:
        menu …/ 菜单名
        depends on ...
        config … /菜单入口
        …………
        endmenu
      另一种则是根据依赖关系生成菜单结构,如果菜单选项在一定程度上依赖于前面的选项,它就能成为该选项的子菜单。如果父选项为 N ,则子选项不可见,如果父选项为 Y 或 M ,则子选项可见,如 Makefile 文件中的 obj-$(CONFIG_...) +=*.o, 这里往往采用变量引用来根据情况确定是编译入内核( Y )、不编译( N )、编译成模块( M )。

实例
      在实例操作中,我们在相应内核源代码 drivers 目录下新增了驱动目录后,为子目录创建了 Kconfig 和 Makefile 文件的同时一定要修改父目录中的 Kconfig( 如加 source “...” 来完成引用 ) 和 Makefile 文件,以便这两个新增文件能被引用,如果 test 驱动目录中包含子菜单选项,也就是其中有菜单的依赖关系,此时子菜单的显示与否由配置变量来确定是 Y 、 M 、 N 。
      test 目录下的 Makefile 文件就会根据配置变量的取值来构建 obj-* 列表,而配置变量可以由用户是否 选择图形菜单下的相应项来确定其值。
      obj 列表也可以是目录,例如 test 下包含 cpu 子目录,则会根据 TEST_CPU 是否等于 y ,等于则会执行 obj-y +=cpu/ ,而此时cpu 目录下也要有相应的 Makefile 文件来编译相应源文件。同时,对于 test 目录也要将 test/ 目录追加到其父目录的 Makefile 文件中以使其能被编译命令作用到并能进入 test 目录。总体上来讲就是你添加了子目录后一定要让其父目录中的 Kconfig 和 Makefile 文件知道,并且能够引用,到此,基本上完成父目录和子目录下的 Kconfig 和 Makefile 文件的修改说明。