Detailed description of U-boot analysis 1makefile

Source: Internet
Author: User
Tags srec

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.