玩转S3C6410之二 s3c-u-boot-1.1.6配置、编译、链接分析(一)

来源:互联网 发布:传智python视频百度云 编辑:程序博客网 时间:2024/05/17 00:05
 

    tiny6410上采用的处理器是S3C6410,我们首先要做的是从网上下载三星公司针对s3c6410修改过的s3c-u-boot-1.1.6的源码,然后对这个源码进行分析,最后再将源码移植到tiny6410上。

    1、uboot初见
    我从网上下载的源码是s3c-u-boot-1.1.6_rel-4-3-2_20080917.tar.bz2,解压后得到s3c-u-boot-1.1.6这个目录。根据顶层的README文件我们可以获取到如下信息:
    1.1 顶层目录结构
    Board:和一些已有开发板相关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
    Common:与体系结构无关的文件,实现各种命令的C文件。
    CPU:CPU相关文件,其中的子目录都是以u-boot所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等。
    Disk:硬盘接口程序
    Doc:开发、试用文档。
    Drivers:通用设备驱动程序,比如各种网卡、支持CFI的flash、串口和USB总线等。
    Dtt:数字温度测量器或者传感器的驱动
    Examples:一些独立运行的应用程序的例子。
    Fs:支持文件系统的文件,u-boot现在支持cramfs、fat、fdos、jffs2、yaffs和registerfs。
    Include:头文件,还有对各种硬件平台支持的会变文件,系统的配置文件和对文件系统支持的文件。
    Lib_arm:存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数,与ARM体系结构相关的代码。
    Lib_*:某一架构通用的文件。
    Lib_generic:通用的多功能函数实现。
    Nand_spl:Uboot一般从ROM、NORFlash等设备启动,现在开始执行NANDFlash启动,但是支持的CPU种类还不多。
    Net:与网络有关的代码,BOOTP协议、TFTP协议RARP协议和NFS文件系统的实现。
    Post:上电自检程序。
    Rtc: 实时时钟驱动。
    Tools:创建S-Record格式文件和U-BOOT images的工具。
    1.2 编译程序
    进入源码目录执行:
    make distclean     --清除所有生成的文件
    make NAME_config   --根据自己使用的开发板进行配置
    make all           --编译源码

    2、uboot的配置过程
    从README文件中我们知道了make NAME_config是用来对自己的开发板进行配置的,那就先来看下到底是怎么配置的。
    这边假设我们的板子是smdk6410,那么应该在源码目录执行make smdk6410_config
    make调用的是顶层目录下的Makefile文件,我们传参数是smdk6410_config,
    所以在Makefile中找到smdk6410_config的相应部分如下:
    smdk6410_config : unconfig
             @$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
    先分析下这条规则:
    smdk6410_config:规则的目标名

    unconfig:规则的依赖,这个在Makefile文件的342行可以找到,如下:
        unconfig:
            @rm -f $(obj)include/config.h $(obj)include/config.mk \
                        $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
        这个就不在分析,就是删除一些文件。

    第二行开头的@:表示该行命令的输出被抑制,即执行的时候不会在终端上打印出来。

    $(MKCONFIG):MKCONFIG这个变量在92行定义MKCONFIG:=$(SRCTREE)/mkconfig,而变量SRCTREE在87行定义SRCTREE  :=$(CURDIR),而CURDIR是Makefile自带的变量表示当前目录,所以$(MKCONFIG)就是当前目录下的mkconfig文件,即顶层目录下的mkconfig文件。
    
    $(@:_config=):$@是make的自动变量,标识规则的目标名,即smdk6410_config。$(@:_config=)意思就是 $@ 中的“_config”替换为空,也就是删掉目标中“_config”这个子串。所以这边$(@:_config=)为smdk6410。
   
    这样看的话在配置时,执行make smdk6410_config实际上执行的是:
    ./mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410
    到这才真正地开始配置开发板,接下来带着这条命令详细分析下mkconfig这个文件。
1  #!/bin/sh -e
//选项-e表示一个命令在执行后返回一个非0状态值时,就退出
2
3  # Script to create header files and links to configure
4  # U-Boot for a specific board.
5  #
6  # Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]
7  #
8  # (C) 2002-2006 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
9  #
10
11  APPEND=no # Default: Create new config file
//APPEND=no这边表示重新创建一个文件,APPEND=yes表示将内容追加到原来的文件中
12  BOARD_NAME="" # Name to print in make output
//BOARD_NAME为开发板的名字
13
14  while [ $# -gt 0 ] ; do
15    case "$1" in
16    --) shift ; break ;;
17   -a) shift ; APPEND=yes ;;
18   -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
19   *)  break ;;
20   esac
21 done
//"$#" 将扩展成传递给脚本的参数的数目
//"$*" 将扩展成传递给脚本的所有参数
//"shift" 将$*中的剩余的参数向左移动一个位置并减少$#的值1
//14-21行判断“./mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410”命令中是否有“--”,“-a”,“-n”等符号,
//这边没有,所以不做任何事情,11行和12行的变量仍然维持原来的值。
22
23  [ "${BOARD_NAME}" ] || BOARD_NAME="$1"
//先判断BOARD_NAME是否为空,为空将命令中的第一个参数smdk6410赋值给BOARD_NAME,即这边BOARD_NAME为“smdk6410”
24
25  [ $# -lt 4 ] && exit 1
26  [ $# -gt 6 ] && exit 1
//"$#" 表示参数的个数,如果参数个数小于4或者大于6就退出,这边$#=6,所以可以继续往下执行。
27
28  echo "Configuring for ${BOARD_NAME} board..."
//打印出开发板的名字
29
30  #
31  # Create link to architecture specific headers
//创建体系结构相关的头文件链接
32  #
33  if [ "$SRCTREE" != "$OBJTREE" ] ; then
34   mkdir -p ${OBJTREE}/include
35  mkdir -p ${OBJTREE}/include2
36  cd ${OBJTREE}/include2
37  rm -f asm
38  ln -s ${SRCTREE}/include/asm-$2 asm
39  LNPREFIX="../../include2/asm/"
40  cd ../include
41  rm -rf asm-$2
42  rm -f asm
43  mkdir asm-$2
44  ln -s asm-$2 asm
45  else
46  cd ./include
47  rm -f asm
48  ln -s asm-$2 asm
49  fi
//33行判断源码目录SRCTREE和目标文件目录SRCTREE是否一样,SRCTREE和SRCTREE在顶层Makefile中定义,
//这边要判断,是因为可以选择在其他目录下编译u-boot的源码,这样可以令源代码目录保存干净,这时SRCTREE和SRCTREE的值就不一样了
//不过我们一般都习惯直接就在源码目录下编译的,所以SRCTREE和OBJTREE都为当前目录,
//那么33行条件不成立,将执行else分支的代码。
//46-48行进入include目录,删除asm文件(这是上一次配置时建立的链接文件),
//然后再次建立asm文件,并令它链接向asm-$2目录,即asm-arm($2表示第二个参数arm)
50
51  rm -f asm-$2/arch
//删除asm-$2/arch目录,即删除asm-arm/arch
52
53  if [ -z "$6" -o "$6" = "NULL" ] ; then
54   ln -s ${LNPREFIX}arch-$3 asm-$2/arch
55  else
56  ln -s ${LNPREFIX}arch-$6 asm-$2/arch
57  fi
//$6表示第6个参数s3c6410,不为空,也不为“NULL”,53行条件不满足,将执行else分支
//其中LNPREFIX为空,$6表示第6个参数s3c6410,$2表示第2个参数arm
//所以“ln -s ${LNPREFIX}arch-$6 asm-$2/arch”即ln -s arch-s3c6410 asm-arm/arch
//前面有进入include目录,这时还在include目录下,
//所以意思是在asm-arm下创建符号链接arch指向arch-s3c6410
58
59  # create link for s3c24xx SoC
60  if [ "$3" = "s3c24xx" ] ; then
61  rm -f regs.h
62  ln -s $6.h regs.h
63  rm -f asm-$2/arch
64  ln -s arch-$3 asm-$2/arch
65  fi
66
67  # create link for s3c64xx SoC
68  if [ "$3" = "s3c64xx" ] ; then
69  rm -f regs.h
70  ln -s $6.h regs.h
71  rm -f asm-$2/arch
72  ln -s arch-$3 asm-$2/arch
73  fi
//$3表示第三个参数s3c64xx,所以满足68行的if语句,注意的是,这时还在include目录下操作
//删除regs.h文件,$6表示第6个参数s3c6410,所以“ln -s $6.h regs.h”表示“ln -s s3c6410.h regs.h”
//$2表示第2个参数arm,$3表示第三个参数s3c64xx,所以后面两句分别是
//rm -f asm-arm/arch
//ln -s arch-s3c6xx asm-arm/arch
74
75  if [ "$2" = "arm" ] ; then
76   rm -f asm-$2/proc
77   ln -s ${LNPREFIX}proc-armv asm-$2/proc
78  fi
//$2表示第2个参数arm,75行条件满足,还是在include目录下操作
//“rm -f asm-$2/proc”表示“rm -f asm-arm/proc”
//${LNPREFIX}为空,“ln -s ${LNPREFIX}proc-armv asm-$2/proc”表示“ln -s proc-armv asm-arm/proc”
79
80  # create link for s3c64xx-mp SoC
81  if [ "$3" = "s3c64xx-mp" ] ; then
82  rm -f regs.h
83  ln -s $6.h regs.h
84  rm -f asm-$2/arch
85  ln -s arch-$3 asm-$2/arch
86  fi
//$3表示第三个参数s3c64xx,81行条件不满足
87
88  #
89  # Create include file for Make
90  #
91  echo "ARCH   = $2" >  config.mk
92  echo "CPU    = $3" >> config.mk
93  echo "BOARD  = $4" >> config.mk
94
95  [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
96
97  [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk
//91-97行创建config.mk文件,并定义变量ARCH、CPU、BOARD、VENDOR、SOC
//91行用了'>'会创建config.mk文件,如果之前存在config.mk文件则将其清空,然后将变量输入到文件中,
//其他行的'>>'会将变量追加到文件中
//最后config.mk文件中的内容为:
//ARCH   = arm
//CPU    = s3c64xx
//BOARD  = smdk6410
//VENDOR = samsung
//SOC    = s3c6410
98
99  #
100 # Create board specific header file
101 #
102 if [ "$APPEND" = "yes" ] # Append to existing config file
103 then
104 echo >> config.h
105 else
106  > config.h  # Create new config file
107 fi
//创建开发板相关的头文件include/config.h
//前面定义了APPEN的值为“no”,102行条件不成立,执行else分支
//'>'会创建config.h文件,如果原来存在config.h文件,则会覆盖其中的内容清空。
108 echo "/* Automatically generated - do not edit */" >>config.h
109 echo "#include <configs/$1.h>" >>config.h
//108行表示向config.h中追加数据“/* Automatically generated - do not edit */”
//$1表示第一个参数smdk6410,所以109行表示向config.h文件中追加数据“#include <configs/smdk6410.h>”
110
111 exit 0
//执行完正常退出

现在总结下,配置命令“make smdk6410_config”,
实际的作用就是执行“./mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410”命令,
其产生的结果如下:
1、设置开发板名称BOARD_NAME为smdk6410
2、创建体系结构相关头文件链接,如下所示:
    ln -s asm-arm asm
    ln -s arch-s3c64xx asm-arm/arch
    ln -s proc-armv asm-arm/proc
3、创建顶层Makefile包含的头文件include/config.mk,如下所示:
    ARCH   = arm
    CPU    = s3c64xx
    BOARD  = smdk6410
    VENDOR = samsung
    SOC    = s3c6410
4、创建开发板相关头文件include/config.h,如下所示:
/* Automatically generated - do not edit */
#include <configs/smdk6410.h>

原创粉丝点击