Analyzing the startup code has always been a small ideal for me. I couldn't find a method for a long time. Later I read some basic books and finally got started with some videos, therefore, I also want to analyze some experiences and see if my friends have problems in some aspects.
A little gossip, the following analysis, here first download the u-boot-1.1.6 version, Do not be scared by the code, as long as we know that the learning process is nothing terrible, analysis U-boot first analysis makefile, it is recommended that you open two books, makefile programming and advanced bash Script Programming Guide. If you have perseverance, you can read these books. Here I want to use them as two dictionaries, we can find something we can't understand to improve our learning efficiency.
After opening the file, we start to analyze it gradually
# Explain the uboot version
# Major version number
Version = 1
# Patch version number
Patchlevel = 1
# Sub-version number
Sublevel = 6
# Extended version number
Extraversion =
# Define version Variables
U_boot_version = $ (Version). $ (patchlevel). $ (sublevel) $ (extraversion)
We recommend that you take a look at the variable section in the advanced bash Script Programming Guide.
OBJ is defined later
Version_file = $ (OBJ) include/version_autogenerated.h
# Uname-M Output Processor Architecture name
# SED is generally used for filtering.-e multiple sed Command Options. S/RE/string replaces the regular expression re with string.
#: = Assign a value once when a function is called. = if a variable is called, The invoke function must be called.
# = Is like the version_file definition above. OBJ can be defined below.
Hostarch: =$ (shell uname-M | \
Sed-e s/I .86/i386 /\
-E s/sun4u/sparc64 /\
-E s/arm. */ARM /\
-E s/sa110/ARM /\
-E s/PowerPC/PPC /\
-E s/macppc/PPC /)
# The parameters following the tr conversion command are regular expressions, which convert all uppercase and lowercase characters
# \ (\) Regular Expression
# Cygwin application platform. We don't need to worry about using Linux here.
Hostos: = $ (shell uname-S | tr '[: Upper:] ''[: lower:]' | \
Sed-E's/\ (cygwin \). */cygwin /')
# Export environment variables
Export hostarch Hostos
# Conflict processing needs to be defined for the Shell version tcsh
# Deal with colliding definitions from tcsh etc.
Vendor =
# Make target file location definition, (1) make o = Dir (2) Set build_dir = dir
# Export build_dir =/tmp/build directly./makeall
# Whether the origin is a function and O is a command line parameter
Ifdef o
Ifeq ("$ (Origin O)", "command line ")
Build_dir: = $ (o)
Endif
Endif
# If build_dir is not empty, set the value to saved-output.
Ifneq ($ (build_dir ),)
Saved-output: = $ (build_dir)
# Attempt to create a output directory.
# Create an output target file directory
# | If the logic or the previous one is true, the subsequent one will not be executed.
# [-D $ {build_dir}] is a judgment statement. If
# (Mkdir)-P is automatically created even if the parent directory does not exist.
$ (Shell [-d $ {build_dir}] | mkdir-p $ {build_dir })
# Enter the Directory and run the PWD command to check whether build_dir exists.
Build_dir: = $ (shell CD $ (build_dir) &/bin/pwd)
# If three-stage judgment if (a, B, c) A is false execution B, B is false execution C
$ (If $ (build_dir), $ (error output directory "$ (saved-output)" does not exist ))
Endif # ifneq ($ (build_dir ),)
# Target tree
# Curdir is the built-in variable of makefile and the value is the current directory.
Objtree: =$ (if $ (build_dir), $ (build_dir), $ (curdir ))
# Source code tree
Srctree: = $ (curdir)
# Source code tree
Topdir: = $ (srctree)
# Target tree
Lndir: = $ (objtree)
# Export environment variables
Export topdir srctree objtree
# Define mkconfig to point to a script
Mkconfig: = $ (srctree)/mkconfig
# Export
Export mkconfig
# If the target path and source code path are defined as remote_build = 1
Ifneq ($ (objtree), $ (srctree ))
Remote_build: = 1
Export remote_build
Endif
# $ (OBJ) and (SRC) are defined in config. mk and the values of these two variables are specified.
Ifneq ($ (objtree), $ (srctree ))
OBJ: = $ (objtree )/
SRC: = $ (srctree )/
Else
OBJ: =
SRC: =
Endif
Export OBJ SRC
# The wildcard function looks for the same file name as config. mk. If the file name is the same, run the following command:
Ifeq ($ (objtree)/include/config. mk, $ (wildcard $ (objtree)/include/config. mk ))
# Import arch, board, and CPU configuration information (architecture, hardware board, and CPU)
# Here, stop reading the makefile and convert it to the $ (objtree)/include/config. mk file. After reading it, return -_-,
# Export the obtained arch CPU board vendor SOC Value
Include $ (objtree)/include/config. mk
Export arch CPU board vendor SOC
# Define cross-Compilation
Ifndef cross_compile
Ifeq ($ (hostarch), PPC)
Cross_compile =
Else
Ifeq ($ (ARCH), PPC)
Cross_compile = PowerPC-Linux-
Endif
Ifeq ($ (ARCH), arm)
Cross_compile = arm-Linux-
Endif
Ifeq ($ (ARCH), i386)
Ifeq ($ (hostarch), i386)
Cross_compile =
Else
Cross_compile = i386-linux-
Endif
Endif
Ifeq ($ (ARCH), MIPS)
Cross_compile = mips_4kc-
Endif
Ifeq ($ (ARCH), NiO)
Cross_compile = nios-elf-
Endif
Ifeq ($ (ARCH), nios2)
Cross_compile = nios2-elf-
Endif
Ifeq ($ (ARCH), m68k)
Cross_compile = m68k-elf-
Endif
Ifeq ($ (ARCH), microblaze)
Cross_compile = Mb-
Endif
Ifeq ($ (ARCH), Blackfin)
Cross_compile = bfin-elf-
Endif
Ifeq ($ (ARCH), avr32)
Cross_compile = avr32-
Endif
Endif
Endif
# Export the Cross Compiler
Export cross_compile
# Load other configuration
# Import other configuration files
Include $ (topdir)/config. mk
######################################## #################################
# U-boot objects... order is important (I. e. Start must be first)
# The sequence of the target file required by U-boot is very important. Start. O must be placed first,
# Arrange the target file layout for different architectures and append the target file to different CPUs.
# This Code # defines variables. Different values are defined for variables based on different conditions.
# These variables are all compiled later
# When, written to the running command parameters, the significance of these variables, as well as the meaning of various parameters, you can view the corresponding
# The parameter manual of the tool is obtained, which has little to do with porting.
# Note the order in which variable values are added. The first variable is added. during compilation, replace the variable.
# Will be put in front, and then compiled, connected, and so on. We can see that the first execution is start. O.
# Content in this file, which is generated by START. s
# Different CPUs load different targets for compilation
Objs = CPU/$ (CPU)/start. o
Ifeq ($ (CPU), i386)
Objs + = CPU/$ (CPU)/start16.o
Objs + = CPU/$ (CPU)/reset. o
Endif
Ifeq ($ (CPU), ppc4xx)
Objs + = CPU/$ (CPU)/resetvec. o
Endif
Ifeq ($ (CPU), mpc83xx)
Objs + = CPU/$ (CPU)/resetvec. o
Endif
Ifeq ($ (CPU), mpc85xx)
Objs + = CPU/$ (CPU)/resetvec. o
Endif
Ifeq ($ (CPU), mpc86xx)
Objs + = CPU/$ (CPU)/resetvec. o
Endif
Ifeq ($ (CPU), BF533)
Objs + = CPU/$ (CPU)/start1.o CPU/$ (CPU)/interrupt. ocpu/$ (CPU)/cache. o
Objs + = CPU/$ (CPU)/cplbhdlr. o cpu/$ (CPU)/cplbmgr. ocpu/$ (CPU)/flush. o
Endif
# Add a prefix (OBJ path) for each directory)
Objs: =$ (addprefix $ (OBJ), $ (objs ))
# Loading static databases
Libs = lib_generic/libgeneric.
Libs + = Board/$ (boarddir)/Lib $ (board).
Libs + = CPU/$ (CPU)/Lib $ (CPU).
Ifdef SOC
Libs + = CPU/$ (CPU)/$ (SOC)/Lib $ (SOC).
Endif
Libs + = lib _ $ (ARCH)/Lib $ (ARCH).
Libs + = FS/cramfs/libcramfs. A fs/fat/libfat. A fs/fdos/libfdos. A fs/jffs2/libjffs2.a \
FS/reiserfs/libreiserfs. A fs/ext2/libext2fs.
Libs + = net/Libnet.
Libs + = Disk/libdisk.
Libs + = RTC/librtc.
Libs + = DTT/libdtt.
Libs + = Drivers/libdrivers.
Libs + = Drivers/NAND/libnand.
Libs + = Drivers/nand_legacy/libnand_legacy.a
Libs + = Drivers/sk98lin/libsk98lin.
Libs + = post/libpost. A post/CPU/libcpu.
Libs + = Common/libcommon.
Libs + = $ (boardlibs)
# Add a prefix (OBJ path) for each directory)
Libs: =$ (addprefix $ (OBJ), $ (libs ))
# Pseudo-target, which is used for parallel Recursion
. Phony: $ (libs)
# Add GCC lib
# Add a GCC Library
# Dirname: remove the path file name and only output the path
Platform_libs + =-L $ (shell dirname '$ (CC) $ (cflags)-print-libgcc-file-name')-lgcc
# The "Tools" are needed early, so put this first
# Don't include stuff already done in $ (libs)
# The content in the tools file needs to be stored in
# Do not include stuff, which has been done in $ (libs)
Subdirs = tools \
Examples \
Post \
Post/CPU
. Phony: $ (subdirs)
# Whether to configure the NAND uboot
Ifeq ($ (config_nand_u_boot), Y)
Nand_spl = nand_spl
# Target file name
U_boot_nand = $ (OBJ) u-boot-nand.bin
Endif
# The SUBST function replaces $ (OBJ) in $ (objs) with an empty value and assigns a value to _ objs.
_ Objs: = $ (SUBST $ (OBJ), $ (objs ))
# The SUBST function replaces $ (OBJ) in $ (libs) with an empty value and assigns a value to _ objs.
_ Libs: = $ (SUBST $ (OBJ), $ (libs ))
######################################## #################################
# Here is the target that defines various targets. The final goal we want is $ (OBJ) U-boot,
# Then let's look at the following: # It trusts many other goals, and then these goals are also defined here,
# Then there is the corresponding $ (make)
#. Therefore, a MAKEFILE file is implemented,
# Here we will introduce many other makefile files to compile the entire project.
######################################## #################################
# Define the target file generated by compilation
# If all is a pseudo target, the makefile automatically processes the first target. Here, compile all to indicate the target.
# If other pseudo targets are put behind them, you need to add the pseudo target name to make compilation.
All = $ (OBJ) u-boot.srec $ (OBJ) u-boot.bin $ (OBJ) system. Map $ (u_boot_nand)
# S-record format of u-boot.srec U-Boot Image
# Original binary format of u-boot.bin U-Boot Image
# System. Map U-boot image symbol table
######################################## ###########
# All three U-boot image formats can be burned to flash, but you need to check whether the loader can recognize these formats.
# General u-boot.bin is the most commonly used, download directly according to the binary format, and burn to flash according to the absolute address can be.
# U-boot and u-boot.srec format images are built-in positioning information.
ALL: $ (all)
# Copy u-boot.hex
# $ {Objcflags} in config. mk, objcflags + = -- gap-fill = 0xff
# $ The u-boot.hex copies the ihex format destination file from U-boot through (objcopy)
# In fact, it is to remove the ELF format from the header to the end and merge the segments.
# Objcopy is one of the GNU tool chains. It is mainly used to copy commands in different formats.
$ (OBJ) u-boot.hex: $ (OBJ) U-boot # ELF format
$ (Objcopy) $ {objcflags}-O ihex $ <$ @
# Copy same as u-boot.srec
$ (OBJ) u-boot.srec: $ (OBJ) U-boot
$ (Objcopy) $ {objcflags}-o srec $ <$ @
# Copy same as u-boot.bin
$ (OBJ) u-boot.bin: $ (OBJ) U-boot
$ (Objcopy) $ {objcflags}-O binary $ <$ @
# Use the u-boot.bin to compile the u-boot.img, the compressed image-C none indicates no compression
# Sed here is the replacement command S/, $ (OBJ) include/version_autogenerated.h. * u_boot_version replaces null
# Use-N and/P together to print the replaced rows
# Sed: "" is required if shell variables are used; otherwise, ''is used''
#-A specify the architecture
#-T specify the image type
#-C Compression
#-A specifies the address to load the image in memory
#-E image running entry point address
#-N specify the image name
#-D specifies the source file for Image Creation
$ (OBJ) u-boot.img: $ (OBJ) u-boot.bin
./Tools/mkimage-A $ (ARCH)-T Firmware-C none \
-A $ (text_base)-E 0 \
-N $ (shell sed-n-e's/. * u_boot_version // P' $ (version_file) | \
Sed-E's /"[
] * $/For $ (board) Board "/')\
-D $ <$ @
# Compile u-boot.dis
# Objdump (View A file similar to CAT)-D disassemble the sections that should have command machine code
$ (OBJ) u-boot.dis: $ (OBJ) U-boot
$ (Objdump)-d $ <>$ @
# Compile U-boot
# Dependency depend version $ (subdirs) $ (objs) $ (libs) $ (ldscript)
# Sort sorting
# Uniq filtering duplicate rows
$ (OBJ) U-boot: depend version $ (subdirs) $ (objs) $ (libs) $ (ldscript)
# Find the u_boot_cmd segment in each source file.
# If you do not want to analyze them one by one, you can directly make and take a look at the last part of the compilation prompt.
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
# Link to the source program for U-boot executable files, and generate u-boot.map files.
# U-boot contains debugging information, such as debug_frame and debug_info.
# The address of each function/variable is recorded in the u-boot.map.
# $ (Make) is used to make recursive calls.-C indicates to modify the subdirectory, and M indicates to return to the directory.
# Example: $ (make)-C/usr/src/linux-source-2.6.15/M =/home/vmeth modules
# Cd/usr/src/linux-source-2.6.15/& $ (make) M =/home/vmeth modules
# Compile the sub-directory CPU/$ (CPU). If remote_build is 0 and objs is empty, filter out the non-directory files of objs and compile them together.
$ (Objs ):
$ (Make)-c cpu/$ (CPU) $ (if $ (remote_build), $ @, $ (notdir $ @))
# Replace $ (OBJ) in libs with null in SUBST
$ (Libs ):
$ (Make)-C $ (DIR $ (SUBST $ (OBJ), $ @))
# Compile all pseudo directories under subdirs
# In fact, it is to run the make all command under the subdirs directory.
$ (Subdirs ):
$ (Make)-C $ @ All
$ (Nand_spl): Version
$ (Make)-C nand_spl/board/$ (boarddir) All
$ (U_boot_nand): $ (nand_spl) $ (OBJ) u-boot.bin
Cat $ (OBJ) nand_spl/u-boot-spl-16k.bin $ (OBJ) u-boot.bin> $ (OBJ) u-boot-nand.bin
# @ Echo control command echo
#> Copy to the target file and overwrite the source file
#>> Copy to the end of the target file without overwriting the source file
Version:
@ Echo-n "# define u_boot_version \" U-Boot ">$ (version_file );\
Echo-n "$ (u_boot_version)" >$ (version_file );\
Echo-N $ (shell $ (config_shell) $ (topdir)/tools/setlocalversion \
$ (Topdir) >>$ (version_file );\
Echo "\" ">>$ (version_file)
# | The execution is performed correctly on the left and not on the right; otherwise, the execution is performed on the right.
Gdbtools:
$ (Make)-C tools/GDB all | Exit 1
Updater:
$ (Make)-C tools/Updater all | Exit 1
Env:
$ (Make)-C tools/ENV all | Exit 1
# When "$" is used in the command or file name, two dollar signs "$" are required.
# In actual use, if a reference exists in the expanded result of the function (Format: $ (x )),
# Replace "$" with "$" in the function parameters, that is, if you need to expand it again
Depend Dep:
For dir in $ (subdirs); do $ (make)-C $ dir _ depend; done
Tags ctags:
Ctags-w-o $ (objtree)/ctags 'Find $ (subdirs) include \
Lib_generic board/$ (boarddir) CPU/$ (CPU) lib _ $ (ARCH )\
FS/cramfs fs/fat fs/fdos fs/jffs2 \
Net disk rtc dtt drivers Drivers/sk98lin common \
\ (-Name CVS-prune \)-O \ (-name '*. [CH]'-Print \)'
Etags:
Etags-a-o $ (objtree)/etags 'Find $ (subdirs) include \
Lib_generic board/$ (boarddir) CPU/$ (CPU) lib _ $ (ARCH )\
FS/cramfs fs/fat fs/fdos fs/jffs2 \
Net disk rtc dtt drivers Drivers/sk98lin common \
\ (-Name CVS-prune \)-O \ (-name '*. [CH]'-Print \)'
$ (OBJ) system. MAP: $ (OBJ) U-boot
@ $ (Nm) $ <| \
Grep-V '\ (Compiled \) \ | \(\. o $ \) \ | \ ([auw] \) \ | \(\. \. ng $ \) \ | \ (lash [RL] Di \) '| \
Sort> $ (OBJ) system. Map
######################################## #################################
Else
All $ (OBJ) u-boot.hex $ (OBJ) u-boot.srec $ (OBJ) u-boot.bin \
$ (OBJ) u-boot.img $ (OBJ) u-boot.dis $ (OBJ) U-boot \
$ (Subdirs) version gdbtools Updater env depend \
Dep tags ctags etags $ (OBJ) system. MAP:
@ Echo "system not configured-see readme"> & 2
@ Exit 1
Endif
. Phony: changelog
Changelog:
Git log -- no-merges U-Boot-1_1_5 .. | \
Unexpand-A | sed-E's/\ s * $ // '> @
# It is explained here. If the $ (objtree)/include/config. mk file does not exist, compilation cannot proceed.
######################################## #################################
# Delete configuration information
Unconfig:
@ RM-F $ (OBJ) include/config. h $ (OBJ) include/config. mk \
$ (OBJ) Board/*/config. tmp $ (OBJ) Board/*/config. tmp
The code below is the configuration for different platforms. I will continue to add this article in the future. I also hope that my friends will know where they want to know more.