久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


linux內核中Makefile的使用

分(fen)享到:
           

    linux內核中Makefile 的作(zuo)用是(shi)根據(ju)配置(zhi)的情況(kuang),構造(zao)出需(xu)要編(bian)譯(yi)(yi)的源(yuan)文件列表,然后分別(bie)編(bian)譯(yi)(yi),并(bing)把目標代碼鏈接到一起,終形成 Linux 內核二進制(zhi)文件。

    由于 Linux 內核源代碼(ma)是按照(zhao)樹形結(jie)構組(zu)織的(de)(de),所以 Makefile 也被(bei)分(fen)布在目錄樹中。Linux 內核中的(de)(de) Makefile 以及(ji)與(yu) Makefile 直接相(xiang)關(guan)的(de)(de)文件有(you):

    1. Makefile:頂層 Makefile,是整個內核配置、編譯的總體控制文件。
    2. config:內核配置文件,包含由用戶選擇的配置選項,用來存放內核配置后的結果(如 make config)。
    3. arch/*/Makefile:位于各種 CPU 體系目錄下的 Makefile,如 arch/arm/Makefile,是針對特定平臺的 Makefile。
    4. 各個子目錄下的 Makefile:比如 drivers/Makefile,負責所在子目錄下源代碼的管理。
    5. Rules.make:規則(ze)文件(jian),被所有(you)的 Makefile 使(shi)用(yong)。

    用戶通過 make config 配置(zhi)后(hou),產(chan)(chan)生了(le)(le)(le) .config。頂層 Makefile 讀入 .config 中(zhong)的(de)配置(zhi)選擇。頂層 Makefile 有兩個(ge)主要的(de)任務(wu):產(chan)(chan)生 vmlinux 文件(jian)和內(nei)核(he)模塊(module)。為了(le)(le)(le)達到(dao)(dao)(dao)此(ci)目(mu)的(de),頂層 Makefile 遞歸的(de)進入到(dao)(dao)(dao)內(nei)核(he)的(de)各個(ge)子(zi)(zi)目(mu)錄中(zhong),分別調(diao)用位于(yu)這(zhe)些子(zi)(zi)目(mu)錄中(zhong)的(de) Makefile。至于(yu)到(dao)(dao)(dao)底進入哪些子(zi)(zi)目(mu)錄,取(qu)決于(yu)內(nei)核(he)的(de)配置(zhi)。在(zai)頂層 Makefile 中(zhong),有一句(ju):include arch/$(ARCH)/Makefile,包(bao)含了(le)(le)(le)特定 CPU 體系結構下的(de) Makefile,這(zhe)個(ge) Makefile 中(zhong)包(bao)含了(le)(le)(le)平臺(tai)相關的(de)信息。

    位于各個子目錄(lu)下的(de)(de) Makefile 同樣(yang)也根據(ju) .config 給出的(de)(de)配置信息,構造出當前配置下需要的(de)(de)源文(wen)(wen)件列表,并在文(wen)(wen)件的(de)(de)后有 include $(TOPDIR)/Rules.make。

    Rules.make 文件起著(zhu)非常重(zhong)要(yao)的(de)作用,它(ta)定義了所(suo)有 Makefile 共用的(de)編(bian)譯規(gui)(gui)則(ze)。比如,如果(guo)需(xu)(xu)要(yao)將本目錄(lu)下所(suo)有的(de) c 程序編(bian)譯成匯編(bian)代碼,需(xu)(xu)要(yao)在 Makefile 中(zhong)有以下的(de)編(bian)譯規(gui)(gui)則(ze):

    %.s: %.c
    $(CC) $(CFLAGS) -S $< -o $@

    有(you)很多子(zi)(zi)目(mu)錄下都有(you)同樣(yang)的(de)要求,就需要在各(ge)自的(de) Makefile 中(zhong)(zhong)包含此(ci)編譯規則(ze)(ze),這會比(bi)較麻(ma)煩(fan)。而 Linux 內核中(zhong)(zhong)則(ze)(ze)把(ba)此(ci)類的(de)編譯規則(ze)(ze)統一放(fang)置到 Rules.make 中(zhong)(zhong),并在各(ge)自的(de) Makefile 中(zhong)(zhong)包含進了 Rules.make(include Rules.make),這樣(yang)就避免了在多個 Makefile 中(zhong)(zhong)重復同樣(yang)的(de)規則(ze)(ze)。對于上面(mian)的(de)例子(zi)(zi),在 Rules.make 中(zhong)(zhong)對應的(de)規則(ze)(ze)為:

    %.s: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@

    Makefile 中的變量

    頂層 Makefile 定義并向環境中(zhong)輸出了許多變量,為各(ge)個子目錄下(xia)的 Makefile 傳遞一(yi)些(xie)信息。有(you)些(xie)變量,比如 SUBDIRS,不僅在頂層 Makefile 中(zhong)定義并且(qie)賦(fu)初(chu)值,而且(qie)在 arch/*/Makefile 還作了擴充(chong)。

    常用(yong)的變量有以下幾類:

    1) 版本信息
   &nbsp; 版本(ben)信(xin)息有:VERSION,PATCHLEVEL, SUBLEVEL, EXTRAVERSION,KERNELRELEASE。版本(ben)信(xin)息定義(yi)了當(dang)前內核的(de)版本(ben),比如 VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它們共同構成內核的(de)發行版本(ben)KERNELRELEASE:2.4.18-rmk7

    2) CPU 體系結構:ARCH
    在頂層 Makefile 的(de)(de)開頭,用 ARCH 定義目標 CPU 的(de)(de)體系結構(gou),比如 ARCH:=arm 等。許多子(zi)目錄的(de)(de) Makefile 中(zhong),要根(gen)據 ARCH 的(de)(de)定義選擇編譯源文件的(de)(de)列表。

    3) 路徑信息:TOPDIR, SUBDIRS
    TOPDIR 定義了 Linux 內(nei)核源(yuan)代碼所在的(de)根目錄。例(li)如,各個子目錄下的(de) Makefile 通過 $(TOPDIR)/Rules.make 就(jiu)可(ke)以找到 Rules.make 的(de)位置。

 &nbsp;  SUBDIRS 定義了(le)(le)一個目錄(lu)列表,在編(bian)譯內核(he)或模(mo)塊時,頂層 Makefile 就是根(gen)據(ju) SUBDIRS 來決(jue)定進入哪些(xie)子(zi)目錄(lu)。SUBDIRS 的值(zhi)取決(jue)于內核(he)的配置(zhi),在頂層 Makefile 中(zhong) SUBDIRS 賦值(zhi)為(wei) kernel drivers mm fs net ipc lib;根(gen)據(ju)內核(he)的配置(zhi)情況(kuang),在 arch/*/Makefile 中(zhong)擴充了(le)(le) SUBDIRS 的值(zhi),參見4)中(zhong)的例子(zi)。

    4) 內核組成信息:HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
&nbsp;   Linux 內(nei)核文件 vmlinux 是(shi)由以下規則產生的:

    vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
    $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
    --start-group \
    x$(CORE_FILES) \
    $(DRIVERS) \
    $(NETWORKS) \
    $(LIBS) \
    --end-group \
    -o vmlinux

    可以(yi)看出(chu),vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 組(zu)成的(de)。這些變量(liang)(如 HEAD)都是用(yong)(yong)來定義(yi)連接生(sheng)成 vmlinux 的(de)目(mu)標(biao)文(wen)件和庫文(wen)件列(lie)表(biao)(biao)。其(qi)中,HEAD在arch/*/Makefile 中定義(yi),用(yong)(yong)來確定被先鏈(lian)接進 vmlinux 的(de)文(wen)件列(lie)表(biao)(biao)。比如,對于 ARM 系列(lie)的(de) CPU,HEAD 定義(yi)為:

    HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
    arch/arm/kernel/init_task.o

 &nbsp;  表(biao)明 head-$(PROCESSOR).o 和(he) init_task.o 需(xu)要先(xian)被(bei)鏈接到 vmlinux 中。PROCESSOR 為 armv 或(huo) armo,取決于目標 CPU。 CORE_FILES,NETWORK,DRIVERS 和(he) LIBS 在頂層 Makefile 中定義,并且由 arch/*/Makefile 根(gen)據(ju)需(xu)要進行擴(kuo)充(chong)。 CORE_FILES 對應著內核(he)的核(he)心文(wen)(wen)件,有 kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,這些是組成(cheng)內核(he)為重要的文(wen)(wen)件。同時,arch/arm/Makefile 對 CORE_FILES 進行了擴(kuo)充(chong):

    # 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 中定義(yi)的(de)(de)是編(bian)(bian)譯(yi)的(de)(de)通用規(gui)則,具體到特(te)定的(de)(de)場合,需要(yao)明(ming)確給出編(bian)(bian)譯(yi)環境(jing),編(bian)(bian)譯(yi)環境(jing)就是在以上(shang)的(de)(de)變量中定義(yi)的(de)(de)。針對(dui)交叉(cha)編(bian)(bian)譯(yi)的(de)(de)要(yao)求,定義(yi)了 CROSS_COMPILE。比如:

    CROSS_COMPILE = arm-linux-
    CC = $(CROSS_COMPILE)gcc
    LD = $(CROSS_COMPILE)ld
    ......

    CROSS_COMPILE 定義了交(jiao)叉(cha)編(bian)譯(yi)器(qi)前綴(zhui) arm-linux-,表明所有的(de)交(jiao)叉(cha)編(bian)譯(yi)工具都是以 arm-linux- 開頭的(de),所以在(zai)各個交(jiao)叉(cha)編(bian)譯(yi)器(qi)工具之(zhi)前,都加入了 $(CROSS_COMPILE),以組成(cheng)一個完整的(de)交(jiao)叉(cha)編(bian)譯(yi)工具文件名,比如 arm-linux-gcc。

 &nbsp;  CFLAGS 定義(yi)了傳遞(di)給 C 編譯器的參數。

&nbsp;   LINKFLAGS 是鏈(lian)接生成 vmlinux 時(shi),由鏈(lian)接器使(shi)用的參數。LINKFLAGS 在 arm/*/Makefile 中定義,比如:

    # arch/arm/Makefile
 &nbsp;  LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds

    6) 配置變量CONFIG_*
    .config 文件中有許多的配置變量等式,用來說明用戶配置的結果。例如 CONFIG_MODULES=y 表明用戶選擇了 Linux 內核的模塊功能。
    .config 被頂層 Makefile 包(bao)含后,就形成(cheng)許多的配(pei)置變(bian)量(liang)(liang),每個配(pei)置變(bian)量(liang)(liang)具有確定的值(zhi):y 表示本(ben)編譯(yi)(yi)選項對應(ying)的內(nei)核(he)(he)代碼被靜態(tai)編譯(yi)(yi)進 Linux 內(nei)核(he)(he);m 表示本(ben)編譯(yi)(yi)選項對應(ying)的內(nei)核(he)(he)代碼被編譯(yi)(yi)成(cheng)模塊;n 表示不選擇(ze)此編譯(yi)(yi)選項;如果根本(ben)就沒有選擇(ze),那么配(pei)置變(bian)量(liang)(liang)的值(zhi)為空。

    Rules.make 變量

    前面(mian)講(jiang)過,Rules.make 是(shi)編譯(yi)規則文(wen)件,所有的 Makefile 中(zhong)都會包括(kuo) Rules.make。Rules.make 文(wen)件定義(yi)了(le)許多變量,為重(zhong)要(yao)是(shi)那些編譯(yi)、鏈(lian)接列表(biao)變量。

    O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:本目(mu)(mu)錄下(xia)需(xu)要編譯(yi)進 Linux 內核(he) vmlinux 的目(mu)(mu)標文件(jian)列表(biao),其中 OX_OBJS 和 LX_OBJS 中的 "X" 表(biao)明(ming)目(mu)(mu)標文件(jian)使用了(le) EXPORT_SYMBOL 輸出符號。

    M_OBJS,MX_OBJS:本目(mu)錄下需要(yao)被編(bian)譯(yi)成(cheng)可(ke)裝載(zai)模塊的目(mu)標文(wen)件(jian)列(lie)表(biao)。同樣,MX_OBJS 中的 "X" 表(biao)明目(mu)標文(wen)件(jian)使用(yong)了 EXPORT_SYMBOL 輸出符號。

&nbsp;   O_TARGET,L_TARGET:每個(ge)子目(mu)錄下都有一個(ge) O_TARGET 或 L_TARGET,Rules.make 首先從源代(dai)碼編譯生(sheng)成 O_OBJS 和 OX_OBJS 中所有的目(mu)標文(wen)件(jian),然后使(shi)用 $(LD) -r 把它們鏈接成一個(ge) O_TARGET 或 L_TARGET。O_TARGET 以 .o 結尾,而 L_TARGET 以 .a 結尾。

    子目錄 Makefile

    子目錄(lu) Makefile 用來控制本級目錄(lu)以下源代碼的(de)編譯規則。我們通過(guo)一個例子來講解(jie)子目錄(lu) Makefile 的(de)組成:

    #
    # Makefile for the linux kernel.
    #
    # All of the (potential) objects that export symbols.
    # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
    export-objs := tc.o
    # Object file lists.
    obj-y        :=
    obj-m        :=
    obj-n        :=
    obj-         :=
    obj-$(CONFIG_TC) += tc.o
    obj-$(CONFIG_ZS) += zs.o
    obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o
    # Files that are both resident and modular: remove from modular.
    obj-m        := $(filter-out $(obj-y), $(obj-m))
    # Translate to Rules.make lists.
    L_TARGET := tc.a
    L_OBJS       := $(sort $(filter-out $(export-objs), $(obj-y)))
    LX_OBJS      := $(sort $(filter     $(export-objs), $(obj-y)))
    M_OBJS       := $(sort $(filter-out $(export-objs), $(obj-m)))
    MX_OBJS      := $(sort $(filter     $(export-objs), $(obj-m)))
    ;include $(TOPDIR)/Rules.make

    a) 注釋

   ;&nbsp;對 Makefile 的說明(ming)和解釋,由#開(kai)始。

    b) 編(bian)譯目標(biao)定(ding)義(yi)

    類似于 obj-$(CONFIG_TC) += tc.o 的(de)語句(ju)是用來定義編譯(yi)的(de)目標(biao)(biao),是子目錄 Makefile 中(zhong)重要(yao)的(de)部分。編譯(yi)目標(biao)(biao)定義那些在本(ben)子目錄下,需要(yao)編譯(yi)到(dao) Linux 內核中(zhong)的(de)目標(biao)(biao)文件列(lie)表。為了只在用戶(hu)選(xuan)擇了此功能后才編譯(yi),所有的(de)目標(biao)(biao)定義都融合了對(dui)配置(zhi)變(bian)量的(de)判(pan)斷(duan)。

    前面說過(guo),每個配置變量取值范圍是(shi):y,n,m 和空,obj-$(CONFIG_TC) 分(fen)別(bie)對應著(zhu) obj-y,obj-n,obj-m,obj-。如果(guo) CONFIG_TC 配置為 y,那(nei)么 tc.o 就(jiu)進入了 obj-y 列(lie)表(biao)。obj-y 為包含到(dao) Linux 內核(he) vmlinux 中的(de)目(mu)標文(wen)件列(lie)表(biao);obj-m 為編譯(yi)成模塊(kuai)的(de)目(mu)標文(wen)件列(lie)表(biao);obj-n 和 obj- 中的(de)文(wen)件列(lie)表(biao)被忽略。配置系統就(jiu)根據這些列(lie)表(biao)的(de)屬性進行編譯(yi)和鏈(lian)接。

    export-objs 中的目標文(wen)件都(dou)使用了(le)(le) EXPORT_SYMBOL() 定義(yi)了(le)(le)公(gong)共的符號,以便可裝(zhuang)載(zai)模塊(kuai)使用。在 tc.c 文(wen)件的后部(bu)分,有 "EXPORT_SYMBOL(search_tc_card);",表明 tc.o 有符號輸出。

    這里(li)需(xu)要指出(chu)的是(shi),對于(yu)編譯目標的定(ding)義(yi),存在著兩種格式,分(fen)別是(shi)老式定(ding)義(yi)和(he)新式定(ding)義(yi)。老式定(ding)義(yi)就是(shi)前面 Rules.make 使(shi)用的那些變量,新式定(ding)義(yi)就是(shi) obj-y,obj-m,obj-n 和(he) obj-。Linux 內核(he)推薦使(shi)用新式定(ding)義(yi),不過(guo)由于(yu) Rules.make 不理解(jie)新式定(ding)義(yi),需(xu)要在 Makefile 中的適配段將其(qi)轉換成老式定(ding)義(yi)。

    c) 適(shi)配(pei)段

    適配(pei)段的(de)作用是將新式(shi)定義(yi)轉(zhuan)(zhuan)換成老式(shi)定義(yi)。在上面的(de)例子中,適配(pei)段就是將 obj-y 和 obj-m 轉(zhuan)(zhuan)換成 Rules.make 能夠理解的(de) L_TARGET,L_OBJS,LX_OBJS,M_OBJS,MX_OBJS。

    L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y))) 定義(yi)了 L_OBJS 的(de)生成(cheng)方式:在 obj-y 的(de)列表(biao)中過濾掉 export-objs(tc.o),然后排序并去(qu)除(chu)重復的(de)文件(jian)名。這里使(shi)用到了 GNU Make 的(de)一些特殊功能,具體的(de)含義(yi)可參考 Make 的(de)文檔(info make)。

&nbsp;   d) include $(TOPDIR)/Rules.make

   熱點鏈接:

   1、嵌入式linux內核的五個子系統
   2、如何分析Linux內核源碼
   3、嵌入式linux內核數據結構之循環鏈表
   4、嵌入式linux內核數據結構之雙向鏈表
   5、嵌入式linux內核數據結構之單向鏈表

更多新聞>>