[uboot] (Chapter 2) uboot process-uboot-spl compilation process

Keywords: Makefile Linux Linker shell

Links to the original text: https://blog.csdn.net/ooonebook/article/details/52949584

The following examples take project X project tiny210 (s5pv210 platform, armv7 architecture) as an example

[uboot] uboot process series:
[project X] tiny210(s5pv210) power-on start-up process (BL0-BL2)

It is suggested that we first look at the "project X] tiny210(s5pv210) power-on start-up process (BL0-BL2)", and learn about the BL0 BL1 BL2 stage after power-on, as well as the operation position and function of each stage according to an example.

=================================================================================

1. uboot-spl compilation and file generation

The compilation of spl is part of the compilation of uboot, and uboot.bin follows two compilation processes, which should be paid attention to.
Normally, the body uboot, or uboot.bin. is compiled first, and then uboot-spl, or uboot-spl.bin, is compiled. Although the compilation commands are together, the compilation process is separate.

1. Compilation method

In the project X project, all mirrors, including uboot, kernel and rootfs, are compiled in the build directory. Specifically refer to the implementation of Makefile built by this project.
Assuming config has been configured, compile commands in build as follows:

make uboot
  • 1

The corresponding commands in Makefile are as follows:

BUILD_DIR=$(shell pwd)
OUT_DIR=$(BUILD_DIR)/out
UBOOT_OUT_DIR=$(OUT_DIR)/u-boot
UBOOT_DIR=$(BUILD_DIR)/../u-boot
uboot:
        mkdir -p $(UBOOT_OUT_DIR)
        make -C $(UBOOT_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(UBOOT_OUT_DIR) $(BOARD_NAME)_defconfig
        make -C $(UBOOT_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(UBOOT_OUT_DIR)
## - C $(UBOOT_DIR) specifies that make should be executed under.. / uboot, which is the code root directory of uboot.
## CROSS_COMPILE=$(CROSS_COMPILE) specifies a cross-compiler
## KBUILD_OUTPUT=$(UBOOT_OUT_DIR) specifies that the final compiled output directory is build/out/u-boot.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Ultimately, it is equivalent to entering the uboot directory and performing the make action.
That is to say, the compilation of spl is a part of compiling uboot, and uboot.bin goes through two compilation processes, which should be paid attention to.
Normally, the body uboot, or uboot.bin. is compiled first, and then uboot-spl, or uboot-spl.bin, is compiled. Although the compilation commands are together, the compilation process is separate.

2. Generating files
After the final compilation is completed, the following files are generated under project-x/build/out/u-boot/spl:

arch   common   dts  include          u-boot-spl      u-boot-spl.cfg  u-boot-spl.map
board  drivers  fs   tiny210-spl.bin  u-boot-spl.bin  u-boot-spl.lds  u-boot-spl-nodtb.bin
  • 1
  • 2

arch, common, dts, include, board, drivers, fs are compiled directories of the corresponding code. Build.o is generated in each directory, which is connected by the target files in the same directory.
Focus on the following documents:

file Explain
u-boot-spl spl file obtained after preliminary links
u-boot-spl-nodtb.bin On the basis of u-boot-spl, the executable program after objcopy removes symbol table information
u-boot-spl.bin Without dtb, it is copied directly from u-boot-spl-nodtb.bin, which is the ultimate goal of compiling spl.
tiny210-spl.bin Depending on the s5pv210 platform, a 16B header is added to the u-boot-spl.bin for verification.
u-boot-spl.lds spl connection script
u-boot-spl.map Symbol table file after connection
u-boot-spl.cfg Files generated by spl configuration

2. uboot-spl compilation process

1. Compiling the whole process

According to the documentation of zero and 2, the simple process is as follows:
(1) Generation of build-in.o in each directory

Created with Rapha l 2.1.0 source file, code file compilation, assembly object file and directory object file connection build-in object file

Realization of Correspondence 2 and 2(5)
(2) Generating u-boot-spl by connecting all built-in.o scripts with u-boot-spl.lds

Created with Rapha l 2.1.0 build-in object file with u-boot-spl.lds as connection script for unified connection u-boot-spl

Realization of Correspondence 2 and 2(4)
(3) Generating u-boot-spl-nodtb.bin from u-boot-spl

Created with Rapha l 2.1.0u-boot-splobjcopy action removes the symbol information table u-boot-spl-nodtb.bin

Realization of Correspondence 2 and 2(3)
(4) u-boot-spl-nodtb.bin is generated from u-boot-spl-nodtb.bin, which is the bin file of spl.

Created with Rapha l 2.1.0u-boot-spl-nodtb.bin and duplicated u-boot-spl.bin without dtb

Realization of Correspondence 2 and 2(2)

The core process of subsequent compilation is to follow the four steps mentioned above.

2. Analysis of specific compilation process

We analyze the entire compilation process directly from the make uboot command, that is, from the dependencies of Makefile under uboot.
Note that the order of analysis is inverse to that of the overall compilation process described above.

  • (1) Entrance analysis
    In project-x/u-boot/Makefile
all:            $(ALL-y)

ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
## When CONFIG_SPL is configured, spl/u-boot-spl.bin is executed when make

spl/u-boot-spl.bin: spl/u-boot-spl
        @:
spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
        $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
## obj=spl generates spl directory under out/u-boot directory
## - f $(srctree)/scripts/Makefile.spl specifies that the Makefile executed is scripts/Makefile.spl
## All is equivalent to make. The goal of all is
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

To sum up, it's CONFIG_SPL that decides whether to compile a spl file, or BL1.
The subsequent equivalent is to execute the "make-f u-boot/scripts/Makefile.spl obj=spl all" command.
In project-x/u-boot/scripts/Makefile.spl,

SPL_BIN := u-boot-spl
ALL-y   += $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg
## So the ultimate goal is spl/u-boot-spl.bin and spl/u-boot-spl.cfg.
  • 1
  • 2
  • 3

The dependencies of spl/u-boot-spl.bin are established in project-x/u-boot/scripts/Makefile.spl. The main body of the subsequent make process is in Makefile.spl.

  • (2) Dependency of spl/u-boot-spl.bin

In project-x/u-boot/scripts/Makefile.spl

$(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-nodtb.bin FORCE
        $(call if_changed,copy)
## The $(obj)/$(SPL_BIN).bin depends on $(obj)/$(SPL_BIN)-nodtb.bin.
## Call if_changed, copy means that when the dependent file changes, the dependent file is copied directly as the target file, that is, $(obj)/$(SPL_BIN)-nodtb.bin is copied directly as $(obj)/$(SPL_BIN).
  • 1
  • 2
  • 3
  • 4

As mentioned above, the Makefile code spl/u-boot-spl.bin relies on spl/u-boot-spl-nodtb.bin and is copied from spl/u-boot-spl-nodtb.bin.
It corresponds to the above two and one (4) processes.

  • (3) Dependency of spl/u-boot-spl-nodtb.bin
    In project-x/u-boot/scripts/Makefile.spl
$(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE
        $(call if_changed,objcopy)
$(obj)/$(SPL_BIN)-nodtb.bin Dependence on $(obj)/$(SPL_BIN). that is spl/u-boot-spl-nodtb.bin Dependence on spl/u-boot-spl.
## The $(call if_changed,objcopy) indicates that when the dependent file changes, the dependent file will be objcopy processed to get the target file.
## That is to say, spl/u-boot-spl symbolic information and some useless information are removed by objcopy, and spl/u-boot-spl-nodtb.bin is obtained.
  • 1
  • 2
  • 3
  • 4
  • 5

As mentioned above, the Makefile code spl/u-boot-spl-nodtb.bin relies on spl/u-boot-spl and is obtained by spl/u-boot-spl after objcopy operation.
It corresponds to the two and one (3) processes mentioned above.

  • (4) Dependency of spl/u-boot-spl
    In project-x/u-boot/scripts/Makefile.spl
$(obj)/$(SPL_BIN): $(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) to generate the target
## (call if_changed,u-boot-spl) corresponds to the cmd_u-boot-spl command
  • 1
  • 2
  • 3
  • 4

As mentioned above, spl/u-boot-spl depends on $(u-boot-spl-init), $(u-boot-spl-main) and spl/u-boot-spl.ld, and eventually calls cmd_u-boot-spl to generate spl/u-boot-spl.
cmd_u-boot-spl is implemented as follows:

quiet_cmd_u-boot-spl = LD      $@
      cmd_u-boot-spl = (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
                       $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \
                       $(patsubst $(obj)/%,%,$(u-boot-spl-main)) --end-group \
                       $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))
  • 1
  • 2
  • 3
  • 4
  • 5

Print out cmd_u-boot-spl by echo command and get the following (split out to see):

cmd_u-boot-spl=(
cd spl && 
/build/arm-none-linux-gnueabi-4.8/bin/arm-none-linux-gnueabi-ld   
-T u-boot-spl.lds  --gc-sections -Bstatic --gc-sections 
arch/arm/cpu/armv7/start.o 
--start-group 
arch/arm/mach-s5pc1xx/built-in.o arch/arm/cpu/armv7/built-in.o arch/arm/cpu/built-in.o arch/arm/lib/built-in.o board/samsung/tiny210/built-in.o board/samsung/common/built-in.o common/init/built-in.o drivers/built-in.o dts/built-in.o fs/built-in.o 
--end-group 
arch/arm/lib/eabi_compat.o 
-L /home/disk3/xys/temp/project-x/build/arm-none-linux-gnueabi-4.8/bin/../lib/gcc/arm-none-linux-gnueabi/4.8.3 -lgcc 
-Map u-boot-spl.map 
-o u-boot-spl)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

It can be seen that the above is a connection command, spl/u-boot-spl.ld as a link script, connect the specified target files of $(u-boot-spl-init), $(u-boot-spl-main) to u-boot-spl.
The important thing about connections is the connection identifier, which is the definition of $(LD)$(LDFLAGS)$(LDFLAGS_$(@F).
Trying to print out $(LD)$(LDFLAGS)$(LDFLAGS__(@F)), the results are as follows:

LD=/home/disk3/xys/temp/project-x/build/arm-none-linux-gnueabi-4.8/bin/arm-none-linux-gnueabi-ld
LDFLAGS=
LDFLAGS_u-boot-spl=-T u-boot-spl.lds --gc-sections -Bstatic --gc-sections
## $(LDFLAGS_$(@F) corresponds to LDFLAGS_u-boot-spl
  • 1
  • 2
  • 3
  • 4

That is to say, the link script is specified in LDFLAGS_u-boot-spl.
Focus on the origin of $(LDFLAGS_$(@F))

## @ F is an automated variable that extracts the file name of the target, such as $(obj)/$(SPL_BIN), or spl/u-boot-spl. Then @F is u-boot-spl.
## So LDFLAGS_$(@F) is LDFLAGS_u-boot-spl.
## Definitions are as follows
LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SPL_TEXT_BASE),)
LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE)
endif
## When you specify CONFIG_SPL_TEXT_BASE, the connection address is configured. In the tiny210 project, because spl is an address-independent code design, there is no connection address set.

## The $(LDFLAGS_FINAL) is defined in the following places
## ./config.mk:19:LDFLAGS_FINAL :=
## ./config.mk:80:LDFLAGS_FINAL += -Bstatic
## ./arch/arm/config.mk:16:LDFLAGS_FINAL += --gc-sections
## ./scripts/Makefile.spl:43:LDFLAGS_FINAL += --gc-sections
## To sum up: Finally, LDFLAGS_u-boot-spl=-Tu-boot-spl.lds -- gc-sections-Bstatic -- gc-sections can understand.
## Correspond to the above two, 1 (2) processes.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • (5) u-boot-spl-init & u-boot-spl-main dependencies (how code is compiled)
    Let's take a look at the two values printed out first.
u-boot-spl-init=spl/arch/arm/cpu/armv7/start.o

u-boot-spl-main= spl/arch/arm/mach-s5pc1xx/built-in.o spl/arch/arm/cpu/armv7/built-in.o spl/arch/arm/cpu/built-in.o spl/arch/arm/lib/built-in.o spl/board/samsung/tiny210/built-in.o 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
  • 1
  • 2
  • 3

You can see the path of a bunch of target files. These target files will eventually be connected to u-boot-spl.
The definition of u-boot-spl-init & u-boot-spl-main is as follows:
project-x/u-boot/scripts/Makefile.spl

u-boot-spl-init := $(head-y)
head-y          := $(addprefix $(obj)/,$(head-y))
## Adding spl path
## . / arch/arm/Makefile is defined as follows:
## head-y := arch/arm/cpu/$(CPU)/start.o

u-boot-spl-main := $(libs-y)
libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
libs-y += common/init/
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ cmd/
libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
libs-y += drivers/
libs-y += dts/
libs-y += fs/ 
libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/
libs-$(CONFIG_SPL_NET_SUPPORT) += net/
libs-y          := $(addprefix $(obj)/,$(libs-y))
## Adding spl path
u-boot-spl-dirs := $(patsubst %/,%,$(filter %/, $(libs-y)))
## Note here that u-boot-spl-dir is defined when libs-y is not suffixed with build-in.o.
libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
## Add build-in.o file suffix
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

So how is u-boot-spl-init & u-boot-spl-main generated?
Need to look at the corresponding dependencies as follows:

$(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ;
## That is to say, $(u-boot-spl-init)$(u-boot-spl-main) depends on $(u-boot-spl-dirs) 
## The sort function sorts by initials and removes duplicates.
## u-boot-spl-dirs := $(patsubst %/,%,$(filter %/, $(libs-y)))
## The $(filter%/, $(libs-y) filters out the string at the end of'/'. Note that at this time the $(libs-y) content has not been suffixed with the build-in.o file.
## patsubst removes the last'/'character from the string.
## Finally, u-boot-spl-dirs is printed as follows:
## u-boot-spl-dirs=spl/arch/arm/mach-s5pc1xx spl/arch/arm/cpu/armv7 spl/arch/arm/cpu spl/arch/arm/lib spl/board/samsung/tiny210 spl/board/samsung/common spl/common/init spl/drivers spl/dts spl/fs
## That's from libs-y.

## The dependency rules of $(u-boot-spl-dirs) are as follows:
$(u-boot-spl-dirs):
        $(Q)$(MAKE) $(build)=$@
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

That is to say, make $(build) = target file is executed for each target file in turn.
The definition of $(build) is as follows:
project-x/u-boot/scripts/Kbuild.include

build := -f $(srctree)/scripts/Makefile.build obj
  • 1

Take arch/arm/mach-s5pc1xx as an example
"$(MAKE)$(build)=$@" is expanded in the following format
make -f ~/code/temp/project-x/u-boot/scripts/Makefile.build obj=spl/arch/arm/mach-s5pc1xx.

Makefile.build defines build-in.o,.lib and the generation rules of the target file.o. This Makefile file generates subdirectory. lib, build-in. o, and target file. o.
Makefile.build's first compilation goal is _build, as follows

PHONY := __build
__build:
## So the goal of _build will be compiled and executed directly, depending on the following
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
         $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
         $(subdir-ym) $(always)
        @:
## Related to build-in.o is the dependency on builtin-target. Let's look at this dependency.

builtin-target := $(obj)/built-in.o
## Take obj=spl/arch/arm/mach-s5pc1xx as an example, then built in-target is spl/arch/arm/mach-s5pc1xx/build-in.o.

## The dependencies are as follows:
$(builtin-target): $(obj-y) FORCE
        $(call if_changed,link_o_target)
## The $(call if_changed,link_o_target) connects all dependencies to the $(built in-target), which is the corresponding build-in.o.
## Specific implementation can see the implementation of cmd_link_o_target, which is not explained in detail here.


## So where does $(obj-y) come from? It is derived from include in Makefile under the corresponding directory.
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
## When obj=spl/arch/arm/mach-s5pc1xx, the corresponding kbuild-file=u-boot/arch/arm/mach-s5pc1xx/Makefile is obtained.
## In u-boot/arch/arm/mach-s5pc1xx/Makefile, obj-y is defined as follows:
## obj-y   = cache.o
## obj-y   += reset.o
## obj-y   += clock.o
## Corresponding to obj-y corresponds to some target files, compiled from C files, which is not explained here.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

It corresponds to the two and one (1) processes mentioned above.

  • (6) spl/u-boot-spl.lds dependencies
    The main purpose here is to find a matching connection file.
$(obj)/u-boot-spl.lds
$(obj)/u-boot-spl.lds: $(LDSCRIPT) FORCE
        $(call if_changed_dep,cpp_lds)
## Depending on $(LDSCRIPT), the $(LDSCRIPT) defines the location of the connection script.
## The link script is then copied into $(obj)/u-boot-spl.lds, or spl/u-boot-spl.lds, after cpp_lds processing.
## The specific implementation of cpp_lds processing is to see the definition of cmd_cpu_lds, which is to expand the macro definition in the corresponding connection script.

## The definition of $(LDSCRIPT) is as follows
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
## That is to say, search u-boot-spl.lds files from board/board directory, cpudir directory, arch/architecture/cpu/directory in turn.
## For example, tiny210(s5vp210 armv7) will eventually search for u-boot-spl.lds under. / arch/arm/cpu/.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

In summary, project-X/u-boot/arch/arm/cpu/u-boot-spl.lds is finally designated as the connection script.

III. Some Key Definitions

  • 1,CONFIG_SPL
    It is explained in two and two (1).
    Used to specify whether SPL needs to be compiled, that is, whether uboot-spl.bin files need to be compiled

  • 2. Location of connection scripts
    It is explained in two and two (6).
    For tiny210(s5pv210 armv7), the location of the connection script is
    project-x/u-boot/arch/arm/cpu/u-boot-spl.lds

  • 3,CONFIG_SPL_TEXT_BASE
    It is explained in two and two (4).
    Used to specify the connection address of SPL, it can be defined in the config file corresponding to the board.

  • 4,CONFIG_SPL_BUILD
    During compiling spl, it is configured
    The following are defined in project-x/scripts/Makefile.spl

KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD
  • 1

That is to say, in the process of compiling uboot-spl.bin, the macro CONFIG_SPL_BUILD is defined.

IV. Explanation of uboot-spl link script

1. Overall analysis of connection scripts

Relatively simple, look directly at the content of the connection script project-x/u-boot/arch/arm/cpu/u-boot-spl.lds
There's a previous article on analysis of connection scripts< [kernel Startup Process] Previous Chapter: Analysis of vmlinux.lds You can refer to it.

ENTRY(_start)
//The address of _start is defined, so the analysis code starts with this function!!!
SECTIONS
{
    . = 0x00000000;

//Define text segments as follows
    . = ALIGN(4);
    .text :
    {
        __image_copy_start = .;
//Define _image_copy_start as the current address
        *(.vectors)
//The vectors segment of all the target files, i.e. the interrupt vector table, is connected here
        CPUDIR/start.o (.text*)
//The. text section of the start.o file is linked here
        *(.text*)
//Link to the. text section of all the target files here
    }

//Define read-only data segments as follows
    . = ALIGN(4);
    .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

//Define data segments as follows
    . = ALIGN(4);
    .data : {
        *(.data*)
//Link to the. data section of all the target files here
    }

//The u_boot_list segment is defined below, and the specific function is unknown.
    . = ALIGN(4);
    .u_boot_list : {
        KEEP(*(SORT(.u_boot_list*)));
    }

    . = ALIGN(4);

    __image_copy_end = .;
//Define the address of the _image_copy_end symbol as the current address
//The range from _image_copy_start to _image_copy_end contains code and data segments.

//The rel.dyn section is defined below, which is used when redirecting uboot resources. It will be explained later.
    .rel.dyn : {
        __rel_dyn_start = .;
//Define the address of the _rel_dyn_start symbol as the current address, which will be used later in the code
        *(.rel*)
        __rel_dyn_end = .;
//Define the address of the _rel_dyn_end symbol as the current address, which will be used later in the code
//The interval from _rel_dyn_start to _rel_dyn_end should be used in the process of code redirection, which will be explained later.
    }

    .end :
    {
        *(.__end)
    }

    _image_binary_end = .;
//Define the address of the _image_binary_end symbol as the current address

//Define the bss segment as follows
    .bss __rel_dyn_start (OVERLAY) : {
        __bss_start = .;
        *(.bss*)
         . = ALIGN(4);
        __bss_end = .;
    }
    __bss_size = __bss_end - __bss_start;
    .dynsym _image_binary_end : { *(.dynsym) }
    .dynbss : { *(.dynbss) }
    .dynstr : { *(.dynstr*) }
    .dynamic : { *(.dynamic*) }
    .hash : { *(.hash*) }
    .plt : { *(.plt*) }
    .interp : { *(.interp*) }
    .gnu : { *(.gnu*) }
    .ARM.exidx : { *(.ARM.exidx*) }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

2. Symbols in Symbol Table

project-x/build/out/u-boot/spl/u-boot-spl.map

Linker script and memory map 
.text           0x00000000      0xd10
                0x00000000                __image_copy_start = . 
 *(.vectors)
                0x00000000                _start
                0x00000020                _undefined_instruction
                0x00000024                _software_interrupt
                0x00000028                _prefetch_abort
                0x0000002c                _data_abort
                0x00000030                _not_used
                0x00000034                _irq
                0x00000038                _fiq
...
                0x00000d10                __image_copy_end = .
.rel.dyn        0x00000d10        0x0
                0x00000d10                __rel_dyn_start = .
 *(.rel*)
 .rel.iplt      0x00000000        0x0 arch/arm/cpu/armv7/start.o
                0x00000d10                __rel_dyn_end = .
.end
 *(.__end)
                0x00000d10                _image_binary_end = .

.bss            0x00000d10        0x0
                0x00000d10                __bss_start = .
 *(.bss*)
                0x00000d10                . = ALIGN (0x4)
                0x00000d10                __bss_end = .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Focus on
* __image_copy_start & __image_copy_end
It defines the location of the code to be used when redirecting the code, and then encounters reanalysis.
* _start
In u-boot-spl.lds, ENTRY(_start) specifies that the entry function of the code is _start. So that's where we start when we analyze the code later.
* __rel_dyn_start & __rel_dyn_end
* _image_binary_end

5. Additional operations of tiny210 (s5pv210)

1. Why does spl of tiny210 require additional operation? What additional operations are required?

It is suggested to refer to the article "Project X tiny210 (s5pv210) Power-on Startup Process (BL0-BL2)".
tiny210 only supports SD boot mode and NAND FLASH boot mode.
From the article "project X] tiny210(s5pv210) boot-up process (BL0-BL2)", we have learned that when using SD boot mode and NAND FLASH boot mode, that is, when BL1 image is stored on SD or NAND flash, the BL0 solidified in s5pv210 needs to check the first 16B header of BL1. BL1 is what we call uboot-spl.bin, but the default compiled uboot-spl.bin is a pure executable file without a special header.
Therefore, we need to generate tiny210-spl.bin after generating uboot-spl.bin and adding a 16B header to it.
The header format of 16B is as follows:

address data
0xD002_0000 The BL1 image includes the length of the header
0xD002_0004 Reserve, set to 0
0xD002_0008 BL1 Mirror Removal header Checksum
0xD002_000c Reserve, set to 0

2. How to generate header? (How to generate tiny210-spl.bin)

project-x/u-boot/scripts/Makefile.spl

ifdef CONFIG_SAMSUNG
ALL-y   += $(obj)/$(BOARD)-spl.bin
endif
## When the platform is a SAMSUNG platform, that is, when CONFIG_SAMSUNG is defined, it is necessary to generate the corresponding board-level spl.bin file, such as tiny210, the corresponding spl/tiny210-spl.bin file should be generated.

ifdef CONFIG_S5PC110
$(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin
        $(objtree)/tools/mks5pc1xxspl $< $@
## If it's a cpu of S5PC110 series, use the header method as above. tiny210's cpu is s5pv210, belonging to the S5PC110 series, so this is the way to go.
## $(objtree)/tools/mks5pc1xxspl corresponds to build/out/u-boot/tools/mks5pc1xxspl generated when uboot is compiled
## Its code path is located in u-boot/tools/mks5pc1xspl.c. According to the header rules of s5pc1xx series, it adds 16B header to the input bin file, with specific reference code.
## This constitutes the process from u-boot-spl.bin to tiny210-spl.bin.
else
$(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin
        $(if $(wildcard $(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl),\
        $(objtree)/spl/board/samsung/$(BOARD)/tools/mk$(BOARD)spl,\
        $(objtree)/tools/mkexynosspl) $(VAR_SIZE_PARAM) $< $@
endif
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

This constitutes the process from u-boot-spl.bin to tiny210-spl.bin.

In summary, the compilation of spl is completed.

Posted by SN1P3R_85 on Mon, 26 Aug 2019 23:20:44 -0700