二、uboot20 s5pv210移植—SPL编译分析

一、uboot20 s5pv210移植—基础环境配置


文章目录

  • 前言
  • 1. 根目录makefile分析
  • 2. Makefile.spl
  • 总结


前言

在进行s5pv210的使用时,由于外设的初始化要求和空间大小,需要在IRAM中执行SPL代码进行一些外设的初始化,随后将u-boot加载到指定的DRAM中。因此,对于SPL的了解和学习十分有必要,而且SPL中的许多操作涉及到ARM相关功能和寄存器的操作,由此也展开对裸机程序的学习。可以通过下图来查看整个设备的启动流程。
二、uboot20 s5pv210移植—SPL编译分析_第1张图片
从上图中可以看出,在IROM中的romcode执行完成后,会将Booting Device中的BL1(SPL)先load到IRAM中,因为IRAM不需要初始化,可以直接上电使用,则加载SPL后就可以执行,完成时钟和DRAM等外设的初始化后,就可以加载BL2(U-Boot)完成其他外设的初始化。为什么需要BL1?

  1. IRAM空间不足,无法加载全部u-boot。且为了节省成本
  2. DRAM需要进行初始化才可以使用,因此需要有一段开机可以执行的代码来进行DRAM的初始化

由于在执行romcode时会从Booting Devices中读取BL1到IRAM中,所以romcode中肯定存在Booting Devices的驱动。

在编译u-boot时,可以编译出spl,那spl和u-boot的区别到底在哪里,这就需要我们分析一下u-boot中spl的编译过程


1. 根目录makefile分析

在编译u-boot时,在执行完make s5pv210_defconfig而生成对应的配置文件后,则可以通过执行make生成设备运行需要的bin文件。而执行make命令时,肯定会去根目录的Makefile中执行。

all: .binman_stamp inputs

起始目标为all,通过上述代码可以看出该目标依赖于inputs,其生成规则如下:

inputs: $(INPUTS-y)

通过代码可以看出inputs依赖于$(INPUTS-y),其中INPUTS-y作为一个变量,里面包含多个内容,代码如下:

INPUTS-y += u-boot.srec u-boot.bin u-boot.sym System.map \
			binary_size_check
INPUTS-$(CONFIG_SPL) += spl/u-boot-spl.bin

从上述代码中可以看出,要想在编译u-boot时生成spl,则需要将宏CONFIG_SPL定义
spl/u-boot-spl.bin的生成规则在根目录中进行了定义

spl/u-boot-spl.bin: spl/u-boot-spl
	@:
	$(SPL_SIZE_CHECK)

spl/u-boot-spl: tools prepare \
		$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) \
		$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_TPL_OF_PLATDATA),dts/dt.dtb)
	$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all

从上面的代码可以看出,spl/u-boot-spl.bin依赖于spl/u-boot-spl,而spl/u-boot-spl在依赖全部满足的条件下,生成的规则则是执行scripts/Makefile.spl中的all目标。因此需要跳转到Makefile.spl中去确认一下spl/u-boot-spl的生成过程

2. Makefile.spl

二、uboot20 s5pv210移植—SPL编译分析_第2张图片

查看Makefile.spl文件中的内容,all目标的生成依赖于$(INPUTS-y)

all:	$(INPUTS-y)

与根目录的操作方法如出一辙,需要确认INPUTS-y变量中包含哪些内容,相关代码如下:

SPL_BIN := u-boot-spl
INPUTS-y	+= $(obj)/$(SPL_BIN).bin

ifdef CONFIG_SAMSUNG
INPUTS-y	+= $(obj)/$(BOARD)-spl.bin
endif

从代码中可以看出,INPUTS-y中至少包含一个文件即spl/u-boot-spl.bin,而如果定义了CONFIG_SAMSUNG的话,则会多一个与board相关的spl/s5pv210-spl.bin文件,因为s5pv210是samsung的开发板,则INPUTS-y实际是包含这两个内容的。
根据代码中的层层推导,先确认spl/u-boot-spl.bin的生成依赖关系

# spl/u-boot-spl.bin依赖spl/u-boot-spl-nodtb.bin
$(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-nodtb.bin FORCE
	$(call if_changed,copy)

# spl/u-boot-spl-nodtb.bin依赖spl/u-boot-spl
$(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE
	$(call if_changed,objcopy)

# spl/u-boot-spl依赖多个目标
$(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \
		$(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
	$(call if_changed,u-boot-spl)

从上述代码可以看出,为了生成spl/u-boot-spl.bin文件,最终依赖于多个变量的内容和链接脚本。对依赖的内容依次分析:

  1. $(u-boot-spl-platdata)
    该变量在Makefile.spl中通过宏控制被赋值如下:

    ifdef CONFIG_SPL_OF_PLATDATA
    u-boot-spl-platdata := $(obj)/dts/dt-platdata.o
    endif
    

    这个宏如果没有定义的话,是不会对该变量赋值的,也就是说该变量为空。宏CONFIG_SPL_OF_PLATDATA与dts相关,在spl中由于IRAM有限,不会开启dts相关的功能,则此宏也不会配置,从而u-boot-spl-platdata为空

  2. $(u-boot-spl-init)

    head-y		:= $(addprefix $(obj)/,$(head-y))
    u-boot-spl-init := $(head-y)
    

    从上述代码中可以看出Makefile.spl中的head-y的值则是在先前head-y的值前面添加前缀spl,而head-y之前的值,则是在arch/arm/Makefile中进行的赋值,即head-y := arch/arm/cpu/armv7/start.o。最终,在Makefile.spl文件中,spl/u-boot-spl.bin的生成则是依赖于spl/arch/arm/cpu/armv7/start.o

  3. $(u-boot-spl-main)

    HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n)
    
    libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
    libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
    libs-y += common/init/
    libs-y += drivers/
    libs-y += dts/
    libs-y += fs/
    libs-y		:= $(addprefix $(obj)/,$(libs-y))
    libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
    u-boot-spl-main := $(libs-y)
    

    从代码中可以看出,u-boot-spl-main中包含多个built-in.o文件。至少包含以下内容

    u-boot-spl-main := spl/board/samsung/common/built-in.o spl/common/init/built-in.o spl/drivers/built-in.o spl/dts/built-in.o spl/fs/built-in.o
    
  4. $(obj)/u-boot-spl.lds

    $(obj)/u-boot-spl.lds: $(LDSCRIPT) FORCE
    	$(call if_changed_dep,cpp_lds)
    

    从代码中可以看出,lds文件依赖于变量LDSCRIPT。代码内容如下:

    # Linker Script
    # First test whether there's a linker-script for the specific stage defined...
    ifneq ($(CONFIG_$(SPL_TPL_)LDSCRIPT),)
    # need to strip off double quotes
    LDSCRIPT := $(addprefix $(srctree)/,$(CONFIG_$(SPL_TPL_)LDSCRIPT:"%"=%))
    else
    # ...then fall back to the generic SPL linker-script
    ifneq ($(CONFIG_SPL_LDSCRIPT),)
    # need to strip off double quotes
    LDSCRIPT := $(addprefix $(srctree)/,$(CONFIG_SPL_LDSCRIPT:"%"=%))
    endif
    endif
    ifeq ($(wildcard $(LDSCRIPT)),)
    	LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot-spl.lds
    endif
    ifeq ($(wildcard $(LDSCRIPT)),)
    	LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot-spl.lds
    endif
    ifeq ($(wildcard $(LDSCRIPT)),)
    	LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot-spl.lds
    endif
    ifeq ($(wildcard $(LDSCRIPT)),)
    $(error could not find linker script)
    endif	
    

    分析以上代码,显示判断是否通过宏CONFIG_SPL_LDSCRIPT指定了链接脚本,如果没有指定的话,则依次去如下位置寻找,直至找到:

    1. board/samsung/s5pv210/u-boot-spl.lds
    2. arch/arm/cpu/armv7/u-boot-spl.lds
    3. arch/arm/cpu/u-boot-spl.lds

    最终,是将变量赋值为了arch/arm/cpu/u-boot-spl.lds

至此,生成spl/u-boot-spl的依赖全部分析完成,查看spl/u-boot-spl的生成规则

$(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \
		$(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
	$(call if_changed,u-boot-spl)

可以确定$(call if_changed,u-boot-spl)是执行cmd_u-boot-spl,而该命令的内容如下:

# Rule to link u-boot-spl
# May be overridden by arch/$(ARCH)/config.mk
quiet_cmd_u-boot-spl ?= LD      $@
      cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \
		       $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \
		       $(patsubst $(obj)/%,%,$(u-boot-spl-main))  \
		       $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \
		       --end-group \
		       $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))

大概的操作则是进入spl/目录,通过交叉编译工具链的ld命令,按照lds链接脚本,将u-boot-spl-initu-boot-spl-mainu-boot-spl-platdata链接到一起,生成u-boot-spl文件。
从而,获取了s5pv210在IRAM中需要用到的spl的elf文件,获取elf文件,则bin文件就唾手可得了。


总结

  • s5pv210中spl.bin的生成使用了与DRAM中u-boot.bin不同的链接脚本,且链接的文件也有差别。

!!!上述的代码只是纸上谈兵,直接分析的代码,没有进行任何实际操作。这算是在移植前的自我疑惑解答,让自己大致了解spl.bin在u-boot中是怎么生成的。

你可能感兴趣的:(U-Boot,u-boot,spl,bootloader)