U-BOOT is a Linux project, before compilation must have installed the corresponding architecture of the Cross-compilation environment, here only for ARM, compiler series software for ARM-Linux -*.
U-BOOT: http://sourceforge.net/projects/u-boot
I downloaded version 1.1.6 and downloaded a new version on FTP at the beginning. The compilation failed. 1.1.6 is okay.
U-boot source code structure
Decompress the package to obtain all u-boot source programs. There are 18 subdirectories under the top-level directory, respectively storing and managing different source programs. The files to be stored in these directories have their own rules and can be divided into three categories.
1st category directories are directly related to the processor architecture or development board hardware;
The 2nd class directory contains some common functions or drivers;
The 3rd class directory is the U-boot application, tool, or document.
U-boot source code top-level directory description
Topic features explanation
The Board platform depends on storing directory files related to the circuit board,
For example: rpxlite (mpc8xx ),
Smdk2410 (ARM920T ),
Sc520_cdp (x86) and other directories
CPU platform depends on storing CPU-related directory files
For example: mpc8xx, ppc4xx,
Arm720t, ARM920T, XScale, i386, and other directories
The lib_ppc platform depends on files that are common to the PowerPC architecture,
It is mainly used to implement functions common to the PowerPC platform.
The lib_arm platform depends on files that are common to the ARM architecture,
It is mainly used to implement general functions of the ARM platform.
The lib_i386 platform depends on files that are common to the X86 architecture,
It is mainly used to implement common functions on the X86 platform.
Include general header files and development board configuration files,
The configuration files of all development boards are under the configs directory.
Common universal multi-function implementation
Implementation of lib_generic universal library functions
Net General Network Storage Program
FS general program for storing file systems
Post general storage power-on self-check program
Drivers is a general-purpose device driver with Ethernet interfaces.
General disk interface program
RTC universal RTC driver
DTT universal digital temperature measuring device or sensor drive
Examples of some independent applications, such as helloworld
Tools are used to store images in S-record or U-boot format,
For example, mkimage
Doc documentation development user documentation
The source code of U-boot includes support for dozens of processors and hundreds of development boards. However, for a specific development board, only some of the programs are required to configure the compilation process. Here we take the S3C2410 & ARM920T processor as an example to analyze the programs on which the S3C2410 processor and the Development Board depend, as well as general functions and tools of U-boot.
Compile
Taking the smdk_2410 Board as an example, the compilation process is divided into two parts:
# Make smdk2410_config
# Make
Top-level makefile Analysis
To understand the structure of a Linux project, you must understand makefile, especially the top layer. There is no way. The Unix world is so helpless. Everything is managed and configured using documents. First of all, I am a newbie in this regard. I only read some makefile rules with limited time.
Taking smdk_2410 as an example, the general process and structure of sequential analysis makefile are as follows:
1) makefile defines the source code and the directory where the generated target file is stored. The build_dir directory of the target file can be specified through make o = dir. If not specified, it is set to the top-level directory of the source code. If the output directory is not specified during compilation, build_dir is empty. Other directory variables are defined as follows:
# Objtree and lndir are the directories for storing generated files, and topdir and srctree are the source code directories.
Objtree: =$ (if $ (build_dir), $ (build_dir), $ (curdir ))
Srctree: = $ (curdir)
Topdir: = $ (srctree)
Lndir: = $ (objtree)
Export topdir srctree objtree
2) Definition variable mkconfig: this variable points to a script, that is, mkconfig in the top-level directory.
Mkconfig: = $ (srctree)/mkconfig
Export mkconfig
Run
# Make smdk2410_config
Smdk2410_config is a target of makefile and is defined as follows:
Smdk2410_config: unconfig
@ $ (Mkconfig) $ (@: _ Config =) arm ARM920T smdk2410 null s3c24x0
Unconfig ::
@ RM-F $ (OBJ) include/config. h $ (OBJ) include/config. mk/
$ (OBJ) Board/*/config. tmp $ (OBJ) Board/*/config. tmp
Obviously, when you run # Make smdk2410_config, run the unconfig target first. Note that when the output target is not specified, the OBJ and SRC variables are empty, the commands below unconfig clean up the header files and makefile inclusion files generated when the last make * _ config command is executed. Mainly include/config. h and include/config. mk files.
Then execute the command
@ $ (Mkconfig) $ (@: _ Config =) arm ARM920T smdk2410 null s3c24x0
Mkconfig is the mkcofig script file in the top-level directory. The last five are input parameters.
For smdk2410_config, mkconfig mainly performs the following three tasks:
Create a file (folder) soft connection under the include folder,
# If the arm system is used, perform the following operations:
# Ln-s ASM-arm ASM
# Ln-s arch-s3c24x0 ASM-arm/Arch
# Ln-s proc-armv ASM-arm/proc
The makefile generated contains the include/config. mk file, which is simple and defines four variables:
Arch = arm
CPU = ARM920T
Board = smdk2410
SOC = s3c24x0
Generate the include/config. h header file with only one line:
/* Automatically generated-do not edit */
# Include "config/smdk2410.h"
The execution of the mkconfig script file is now complete, and the remaining parts of the makefile are analyzed.
3) include/config. mk, which is equivalent to defining the above four variables in makefile.
4) Specify the cross-compiler Prefix:
Ifeq ($ (ARCH), arm) # specify the compiler prefix Based on the arch variable.
Cross_compile = arm-Linux-
Endif
5) include config. mk:
# Contains config. mk in the top-level directory. This file mainly defines cross-compiler and options and compilation rules.
# Load other configuration
Include $ (topdir)/config. mk
The following is an analysis of config. mk:
@ Inclusion system, Development Board, CPU-specific rule file:
Ifdef arch # specify pre-compiled architecture options
Sinclude $ (topdir)/$ (ARCH) _ config. mk # include architecture dependend rules
Endif
Ifdef CPU # define options such as alignment during compilation and floating point
Sinclude $ (topdir)/CPU/$ (CPU)/config. mk # include CPU specific rules
Endif
Ifdef SOC # This file does not exist
Sinclude $ (topdir)/CPU/$ (CPU)/$ (SOC)/config. mk # include SOC specific rules
Endif
Ifdef board # specify the memory base address when the image of a specific board is connected. Important!
Sinclude $ (topdir)/board/$ (boarddir)/config. mk # include Board specific rules
Endif
@ Define the cross-compilation link Tool
# Include the make variables (CC, Etc ...)
#
As = $ (cross_compile)
LD = $ (cross_compile) LD
Cc = $ (cross_compile) GCC
CPP = $ (CC)-e
AR = $ (cross_compile) Ar
Nm = $ (cross_compile) nm
Strip = $ (cross_compile) strip
Objcopy = $ (cross_compile) objcopy
Objdump = $ (cross_compile) objdump
Ranlib = $ (cross_compile) ranlib
@ Define the AR option arflags, debug option dbgflags, and optimization option optflags
Pre-processing options cppflags, C compiler options cflags, connection options ldflags
Ldflags + =-bstatic-T $ (ldscript)-ttext $ (text_base) $ (platform_ldflags) # specify the starting address text_base
@ Specify the compilation rules:
$ (OBJ) %. S: %. s
$ (CPP) $ (aflags)-o $ @ $ <
$ (OBJ) %. O: %. s
$ (CC) $ (aflags)-c-o $ @ $ <
$ (OBJ) %. O: %. c
$ (CC) $ (cflags)-c-o $ @ $ <
Return to the top-level MAKEFILE file:
6) target file required by U-boot.
Objs = CPU/$ (CPU)/start. O # The sequence is very important. Start. O must be placed first.
7) required library files:
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)
Libs: =$ (addprefix $ (OBJ), $ (libs ))
. Phony: $ (libs)
Based on the arch, CPU, board, and SOC variables defined in the include/config. mk File above. The directory files that the hardware platform depends on can be determined based on these definitions. The related directories of the smdk2410 platform and the generated library files are as follows.
Board/smdk2410/: library file board/smdk2410/libsmdk2410.a
CPU/ARM920T/: library file CPU/ARM920T/libarm920t.
CPU/ARM920T/s3c24x0/: library file CPU/ARM920T/s3c24x0/libs3c24x0.
Lib_arm/: library file lib_arm/libarm.
Include/ASM-arm/: The following two are header files.
Include/configs/smdk2410.h
8) Various final image files:
All = $ (OBJ) u-boot.srec $ (OBJ) u-boot.bin $ (OBJ) system. Map $ (u_boot_nand)
ALL: $ (all)
$ (OBJ) u-boot.hex: $ (OBJ) U-boot
$ (Objcopy) $ {objcflags}-O ihex $ <$ @
$ (OBJ) u-boot.srec: $ (OBJ) U-boot
$ (Objcopy) $ {objcflags}-o srec $ <$ @
$ (OBJ) u-boot.bin: $ (OBJ) U-boot
$ (Objcopy) $ {objcflags}-O binary $ <$ @
# Here, the ELF File image of U-boot is generated.
$ (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
Analyze the generation of the most critical U-boot ELF File image:
@ Dependency target depend: generate the. Depend file for each subdirectory, And. Depend lists the dependent files of each target file. Call make _ depend in each subdirectory.
Depend Dep:
For dir in $ (subdirs); do $ (make)-C $ dir _ depend; done
@ Dependency target version: Generate version information to version_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)
@ Pseudo-target subdirs: Execute the make file under the tools, examples, post, post/CPU subdirectory.
Subdirs = tools/
Examples/
Post/
Post/CPU
. Phony: $ (subdirs)
$ (Subdirs ):
$ (Make)-C $ @ All
@ Dependency target $ (objs), that is, CPU/start. o
$ (Objs ):
$ (Make)-c cpu/$ (CPU) $ (if $ (remote_build), $ @, $ (notdir $ @))
@ Dependency target $ (libs). There are too many targets, all of which are the library files *. A in each subdirectory. This is done by executing make in the corresponding subdirectory:
$ (Libs ):
$ (Make)-C $ (DIR $ (SUBST $ (OBJ), $ @))
@ Dependency target $ (ldscript ):
Ldscript: = $ (topdir)/board/$ (boarddir)/u-boot.lds
Ldflags + =-bstatic-T $ (ldscript)-ttext $ (text_base) $ (platform_ldflags)
For smdk2410, ldscript means that the connection script file is board/smdk2410/u-boot.lds, which defines how each target file is organized during the connection. The content is as follows:
Output_format ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm ")
/* Output_format ("elf32-arm", "elf32-arm", "elf32-arm ")*/
Output_arch (ARM)
Entry (_ start)
Sections
{
. = 0x00000000;
. = Align (4 );
. Text:/*. The base address of text is specified by-ttext $ (text_base) in ldflags */
{/* The base address specified by smdk2410 is 0x33f80000 */
CPU/ARM920T/start. O (. Text)/* start. O led */
* (. Text)
}
. = Align (4 );
. Rodata: {* (. rodata )}
. = Align (4 );
. Data: {* (. Data )}
. = Align (4 );
. Got: {* (. Got )}
. = .;
_ U_boot_1__start = .;
. U_boot_cmd: {* (. u_boot_cmd )}
_ U_boot_1__end = .;
. = Align (4 );
_ Bss_start = .;
. BSS: {* (. BSS )}
_ End = .;
}
@ Execute the connection command:
CD $ (lndir) & $ (LD) $ (ldflags) $ undef_sym $ (_ objs )/
-- Start-group $ (_ libs) -- end-group $ (platform_libs )/
-Map u-boot.map-o u-boot
In fact, it is to start. O and each sub-directory makefile generated library files are connected according to ldflags, generate the ELF File U-boot and the memory distribution graph file u-boot.map when the connection.
9) for makefile files in each subdirectory, generate *. O files and execute ar to generate corresponding library files. For example, makefile in the lib_generic Folder:
Lib = $ (OBJ) libgeneric.
Cobjs = bzlib. O bzlib_crctable.o bzlib_decompress.o/
Bzlib_randtable.o bzlib_huffman.o/
Crc32.o ctype. O display_options.o ldiv. O/
String. O vsprintf. O zlib. o
SRCS: =$ (cobjs:. O =. c)
Objs: =$ (addprefix $ (OBJ), $ (cobjs ))
$ (LIB): $ (OBJ). Depend $ (objs) # Make libgeneric.
$ (AR) $ (arflags) $ @ $ (objs)
The remaining contents of the entire makefile are all * _ config of different development boards: the definition of the target.
In summary, the compilation process of the project is to input arch, CPU, board, and SOC parameters by executing make * _ config, mkconfig connects the corresponding header folder of the include header folder according to the parameter to generate config. h. Then execute make to call makefile of each subdirectory to generate all OBJ files and OBJ library files *. A. Connect all target files and generate images. Images of different formats are directly or indirectly generated by Elf images by calling corresponding tools.