uboot 2013.04版编译过程及原理说明

使用如何阅读U-Boot的Makefile中的方法我们同样可以获取make_boot_compile.log.1,下面是其中内容的详细解释。

目标autoconf.mk和autoconf.mk.dep

make[1]: Entering directory `/disk2/boot'
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
make[1]: Leaving directory `/disk2/boot'

boot/Makefile中有

all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk

虽然boot/Makefile中有两个all目标,但是在执行make时首先会执行第一个all,第一个all目标只是说明了sinclude两个文件,这两个文件在下面有创建的规则,所以会直接执行这两个目标。

autoconf.mk

$(obj)include/autoconf.mk: $(obj)include/config.h
    @$(XECHO) Generating $@ ; \
    set -e ; \
    : Extract the config macros ; \
    $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
        sed -n -f tools/scripts/define2mk.sed > [email protected] && \
    mv [email protected] $@

依赖include/config.hXECHO根据环境变量中是否有s静默模式赋值为echo或者::表示注释,CPPgcc -E,表示展开宏,定义在config.mk-dM include/common.h表示展开文件中的宏,利用脚本define2mk.sed将宏定义转换成CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000

include/config.h在U-boot配置时创建。

autoconf.mk.dep

$(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
    @$(XECHO) Generating $@ ; \
    set -e ; \
    : Generate the dependancies ; \
    $(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS) \
        -MQ $(obj)include/autoconf.mk include/common.h > $@

依赖include/config.hinclude/common.h,提取所有依赖的头文件。

目标all

这里的目标all指的是第二个

all:        $(ALL-y) $(SUBDIR_EXAMPLES)

只有依赖文件,没有命令,所以只需要关注变量$(ALL-y)$(SUBDIR_EXAMPLES)

ALL-y

ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)u-boot.dis $(obj)System.map
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin

有两种赋值形式,需要了解的是第二种,根据宏是否定义为y来决定ALL-y是否包含。

u-boot.srec

继续看make_boot_compile.log.1

 文件“all”不存在。
   文件“u-boot.srec”不存在。
     文件“u-boot”不存在。
...
  必须重新创建目标“u-boot.srec”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objcopy -O srec u-boot u-boot.srec
  重新创建目标文件“u-boot.srec”成功。

对应的makefile内容是

$(obj)u-boot.srec:  $(obj)u-boot
        $(OBJCOPY) -O srec $< $@
u-boot[重要]
     文件“u-boot”不存在。
       文件“depend”不存在。
        ...
      重新创建目标文件“depend”成功。
        ...
cd /disk2/boot && /disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x4ff00000 arch/arm/cpu/arm920t/start.o --start-group arch/arm/cpu/arm920t/libarm920t.o arch/arm/lib/libarm.o common/libcommon.o drivers/crypto/libcrypto.o drivers/i2c/libi2c.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/spi/libspi_flash.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/usb/ulpi/libusb_ulpi.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o board/samsung/smdk2440/libsmdk2440.o --end-group /disk2/boot/arch/arm/lib/eabi_compat.o  -L /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2 -lgcc -Map u-boot.map -o u-boot
    重新创建目标文件“u-boot”成功。

对应Makefile的代码

GEN_UBOOT = \
        cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
            $(__OBJS) \
            --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
            -Map u-boot.map -o u-boot

$(obj)u-boot:   depend \
        $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
        $(GEN_UBOOT)

依赖文件是depend$(SUBDIR_TOOLS)$(OBJS)$(LIBBOARD)$(LIBS)$(LDSCRIPT)$(obj)u-boot.lds,待这些依赖文件全部更新后执行$(GEN_UBOOT)

下面我们对每一个进行分析

depend

Makefile内容

depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) \
        $(obj)include/autoconf.mk \
        $(obj)include/generated/generic-asm-offsets.h \
        $(obj)include/generated/asm-offsets.h
        for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do \
            $(MAKE) -C $$dir _depend ; done
  1. TIMESTAMP_FILE是时间戳文件include/generated/timestamp_autogenerated.h
  2. VERSION_FILE是版本信息,包括boot的版本信息、arm-linux-gccarm-linux-ld的版本信息;
  3. include/autoconf.mk之前已经分析过了;
  4. lib/asm-offsets.c中定义了global_data结构体的一些信息,利用该文件生成lib/asm-offsets.s,再利用tools/scripts/make-asm-offsetslib/asm-offsets.s生成include/generated/generic-asm-offsets.h
  5. 利用$(src)$(CPUDIR)/$(SOC)/asm-offsets.c生成$(CPUDIR)/$(SOC)/asm-offsets.s,不存在则该文件为空,再利用tools/scripts/make-asm-offsets$(CPUDIR)/$(SOC)/asm-offsets.s生成include/generated/asm-offsets.h
  6. toolsarch/arm/cpu/arm920t/disk2/boot/board/samsung/smdk2440/分别执行make -C $dir _depend,将在这些目录下生成.depend文件,内容是.c文件编译时所依赖的头文件。
$(SUBDIR_TOOLS)

在boot下面的Makefile中SUBDIR_TOOLS = tools

TOOLSUBDIRS = 

BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
BINS    := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
all:    $(obj).depend $(BINS) $(LOGO-y) subdirs

$(obj)envcrc$(SFX): $(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o
    $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^

subdirs:
ifeq ($(TOOLSUBDIRS),)
    @:
else
    @for dir in $(TOOLSUBDIRS) ; do \
        $(MAKE) \
        HOSTOS=$(HOSTOS) \
        HOSTARCH=$(HOSTARCH) \
        -C $$dir || exit 1 ; \
    done
endif

.depend之前已经更新了;BIN表示诸如envcrc的可执行文件,在boot/rules.mk中关于.c编译成.o;LOGO-y表示头文件;subdirs表示其他需要编译的目录,这里定义是空。

$(HOSTOBJS): $(obj)%.o: %.c
    $(HOSTCC) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) $(HOSTCFLAGS_$(BCURDIR)) -o $@ $< -c

tool中的可执行文件使gcc编译的,也就是说这些工具是在

$(OBJS)

boot/MakefileOBJS的定义是arch/arm/cpu/arm920t/start.o

OBJS  = $(CPUDIR)/start.o
OBJS := $(addprefix $(obj),$(OBJS))
$(OBJS):    depend
        $(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))

执行的命令等同于

make -C arch/arm/cpu/arm920t start.o

对应make_boot_compile.log.1中的内容

       文件“arch/arm/cpu/arm920t/start.o”不存在。
      必须重新创建目标“arch/arm/cpu/arm920t/start.o”。
make -C arch/arm/cpu/arm920t start.o

 文件“start.o”不存在。
必须重新创建目标“start.o”。
make[2]: Entering directory `/disk2/boot/arch/arm/cpu/arm920t'
/disk2/cross_compiler/bin/arm-linux-gcc   -D__ASSEMBLY__ -g  -Os   -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x4ff00000 -DCONFIG_SPL_TEXT_BASE=0x200000 -DCONFIG_SPL_PAD_TO=0 -I/disk2/boot/include -fno-builtin -ffreestanding -nostdinc -isystem /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2/include -pipe  -DCONFIG_ARM -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -march=armv5   -o start.o start.S -c
重新创建目标文件“start.o”成功。
$(LIBBOARD)
LIBS-y += lib/libgeneric.o
LIBS-y += lib/lzma/liblzma.o
...
LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
LIBS := $(addprefix $(obj),$(sort $(LIBS-y)))

SUBDIR_TOOLS = tools
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))

$(LIBS):    depend $(SUBDIR_TOOLS)
        $(MAKE) -C $(dir $(subst $(obj),,$@))

$(LIBBOARD):    depend $(LIBS)
        $(MAKE) -C $(dir $(subst $(obj),,$@))

依赖文件是depend$(LIBS)depend之前已经更新过了,所以这里只需要考虑$(LIBS)的更新。根据(LIBS)的定义可以看出是.o文件,编译的方法类似于

make -C arch/arm/cpu/arm920t/

LIBBOARD的定义是board/samsung/smdk2440/libsmdk2440.o,因此编译的命令相当于

make -C board/samsung/smdk2440/
$(LIBS)

之前更新$(LIBBOARD)时已经更新过了。

$(LDSCRIPT)
    ifeq ($(wildcard $(LDSCRIPT)),)
        LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
    endif

对应make_boot_compile.log.1

       目标“/disk2/boot/board/samsung/smdk2440/u-boot.lds”的前提“depend”不存在。
      必须重新创建目标“/disk2/boot/board/samsung/smdk2440/u-boot.lds”。
make -C /disk2/boot/board/samsung/smdk2440/ u-boot.lds

u-boot.lds文件存在,不需要更新。

$(obj)u-boot.lds

boot/Makefile

$(obj)u-boot.lds: $(LDSCRIPT)
        $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$< >$@

对应make_boot_compile.log.1

文件“u-boot.lds”不存在。
      必须重新创建目标“u-boot.lds”。
/disk2/cross_compiler/bin/arm-linux-gcc -E -g  -Os   -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x4ff00000 -DCONFIG_SPL_TEXT_BASE=0x200000 -DCONFIG_SPL_PAD_TO=0 -I/disk2/boot/include -fno-builtin -ffreestanding -nostdinc -isystem /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2/include -pipe  -DCONFIG_ARM -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -march=armv5 -include /disk2/boot/include/u-boot/u-boot.lds.h -DCPUDIR=arch/arm/cpu/arm920t  -ansi -D__ASSEMBLY__ -P - u-boot.lds
      重新创建目标文件“u-boot.lds”成功。

u-boot.bin

   文件“u-boot.bin”不存在。
  必须重新创建目标“u-boot.bin”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
  重新创建目标文件“u-boot.bin”成功。

对应的makefile内容是

$(obj)u-boot.bin:   $(obj)u-boot
        $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
        $(BOARD_SIZE_CHECK)

u-boot.bin用于烧写。

u-boot.dis

   文件“u-boot.dis”不存在。
  必须重新创建目标“u-boot.dis”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objdump -d u-boot > u-boot.dis
  重新创建目标文件“u-boot.dis”成功。

对应的makefile内容是

$(obj)u-boot.dis:   $(obj)u-boot
        $(OBJDUMP) -d $< > $@

反汇编u-boot,u-boot.dis一般用于定位问题。

System.map

   文件“System.map”不存在。
  必须重新创建目标“System.map”。
  重新创建目标文件“System.map”成功。

对应的makefile内容是

SYSTEM_MAP = \
        $(NM) $1 | \
        grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
        LC_ALL=C sort
$(obj)System.map:   $(obj)u-boot
        @$(call SYSTEM_MAP,$<) > $(obj)System.map

依赖文件u-boot,命令是$(call SYSTEM_MAP,$<) > $(obj)System.map,等同于

$(CROSS_COMPILE)nm u-boot | \
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
LC_ALL=C sort > System.map

生成符号表System.map

spl/u-boot-spl.bin

$(obj)spl/u-boot-spl.bin:   $(SUBDIR_TOOLS) depend
        $(MAKE) -C spl all

SUBDIR_EXAMPLES

例子所在的文件夹,可以直接注释掉

SUBDIR_EXAMPLES = examples/standalone examples/api
Image 1.png

你可能感兴趣的:(uboot 2013.04版编译过程及原理说明)