u-boot2013.01 sdmk2410 配置和编译过程分析

时间:2022-05-14 16:32:46

1.jz2440移植新u-boot,带有设备树 kernel 准备资料
分析自带的smdk2410 的配置过程
2. u-boot2013.01 版本的
3. 编译
3.1 boards.cfg 有smdk2410 的配置
3.2 make smdk2410_config
    Configuring for smdk2410  board...
3.3 make

4.概述分析
4.1 在*目录下的boards.cfg中包含了大多数的板级配置文件
基本信息如下。例如smdk2410的配置信息
# Target                     ARCH        CPU         Board name          Vendor            SoC         Options
smdk2410                     arm         arm920t     -                   samsung        s3c24x0

boards.cfg 从 uboot2010.09  开始出现
4.2  这个编译的过程需要先配置,后编译。
        配置执行make sdmk2410_config 文件
        随后make
5 分析配置过程

5.1 顶层目录 README 下 For all supported boards there are ready-to-use default 指明了如何进行编译    
  顶层目录下的Makefile中并没有smdk2410_config 文件,取而带之的是 %_config ,%代表着任意字符
    make smdk2410_config 会执行
        会在makefile 文件中找到
     %_config::    unconfig
     @$(MKCONFIG) -A $(@:_config=)
    
    分析参考链接: http://blog.chinaunix.net/uid-18921523-id-165029.html
    
      %_config::    unconfig  
 5.1.1
     %代表着任意字符     unconfig  前边有双 ::  这就是Makefile中的双引号规则  
      Makefile 中规定:一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。
      而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下几个方面:
    1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,
    当引用此目标时,规则的命令将会被无条件执行。
    而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
    2 .当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。
    这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,
    make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
        
        unconfig 也是一个 也是一个目标
        即
        unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
     故 先删除一些文件
    5.1.2
      @$(MKCONFIG) -A $(@:_config=)
      第一个@ 表示的功能是取消回显
      $(MKCONFIG) 表示取MKCONFIG的内容
      搜索得到
      SRCTREE        := $(CURDIR)
      MKCONFIG    := $(SRCTREE)/mkconfig
        export MKCONFIG
        即: MKCONFIG 就是 当前目录下的mkconfig 文件
        @:_config=
        @ 表示目标 即%_config ,也就是 smdk2410_config
        :_config=  表示将_config= 赋值为空,从而得到了
        smdk2410
        
          @$(MKCONFIG) -A $(@:_config=)
        ==> mkconfig -A smdk2410
        
     执行mkconfig 的配置过程
6  执行mkconfig 的过程
mkconfig的目的:Script to create header files and links to configure
生成头文件和连接的
6.1  if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
        $# 传给脚本的参数的格式
        判读输入的参数是等于2  ,并且第一个参数是否我 -A 成立则执行

    line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
        echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
        exit 1
    }
    egrep -i 一行一行的从boards.cfg中读取数据
    "^[[:space:]]*${2}[[:space:]]"表示第二个参数及 smdk2410的前边没有空格,后边有空格
    ==>
    line = smdk2410       arm         arm920t     -         samsung        s3c24x0
                     $1                        $2                        $3                 $4                     $5                            $6
                    
    set ${line}
    
        while [ $# -gt 0 ] ;   //参数的格式大于0, 则执行 判断$1(smdk2410 是否为 -- -a -n 等。)
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*) break ;;
esac


    done
    以上语句不执行
    
    # Strip all options and/or _config suffixes
    CONFIG_NAME="${1%_config}"
====》CONFIG_NAME=smdk2410_config

[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
[ "${BOARD_NAME}" ]  BOARD_NAME没有赋值过,故执行BOARD_NAME="${1%_config}"
==>BOARD_NAME = sdmk2410_config

arch="$2"
cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
    
==> arch = arm
        cpu = arm920t
        spl_cpu = arm920t
            
        awk 参考连接     http://www.cnblogs.com/emanlee/p/3327576.html
        
  
 if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4"
fi

==> $4 为 board = smdk2410

[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
[ $# -gt 6 ] && [ "$7" != "-" ] && {
==》vendor = samsung
soc = s3c24x0


        
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
exit 1
fi


以上不执行
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi


执行  echo "Configuring for ${BOARD_NAME} board..."


#
# Create link to architecture specific headers
#
执行
    cd ./include
rm -f asm
ln -s ../arch/${arch}/include/asm asm


    创建软连接
    当前所在的目录  include目录
    ls -s ../arm/arm/include/asm asm
    将 ../arm/arm/include/asm 文件在 include 目录下创建一个软连接 asm
    ==>lrwxrwxrwx 1 gus gus 23 Jul 11 18:49 asm -> ../arch/arm/include/asm
    
    rm -f asm/arch
if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi



if判断中-z用法 判断字符串是否有值,有值返回0
执行     ln -s ${LNPREFIX}arch-${soc} asm/arch
==》 ln -s arch-s3c24x0 asm/arch
     lrwxrwxrwx 1 gus gus 12 Jul 11 18:49 asm/arch -> arch-s3c24x0
         
if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi



    ln -s ${LNPREFIX}proc-armv proc-armv
 ==》 ln -s proc-armv proc-armv
  lrwxrwxrwx 1 gus gus 9 Jul 11 18:49 asm/proc -> proc-armv
 
 
#
# Create include file for Make
#
echo "ARCH = ${arch}"
if [ ! -z "$spl_cpu" ] ; then
echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
echo "CPU = ${spl_cpu}"
echo "else"
echo "CPU = ${cpu}"
echo "endif"
else
echo "CPU = ${cpu}"
fi
echo "BOARD = ${board}"
[ "${vendor}" ] && echo "VENDOR = ${vendor}"
[ "${soc}" ] && echo "SOC = ${soc}"
exit 0 ) > config.mk

 ==>config.mk 的内容     
   
     ARCH = arm
CPU = arn920t
BOARD = smdk2410
VENDOR = samsung
SOC = s3c24x0.

    
# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
fi



==> BOARDDIR=${vendor}/${board}
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi


==》    > config.h        # Create new config file

echo "/* Automatically generated - do not edit */" >>config.h
echo "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.h
echo "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.h
echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h
==>#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "arm920t"
#define CONFIG_SYS_BOARD "smdk2410"


    
[ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
[ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.h


==》
#define CONFIG_SYS_VENDOR  samsung
#define CONFIG_SYS_SOC s3c24x0


#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>


==》 #define CONFIG_BOARDDIR board/samsung/smdk2410

config.h
/* Automatically generated - do not edit */
#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "arm920t"
#define CONFIG_SYS_BOARD "smdk2410"
#define CONFIG_SYS_VENDOR "samsung"
#define CONFIG_SYS_SOC "s3c24x0"
#define CONFIG_BOARDDIR board/samsung/smdk2410
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/smdk2410.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>



==================================================编译过程=================================================================
参考连接: http://www.cnblogs.com/heaad/archive/2010/07/17/1779806.html
7.编译过程
7.1 若没有执行 make <board_name>_config 则出现 System not configured - see README
7.2 配置过程的文件和 编译过程怎么关联在一起
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC

导出了 config.mk 中的 ARCH CPU BOARD VENDOR SOC

# load other configuration
include $(TOPDIR)/config.mk


将顶层目录的 config.mk导入 Makefile
其中包括了
CPUDIR=arch/$(ARCH)/cpu/$(CPU)
==> CPUDIR =arch/arm/cpu/arm920t
7.3 make
执行的
all:        $(ALL-y) $(SUBDIR_EXAMPLES)
$(ALL-y)的具体内容
# Always append ALL so that arch config.mk's can add custom ones
ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

u-boot.bin
$(obj)u-boot.bin:    $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(BOARD_SIZE_CHECK)

目标:u-boot.bin 依赖u-boot
命令$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
        $(BOARD_SIZE_CHECK)

依赖u-boot
$(obj)u-boot:    depend \
$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)


        
        u-boot 依赖 $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
        命令 $(GEN_UBOOT)

$(SUBDIR_TOOLS)
SUBDIR_TOOLS = tools
$(OBJS)

# U-Boot objects....order is important (i.e. start must be first)
OBJS = $(CPUDIR)/start.o
ifeq ($(CPU),x86)
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += $(CPUDIR)/resetvec.o
endif



OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))

==》
OBJS  = $(CPUDIR)/start.o        ==arch/arm/cpu/arm920t/start.o ==>首先被执行的文件

-------------------------------------------------------------------------
OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))

$(addprefix <prefix>,<names...>)  
名称:加前缀函数——addprefix。  
功能:把前缀<prefix>加到<names>中的每个单词后面。  
返回:返回加过前缀的文件名序列。  
示例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。  
$(obj) = 空
$(OBJS) = arch/arm/cpu/arm920t/start.o
 $(RESET_OBJS-)  也为空
 ==》OBJS :=arch/arm/cpu/arm920t/start.o
 
 GEN_UBOOT 对应的信息
GEN_UBOOT = \
UNDEF_LST=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
sed -n -e 's/.*\($(SYM_PREFIX)_u_boot_list_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
$$UNDEF_LST $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot


            
$(@F 查看自动化变量  LDFLAGS_u-boot  
怎么得到的这个 LDFLAGS_u-boot
分析: GEN_UBOOT 这个变量 下的代码会在
 依赖u-boot
$(obj)u-boot:    depend \
        $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
        $(GEN_UBOOT)
    处进行展开
    此处的$@ 表示的是u-boot
    $(@F) 表示什么呢? 其实就是 u-boot  
    从而得到  LDFLAGS_u-boot
     LDFLAGS_u-boot 这个变量在哪里定义的和具体的值是什么呢?
     LDFLAGS_u-boot  在顶层目录下的config.mk 中进行定义的
    
 LDFLAGS_FINAL += -Bstatic
LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)


     ==》 LDFLAGS_u-boot  += -T  u-boot.lds  -Bstatic  
     
     在加上
     ifneq ($(CONFIG_SYS_TEXT_BASE),)
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)


CONFIG_SYS_TEXT_BASE 没有定义应当为空
==》 LDFLAGS_u-boot =  -T  u-boot.lds  -Bstatic  Ttext   0x00  

 $(__OBJS) 怎么解读:
==》 __OBJS := $(subst $(obj),,$(OBJS))

 $(subst <from>,<to>,<text>)  
名称:字符串替换函数——subst。  
功能:把字串<text>中的<from>字符串替换成<to>。
返回:函数返回被替换过后的字符串。  
前边已经推导出:
$(obj) = 空
$(OBJS) = arch/arm/cpu/arm920t/start.o
==》__OBJS  = arch/arm/cpu/arm920t/start.o

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

8 u-boot 连接时候的信息
UNDEF_LST=`arm-linux-objdump -x board/samsung/smdk2410/libsmdk2410.o
api/libapi.o
arch/arm/cpu/arm920t/libarm920t.o
arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.o
arch/arm/lib/libarm.o
board/samsung/common/libsamsung.o
common/libcommon.o
disk/libdisk.o
drivers/bios_emulator/libatibiosemu.o
drivers/block/libblock.o
drivers/dfu/libdfu.o
drivers/dma/libdma.o
drivers/fpga/libfpga.o
drivers/gpio/libgpio.o
drivers/hwmon/libhwmon.o
drivers/i2c/libi2c.o
drivers/input/libinput.o
drivers/misc/libmisc.o
drivers/mmc/libmmc.o
drivers/mtd/libmtd.o
drivers/mtd/nand/libnand.o
drivers/mtd/onenand/libonenand.o
drivers/mtd/spi/libspi_flash.o
drivers/mtd/ubi/libubi.o
drivers/net/libnet.o
drivers/net/phy/libphy.o
drivers/pci/libpci.o
drivers/pcmcia/libpcmcia.o
drivers/power/battery/libbattery.o
drivers/power/fuel_gauge/libfuel_gauge.o
drivers/power/libpower.o
drivers/power/pmic/libpmic.o
drivers/rtc/librtc.o
drivers/serial/libserial.o
drivers/sound/libsound.o
drivers/spi/libspi.o
drivers/twserial/libtws.o
drivers/usb/eth/libusb_eth.o
drivers/usb/gadget/libusb_gadget.o
drivers/usb/host/libusb_host.o
drivers/usb/musb-new/libusb_musb-new.o
drivers/usb/musb/libusb_musb.o
drivers/usb/phy/libusb_phy.o
drivers/usb/ulpi/libusb_ulpi.o
drivers/video/libvideo.o
drivers/watchdog/libwatchdog.o
fs/cbfs/libcbfs.o fs/cramfs/libcramfs.o
fs/ext4/libext4fs.o
fs/fat/libfat.o
fs/fdos/libfdos.o
fs/jffs2/libjffs2.o
fs/libfs.o
fs/reiserfs/libreiserfs.o
fs/ubifs/libubifs.o
fs/yaffs2/libyaffs2.o
fs/zfs/libzfs.o
lib/libfdt/libfdt.o
lib/libgeneric.o
lib/lzma/liblzma.o
lib/lzo/liblzo.o
lib/zlib/libz.o
net/libnet.o
post/libpost.o
test/libtest.o



| sed  -n -e 's/.*\(_u_boot_list_.*\)/-u\1/p'|sort|uniq`;
=======================================================
链接脚本u-boot.lds 决定下边的排列顺序  最先排放的是 arch/arm/cpu/arm920t/start.o  
=========================================================
cd /home/gus/jz2440/system/u-boot-2013.01-20160711-2440
&& arm-linux-ld.bfd -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_LST

arch/arm/cpu/arm920t/start.o
--start-group
api/libapi.o
arch/arm/cpu/arm920t/libarm920t.o
arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.o
arch/arm/lib/libarm.o
board/samsung/common/libsamsung.o
common/libcommon.o
disk/libdisk.o
drivers/bios_emulator/libatibiosemu.o
drivers/block/libblock.o
drivers/dfu/libdfu.o
drivers/dma/libdma.o
drivers/fpga/libfpga.o
drivers/gpio/libgpio.o
drivers/hwmon/libhwmon.o
drivers/i2c/libi2c.o
drivers/input/libinput.o
drivers/misc/libmisc.o
drivers/mmc/libmmc.o
drivers/mtd/libmtd.o
drivers/mtd/nand/libnand.o
drivers/mtd/onenand/libonenand.o
drivers/mtd/spi/libspi_flash.o
drivers/mtd/ubi/libubi.o
drivers/net/libnet.o
drivers/net/phy/libphy.o
drivers/pci/libpci.o
drivers/pcmcia/libpcmcia.o
drivers/power/battery/libbattery.o
drivers/power/fuel_gauge/libfuel_gauge.o
drivers/power/libpower.o
drivers/power/pmic/libpmic.o
drivers/rtc/librtc.o
drivers/serial/libserial.o
drivers/sound/libsound.o
drivers/spi/libspi.o
drivers/twserial/libtws.o
drivers/usb/eth/libusb_eth.o
drivers/usb/gadget/libusb_gadget.o
drivers/usb/host/libusb_host.o
drivers/usb/musb-new/libusb_musb-new.o
drivers/usb/musb/libusb_musb.o
drivers/usb/phy/libusb_phy.o
drivers/usb/ulpi/libusb_ulpi.o
drivers/video/libvideo.o
drivers/watchdog/libwatchdog.o
fs/cbfs/libcbfs.o fs/cramfs/libcramfs.o
fs/ext4/libext4fs.o fs/fat/libfat.o
fs/fdos/libfdos.o fs/jffs2/libjffs2.o
fs/libfs.o fs/reiserfs/libreiserfs.o
fs/ubifs/libubifs.o
fs/yaffs2/libyaffs2.o
fs/zfs/libzfs.o
lib/libfdt/libfdt.o
lib/libgeneric.o
lib/lzma/liblzma.o
lib/lzo/liblzo.o
lib/zlib/libz.o
net/libnet.o
post/libpost.o
test/libtest.o
board/samsung/smdk2410/libsmdk2410.o
--end-group /home/gus/jz2440/system/u-boot-2013.01-20160711-2440/arch/arm/lib/eabi_compat.o
-L /home/toolchain/gcc-4.6.4/bin/../lib/gcc/arm-arm1176jzfssf-linux-gnueabi/4.6.4 -lgcc -Map u-boot.map -o u-boot
arm-linux-objcopy -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin