91精品人妻系列动画无码 - 国产精品夜间视频香蕉 - 91丝袜人妻一区二区三区 - 久久伊伊香蕉精品网站

信盈達(dá)—您身邊的嵌入式&人工智能專家
全國免費(fèi)咨詢熱線:400-8788-909

嵌入式培訓(xùn):如何快速高效掌握Linux內(nèi)核編譯過程

時(shí)間:2018-08-26 00:00:00 來源:信盈達(dá) 作者:信盈達(dá)

Linux內(nèi)核編譯

 

一、linux內(nèi)核的配置與編譯:

 

1.配置內(nèi)核

 

1)導(dǎo)入默認(rèn)配置:

 

make xxxx_defconfig

 

1:xxxx表示內(nèi)核支持的芯片的名稱 比如make exynos_defconfig

 

2:內(nèi)核源碼中對(duì)每個(gè)支持的芯片都有默認(rèn)的配置,默認(rèn)配置很少只能保證系統(tǒng)完成最基本的功能

 

3:可以通過直接修改.config文件來進(jìn)行內(nèi)核的配置(麻煩),所有內(nèi)核配置的本質(zhì)都是修改.config文件

 

4:配置文件中xxxx=y表示添加了該功能,注釋表示不添加該功能(減小內(nèi)核體積)

 

2)修改配置(內(nèi)核提供了幾種簡單的配置方法,其本質(zhì)都是修改.config文件中的配置)

 

make gconfig 依賴于GTK庫

 

make xconfig 依賴于QT庫

 

make config 麻煩

 

-> make menuconfig

 

選中的狀態(tài)切換:空格

 

搜索一個(gè)選項(xiàng):/

 

[ ] 有兩種狀態(tài)。

 

輸入Y,顯示為“*”,表示內(nèi)核中該功能被選中,相關(guān)功能代碼將會(huì)被編譯進(jìn)內(nèi)核。

 

輸入N,顯示為空,表示內(nèi)核中該功能沒有被選中。

 

< > 有三種狀態(tài)

 

輸入Y,顯示為“*”,表示內(nèi)核中該功能被選中

 

輸入N,顯示為空,表示內(nèi)核中該功能沒有被選中

 

輸入M,則顯示為“M”,表示內(nèi)核中該功能被選為模塊(編譯后與內(nèi)核鏡像不在同一文件)

 

2.編譯內(nèi)核

 

make uImage 編譯內(nèi)核鏡像(編譯選中為“*”的選項(xiàng)到內(nèi)核)

 

make modules 編譯內(nèi)核模塊(編譯選中為“M”的選項(xiàng))

 

make dtbs 編譯設(shè)備樹文件(使驅(qū)動(dòng)與設(shè)備建立關(guān)系的文件)

 

make clean 刪除文件

 

二、在內(nèi)核中添加子菜單:

 

每一級(jí)目錄中都包含一個(gè)Kconfig文件,用于生成選配菜單的。按照Kconfig的語法修改對(duì)應(yīng)的Kconfig文件就可以在菜單中添加自己的選項(xiàng)。在一個(gè)Kconfig文件中menu是本級(jí)菜單,如menu "Character devices",如果我們想在該菜單下自己添加子菜單按照語法添加在menu和endmenu之間即可

 

語法:

 

config FS4412_LED # 固定語法,config XXX,XXX用來與MakeFile關(guān)聯(lián),即配置后MakeFile會(huì)按照該配置進(jìn)行編譯

 

tristate "FS4412LED Device Support"

 

# tristate “菜單顯示名稱”;tristate表示該選項(xiàng)有三個(gè)狀態(tài)<>(即可以選擇成N/Y/M),bool表示有兩個(gè)選項(xiàng)[](N/Y)

 

default n

 

# default n 默認(rèn)是'N',即不添加該功能 default y 默認(rèn)添加該功能default m 默認(rèn)編譯成模塊(重新配置后生效)

 

depends on ARCH_EXYNOS4

 

# depends on 依賴的菜單 當(dāng)有依賴關(guān)系的選項(xiàng)沒有被選擇時(shí)該選項(xiàng)也不顯示

 

help

 

support leddevice on FS4412 develop board # 幫助文檔 可有可無

 

詳情參考:Documentation/kbuild

 

將自己的模塊添加到菜單的步驟:

 

1.修改Kconfig添加子菜單

 

2.添加對(duì)應(yīng)的.C文件(驅(qū)動(dòng)文件)

 

3.修改對(duì)應(yīng)的Makefile使菜單與編譯關(guān)聯(lián)(將驅(qū)動(dòng)文件編譯)

 

三、linux內(nèi)核(uImage)的編譯過程:

 

1.在頂層目錄下執(zhí)行make uImage

 

2.頂層目錄下的MakeFile

 

155 srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))

 

# srctree為當(dāng)前MakeFile所在目錄

 

198 ARCH ?= arm # 自己修改的

 

203 SRCARCH := $(ARCH)

 

504 include $(srctree)/arch/$(SRCARCH)/Makefile

 

-> include arch/arm/MakeFile

 

-> 執(zhí)行make uImage后會(huì)根據(jù)我們?cè)O(shè)置的CPU架構(gòu),執(zhí)行對(duì)應(yīng)架構(gòu)下的MakeFile

 

3.arch/arm/MakeFile

 

291 boot := arch/arm/boot

 

299 BOOT_TARGETS = zImage Image xipImage bootpImage uImage

 

# uImage屬于BOOT_TARGETS中的一個(gè)成員

 

304 $(BOOT_TARGETS): vmlinux

 

# 生成uImage就要生成BOOT_TARGETS大目標(biāo)

 

# 依賴源碼頂層目錄下的vmlinux(編譯過程中生成的文件)

 

305 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

 

# Q是對(duì)@的封裝 不輸出編譯信息

 

# MAKE是對(duì)make -C的封裝 -C表示切換到指定目錄下的MakeFile

 

# $(build)=$(boot) -> build = arch/arm/boot

 

# MACHINE=$(MACHINE) -> MACHINE := arch/arm/mach-exynos

 

# $(boot)/$@ -> arch/arm/boot/uImage

 

-> make -C arch/arm/boot MACHINE=arch/arm/mach-exynos arch/arm/boot/uImage

 

-> 依賴頂層目錄下的vmlinux,切到arch/arm/boot下的MakeFile(參數(shù)是MACHINE)執(zhí)行,在arch/arm/boot/下生成目標(biāo)uImage(uImage就是在該目錄)

 

/***************MACHINE變量的來源******************/

 

.config/291 CONFIG_ARCH_EXYNOS=y

 

155 machine-$(CONFIG_ARCH_EXYNOS) += exynos

 

-> 在最開始導(dǎo)入配置時(shí)產(chǎn)生了.config文件,.config中只對(duì)CONFIG_ARCH_EXYNOS進(jìn)行了賦值(其他都注釋)

 

-> machine-y += exynos 即 machine-y = exynos

 

232 ifneq ($(machine-y),)

 

# 比較machine-y與空的值(machine-y = exynos),不相等

 

233 MACHINE := arch/arm/mach-$(word 1,$(machine-y))/ # word 1,$(machine-y) word為函數(shù) 表示從machine-y變量中取第一個(gè)單詞

 

-> MACHINE := arch/arm/mach-exynos

 

/********************************************************************/

 

4.arch/arm/boot/Makefile

 

78 $(obj)/uImage: $(obj)/zImage FORCE

 

# 依賴于zImage obj表示當(dāng)前MakeFile所在路徑 FORCE強(qiáng)制編譯不管是否編譯過

 

79 @$(check_for_multiple_loadaddr)

 

80 $(call if_changed,uimage)

 

81 @$(kecho) ' Image $@ is ready' # 輸出信息

 

-> 依賴當(dāng)前目錄下的zImage生成uImage

 

-> 追蹤zImage

 

30 ifeq ($(CONFIG_XIP_KERNEL),y)

 

# CONFIG_XIP_KERNEL在.config中定義 沒有賦值

 

41 else

 

54 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE

 

# 依賴arch/arm/boot/compressed/vmlinux(與之前不是同一個(gè))

 

55 $(call if_changed,objcopy)

 

# 使用gcc編譯出的程序都是elf格式的,需要進(jìn)行二進(jìn)制格式的轉(zhuǎn)換

 

56 @$(kecho) ' Kernel: $@ is ready' # 顯示信息

 

51 $(obj)/compressed/vmlinux: $(obj)/Image FORCE

 

# vmlinux依賴于arch/arm/boot/Image

 

52 $(Q)$(MAKE) $(build)=$(obj)/compressed $@

 

# make -C arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux

 

-> 依賴arch/arm/boot/Image,切換到arch/arm/boot/compressed/下的MakeFile生成vmlinux

 

/***********MACHINE參數(shù)的引用*******************/

 

arch/arm/boot/Makefile

 

14 ifneq ($(MACHINE),)

 

# arch/arm/MakeFile中傳參進(jìn)來MACHINE=arch/arm/mach-exynos

 

15 include $(srctree)/$(MACHINE)/Makefile.boot

 

# include arch/arm/mach-exynos/Makefile.boot

 

16 endif

 

arch/arm/mach-exynos/Makefile.boot

 

1 zreladdr-y += 0x40008000

 

# 內(nèi)核的入口地址(運(yùn)行起始地址)

 

2 params_phys-y := 0x40000100

 

# uboot和內(nèi)核協(xié)商好的存放參數(shù)的位置

 

arch/arm/boot/Makefile

 

22 ZRELADDR := $(zreladdr-y)

 

# ZRELADDR = 0x40008000

 

23 PARAMS_PHYS := $(params_phys-y)

 

# PARAMS_PHYS = 0x40000100

 

24 INITRD_PHYS := $(initrd_phys-y)

 

25

 

26 export ZRELADDR INITRD_PHYS PARAMS_PHYS

 

# 導(dǎo)出讓全局可用

 

/*****************************************************************/

 

5.arch/arm/boot/compressed/MakeFile

 

185 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \

 

186 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \

 

187 $(bswapsdi2) FORCE

 

# vmlinux依賴很多文件產(chǎn)生

 

# 依賴文件的來源

 

# $(obj)/vmlinux.lds

 

# arch/arm/boot/compressed/vmlinux.lds 鏈接腳本決定elf文件的排版(內(nèi)核源文件)

 

# $(obj)/$(HEAD) = arch/arm/boot/compressed/$(HEAD)

 

# 25 HEAD = head.o 由 head.S生成(內(nèi)核源文件)

 

# $(obj)/piggy.$(suffix_y).o

 

# 86 suffix_$(CONFIG_KERNEL_GZIP) = gzip

 

# .config/40 CONFIG_KERNEL_GZIP=y 導(dǎo)入默認(rèn)配置時(shí)配置的內(nèi)核的壓縮格式

 

# ->suffix_y = gzip

 

# -> $(obj)/piggy.$(suffix_y).o = arch/arm/boot/compressed/piggy.gzip.o 由 piggy.gzip.S(編譯中間生成)生成

 

# $(addprefix $(obj)/, $(OBJS)) # 給變量$(OBJS))添加前綴$(addprefix $(obj)/

 

# 26 OBJS += misc.o decompress.o -> OBJS = misc.o decompress.o

 

# -> $(addprefix $(obj)/, $(OBJS)) = arch/arm/boot/compressed/misc.o decompress.o 由 misc.c decompress.c生成(內(nèi)核源文件)

 

# 這兩個(gè)文件用于解壓內(nèi)核 內(nèi)核當(dāng)中包含了解壓的代碼

 

# $(lib1funcs)

 

# 148 lib1funcs = $(obj)/lib1funcs.o -> lib1funcs = arch/arm/boot/compressed/lib1funcs.o(lib1funcs.S生成)

 

# 150 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S(內(nèi)核源文件)

 

# $(ashldi3)

 

# 154 ashldi3 = $(obj)/ashldi3.o -> ashldi3 = arch/arm/boot/compressed/ashldi3.o(ashldi3.S生成)

 

# 156 $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S(內(nèi)核源文件)

 

# $(bswapsdi2)

 

# 160 bswapsdi2 = $(obj)/bswapsdi2.o -> bswapsdi2 = arch/arm/boot/compressed/bswapsdi2.o(bswapsdi2.S生成)

 

# 162 $(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S(內(nèi)核源文件)

 

/******************************piggy.gzip.o********************************/

 

# 195 $(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE -> piggy.gzip.o:piggy.gzip -> piggy.gzip.o依賴piggy.gzip

 

# 192 $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE -> piggy.gzip:arch/arm/boot/Image FORCE -> piggy.gzip依賴上層目錄的Image

 

-> 退回上層目錄追蹤arch/arm/boot/Image

 

/*************************************************************************/

 

6.arch/arm/boot/MakeFile

 

47 $(obj)/Image: vmlinux FORCE

 

# 依賴頂層源碼下的vmlinux FORCE強(qiáng)制執(zhí)行

 

48 $(call if_changed,objcopy)

 

49 @$(kecho) ' Kernel: $@ is ready'

 

-> 退回頂層源碼下追蹤vmlinux

 

7.頂層目錄MakeFile

 

817 vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE

 

# scripts/link-vmlinux.sh 編譯需要的腳本

 

# 809 vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)

 

# 追蹤得到一些路徑下的源文件

 

# 802 export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)

 

# 803 export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)

 

# 804 export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds

 

# 鏈接腳本(兩次鏈接過程)

 

逆序總結(jié):uImage由zImage通過uboot中的工具為其添加頭部生成

 

zImage由arch/arm/boot/compressed/vmlinux(elf格式)文件經(jīng)過二進(jìn)制格式轉(zhuǎn)換生成

 

vmlinux由/arch/arm/boot/compressed/piggy.gzip(壓縮后的內(nèi)核)和misc.c、decompress.c、(用于解壓內(nèi)核的代碼)按照vmlinux.lds鏈接生成(二次鏈接)

 

piggy.gzip由/arch/arm/boot/Image文件(不包含解壓代碼的二進(jìn)制內(nèi)核文件)壓縮得到

 

Image文件是由源碼頂層目錄下的vmlinux(elf格式)經(jīng)過二進(jìn)制轉(zhuǎn)換生成的

 

vmlinux是由一系列的內(nèi)核源碼與工具按照鏈接腳本arch/arm/kernel/vmlinux.lds鏈接生成(一次鏈接)

 

順序總結(jié):一系列的源碼與工具按照arch/arm/kernel/vmlinux.lds與各級(jí)Makefile的規(guī)則編譯生成源碼頂層目錄下的vmlinux(elf格式內(nèi)核)即第一次鏈接

 

vmlinux經(jīng)過二進(jìn)制轉(zhuǎn)換生成arch/arm/boot/Image(二進(jìn)制格式的內(nèi)核)

 

Image文件經(jīng)過壓縮得到piggy.gzip文件(壓縮后的二進(jìn)制內(nèi)核)(piggy.gzip文件的運(yùn)行需要解壓)

 

piggy.gzip與解壓該文件的代碼misc.c、decompress.c、等按照鏈接腳本arch/arm/boot/compressed/vmlinux.lds鏈接成一個(gè)文件(第二次鏈接)vmlinux(elf)

 

vmlinux文件經(jīng)過二進(jìn)制轉(zhuǎn)換生成zImage

 

zImage經(jīng)過添加頭部生成uImage


信盈達(dá)2008年在深圳特區(qū)南山高新科技園成立。自成立至今近九年來專注為企業(yè)和個(gè)人提供高端方案設(shè)計(jì)、高端嵌入式/Android培訓(xùn)等服務(wù)。公司下設(shè)信盈達(dá)實(shí)訓(xùn)學(xué)院、信盈達(dá)研發(fā)中心、信盈達(dá)教學(xué)儀器三大業(yè)務(wù)板塊。九年來公司堅(jiān)持"技術(shù)領(lǐng)先、服務(wù)領(lǐng)先",以雄厚的實(shí)力和專業(yè)的品質(zhì)成為國內(nèi)唯一有實(shí)力從產(chǎn)品最底層研發(fā)到系統(tǒng)層開發(fā)的嵌入式實(shí)訓(xùn)、產(chǎn)品解決方案提供商。為中國IT行業(yè)提供最具價(jià)值的職業(yè)教育服務(wù)。專業(yè)訓(xùn)嵌入式、物聯(lián)網(wǎng)、人工智能Java、單片機(jī)等課程,想了解更多信息點(diǎn)擊立馬咨詢