您的位置:首页 > 运维架构 > Linux

【ZYNQ_LINUX】linux 内核编译中 makefile 与 Kconfig 的关系

2018-02-03 00:17 344 查看
本文转载自:http://blog.sina.com.cn/s/blog_4ba5b45e0102e6vp.html
http://blog.csdn.net/sinat_16790541/article/details/45891143
最近在学习设备驱动程序,编写完之后进行编译之前,要在Kconfig和Makefile文件里面添加一些内容,参考了
其他的源码,发现源码树目录下几乎都有Kconfig和Makefile文件,并且在内核编译之前,要使用make menuconfig
(或者xconfig)生成配置文件。那么到底这些文件对于内核的编译有什么作用?它们之间是怎么样的关系,网上
参考了一些文章,然后自己实地操作了一番,现简单总结下来:
一、内核编译及Kconfig,.config和Makefile三者关系
      1.1  当我们在写驱动程序的时候,可以选择把它之间编译进内核,也可以以模块的形式(module)存在,
            编译成模块(编译成模块的好处就是 我们修改了内核,但是编译的时候不会全部重新编译整个
           内核,而是只编译模块这一小部分,节省时间,并且可以随时插入或者删除模块更加灵活)。
            在编写完某个驱动程序比如vfio-ccw.c的时候,我们如何把它以内核或者模块编译,或者不编译?
             我们需要修改两个文件: Makefile和Konconfig
           1.  参考一些源代码,我们在Makefile中看到了类似的: obj-m+= ccw.o
                                                                           obj-y += vfio.o
                                                                           obj-x + = ccw-xx.o
                     
4000
                                                      obj-$(CONFIG_KVM) += vfio-ccw.o
               就是这些类似的语句(目标定义)用来定义哪些内容(文件)要作为模块编译,或者直接编译进内核,
               或不编译,或根据某个配置选项的选择来进行何种编译。我们平常所用的make命令就是根据Makefile
               里面的规则来进行编译的。
           2. 那么这些配置变量CONFIG_KVM的值从哪里获得呢?
               make命令从源目录/Linux-2.6.16中的.config文件获得,里面每一行都是一个配置变量的赋值。那么
               这个.config文件从何而来?里面的配置变量何时赋值?
          3. 在我们新得到linux源码的时候,在主目录里面并没有.config文件,我们需要使用autoconfig生成或者
              手动赋值.config文件,但是这样的方法要么缺乏灵活性(不能实现按需定制的要求。如果要添加或
              删掉某个驱动,将要在.config文件中找到相应的项进行修改。非常的不方便。)要么手动工作量太大。
              那么就引入了Kconfig和make menuconfig. 对于每个配置选项(eg CONFIG_KVM),我们在Kconfig
              文件里面进行定义, 设定它的 选项, 然后在make之前,先使用make menuconfig进入配置选项设定
              的菜单,然后在菜单界面上找到你想要设置的配置选项(这里是CONFIG_KVM 对应的描述,找到后,
              按空格键选择*代表y,编译进内核,m代表m,编译为模块,空代表不编译。
              这样就为CONFIG_KVM进行了赋值,在make时候读取Makefile,就 可以给$(CONFIG_KVM)赋值了
              可以知道将obj-$(CONFIG_KVM) +=vfio-ccw.o中的vfio-ccw.o如何编译,
              也即将我们的驱动程序如何编译。
         4. 由此,我们可以看到Makefile,.config.Kconfig三者之间的关系。
              Makefile:一个文本形式的文件,其中包含一些规则告诉make编译哪些文件以及怎样编译这些文件。
             .config:文件是在进行内核配置的时候,经过配置后生成的内核编译参考文件。
              Kconfig:一个文本形式的文件,其中主要作用是在内核配置时候,作为配置选项。
              Kconfig(配置选项)  ---->make menuconfig (菜单选择)--->.config(生成值)-->Makefile(使用选项)---->make (make modules)
 
    二、Kconfig,Makefile的结构及其编写规则 
            内核源码树目录下都有两个文件Kconfig和Makefile,分布到各目录的Kconfig构成了一个分布式的内核
             配置数据库,每个Kconfig描述了所属目录源文件相关的内核配置菜单。在Kconfig文件中,一般的内核
             配置菜单如下:
              menu "Virtulization"
              config  KVM

                      select KVM_VFIO
                      select VFIO_IOMMU_ADAPTER if (VFIO_IOMMU)
              config XEN
               ....
             endmenu

              config  VFIO_IOMMU

                      bool “VFIO IOMMU"

                      depends on VFIO

                      default n
                      help
                           this is vfio iommu driver
              config VFIO_IOMMU_TYPE1
               ....
          1.每个菜单项(config定义的)就是menu/endmenu中Virtualization这个菜单的菜单项。
          2. config下面bool,depends on, default,help,select等为config的属性,用来定义该配置
             选项的类型,依赖,默认值,描述等。
          3. config的类型定义:bool(y or m), tristate(y,m or n), string(字符串), hex(16进制)
              integer(整型),一般情况下选择bool或者tristate的多。
              例如: 上面的例子    bool 类型的只能选中或不选中,显示为[ ]; tristate类型的菜单项多了
              编译成内核模块的选项,显示为< > , 假如选择编译成内核模块,则会在.config中生成一个
              CONFIG_VFIO_IOMMU=m的配置,假如选择内建,就是直接编译成内核影响,就会
              在.config中生成一个 CONFIG_VFIO_IOMMU=y的配置. hex十六进制类型显示为( )。
         4. depends on说明该配置选项的生效要依赖于后面的这个配置选项才能有效, select则与
             depends on正好相反。如上面的例子,还可以使用if (VFIO_IOMMU)来进行限定。
         5. Kconfig目录层次迭代
              在drivers/vfio/Kconfig中source "driver/vfio/pci/Kconfig” 这样的语句用来嵌套子目录或者
              其他目录的Kconfig文件,这样的好处就是不同的目录各种管理自己的配置选项,而不用
              都写在同一个文件里面。
        
       Makefile:
         2.6内核的Makefile分为5个部分:
            * 最顶层的Makefile(在编译之前可更改上面几行版本名字,这样生成的新内核就是特定的名字)
            *  内核的.config配置文件
            *   在arch/$(ARCH)目录下的体系结构相关的Makefile
            *  在s目录下的Makefile.*文件,是一些Makefile的通用规则
            *  各级目录下的大概约500个kbuild Makefile文件
          顶层的Makefile文件读取.config文件的内容,并总体上负责build内核和模块,各级体系架构的
          Makefile负责架构相关的信息。s目录下的Makefile文件包含了所有用来根据kbuild Makefile
          构建内核所需要的定义和规则。
           makefile文件的编写可以参考:一起来写makefile
 
    三、具体实例

          我们根据一个简单的例子来说明这几个文件的关系:
           要实现一个vfio-ccw的驱动,在/Linux/drivers/vfio/ccw目录下完成vfio-ccw.c文件,然后想要将其编译
            为模块或者模块或者不编译,它要依赖与VFIO, CCW和VFIO_IOMMU这几个配置选项。
           1. 编写Kconfig
              1.1由于ccw是新建的目录,所以首先在ccw目录下面添加Kconfig文件,添加菜单项
                    config VFIO_CCW

                          tristate "VFIO support for CCW devices"

                          depends on VFIO && CCW && VFIO_IOMMU

                           help
                                  *****
                   因为还有上级目录vfio,所以在vfio目录的Kconfig里面添加source "drivers/vfio/ccw/Kconfig"
              1.2 我们使用make menuconfig进入配置选择菜单,根据源码目录,我们找到一级级的菜单项进入。
                 


                    在VFIO support for CCW devices前面选择M, 表示要把该选项编译为模块,按空格键可以选择*或者空,
               1.3 保存退出后,在.config文件中我们找到了:
                    CONFIG_VFIO=m
                    CONFIG_VFIO_CCW=m
             2. 编写Makefile
                  通过上一步,我们虽然可以在配置内核的时候进行选择,但实际上此时执行编译内核
                  还是不能把vfio-ccw.c
编译进去的,还需要在Makefile 中把内核配置选项和真正的源
                 代码联系起来,在ccw下面新建Makefile文件,添加:
                   vfio-ccw-y := vfio_ccw.o

                   obj-$(CONFIG_VFIO_CCW) += vfio-ccw.o
                 这样make时候,根据Makefile里面obj-$(CONFIG_VFIO_CCW) += vfio-ccw.o,
                 意味着将vfio-ccw.o编译为模块。
            
 
 
 
 
 
 
 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐