在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Arm Linux Kernel 構(gòu)建 情景分析

            Arm Linux Kernel 構(gòu)建 情景分析

            作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò) 收藏

            概述

            構(gòu)建一個(gè)內(nèi)核,一般是先配置,后編譯。這里以構(gòu)建 Nexus5 內(nèi)核為例,代號(hào)為hammerhead。

            配置

            通常做法是以廠商預(yù)置的配置為基礎(chǔ),根據(jù)自己需要進(jìn)行配置。命令:
            make ARCH=arm hammerhead_defconfig

            本文引用地址:http://www.biyoush.com/article/201611/317990.htm
            執(zhí)行完畢后,"arch/arm/configs/hammerhead_defconfig" 文件會(huì)被到 ".config" ,作為默認(rèn)配置。
            然后運(yùn)行以下命令根據(jù)自己需要進(jìn)行配置:
            make ARCH=arm menuconfig

            編譯

            通常,需要生成 zImage 和 內(nèi)核模塊。如果不指定目標(biāo),這兩個(gè)都會(huì)默認(rèn)生成。命令:
            1. # CROSS_COMPILE 的值根據(jù)自己情況設(shè)定
              make ARCH=arm CROSS_COMPILE=arm-linux-androideabi-

            這條命令做了什么呢,把 make 輸出到控制臺(tái)的信息貼出來(lái)(省略中間相似的信息):
            make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- CONFIG_DEBUG_SECTION_MISMATCH=yscripts/kconfig/conf --silentoldconfig KconfigWRAP arch/arm/include/generated/asm/auxvec.hWRAP arch/arm/include/generated/asm/bitsperlong.hWRAP arch/arm/include/generated/asm/cputime.h...WRAP arch/arm/include/generated/asm/siginfo.hWRAP arch/arm/include/generated/asm/sizes.hCHK include/linux/version.hUPD include/linux/version.hCHK include/generated/utsrelease.hUPD include/generated/utsrelease.hGenerating include/generated/mach-types.hCC kernel/bounds.sGEN include/generated/bounds.hCC arch/arm/kernel/asm-offsets.sGEN include/generated/asm-offsets.hCALL scripts/checksyscalls.shHOSTCC scripts/dtc/checks.oHOSTCC scripts/dtc/data.o...HOSTCC scripts/conmakehashHOSTCC scripts/recordmcountCC init/main.oCHK include/generated/compile.hUPD include/generated/compile.hCC init/version.oCC init/do_mounts.oCC init/do_mounts_rd.oCC init/do_mounts_initrd.oLD init/mounts.oCC init/initramfs.oCC init/calibrate.oLD init/built-in.o...AR lib/lib.aLD vmlinux.oMODPOST vmlinux.oGEN .versionCHK include/generated/compile.hUPD include/generated/compile.hCC init/version.oLD init/built-in.oLD .tmp_vmlinux1KSYM .tmp_kallsyms1.SAS .tmp_kallsyms1.oLD .tmp_vmlinux2KSYM .tmp_kallsyms2.SAS .tmp_kallsyms2.oLD vmlinuxSYSMAP System.mapSYSMAP .tmp_System.mapOBJCOPY arch/arm/boot/ImageKernel: arch/arm/boot/Image is readyAS arch/arm/boot/compressed/head.oGZIP arch/arm/boot/compressed/piggy.gzipAS arch/arm/boot/compressed/piggy.gzip.oCC arch/arm/boot/compressed/misc.oCC arch/arm/boot/compressed/decompress.oCC arch/arm/boot/compressed/string.oAS arch/arm/boot/compressed/lib1funcs.oAS arch/arm/boot/compressed/ashldi3.oLD arch/arm/boot/compressed/vmlinuxOBJCOPY arch/arm/boot/zImageKernel: arch/arm/boot/zImage is readyDTC arch/arm/boot/msm8974-hammerhead-rev-11.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-11j.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-10.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-c.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-b.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-bn.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-a.dtbDTC arch/arm/boot/msm8974-hammerhead-rev-f.dtbCAT arch/arm/boot/zImage-dtbKernel: arch/arm/boot/zImage-dtb is readymake[1]:沒(méi)有什么可以做的為`arch/arm/boot/dtbs。

            簡(jiǎn)單分析一下,大致做了這么幾件事情:
            1. 根據(jù)配置信息,生成了一些頭文件
            2. 編譯了一些小工具
            3. 根據(jù)配置信息,有選擇性地編譯一些源碼,將輸出的 obj 鏈接成對(duì)應(yīng)的 built-in.o
            4. 生成符號(hào)表文件
            5. 將所有的 built-in.o 和符號(hào)表鏈接成內(nèi)核 vmlinux
            6. 使用 BOJCOPY 從 vmlinux 生成 Image
            7. 生成壓縮過(guò)的內(nèi)核 arch/arm/boot/compressed/vmlinux
            8. 使用 OBJCOPY 從 壓縮過(guò)的內(nèi)核 vmlinux 生成 zImage
            9. 生成 dtb(device tree blob)
            10. 將 zImage 和 dtb 連接成一個(gè)文件:zImage-dtb
            而我們最終需要的文件就是 zImage-dtb(注意:這里沒(méi)有生成內(nèi)核模塊,因?yàn)樗械膬?nèi)核功能都被配置為 built-in ,編譯進(jìn) zImage-dtb 了)。

            要點(diǎn)分析

            內(nèi)核配置和編譯,依靠的是 make 和 kbuild 系統(tǒng)。無(wú)論是 make 還是 kbuild,都只是工具,我們并不一定要完全弄清其內(nèi)部工作原理,只需要熟悉和工作相關(guān)的部分即可。
            這里涉及到的有如下幾點(diǎn):
            • vmlinux 的構(gòu)建過(guò)程
            • arch/arm/boot/compressed/vmlinux 的構(gòu)建過(guò)程
            • 源碼是如何選擇性地參與內(nèi)核的構(gòu)建的
            之所以要分析 vmlinux 和 arch/arm/boot/compressed/vmlinux ,是因?yàn)檫@個(gè)兩個(gè)文件是最原始的兩個(gè)可執(zhí)行文件:Image 由 vmlinux 生成;zImage 由 arch/arm/boot/compressed/vmlinux 生成。分析這連個(gè)文件的生成,還有助于分析 linux 內(nèi)核的啟動(dòng)過(guò)程。

            基礎(chǔ)

            vmlinux 是 makefile 中的一個(gè)目標(biāo)。makefile 中的規(guī)則定義了目標(biāo)和源碼的關(guān)系,命令則定義了如何由源碼生成目標(biāo),變量起輔助作用。規(guī)則、命令和變量是 makefile 的三大要素。理清 makefile 規(guī)則中定義的依賴關(guān)系是分析構(gòu)建過(guò)程的關(guān)鍵。涉及到的幾個(gè)重要文件:
            Makefilearch/arm/Makefilearch/arm/boot/Makefilearch/arm/mach-msm/Makefile.bootarch/arm/compressed/Makefile


            vmlinux 是一個(gè)可執(zhí)行程序,其鏈接過(guò)程必然涉及的鏈接腳本,鏈接腳本是做什么的?看看 ld 手冊(cè)中的描述:
            通過(guò) lds 文件,我們至少可以知道一個(gè)可執(zhí)行程序的入口在哪里。
            這里又要涉及到幾個(gè)重要文件:
            # 對(duì)應(yīng) vmlinuxarch/arm/kernel/vmlinux.lds# 對(duì)應(yīng) /arch/arm/boot/compressed/vmlinuxarch/arm/boot/compressed/vmlinux.lds

            vmlinux 是一個(gè)可執(zhí)行程序,由源碼編譯、鏈接而來(lái)。那么是哪些源碼參與了構(gòu)建過(guò)程,又是如何控制這些源碼參與的?后面會(huì)分析。
            為了分析 makefile,這里借用了 UML 的概念。
            用 包 表示 makefile 文件;用 類 表示 目標(biāo)和文件;用類間依賴表示目標(biāo)的依賴;用組合表示變量的定義。
            下面是一個(gè)總圖,表明了各個(gè)目標(biāo)之間的依賴關(guān)系:
            (紅色邊框是可執(zhí)行程序,藍(lán)色邊框是對(duì)應(yīng)的鏈接腳本)
            vmlinux 的構(gòu)建過(guò)程

            和 lds 文件的關(guān)系

            ?依賴鏈:
            _all->all->vmlinux->$(vmlinux-lds)=arch/arm/kernel/vmlinux.lds

            從 _all 到 all:

            PHONY += allifeq ($(KBUILD_EXTMOD),)_all: allelse_all: modulesendif

            KBUILD_EXTMOD 只有在內(nèi)核樹(shù)外編譯內(nèi)核模塊的時(shí)候才會(huì)定義 M 變量,從而給其賦值,否則為空,這里為空。

            從 all 到 vmlinux:
            all: vmlinux

            從 vmlinux 到 $(vmlinux-lds):
            vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

            $(vmlinux-lds) 定義:
            vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds

            和源碼的關(guān)系

            ?依賴鏈:
            _all->all->vmlinux->$(vmlinux-init)+$(vmlinux-main)

            看看這個(gè):
            # vmlinux# ^# # +-< $(vmlinux-init)#  +--< init/version.o + more# # +--< $(vmlinux-main)#  +--< driver/built-in.o mm/built-in.o + more# # +-< kallsyms.o (see description in CONFIG_KALLSYMS section)

            關(guān)鍵部分上面已經(jīng)列出,這里再次列出來(lái):
            vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

            那么 $(vmlinux-init) 連個(gè)變量是什么呢?通過(guò)分析,第一次展開(kāi)后為:“$(head-y) $(init-y)”。沒(méi)有找到 $(head-y),而 $(init-y) 最終展開(kāi)為:init/built-in.o。
            到這里有點(diǎn)眉目了(回頭看看 make 過(guò)程輸出的信息,里面有大量的 built-in.o)。可以說(shuō)是眾多的 built-in.o構(gòu)成了vmlinux。所以 vmlinux 和源碼的關(guān)系轉(zhuǎn)變成了 built-in.o 和源碼的關(guān)系。
            還是看 make 的輸出信息:
            CC init/version.oCC init/do_mounts.oCC init/do_mounts_rd.oCC init/do_mounts_initrd.oLD init/mounts.oCC init/initramfs.oCC init/calibrate.oLD init/built-in.o

            可以推測(cè):init/built-in.o 是由 init 目錄下的 源碼編譯、鏈接而成。在 init 目錄下發(fā)現(xiàn) Makefile:
            obj-y := main.o version.o mounts.oifneq ($(CONFIG_BLK_DEV_INITRD),y)obj-y += noinitramfs.oelseobj-$(CONFIG_BLK_DEV_INITRD)+= initramfs.oendifobj-$(CONFIG_GENERIC_CALIBRATE_DELAY)+= calibrate.omounts-y := do_mounts.omounts-$(CONFIG_BLK_DEV_RAM)+= do_mounts_rd.omounts-$(CONFIG_BLK_DEV_INITRD)+= do_mounts_initrd.omounts-$(CONFIG_BLK_DEV_MD)+= do_mounts_md.o

            有內(nèi)核開(kāi)發(fā)經(jīng)驗(yàn)的開(kāi)發(fā)者應(yīng)該知道,賦值到 obj-y 的目標(biāo)會(huì)被編譯進(jìn) vmlinux,至于是如何控制的,推測(cè) kbuild 系統(tǒng)是有參與的,這屬于 make 和 kubild 的內(nèi)部原理,這里不分析了,知道有這么回事,會(huì)用就行了。$(CONFIG_BLK_DEV_INITRD) 等變量在 .config(沒(méi)錯(cuò),就是保存內(nèi)核配置的文件) 文件中定義:
            CONFIG_RELAY=yCONFIG_BLK_DEV_INITRD=yCONFIG_INITRAMFS_SOURCE=""

            這里 vmlinux 和源碼的關(guān)系就搞清了,是由 built-in.o 來(lái)當(dāng)中間人的:
            vmlinux<->built-in.o<->*.c

            和符號(hào)表的關(guān)系

            略。

            arch/arm/boot/comressed/vmlinux 的構(gòu)建過(guò)程

            有了分析 vmlinux 的基礎(chǔ),分析壓縮過(guò)的 vmlinux 就容易了???規(guī)則:
            $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE@$(check_for_multiple_zreladdr)$(call if_changed,ld)@$(check_for_bad_syms)

            參與壓縮過(guò)的 vmlinux 的構(gòu)建過(guò)程的主要有三類文件:
            • 鏈接腳本:arch/arm/boot/compressed/vmlinux.lds
            • 解壓代碼:arch/arm/boot/compressed/ 下的源碼
            • 壓縮的數(shù)據(jù):壓縮的 Image(由未經(jīng)壓縮的 vmlinux 生成)
            因?yàn)榻鈮嚎s功能和內(nèi)核開(kāi)發(fā)關(guān)系不大,就不具體分析了。


            關(guān)鍵詞: ArmLinuxKernel情景分

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉