国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Linux-Android啟動(dòng)之zImage生成過(guò)程詳解

Linux-Android啟動(dòng)之zImage生成過(guò)程詳解收藏

可以看到,在頂層makefile的第278行,包含了scripts/Kbuild.include文件,在這里定義了大量的函數(shù)和變量,供頂層makefile和其他makefile文件使用。
 
在頂層makefile文件的第412行,包含了arch/arm/Makefile。這個(gè)是體系結(jié)構(gòu)相關(guān)makefile文件。它定義了體系結(jié)構(gòu)相關(guān)的一些變量及規(guī)則。
 
當(dāng)執(zhí)行”make”時(shí),arch/arm/Makefile中的185行的規(guī)則將是make遇到的第一個(gè)規(guī)則:
 
all:  $(KBUILD_IMAGE)
 
KBUILD_IMAGE這個(gè)變量是arch/arm/Makefile的第182行定義。
 
KBUILD_IMAGE := zImage
 
然后看zImage的構(gòu)建規(guī)則,在arch/arm/Makefile的第212行開(kāi)始定義
 
zImage Image xipImage bootpImage uImage: vmlinux
      $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
 
build變量在scripts/Kbuild.include文件中第114行定義:
 
build := -f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
 
boot變量在arch/arm/Makefile的187行定義:
 
boot := arch/arm/boot
 
MACHINE變量的值在arch/arm/Makefile的147行開(kāi)始定義
 
ifneq ($(machine-y),)
MACHINE := arch/arm/mach-$(machine-y)/
else
MACHINE  :=
endif
 
這里machine-y := s3c2410,所以變量MACHINE的值為
 
MACHINE  :=arch/arm/mach-s3c2410
 
所以上面的規(guī)則可寫(xiě)為如下形勢(shì)
 
 
zImage:vmlinux
       $(Q)$(MAKE) -f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj= \
      arch/arm/boot MACHINE= arch/arm/mach-s3c2410 arch/arm/boot/ zImage
 
這個(gè)規(guī)則的依賴(lài)是vmlinux,下面先看看這個(gè)依賴(lài)目標(biāo)的創(chuàng)建規(guī)則。
 
vmlinux目標(biāo)的規(guī)則在頂層Makefile的第738行定義。
 
vmlinux: $(vmlinux-lds) $(vmlinux-init)$(vmlinux-main) $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
      $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
      $(call if_changed_rule,vmlinux__)
       $(Q)$(MAKE) -f$(srctree)/scripts/Makefile.modpost $@
       $(Q)rm -f .old_version
 
這里涉及到幾個(gè)變量,先看看這幾個(gè)變量的定義,前三個(gè)變量分別在605、602、603行定義。
 
vmlinux-init:= $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y)$(drivers-y) $(net-y)
vmlinux-lds  :=arch/$(ARCH)/kernel/vmlinux.lds
 
其中head-y在arch/arm/Makefile中第89行定義,
 
head-y            := arch/arm/kernel/head$(MMUEXT).oarch/arm/kernel/init_task.o
 
init-y在頂層makefile的433行定義
 
init-y             := init/
 
后又在第567行進(jìn)行處理
 
init-y              :=$(patsubst %/, %/built-in.o, $(init-y))
 
所以變量init-y應(yīng)為
 
init-y             := init/built-in.o
 
因此
 
vmlinux-init :=arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.oinit/built-in.o
 
同理,其他幾個(gè)變量也可通過(guò)類(lèi)似方法進(jìn)行分析,這里不一一分析了。vmlinux-init這個(gè)變量的構(gòu)建規(guī)則在748行定義:
 
$(sort $(vmlinux-init) $(vmlinux-main))$(vmlinux-lds): $(vmlinux-dirs) ;
 
這里是一個(gè)空命令的規(guī)則。空命令行可以防止make在執(zhí)行時(shí)試圖為重建這個(gè)目標(biāo)去查找隱含命令。其依賴(lài)為vmlinux-dirs,這個(gè)變量在頂層Makefile第558行定義:
 
vmlinux-dirs  := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                  $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
                  $(net-y) $(net-m) $(libs-y) $(libs-m)))
 
這個(gè)變量指定了一系列要進(jìn)入的下層目錄。他的規(guī)則在頂層Makefile第757行定義
 
$(vmlinux-dirs): prepare scripts
      $(Q)$(MAKE) $(build)=$@
 
這里的兩個(gè)依賴(lài)就不分析了,主要看一下這個(gè)規(guī)則的命令,build和$@變量展開(kāi)后如下
 
       $(Q)$(MAKE) -f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build  \
        obj=$(vmlinux-dirs)
 
這里會(huì)再一次進(jìn)入scripts/Makefile.build執(zhí)行83行規(guī)則
 
__build:$(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
       $(if $(KBUILD_MODULES),$(obj-m)) \
        $(subdir-ym) $(always)
      @:
 
因?yàn)镵BUILD_BUILTIN在頂層Makefile中被初始化為1,所以這個(gè)規(guī)則的依賴(lài)有一個(gè)builtin-target變量。這個(gè)變量在scripts/Makefile.build的78行定義
 
ifneq ($(strip$(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
builtin-target:= $(obj)/built-in.o
endif
 
變量obj就是vmlinux-dirs變量指定的目錄。所以這里會(huì)構(gòu)建$(vmlinux-dirs)/built-in.o目標(biāo),在scripts/Makefile.build文件的261行開(kāi)始,有這個(gè)目標(biāo)的規(guī)則及命令的定義
 
ifdef builtin-target
quiet_cmd_link_o_target =LD      $@
# If the list of objects to link is empty, just create anempty built-in.o
cmd_link_o_target = $(if $(strip $(obj-y)),\
                   $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
                   rm -f $@; $(AR) rcs $@)
 
$(builtin-target): $(obj-y)FORCE
       $(call if_changed,link_o_target),
 
scripts/Makefile.build在第16行開(kāi)始包含了vmlinux-dirs變量指定目錄中的Makefile文件,在這些makefile文件中會(huì)指定obj-y變量,它指定的都是一些*.o目標(biāo)文件,
 
kbuild-dir := $(if $(filter/%,$(src)),$(src),$(srctree)/$(src))
include $(if $(wildcard$(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
 
這些*.o文件的生成方法由scripts/Makefile.build文件202行的模式規(guī)則指定
 
%.o: %.cFORCE
       $(call cmd,force_checksrc)
       $(callif_changed_rule,cc_o_c)
 
通過(guò)上面這一系列的步驟,就編譯鏈接出由變量vmlinux-init指定的目標(biāo),vmlinux-main變量指定的目標(biāo)的構(gòu)建與此類(lèi)似。再看看vmlinux的構(gòu)建規(guī)則
 
vmlinux:$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
ifdefCONFIG_HEADERS_CHECK
       $(Q)$(MAKE) -f $(srctree)/Makefileheaders_check
endif
       $(call if_changed_rule,vmlinux__)
      $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
       $(Q)rm-f .old_version
 
現(xiàn)在vmlinux的依賴(lài)都處理好了,開(kāi)始執(zhí)行這個(gè)規(guī)則的命令,命令
 
$(Q)$(MAKE)-f $(srctree)/Makefile headers_check
 
是進(jìn)行頭文件的相關(guān)檢測(cè),這里不作詳細(xì)分析。看第二條命令
 
       $(call if_changed_rule,vmlinux__)
 
這里通過(guò)函數(shù)調(diào)用,執(zhí)行rule_vmlinux__,在頂層Makefile第636行開(kāi)始定義
 
define rule_vmlinux__
      :
       $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
 
       $(call cmd,vmlinux__)
       $(Q)echo 'cmd_$@ :=$(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
 
       $(Q)$(if$($(quiet)cmd_sysmap),                                      \
        echo '  $($(quiet)cmd_sysmap)  System.map'&&)                     \
       $(cmd_sysmap) $@System.map;                                         \
       if [$$? -ne 0 ]; then                                               \
             rm -f $@;                                                    \
             /bin/false;                                                  \
      fi;
       $(verify_kallsyms)
endef
 
這里主要還是調(diào)用cmd_vmlinux__,定義在頂層Makefile的610行
 
      cmd_vmlinux__ ?= $(LD)$(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
      -T $(vmlinux-lds)$(vmlinux-init)                          \
      --start-group$(vmlinux-main) --end-group                  \
      $(filter-out$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
 
通過(guò)這個(gè)命令將變量vmlinux-init和vmlinux-main指定的目標(biāo)鏈接成vmlinux文件。鏈接腳本由vmlinux-lds指定。在頂層Makefile 605行定義:
 
vmlinux-lds  :=arch/$(ARCH)/kernel/vmlinux.lds
 
現(xiàn)在再看一下zImage的構(gòu)建規(guī)則
 
zImage:vmlinux
       $(Q)$(MAKE) -f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj= \
      arch/arm/boot MACHINE= arch/arm/mach-s3c2410 arch/arm/boot/ zImage
 
其依賴(lài)vmlinux已經(jīng)構(gòu)建完成,它的命令同樣是執(zhí)行scripts/Makefile.build文件,它的開(kāi)頭包含了arch/arm/boot/Makefile文件,在這個(gè)文件的第56行開(kāi)始就是arch/arm/boot/zImage的構(gòu)建規(guī)則:
 
$(obj)/zImage:$(obj)/compressed/vmlinux FORCE
       $(call if_changed,objcopy)
      @echo '  Kernel: $@ is ready'
 
變量obj的值就是arch/arm/boot,前面已經(jīng)分析過(guò)。其依賴(lài)  $(obj)/compressed/vmlinux的構(gòu)建規(guī)則在arch/arm/boot/Makefile的53行開(kāi)始定義的
 
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
      $(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
這個(gè)規(guī)則的依賴(lài)$(obj)/Image的構(gòu)建規(guī)則在arch/arm/boot/Makefile的49行開(kāi)始定義:
 
$(obj)/Image: vmlinuxFORCE
       $(call if_changed, objcopy)
       @echo '  Kernel:$@ is ready'
 
在這個(gè)規(guī)則中,將前面創(chuàng)建的vmlinux文件通過(guò)二進(jìn)制工具objcopy進(jìn)行處理,在scripts/Makefile.build的第19行包含了scripts/Makefile.lib
 
includescripts/Makefile.lib
 
在這個(gè)makefile文件中,有cmd_objcopy的定義,在156行開(kāi)始定義
 
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY)$(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
變量OBJCOPY在頂層Makefile中289行定義:
 
OBJCOPY             = $(CROSS_COMPILE)objcopy
 
OBJCOPYFLAGS變量在arch/arm/Makefile中第15行定義
 
OBJCOPYFLAGS :=-O binary -R .note -R .comment –S
 
所以命令cmd_objcopy可擴(kuò)展為
 
cmd_objcopy = $(CROSS_COMPILE)objcopy -O binary -R .note -R.comment –S $< $@
 
這就是處理vmlinux的命令。然后看看規(guī)則
 
$(obj)/compressed/vmlinux:$(obj)/Image FORCE
       $(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
的命令行,變量擴(kuò)展后為:
 
$(Q)$(MAKE) -f $(if$(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj= \
            $(obj)/compressed $(obj)/compressed/vmlinux
 
于是在scripts/Makefile的開(kāi)頭會(huì)包含arch/arm/boot/compressed/Makefile文件,并執(zhí)行其中的$(obj)/vmlinux目標(biāo)所在的規(guī)則,在這個(gè)Makefile文件的第98行開(kāi)始定義:
 
$(obj)/vmlinux:$(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
            $(addprefix $(obj)/, $(OBJS)) FORCE
       $(call if_changed,ld)
      @:
 
這里先看$(obj)/piggy.o,在arch/arm/boot/compreseed/Makefile的103行開(kāi)始
 
$(obj)/piggy.gz: $(obj)/../Image FORCE
       $(callif_changed,gzip)
 
$(obj)/piggy.o:  $(obj)/piggy.gz FORCE
 
這兩個(gè)規(guī)則的第一個(gè)就是把由vmlinux生成的Image進(jìn)行壓縮生成piggy.gz,然后生成piggy.o
 
cmd_ld命令在scripts/Makefile.lib文件149行定義:
 
quiet_cmd_ld = LD      $@
cmd_ld= $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \
             $(filter-out FORCE,$^) -o $@
 
這里根據(jù)鏈接腳本arch/arm/boot/compressed/vmlinux.lds鏈接生成了arch/arm/boot/compressed/vmlinux文件。然后在arch/arm/boot/Makefile的第56行的規(guī)則中
 
$(obj)/zImage:$(obj)/compressed/vmlinux FORCE
       $(call if_changed,objcopy)
      @echo '  Kernel: $@ is ready'
 
經(jīng)過(guò)objcopy處理后便生成的最終的zImage 。
 
 
 
下面看一下頂層Makefile生成的vmlinux以及arch/arm/boot/compressed/makefile生成的vmlinux的起始地址。
 
通過(guò)頂層Makefile中的規(guī)則生成vmlinux是根據(jù)arch/arm/kernel/vmlinux.lds這個(gè)腳本鏈接生成的。arch/arm/kernel/vmlinux.lds是由arch/arm/kernel/vmlinux.lds.S生成的,其生成規(guī)則在scripts/Makefile.build的第246行開(kāi)始定義
 
quiet_cmd_cpp_lds_S= LDS     $@
      cmd_cpp_lds_S = $(CPP) $(cpp_flags)-D__ASSEMBLY__ -o $@ $<
 
%.lds: %.lds.S FORCE
      $(call if_changed_dep,cpp_lds_S)
 
在arch/arm/kernel/vmlinux.lds.S的開(kāi)始處有
 
#ifdef CONFIG_XIP_KERNEL
       . =XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
#else
       . =PAGE_OFFSET + TEXT_OFFSET;
#endif
 
我們這里的起始地址就是PAGE_OFFSET +TEXT_OFFSET。
 
在include/asm-arm/memory.h的49行開(kāi)始有
 
#ifndefPAGE_OFFSET
#define PAGE_OFFSET        UL(0xc0000000)
#endif
 
而arch/arm/kernel/vmlinux.lds.S的開(kāi)頭有
 
#include<asm/memory.h>
 
asm是一個(gè)符號(hào),鏈接到asm-arm上的
 
在arch/arm/Makefile第140行,有
 
TEXT_OFFSET := $(textofs-y)
 
第90行有
 
textofs-y := 0x00008000
 
所以TEXT_OFFSET := 0x00008000
 
在153行有exportTEXT_OFFSET將此變量輸出。這樣arch/arm/kernel/vmlinux.lds.S也就獲得了PAGE_OFFSET +TEXT_OFFSET的值。
 
 
現(xiàn)在看看arch/arm/boot/compressed/makeflie生成的vmlinux。它是根據(jù)arch/arm/boot/compressed/vmlinux.lds鏈接腳本生成的。這個(gè)腳本由arch/arm/boot/compressed/vmlinux.lds.in生成,在這個(gè)文件的開(kāi)始處有
 
  . = TEXT_START;
 
現(xiàn)在看arch/arm/boot/compressed/Makefile,在110行有
 
$(obj)/vmlinux.lds:$(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
       @sed"$(SEDFLAGS)" < $ $@
 
這就是由vmlinux.lds.in生成vmlinux.lds的規(guī)則,在它的命令中有個(gè)變量SEDFLAGS,在74行定義
 
SEDFLAGS    =s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 
這里就把TEXT_START換成了ZTEXTADDR。再往上看從66行起
 
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR:= $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR    := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR := 0
ZBSSADDR    := ALIGN(4)
endif
 
如果zImage是從ram中啟動(dòng)ZTEXTADDR      := 0,否則從rom或flash啟動(dòng)時(shí)ZTEXTADDR :=$(CONFIG_ZBOOT_ROM_TEXT),這里要在配置時(shí)設(shè)定CONFIG_ZBOOT_ROM_TEXT的值。
 
到這里,關(guān)于zImage的生成過(guò)程算是可以結(jié)束了。


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
7. zImage的生成和加載
Linux 2.6內(nèi)核Makefile分析
zImage解壓過(guò)程
也談Linux Kernel Hacking – Kconfig與Kbuild | Tony Bai
KBUILD系統(tǒng)原理分析--MAKE原理介紹
KBUILD系統(tǒng)原理分析
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服