Linux内核中Kconfig和Makefile文件分析

主要关注内核安全模块:/usr/src/linux-xx/security/xxx

这些源码树目录下一般都会有两个文件:Kconfig和Makefile,

1 KConfig

其中分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单

也就是说Kconfig对应内核的配置文件,是配置信息的宏定义。

我们以apparmor为例,截取一部分apparmor对应文件夹下的Kconfig文件

config SECURITY_APPARMOR
    bool "AppArmor support"
    depends on SECURITY && NET
    select AUDIT
    select SECURITY_PATH
    select SECURITYFS
    select SECURITY_NETWORK
    default n
    help
      This enables the AppArmor security module.
      Required userspace tools (if they are not included in your
      distribution) and further information may be found at
      http://apparmor.wiki.kernel.org

      If you are unsure how to answer this question, answer N.

config SECURITY_APPARMOR_BOOTPARAM_VALUE
    int "AppArmor boot parameter default value"
    depends on SECURITY_APPARMOR
    range 0 1
    default 1
    help
      This option sets the default value for the kernel parameter
      'apparmor', which allows AppArmor to be enabled or disabled
          at boot.  If this option is set to 0 (zero), the AppArmor
      kernel parameter will default to 0, disabling AppArmor at
      boot.  If this option is set to 1 (one), the AppArmor
      kernel parameter will default to 1, enabling AppArmor at
      boot.

      If you are unsure how to answer this question, answer 1.

config SECURITY_APPARMOR_HASH
    bool "Enable introspection of sha1 hashes for loaded profiles"
    depends on SECURITY_APPARMOR
    select CRYPTO
    select CRYPTO_SHA1
    default y
    help
      This option selects whether introspection of loaded policy
      is available to userspace via the apparmor filesystem.

那么我们使用make menuconfig编译内核,生成内核菜单,对应与apparmor这一块的内容就是:

 

 可以看出对应关系,depends on代表这个config是在哪一级,bool后面接的是菜单对应的名称。

正式一点的说法呢,bool对应的是该菜单项的类型定义,每个config菜单项都必须有类型定义,bool类型只能选中y/不选中n;除此类型之外,还有tristate内建/模块/移除三态、string字符串、hex十六进制、integer整型。

depends on对应的是该菜单项以来于哪一个菜单项定义,这也就解释了为什么不是KConfig文件里的每一项都会显示,因为依赖于另一项,只有在被依赖的另一项为true时,该项才会显示/才能被选。

  即A depends on B:只有B被选中时,才能选A

select表示反向依赖,

  即A select B:只要选中A,就会选中B

range表示可选择的范围,比如上方SECURITY_APPARMOR_BOOTPARAM_VALUE就规定了0-1,因为是int型,所以就是选择0/1

default表示默认值

那么每个配置目录前面的[ ]/[*]/[M]是啥呢?这些是读取内核根目录下.config文件生成的配置项,其中[ ]不编译/[*]编译进内核/[M]编译为模块

2 Makefile

LInux内核中每个子目录下的Makefile文件,被称为Kbuild-makefile,它指定当前目录下的文件,哪些被编译进当前目录的built-in.o、那些被编译成模块、那些不编译。定义编译规则

我们还是以security/apparmor作为分析,截取对应子目录下的Makefile文件中的开头部分

obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o

apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
              path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
              resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
              af_unix.o
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o

clean-files := capability_names.h rlim_names.h net_names.h

如$(CONFIG_SECURITY_APPARMOR) 是一个整体,表示引用CONFIG_SECURITY_APPARMOR变量,我们发现这个变量在KConfig文件中有对应。

obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o  //把apparmor添加进内核配置系统

而后面的apparmor-y := apparmorfs .o audit.o  ...    则表示会创建一个基于apparmorfs .o&audit.o&... 的库文件,即需要编译链接后面一系列.o文件。

除了y(编译进内核)或m(编译进模块)以外的obj-x形式的目标都不会被编译

:= 覆盖之前的值,即变量的值取决于它的makefile的位置,不是整个makefile展开后的值。

+=添加等号后的值

 

3 使用make menuconfig的流程

        首先确定架构arch,然后读取arch目录的Kconfig中的配置宏定义,生成编译条目,然后读取Linux内核根目录下的.config选项, 将.config中的配置信息显示在图形界面上[*] [M] or []。在图形界面中更改配置选项会自动保存到.config文件中。编译过程根据.config随后生成auto.conf文件,它决定了makefile中各个文件的编译类型,静态编译进内核、编译成模块、不编译;同时生成autoconf.h,它以C语言宏定义的形式表达了 各个文件是否被编译,源码中会判断某文件是否被编译进行不同的处理。  (https://blog.csdn.net/lizuobin2/article/details/51429937

posted @ 2019-11-06 11:18  闲不住的小李  阅读(673)  评论(0编辑  收藏  举报