(三)u-boot2013.01.01 for s5pv210:《mkconfig分析》
来源:互联网 发布:网络直播受众范围 编辑:程序博客网 时间:2024/06/01 11:20
转载地址:http://blog.csdn.net/zsy2020314/article/details/9312147
- /* 和分析makefile一样,分析mkconfig同样注重句法分析 */
- #####################################################################
- #!/bin/sh -e
- # 上面这句指定执行该脚本所使用的解释器, -e相当于使用/bin/bash
- # Script to create header files and links to configure
- # U-Boot for a specific board.
- # Parameters: Target Architecture CPU Board [VENDOR] [SOC]
- # (C) 2002-2010 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
- #
- #####################################################################
- # mkconfig脚本文件存在的理由:因为uboot是一个多CPU多架构的统一bootloader,为了完成针
- # 对特定目标单板,目标架构的编译,需要给Makefile指明,哪些文件需要编译,相当与从整体上控制
- # 需要编译的cpu,单板等。
- # 当执行make xxx_config U-boot时就会调用这个mkconfig文件。mkconfig会处理单板信息
- # (在boards.cfg文件中定义有各种单板信息,smdkc100_config只是其中一个)并生成单板信息到
- # U-boot源码顶层目录/include/config.mk这个文件中(会自动创建)。
- # 以make smdkc100_config为例,执行成功后,mkconfig会产生5个变量分别为:
- # ARCH CPU BOARD VENDOR SOC
- # arm armv7 smdkc100 samsung s5pc1xx
- # (ARCH=目标板的CPU架构 CPU=具体使用的CPU型号 BOARD = 目标板名称 SOC = 芯片名称)
- APPEND=no # 默认创建一个新的配置文件
- BOARD_NAME="" # make 执行xxx_config的时候打印输出单板名
- TARGETS=""
- arch=""
- cpu=""
- board=""
- vendor=""
- soc=""
- options=""
- #####################################################################
- # SHELL常用内部参数:
- # $# ----传递给程序的总的参数数目
- # $? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。
- # $* ----传递给程序的所有参数组成的字符串。
- # $n ----表示第几个参数,$1 表示第一个参数,$2 表示第二个参数 ...
- # $0 ----当前程序的名称
- # $@ ----以"参数1" "参数2" ... 形式保存所有参数
- # $$ ----本程序的(进程ID号)PID
- # $! ----上一个命令的PID
- # 下面对$?多做些说明,当补充shell知识吧
- # 切记:$?永远表示shell命令最后一次执行后的退出状态,当函数执行完毕后,如果又执行了其它命
- # 令,则$?不再表示函数执行后的状态,而表示其它命令的退出状态.
- #-a 表示(and)两个条件同时成立
- # -eq 表示两数值相等
- # -gt 表示n1大于n2,即前面大于后面
- # -lt 表示n1小于n2,即前面小于后面
- # "\(" "\)"是对圆括号的转义,转成普通圆括号"()"来包裹条件表达式
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # !!!!注意!!!:从下面开始我们做个约定$0,$1,$2,...我们称$0为第0个变量,$1为第1个变量!!!!
- # !!!!!这样排号从描述上比较便!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # if[...]中的表达式意思为:如果传递给mkconfig的参数个数($#)等于2个并且第1个变量为
- # "-A"($1),则执行出错提示.那么$0,$1,$2,...是什么呢?我们看Makefile中是怎么执行make
- # xxx_config这个伪目标的.
- # Makefile中是这么写的:
- # %_config:: unconfig
- # @$(MKCONFIG) -A $(@:_config=)
- # MKCONFIG的值为mkconfig(这是在Makefile里有定义的,自己搜索一下就可以到),$(MKCONFIG)
- # 就是执行mkconfig脚本,则传入的参数 $0=U-boot源码顶层目录/mkconfig $1 = -A $2 =
- # $(@:_config),当我们输入的是make smdkc100_config时$(@:_config) = smdkc100,所以# 这个表达式意思是把输入的参数中的字符串"_config"去掉然后返回剩下的部分,
- # smdkc100_config去掉"_config"后当然就剩下"smdkc100",所以$(@:_config) = smdkc100,
- # 进而$2 = $(@:_config) = smdkc100。所以很明显,执行@$(MKCONFIG) -A $(@:_config=)
- # 后,传入给mkconfig的参数的确是有两个并且第1个变量$1=-A,所以if表达式为真然后会执行then
- # 后面的脚本语句!!
- if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
- ########################################################################
- # egrep是grep的扩展,egrep支持扩展型的正则表达式。-i参数表示不区分大小写。
- # "^[[:space:]]*${2}[[:space:]]"。'^'表示反向选择,'*'是通配符,代表任意(0个或
- # 多个)字符*${2}则表示1个以上的任意多个${2}。所以这个表达式的意思是:从boards.cfg文
- # 件中搜索符合条件:非空格开头但以空格结尾的包含至少1个"smdkc100"字符串的行.如果搜索
- # 不到,则说明不存在对应的单板信息,则会报错说找不到创建目标的规则并退出不再执行脚本。
- # !!!说了这么多,总结起来这个if判断表达式所做的工作就是从boards.cfg文件中找到执行
- # xxx_config的单板信息,找不到就无法完成单板配置,U-boot编译自然也无法完成!!!!
- line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
- echo "make: *** No rule to make target \`$2_config'. Stop." >&2
- exit 1
- }
- ########################################################################
- # 了解这句的意思前先做些功课吧,看完不用我解释相信你也清楚是干嘛用的了
- # 扩展阅读:set,env和export这三个命令都可以用来显示shell变量,其区别是什么?
- # set 用来显示本地变量
- # env 用来显示环境变量
- # export 用来显示和设置环境变量
- # set 显示当前shell的变量,包括当前用户的变量
- # env 显示当前用户的变量
- # export 显示当前导出成用户变量的shell变量
- # 每个shell有自己特有的变量(set)显示的变量,这个和用户变量是不同的,当前用户变量和你
- # 用什么shell无关,不管你用什么shell都在,比如HOME,SHELL等这些变量,但shell自己的
- # 变量不同,shell是不同的,比如BASH_ARGC, BASH等,这些变量只有set才会显示,是bash
- # 特有的,export不加参数的时候,显示哪些变量被导出成了用户变量,因为一个shell自己的变
- # 量可以通export “导出”变成一个用户变量。set ${line}意思是设置line中的变量为本地环
- # 境变量,变量的集合为line,你可以在这句的下面加上显示本地环境变量的语句echo `set`,
- # 终端会打印出所有本地变量,找一下就可以发现其中有一句内容是:line = 'smdkc100 arm #
- # armv7 smdkc100 sansung s5pc1xx'。要是缺少了set ${line}就等着出错吧!(上述结果
- # 是基于make smdkc100_config而言的)
- set ${line}
- #echo `set` # 删掉echo前面的'#',该语句将会被执行。2012-12-25圣诞节^_^
- #######################################################################
- # 如果boards.cfg搜索到的单板信息行的变量只有3个,如果有需要的话则把变量${1}作为默认
- # 单板名称
- [ $# = 3 ] && set ${line} ${1}
- ###########################################################################
- # 接上面的if表达式的分支,即如果make smdkc100_config时,即执行
- # %_config:: unconfig
- # @$(MKCONFIG) -A $(@:_config=)
- # 后传入的参数不是2个或者第1个变量不是-A则执行elif下面的判断
- # 如果${MAKEFLAGS+set}${MAKELEVEL+set} = setset则向终端打印警告信息并使用sleep 5
- # 来做延时提示,延时一下信息会停留在终端一段时间然后继续往下执行,这样做只是为了让程序猿更
- # 容易注意到这个这个警告条目吧,我的想法是这样的,有更好解释的可以告知我,谢谢!"cat << -EOF
- # 信息 EOF" 是用来显示文本内容的,EOF就是"end of file"的意思实际上正常情况下
- # "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset"是成立的,只是执行if了。所以轮不到
- # elif执行!
- elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then
- # only warn when using a config target in the Makefile
- cat <<-EOF
- warning: Please migrate to boards.cfg. Failure to do so will
- mean removal of your board in the next release.
- EOF
- sleep 5
- fi
- ###########################################################################
- # 如果上面一切正常的话,执行了make smdkc100_config后就会有6个变量传进来,分别是:
- # smdkc100 arm armv7 smdkc100 sansung s5pc1xx
- # 此时$# = 6,while [ $# -gt 0 ]的意思就是当S#不为0时循环执行do ... done之间的语句
- # shift的作用是使$1=$2,$2=$3,$3=$4….,而原来的$1将丢失。因此while循环的作用是,依次# 处理传递给mkconfig脚本的选项(--,-a,-n,-t,*)。由于我们并没有传递给mkconfig任何的选
- # 项,因此while循环中的代码不起作用。具体的处理是比较简单了,既然没用到也就不多废话了。
- while [ $# -gt 0 ] ; do
- 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
- ###########################################################################
- # 检查如果传进来的变量个数,如果小于4个则退出,若大于7个也要退出
- [ $# -lt 4 ] && exit 1
- [ $# -gt 7 ] && exit 1
- ###########################################################################
- # 变量赋值,CONFIG_NAME = smdkc100,${1%_config}意思是将$1的字符串右边拿掉"_config"(如果有的话)
- CONFIG_NAME="${1%_config}"
- ###########################################################################
- # 如果BOARD_NAME(单板名称)不为空则什么都不做,如果为空则BOARD_NAME="${1%_config}
- # ${1%_config}意思是将$1的字符串右边拿掉"_config"(如果有的话)
- # 脚本文件开头BOARD_NAME = "",所以执行下句后BOARD_NAME = smdkc100
- [ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
- ###########################################################################
- # arch = arm
- # 处理cpu赋值时,先用echo $3读入要处理的信息行,即armv7,armv7会被赋值到$1中,即$1=armv7
- # 而$2 = 空,然后awk 'BEGIN {FS = ":"}; {print $1}'意思是以冒号为分隔符,提取出输入
- # 行的第一个变量,结果是cpu = armv7。同理spl_cpu = $2,而$2为空,所以spl_cpu为空
- arch="$2"
- cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
- spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
- ###########################################################################
- # 如果$4的值为'-',则board = ${BOARD_NAME} = "smdkc100"(正常情况下),
- # 否则board="$4"="smdkc100",为什么这么做呢,其实是为了防止boards.cfg中单板信息不足的
- # 情况下还能从ARCH信息中把单板名字提取出来然后复制给board变量。(PS:开发者想得真周到)
- if [ "$4" = "-" ] ; then
- board=${BOARD_NAME}
- else
- board="$4"
- fi
- ###########################################################################
- # 当传进来的变量数目大于4的时候而且第5个变量不等于"-"时vendor="$5"="samsung"
- # 当传进来的变量数目大于5的时候而且第6个变量不等于"-"时soc="$6"="s5pc1xx"
- # 当传进来的变量数目大于6的时候而且第7个变量不等于"-"时执行{..}中的处理
- [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
- [ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
- [ $# -gt 6 ] && [ "$7" != "-" ] && {
- # check if we have a board config name in the options field
- # the options field mave have a board config name and a list
- # of options, both separated by a colon (':'); the options are
- # separated by commas (',').
- #
- # Check for board name
- #############################################################
- # 检查在选项区域(Options)中是否存在一个单板配置选项,该选项区域可能含有单板名称和选项
- # 表。单板名称和选项之间使用':'做分隔符,选项表成员之间则用','做分隔符
- # 举例:对于mx51_efikamx单板来说,它的Options为:
- # mx51_efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/genesi/m
- # x51_efikamx/imximage_mx.cfg即
- #"$7"="mx51_efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/g
- # enesi/mx51_efikamx/imximage_mx.cfg"
- # ${7%:*}:从字符串"$7"右边开始删掉字符,直到遇到(从右部数起的)第一个':'
- # temp = mx51_efikamx
- tmp="${7%:*}"
- # 如果tmp不是空的则配置名称CONFIG_NAME = "$tmp" = "mx51_efikamx"
- if [ "$tmp" ] ; then
- CONFIG_NAME="$tmp"
- fi
- # 注意!确保Options域中的内容中只有一个':'号
- # "${tmp}" != "$7"用这句来做比较,确认上一步处理是否成功
- # ${7#*:},这个表达式意思是从字符串"$7"左边开始删掉直到遇到第一个':'为止
- # options=${7#*:}=MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/genes
- # i/mx51_efikamx/imximage_mx.cfg
- # echo ${options}这句是将options作为sed的处理源
- # sed 's:,: :g',开头的's'代表搜索,搜索','然后把搜索到的','替换成空格' '
- # TARGETS = MACH_TYPE=MACH_TYPE_MX51_EFIKAMX
- # IMX_CONFIG=board/genesi/mx51_efikamx/imximage_mx.cfg
- if [ "${tmp}" != "$7" ] ; then
- options=${7#*:}
- TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"
- fi
- }
- ###########################################################################
- # 如果变量ARCH的值存在而且变量ARCH的值与变量arch的值不相等的话则配置失败,打印错误信息
- # ARCH和arch必须相等!
- if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
- echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
- exit 1
- fi
- ###########################################################################
- # 如果options存在则把options信息一并打印出来,否则的话就没必要打印!
- # 这里就是我们执行make xxx_config后会打印到终端上的信息!
- if [ "$options" ] ; then
- echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
- else
- echo "Configuring for ${BOARD_NAME} board..."
- fi
- ###########################################################################
- # 如果源码顶层目录(SRCTREE)和存放编译生成文件的目录(OBJTREE)不一致的话就在
- # 存放编译生成文件的目录(OBJTREE)建立两个文件include和include2
- # 然后进入include2目录中,删除asm文件夹,建立一个 软链接asm,链接指向目录
- # ${SRCTREE}/arch/${arch}/include/asm
- # LNPREFIX多加了一个'/'作为路径,然后退到上层目录进入include文件夹,创建一个名为asm的文# 件夹
- if [ "$SRCTREE" != "$OBJTREE" ] ; then
- mkdir -p ${OBJTREE}/include
- mkdir -p ${OBJTREE}/include2
- cd ${OBJTREE}/include2
- rm -f asm
- ln -s ${SRCTREE}/arch/${arch}/include/asm asm
- LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
- cd ../include
- mkdir -p asm
- else
- ########################################################################
- # 如果二者目录相同的话就直接进入当前目录(此时当前目录就是U-boot源码的顶层目录)的
- # include文件夹中删除 asm文件夹,直接建立一个软链接asm,链接指向目
- # 录../arch/${arch}/include/asm
- # 一般我们采用这个分支的方法来编译U-boot,OBJTREE目录就是U-boot源码顶层目录相当于
- # ln -s ../arch/arm/include/asm asm
- cd ./include
- rm -f asm
- ln -s ../arch/${arch}/include/asm asm
- fi
- ###########################################################################
- # 删除 asm/arch,这个时候的asm是个软连接,实际上是对链接的目标进行操作,建立软件接的目的就# 是方便程序的编写和编译,提高效率,你写程序的时候总不想常常打一长串的路径吧
- rm -f asm/arch
- ###########################################################################
- # 如果soc不为空则建立软连接asm/arch,指向${LNPREFIX}arch-${cpu},由于OBJTREE目录就是
- # U-boot源码顶层目录,LNPREFIX为空
- # 一般soc也不为空,则相当于执行: ln -s arch-armv7 asm/arch
- if [ -z "${soc}" ] ; then
- ln -s ${LNPREFIX}arch-${cpu} asm/arch
- else
- ln -s ${LNPREFIX}arch-${soc} asm/arch
- fi
- ###########################################################################
- # 如果架构是arm架构,则删除当前目录(此时当前目录是U-boot源码顶层目录/include)下的
- # asm/proc目录建立软链接ln -s proc-armv asm/proc
- if [ "${arch}" = "arm" ] ; then
- rm -f asm/proc
- ln -s ${LNPREFIX}proc-armv asm/proc
- fi
- ###########################################################################
- # 生成make的头文件config.mk
- # ARCH=arm CPU=armv7 BOARD=smdkc100 VENDOR=samsung SOC=s5pc1xx
- # 加一个exit0(返回成功值),然后这些统统写入config.mk文件中, > config.mk是强行覆盖创建# config.mk然后把数据导入config.mk中
- ( 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
- ###########################################################################
- # 如果厂商名不为空则BOARDDIR = ${vendor}/${board},vendor=samsung,所以
- # BOARDDIR = samsung/smdkc100
- if [ -z "${vendor}" ] ; then
- BOARDDIR=${board}
- else
- BOARDDIR=${vendor}/${board}
- fi
- ###########################################################################
- # 创建指定的配置的头文件,默认APPEND=no(本文件开头有赋值),所以执行else分支,创建
- # config.h文件
- if [ "$APPEND" = "yes" ] # Append to existing config file
- then
- echo >> config.h
- else
- > config.h # Create new config file
- fi
- ###########################################################################
- # 向config.h中写入信息
- echo "/* Automatically generated - do not edit */" >>config.h
- ###########################################################################
- # 如果没有Options选项的话,TARGETS为空,for不执行,如果有Options选项,则i=TARGETS中变# 量的个数变量之前已经被处理成以空格符' '分隔,例如:TARGETS =
- # MACH_TYPE=MACH_TYPE_MX51_EFIKAMX
- # IMX_CONFIG=board/genesi/mx51_efikamx/imximage_mx.cfg,然后用echo ${i}逐条导入
- # sed进行处理,sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'的作用是搜索等号'=',然后把
- # 等号替换成TAB符' ',接着参数q意思是退出当前动作执行下一个动作,下一个动作用分号';'分隔,
- # 最后加上#define CONFIG_${i}后写入config.h中。
- # "MACH_TYPE=MACH_TYPE_MX51_EFIKAMX"处理成:
- # "#define CONFIG_MACH_TYPE MACH_TYPE_MX51_EFIKAMX"
- # "IMX_CONFIG=board/genesi/mx51_efikamx/imximage_mx.cfg"处理成:
- # "#define CONFIG_IMX_CONFIG board/genesi/mx51_efikamx/imximage_mx.cfg"
- for i in ${TARGETS} ; do
- i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"
- echo "#define CONFIG_${i}" >>config.h ;
- done
- ###########################################################################
- # 如果是smdkc100,config.h中会多出以下头文件
- # #define CONFIG_SYS_ARCH "arm"
- # #define CONFIG_SYS_CPU "armv7"
- # #define CONFIG_SYS_BOARD "smdkc100"
- # #define CONFIG_SYS_VENDOR "samsung"
- # #define CONFIG_SYS_SOC "s5pc1xx"
- echo "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.h
- echo "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.h
- echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h
- [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
- [ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.h
- ###########################################################################
- # 添加别的头文件,利用cat << EOF >> config.h ...内容... EOF把信息写入config.h中
- cat << EOF >> config.h
- #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>
- EOF
- # 返回成功状态
- exit 0
0 0
- (三)u-boot2013.01.01 for s5pv210:《mkconfig分析》
- (三)u-boot2013.01.01 for s5pv210:《mkconfig分析》
- (四)u-boot2013.01.01 for s5pv210:《mkconfig分析》
- (四)u-boot2013.01.01 for s5pv210:《mkconfig分析》
- u-boot2013.01.01 for s5pv210:《Makefile分析》
- (二)u-boot2013.01.01 for s5pv210:《Makefile分析》
- (二)u-boot2013.01.01 for s5pv210:《Makefile分析》
- (七)u-boot2013.01.01 for s5pv210:《u-boot启动流程》
- u-boot2013.01.01 for s5pv210:《u-boot启动流程》
- u-boot2013.01.01 for s5pv210: u-boot启动流程
- (七)u-boot2013.01.01 for s5pv210:《u-boot启动流程》
- (一)u-boot2013.01.01 for s5pv210:《Uboot简介》
- (一)u-boot2013.01.01 for s5pv210:《Uboot简介》
- (五)u-boot2013.01.01 for s5pv210:《移植前的准备及u-boot初编译》
- (六)u-boot2013.01.01 for s5pv210:《精简u-boot文件目录,定制自己的目标板》
- (五)u-boot2013.01.01 for s5pv210:《移植前的准备及u-boot初编译》
- S5PV210-uboot解析(一)-mkconfig分析
- u-boot mkconfig文件分析
- 关于GWT使用servlet的图形验证码
- POJ2186 Popular Cows
- redis---应用的场景
- 给Webkit内核的浏览器控件增加互交功能
- Centos6.3 修改静态ip
- (三)u-boot2013.01.01 for s5pv210:《mkconfig分析》
- 《城市建设理论研究》期刊杂志投稿
- 查找符合半径范围内的精灵
- 的发射点发的司法所地方
- yum
- Qt linux下设置系统时间
- Asce's Summer Ranking No.6
- Linux Shell 中的反引号,单引号,双引号
- (四)u-boot2013.01.01 for s5pv210:《mkconfig分析》