linux核心配置系統分析

來源:互聯網
上載者:User

隨著 Linux 作業系統的廣泛應用,特別是 Linux 在嵌入式領域的發展,越來越多的人開始投身到 Linux 核心級的開發中。面對日益龐大的 Linux 核心原始碼,開發人員在完成自己的核心代碼後,都將面臨著同樣的問題,即如何將原始碼融入到 Linux 核心中,增加相應的 Linux 配置選項,並最終被編譯進 Linux 核心。這就需要瞭解 Linux 的核心配置系統。
  
  眾所周知,Linux 核心是由分布在全球的 Linux 愛好者共同開發的,Linux 核心每天都面臨著許多新的變化。但是,Linux 核心的組織並沒有出現混亂的現象,反而顯得非常的簡潔,而且具有很好的擴充性,開發人員可以很方便的向 Linux 核心中增加新的內容。原因之一就是 Linux 採用了模組化的核心配置系統,從而保證了核心的擴充性。
  
  本文首先分析了 Linux 核心中的配置系統結構,然後,解釋了 Makefile 和設定檔的格式以及配置語句的含義,最後,通過一個簡單的例子--TEST Driver,具體說明如何將自行開發的代碼加入到 Linux 核心中。在下面的文章中,不可能解釋所有的功能和命令,只對那些常用的進行解釋,至於那些沒有討論到的,請讀者參考後面的參考文獻。
  
  1. 配置系統的基本結構
  Linux核心的配置系統由三個部分組成,分別是:
  
  Makefile:分布在 Linux 核心原始碼中的 Makefile,定義 Linux 核心的編譯規則;
  設定檔(config.in):給使用者提供配置選擇的功能;
  組態工具:包括配置命令直譯器(對配置指令碼中使用的配置命令進行解釋)和配置使用者介面(提供基於字元介面、基於 Ncurses 圖形介面以及基於 Xwindows 圖形介面的使用者配置介面,各自對應於 Make config、Make menuconfig 和 make xconfig)。
  這些組態工具都是使用指令碼語言,如 Tcl/TK、Perl 編寫的(也包含一些用 C 編寫的代碼)。本文並不是對配置系統本身進行分析,而是介紹如何使用配置系統。所以,除非是配置系統的維護者,一般的核心開發人員無須瞭解它們的原理,只需要知道如何編寫 Makefile 和設定檔就可以。所以,在本文中,我們只對 Makefile 和設定檔進行討論。另外,凡是涉及到與具體 CPU 體繫結構相關的內容,我們都以 ARM 為例,這樣不僅可以將討論的問題明確化,而且對內容本身不產生影響。
  
  2. Makefile
  2.1 Makefile 概述
  
  Makefile 的作用是根據配置的情況,構造出需要編譯的源檔案清單,然後分別編譯,並把目標代碼連結到一起,最終形成 Linux 核心二進位檔案。
  
  由於 Linux 核心原始碼是按照樹形結構組織的,所以 Makefile 也被分布在分類樹中。Linux 核心中的 Makefile 以及與 Makefile 直接相關的檔案有:
  
  Makefile:頂層 Makefile,是整個核心配置、編譯的總體控制檔案。
  .config:核心設定檔,包含由使用者選擇的配置選項,用來存放核心配置後的結果(如 make config)。
  arch/*/Makefile:位於各種 CPU 體系目錄下的 Makefile,如 arch/arm/Makefile,是針對特定平台的 Makefile。
  各個子目錄下的 Makefile:比如 drivers/Makefile,負責所在子目錄下原始碼的管理。
  Rules.make:規則檔案,被所有的 Makefile 使用。
  使用者通過 make config 配置後,產生了 .config。頂層 Makefile 讀入 .config 中的配置選擇。頂層 Makefile 有兩個主要的任務:產生 vmlinux 檔案和核心模組(module)。為了達到此目的,頂層 Makefile 遞迴的進入到核心的各個子目錄中,分別調用位於這些子目錄中的 Makefile。至於到底進入哪些子目錄,取決於核心的配置。在頂層 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 體繫結構下的 Makefile,這個 Makefile 中包含了平台相關的資訊。
  
  位於各個子目錄下的 Makefile 同樣也根據 .config 給出的配置資訊,構造出當前配置下需要的源檔案清單,並在檔案的最後有 include $(TOPDIR)/Rules.make。
  
  Rules.make 檔案起著非常重要的作用,它定義了所有 Makefile 共用的編譯規則。比如,如果需要將本目錄下所有的 c 程式編譯成彙編代碼,需要在 Makefile 中有以下的編譯規則:
  
    %.s: %.c
    $(CC) $(CFLAGS) -S $< -o $@
    
  有很多子目錄下都有同樣的要求,就需要在各自的 Makefile 中包含此編譯規則,這會比較麻煩。而 Linux 核心中則把此類的編譯規則統一放置到 Rules.make 中,並在各自的 Makefile 中包含進了 Rules.make(include Rules.make),這樣就避免了在多個 Makefile 中重複同樣的規則。對於上面的例子,在 Rules.make 中對應的規則為:
  
    %.s: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@
    
  2.2 Makefile 中的變數
  
  頂層 Makefile 定義並向環境中輸出了許多變數,為各個子目錄下的 Makefile 傳遞一些資訊。有些變數,比如 SUBDIRS,不僅在頂層 Makefile 中定義並且賦初值,而且在 arch/*/Makefile 還作了擴充。
  
  常用的變數有以下幾類:
  
  1) 版本資訊
  版本資訊有:VERSION,PATCHLEVEL, SUBLEVEL, EXTRAVERSION,KERNELRELEASE。版本資訊定義了當前核心的版本,比如 VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它們共同構成核心的發行版本KERNELRELEASE:2.4.18-rmk7
  
  2) CPU 體繫結構:ARCH
  在頂層 Makefile 的開頭,用 ARCH 定義目標 CPU 的體繫結構,比如 ARCH:=arm 等。許多子目錄的 Makefile 中,要根據 ARCH 的定義選擇編譯源檔案的列表。
  
  3) 路徑資訊:TOPDIR, SUBDIRS
  TOPDIR 定義了 Linux 核心原始碼所在的根目錄。例如,各個子目錄下的 Makefile 通過 $(TOPDIR)/Rules.make 就可以找到 Rules.make 的位置。
  SUBDIRS 定義了一個目錄列表,在編譯核心或模組時,頂層 Makefile 就是根據 SUBDIRS 來決定進入哪些子目錄。SUBDIRS 的值取決於核心的配置,在頂層 Makefile 中 SUBDIRS 賦值為 kernel drivers mm fs net ipc lib;根據核心的配置情況,在 arch/*/Makefile 中擴充了 SUBDIRS 的值,參見4)中的例子。
  
  4) 核心組成資訊:HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
  Linux 核心檔案 vmlinux 是由以下規則產生的:
  
  
  vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
   $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o --start-group $(CORE_FILES) $(DRIVERS) $(NETWORKS) $(LIBS) --end-group -o vmlinux
  
  可以看出,vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 組成的。這些變數(如 HEAD)都是用來定義串連產生 vmlinux 的目標檔案和庫檔案清單。其中,HEAD在arch/*/Makefile 中定義,用來確定被最先連結進 vmlinux 的檔案清單。比如,對於 ARM 系列的 CPU,HEAD 定義為:
  HEAD      := arch/arm/kernel/head-$(PROCESSOR).o           arch/arm/kernel/init_task.o
  
  表明 head-$(PROCESSOR).o 和 init_task.o 需要最先被連結到 vmlinux 中。PROCESSOR 為 armv 或 armo,取決於目標 CPU。 CORE_FILES,NETWORK,DRIVERS 和 LIBS 在頂層 Makefile 中定義,並且由 arch/*/Makefile 根據需要進行擴充。 CORE_FILES 對應著核心的核心檔案,有 kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,這些是組成核心最為重要的檔案。同時,arch/arm/Makefile 對 CORE_FILES 進行了擴充:
  
  # arch/arm/Makefile
  
  # If we have a machine-specific directory, then include it in the build.
  MACHDIR     := arch/arm/mach-$(MACHINE)
  ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
  SUBDIRS     += $(MACHDIR)
  CORE_FILES   := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
  endif
  
  HEAD      := arch/arm/kernel/head-$(PROCESSOR).o           arch/arm/kernel/init_task.o
  SUBDIRS     += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
  CORE_FILES   := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
  LIBS      := arch/arm/lib/lib.a $(LIBS)
  
  
  5) 編譯資訊:CPP, CC, AS, LD, AR,CFLAGS,LINKFLAGS
  在 Rules.make 中定義的是編譯的通用規則,具體到特定的場合,需要明確給出編譯環境,編譯環境就是在以上的變數中定義的。針對交叉編譯的要求,定義了 CROSS_COMPILE。比如:
  
  
  CROSS_COMPILE  = arm-linux-
  CC       = $(CROSS_COMPILE)gcc
  LD       = $(CROSS_COMPILE)ld
  ......
  
  CROSS_COMPILE 定義了交叉編譯器首碼 arm-linux-,表明所有的交叉編譯工具都是以 arm-linux- 開頭的,所以在各個交叉編譯器工具之前,都加入了 $(CROSS_COMPILE),以組成一個完整的交叉編譯工具檔案名稱,比如 arm-linux-gcc。
  CFLAGS 定義了傳遞給 C 編譯器的參數。
  LINKFLAGS 是連結產生 vmlinux 時,由連結器使用的參數。LINKFLAGS 在 arm/*/Makefile 中定義,比如:
  
  # arch/arm/Makefile
  
  LINKFLAGS    :=-p -X -T arch/arm/vmlinux.lds
  
  
  6) 組態變數CONFIG_*
  .config 檔案中有許多的組態變數等式,用來說明使用者配置 

 

 

 

 

原文來自: http://blog.chinaunix.net/u3/111961/showart_2186113.html   尊重原創!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.