0
点赞
收藏
分享

微信扫一扫

Linux应用开发(十七)——U-Boot的编译、连接过程

芝婵 2022-01-23 阅读 93
linuxu-boot

文章目录


U-Boot的编译

配置完成后,执行“make all”即可编译,从Makefile中可以了解到U-Boot使用了那些文件、那个文件首先执行、可执行文件占用内存的情况。

先确定用到的那些文件,下面所示为Makefile中与ARM相关的部分。

include $(OBJTREE)/include/config.mk
export	ARCH CPU BOARD VENDOR SOC
...
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
...
# load other configuration
include $(TOPDIR)/config.mk

在这里插入图片描述在这里插入图片描述在这里插入图片描述

找到BOARDDIR、LDFLAGS的值

 BOARDDIR = $(BOARD)
...
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk  # include board specific rules
...
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
...
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)

原文件顶层目录下的config.mk分析

在board/smdk2410/config.mk中,定义了"TEXT_BASE=0x33F80000"。
在这里插入图片描述所以,最终结果如下:BOARDDIR为 smdk2410:LDFLAGS中有“-T board/smdk2410/U-Boot.lds -Ttext 0x33F80000”字样。

继续分析Makefile

#########################################################################
# U-Boot objects....order is important (i.e. start must be first)

OBJS  = cpu/$(CPU)/start.o
...
LIBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
...
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
	fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
...
LIBS += $(BOARDLIBS)
...

在这里插入图片描述在这里插入图片描述OBJS、LINS所代表的.a,.o文件就是U-Boot的构成,它们通过如下命令有相应的源文件(或相应子目录下的文件)编译的到。

$(OBJS):
		$(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

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

$(SUBDIRS):
		$(MAKE) -C $@ all

在这里插入图片描述

U-Boot的连接过程

当所有的OBJS,LIBS所表示的.a和.o文件都生成以后,就剩下最后的连接了,这对应Makefile中如下几行

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

$(obj)u-boot.bin:	$(obj)u-boot
		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
...
$(obj)u-boot:		depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
		UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
		cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
			--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
			-Map u-boot.map -o u-boot

在这里插入图片描述
board/smdk2410/U-Boot.lds文件如下:

SECTIONS
{
        . = 0x00000000;

        . = ALIGN(4);
        .text      :
        {
          cpu/arm920t/start.o   (.text)
          *(.text)
        }

        . = ALIGN(4);
        .rodata : { *(.rodata) }

        . = ALIGN(4);
        .data : { *(.data) }

        . = ALIGN(4);
        .got : { *(.got) }

        . = .;
        __u_boot_cmd_start = .;
        .u_boot_cmd : { *(.u_boot_cmd) }
        __u_boot_cmd_end = .;

        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) }
        _end = .;
}

在这里插入图片描述在这里插入图片描述

总结U-Boot的编译流程

  1. 首先编译cpu/$(CPU)/start.S,对于不同的CPU,还可能编译cpu/ $(CPU)下的其他文件(为什么要先编译它呢?因为U-Boot的入口点在这个文件中)
  2. 然后,对于平台/开发板相关的每个目录、每个通用目录都是使用它们各自的Makefidle生成相应的库。
  3. 将1、2步骤生成的.a和.o文件按照board/$(BOARDDIR)/config.mk文件中指定的代码起始地址、board/ $(BORADDIR)/U-Boot.lds连接脚本进行连接。
  4. 第3步得到的就是ELF格式的U-Boot,后面Makefile还会将它转换为二进制格式,S-Record格式。

总结

总结以下,U-Boot很难,我们现在也只是分析了Makefile中核心的部分,但是这个Makefile有2000多行,所以这会是一个漫长的过程。
在这里插入图片描述加油,相信终有一天能彻底明白其思想!

举报

相关推荐

0 条评论