天天看點

Linux核心編譯中遇到的Kconfig,.confi和Makefile的關系

最近在學習裝置驅動程式,編寫完之後進行編譯之前,要在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

                                                                           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進入配置選擇菜單,根據源碼目錄,我們找到一級級的菜單項進入。

Linux核心編譯中遇到的Kconfig,.confi和Makefile的關系

                    在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編譯為子產品。

繼續閱讀