zoukankan      html  css  js  c++  java
  • uboot的mkconfig分析

        uboot的mkconfig是一个shell脚本。对于笔者这种Linux学习初学者,不太可能认真的把shell脚本学习一遍。但是,倘若不能理解mkconfig的含义,又很难从整体的理解uboot(我认为只片面地理解程序代码,而不明白它们的连接、编译,也就是Makefile是不行的。对于致力于从事Linux开发者而言,总有一天要涉及到这方面的内容)。

        笔者认为“echo”是一个绝好的命令,它可以打印出我们想知道的很多内容的信息。以此类推,凡是能通过界面生动地告知我们计算机内部数据的工具,都是绝佳的。例如串口工具,当然这要归功于printf函数的强大功能。我就是通过这个命令,一点一点的把mkconfig中的内容打印出来,这样我们很容易就知道它的含义。首先,我把mkconfig的代码插入。红色字体的代码是我加入的打印命令。

     1 #!/bin/sh -e
     2 
     3 echo "$""#"=$#
     4 echo "$""1"=$1
     5 echo "$""2"=$2
     6 echo "$""3"=$3
     7 echo "$""4"=$4
     8 echo "$""5"=$5
     9 echo "$""6"=$6
    10 
    11 while [ $# -gt 0 ] ; do
    12     case "$1" in
    13     --) shift ; break ;;
    14     -a) shift ; APPEND=yes ;;
    15     -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
    16     *)  break ;;
    17     esac
    18 done
    19 
    20 echo "BOARD_NAME="$BOARD_NAME
    21 [ "${BOARD_NAME}" ] || BOARD_NAME="$1"
    22 echo "BOARD_NAME="$BOARD_NAME
    23 
    24 echo "$""#"=$#
    25 [ $# -lt 4 ] && exit 1
    26 [ $# -gt 6 ] && exit 1
    27 
    28 echo "Configuring for ${BOARD_NAME} board..."
    29 
    30 echo "$""SRCTREE="$SRCTREE
    31 echo "$""OBJTREE="$OBJTREE
    32 #
    33 # Create link to architecture specific headers
    34 #
    35 if [ "$SRCTREE" != "$OBJTREE" ] ; then
    36     mkdir -p ${OBJTREE}/include
    37     mkdir -p ${OBJTREE}/include2
    38     cd ${OBJTREE}/include2
    39     rm -f asm
    40     ln -s ${SRCTREE}/include/asm-$2 asm
    41     LNPREFIX="../../include2/asm/"
    42     cd ../include
    43     rm -rf asm-$2
    44     rm -f asm
    45     mkdir asm-$2
    46     ln -s asm-$2 asm
    47 else
    48     cd ./include
    49     rm -f asm
    50     ln -s asm-$2 asm
    51 fi
    52 
    53 rm -f asm-$2/arch
    54 
    55 if [ -z "$6" -o "$6" = "NULL" ] ; then
    56     ln -s ${LNPREFIX}arch-$3 asm-$2/arch
    57 else
    58     ln -s ${LNPREFIX}arch-$6 asm-$2/arch
    59 fi
    60 
    61 if [ "$2" = "arm" ] ; then
    62     rm -f asm-$2/proc
    63     ln -s ${LNPREFIX}proc-armv asm-$2/proc
    64 fi
    65 
    66 pwd
    67 #
    68 # Create include file for Make
    69 #
    70 echo "ARCH   = $2" >  config.mk
    71 echo "CPU    = $3" >> config.mk
    72 echo "BOARD  = $4" >> config.mk
    73 
    74 [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
    75 
    76 [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk
    77 
    78 #
    79 # Create board specific header file
    80 #
    81 if [ "$APPEND" = "yes" ]    # Append to existing config file
    82 then
    83     echo >> config.h
    84 else
    85     > config.h        # Create new config file
    86 fi
    87 echo "/* Automatically generated - do not edit */" >>config.h
    88 echo "#include <configs/$1.h>" >>config.h
    89 
    90 exit 0

        我再把运行结果图片贴出来。

       (1) 从中,我们不难看出$#、$1、$2、$3、$4、$5、$6的含义。$#代表传入参数的个数,$1代表第一个参数,一次类推。

       (2)第11到18行,是包含了"while[]"语句、case语句,并利用了break语句。这分别与c语言中的"while()"语句、switch-case语句、break语句类似。"-gt"是判断第一个数是否大于第二个数,这里放在"while[]"语句中也就好像是c语言中"while()"语句的条件判断,如果为真就循环。由于"$#"大于0,所以执行循环;又由于"$1"中没有"--"、"-a"、"-n"等符号,所以执行"*)"后边的break语句;break语句具有跳出循环的作用,所以就跳出这个循环。总结这一段语句并没有起到任何作用。

       (3)源代码第20行打印出"BOARD_NAME"是空的,而经过第21行的处理后,到了第22行打印的时候就变成了smdk2410,你就知道第21行做了什么样的工作。第21行的内容如下,中括号里边判断"BOARD_NAME"是否为真(有内容),"||"代表"else"的意思。由于一开始"BOARD_NAME"为空,所以执行BOARD_NAME="$1"。

    21 [ "${BOARD_NAME}" ] || BOARD_NAME="$1"

        (4)第24行到第26行,判断参数个数是否在允许范围内,如果不在就直接跳出。第25行内容如下,"-lt"是小于的意思,"&&"是“如果条件为真,就执行后边语句”的意思。首先判断"$#"是否小于4,由于"$#"不小于4,所以也不会执行“exit 1”这句话。

    25 [ $# -lt 4 ] && exit 1

         (5)第30到51行,目的是建立链接文件(我把链接文件理解为windows下的快捷方式)。                              

    30 echo "$""SRCTREE="$SRCTREE
    31 echo "$""OBJTREE="$OBJTREE
    32 #
    33 # Create link to architecture specific headers
    34 #
    35 if [ "$SRCTREE" != "$OBJTREE" ] ; then
    36     mkdir -p ${OBJTREE}/include
    37     mkdir -p ${OBJTREE}/include2
    38     cd ${OBJTREE}/include2
    39     rm -f asm
    40     ln -s ${SRCTREE}/include/asm-$2 asm
    41     LNPREFIX="../../include2/asm/"
    42     cd ../include
    43     rm -rf asm-$2
    44     rm -f asm
    45     mkdir asm-$2
    46     ln -s asm-$2 asm
    47 else
    48     cd ./include
    49     rm -f asm
    50     ln -s asm-$2 asm
    51 fi

       "if then else fi"语句跟c语言中if-else语句类似,只不过形式上有区别。第30到第31行,是打印出""SRCTREE"(源代码目录)、"OBJTREE"(目标代码目录)的内容。我们看到运行结果图片上打印的是空。这是因为mkconfig文件并没有定义这两个变量,所以直接使用就是空。事实上,这两个参数是从顶层Makefile中导出的,顶层Makefile中定义了这两个变量。

        可以看到,当使用"make smdk2410_config"命令来调用mkconfig脚本时,就能把Makefile中那两个参数传入到mkconfig脚本中。由于,if语句判断两个目录相同,所以执行else分支;先进入include目录中,然后把asm链接文件删除,再重新建立指向"asm-$2"的链接文件asm。通过"ls -l asm"命令可以看出asm文件与普通文件/文件夹的区别,你也可以在linux操作系统下查看"u-boot/inlclude"目录中asm文件的图标来理解这种链接文件的内涵。

        最后,我想谈一谈我对asm这个链接文件的认识。通过,执行"make smdk2410_config"命令,可以将asm-arm这个文件夹被调出来,而其他的例如asm-avr32那些则不会被调出来。通过建立asm这个链接文件,可以从众多的架构中只选择出对应架构的文件。

        (6)第53到64行是建立asm-$2/arch和asm-$2/proc这两个链接文件。建立方式,与(5)中建立asm链接文件的方法都一样,先将远离的链接文件删除,然后重新建立一个新的链接文件。"-z"是逻辑判断空串的意思,"-o"是逻辑或的意思。 

    53 rm -f asm-$2/arch
    54 
    55 if [ -z "$6" -o "$6" = "NULL" ] ; then
    56     ln -s ${LNPREFIX}arch-$3 asm-$2/arch
    57 else
    58     ln -s ${LNPREFIX}arch-$6 asm-$2/arch
    59 fi
    60 
    61 if [ "$2" = "arm" ] ; then
    62     rm -f asm-$2/proc
    63     ln -s ${LNPREFIX}proc-armv asm-$2/proc
    64 fi

        (7)第67到76行是在include目录下建立一个顶层Makefile包含的文件config.mk。">"是重定向符号,我的理解就是能够创建一个新的文件。">>"可以将ehco后边的字符串追加到config.mk后边,而不去覆盖它。

    67 #
    68 # Create include file for Make
    69 #
    70 echo "ARCH   = $2" >  config.mk
    71 echo "CPU    = $3" >> config.mk
    72 echo "BOARD  = $4" >> config.mk
    73 
    74 [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
    75 
    76 [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk

        (8)第78句到88句是在include目录下建立一个头文件config.h。建立的方法与(7)中建立config.mk的方法类似。

    78 #
    79 # Create board specific header file
    80 #
    81 if [ "$APPEND" = "yes" ]    # Append to existing config file
    82 then
    83     echo >> config.h
    84 else
    85     > config.h        # Create new config file
    86 fi
    87 echo "/* Automatically generated - do not edit */" >>config.h
    88 echo "#include <configs/$1.h>" >>config.h

        最后,我想谈谈我对include/config.h的认识。由于,uboot支持众多的开发板,所以在编译过程中,注定对应开发板的文件被编译,而那些不匹配的将被抛弃。而config.h可以看做是一个针对开发板预留的一个头文件,这里边究竟是哪个开发板的头文件,将来可以通过这部分shell程序添加进去。

    总结 

    (1)开发板名称BOARD_NAME等于$1

    (2)创建到平台/开发板相关的头文件的链接,如下所示

    ln -s asm-$2 asm
    ln -s arch-$6 asm-$2/arch
    ln -s pro-armv asm-$2/proc

    (3)创建顶层Makeflie包含的文件include/config.mk,如下所示:

    ARCH   = $2
    CPU    = $3
    BOARD  = $4
    VENDOR = $5
    SOC    = $6

    (4)创建开发板相关的头文件include/config.h,如下所示:

    /* Automatically generated - do not edit */ 
    #include <configs/$1.h>"

     

    参考资料:韦东山 《嵌入式Linux应用开发完全手册》

                  linux命令及shell.pdf

  • 相关阅读:
    Cookie和Session的区别
    get和post的区别
    TCP和UDP的区别
    TCP三次握手过程
    docker 安装prometheus
    大数据集群环境搭建之一 hadoop-ha高可用安装
    大数据集群环境 zookeeper集群环境安装
    Centos 脚本中几个特殊符号的作用笔记
    VMware 设置虚拟机Centos 上网的两种方式
    大数据集群环境搭建之一 Centos基本环境准备
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3385419.html
Copyright © 2011-2022 走看看