Uboot 2014.07 makefile分析 - 其他Cortex系列

uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是。
官网::
http://www.denx.de/wiki/U-Boot
ftp下载:
ftp://ftp.denx.de/pub/u-boot/

本文以uboot 2014.07为例,一般第一步总是类似这样:
make smdkc100_config
然后执行make

先看Makefile第481 行
%_config:: outputmakefile
@$(MKCONFIG) -A $(@:_config=)
当输入make smdkc100_config时,就会匹配到%_config目标,%是通配符,即输入XXX_config格式的目标就会匹配到%_config。
MKCONFIG的定义在前面:
MKCONFIG := $(srctree)/mkconfig
export MKCONFIG

srctree的定义:
srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))//if KBUILD_SRC被定义,则srctree=KBUILD_SRC,else = CURDIR,

KBUILD_SRC的定义:
ifeq ($(KBUILD_SRC),)
# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
#O就是output目录变量,使用方法:make O= XXXDIR
ifeq ("$(origin O)", "command line")
#如果O变量来自命令行(origin返回变量的来源)
  KBUILD_OUTPUT := $(O)
endif

事实上我没用O去定义KBUILD_SRC变量,所以srctree=当前目录,也就是uboot的目录
objtree := $(CURDIR)
src := $(srctree)

以上语句可翻译为:
smdkc100_config:: outputmakefile
./mkconfig -A $(@:_config=)

这里的规则用了双冒号 :: 
1.        双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。

$(@:_config=):请看Gnu Make中文手册5.3.1 变量的替换引用。
$(@)代表目标smdkc100_config,$(@:_config=):表示用等号后面的内容替代掉:和=之间的内容,=后面为空,那么_config就等于被删去了,$(@:_config=)就代表smdkc100
./mkconfig -A $(@:_config=)

现在可以看mkconfig文件了。mkconfig没有目标,从第一句开始执行:
第一个if段:

if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
# Automatic mode
line=`awk ‘($0 !~ /^#/ && $7 ~ /^‘"$2"‘$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }‘ $srctree/boards.cfg`
if [ -z "$line" ] ; then
echo "make: *** No rule to make target \`$2_config‘.  Stop." >&2
exit 1
fi

set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
fi

######    $#表示传入参数个数,由上可知$# = 2,符合条件。 -a表示逻辑与。$1表示第一个参数,等于-A,符合条件,所以then后面的语句被执行。
这段代码符号比较多,看起来比较复杂,请百度shell 符号,你会有所收获。

line=`awk**************`
用倒引号``把命令的输出作为字串,如果是"",则里面的内容不被当做命令执行,而是当做纯粹的字符串,但可引用变量
‘  ‘单引号内的内容作为字串,但变量$符号不会起作用(忽略任何引用),
单括号()内可以的内容可以执行命令,也就是说,()内先执行,再用‘‘把()的输出当做纯字串,大括号同理。
//斜杠表示里面的内容是正则表达式。
($0 !~ /^#/ && $7 ~ /^‘"$2"‘$/)
在awk命令里,$不是shell变量符号,而是域标记。但是也有例外:双引号""中的$可以引用变量(参见《LINUX与UNIX
SHELL编程指南》67页,9.2.2节,“域和记录”和第15章,引号),所以这里的$7
为boards.cfg里的域7,而$2则表示mkconfig的第二个参数,没错,就是smdkc100,/^‘"$2"‘$/表示只包含变量$2的行,依然是smdkc100。
$0表示所有域,$0 !~ /^#/ 意思是,awk排除以#开头的行,这句话用来排除那些以#开头的注释内容。$7 ~ /^‘"$2"‘$/表示记录的域7必须为smdkc100。

boards.cfg只有下面这行符合条件:
Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100
然后执行{ print $1, $2, $3, $4, $5, $6, $7, $8 }
这样line就等于Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100

接下来:
set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}

set命令
参见《高级bash脚本编程指南》202页
set 命令用来修改内部脚本变量的值.一个作用就是触发选项标志位来帮助决定脚本的行
为.另一个应用就是以一个命令的结果(set `command`)来重新设置脚本的位置参数.脚本
将会从命令的输出中重新分析出位置参数。

所以mkconfig 的位置参数被重新定义为$(line)的内容,即:
$1=Active  $2=arm         $3=armv7          $4=s5pc1xx    
$5=samsung         $6=smdkc100            $7=smdkc100
 $8=-(注意是短破折号,不是空格)
补充一下,以上排列为:
# Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options
 
对于[ $# = 3 ] && set ${line} ${1}:
&&的说明参见《LINUX与UNIX SHELL编程指南》6.1 使用&&
这里先判断$# 是否等于 3(明显不等),相等则执行&&右边的命令。那么,直接跳过吧。

1 while [ $# -gt 0 ] ; do
2     case "$1" in
3     --) shift ; break ;;
4     -a) shift ; APPEND=yes ;;
5     -n) shift ; BOARD_NAME="${7%_config}" ; shift ;;
6     -t) shift ; TARGETS="`echo $1 | sed ‘s:_: :g‘` ${TARGETS}" ; shift ;;
7     *)  break ;;
8     esac
9 done

其实上面的参数都不会匹配到。(没有指定-a -n -t选项)
这里只说一下${7%_config},结果等于smdkc100 ,请百度shell 截取 变量。

%号截取,删除右边字符,保留左边字符

echo ${var%/*}

%/* 表示从右边开始,删除第一个 / 号及右边的字符

实际上$7本身等于smdkc100了,那么${7%_config}依然是smdkc100。
后面的代码比较简单了,实现如下功能:

变量arch="arm"
建立软连接:
arch\arm\include\asm\arch-s5pc1xx 生成链接符号 arch\arm\include\asm\arch

进入include目录

01 # Create include file for Make
02 #
03 ( echo "ARCH   = ${arch}"
04     if [ ! -z "$spl_cpu" ] ; then
05 echo ‘ifeq ($(CONFIG_SPL_BUILD),y)‘
06 echo "CPU    = ${spl_cpu}"
07 echo "else"
08 echo "CPU    = ${cpu}"
09 echo "endif"
10     else
11 echo "CPU    = ${cpu}"
12     fi
13     echo "BOARD  = ${board}"
14  
15     [ "${vendor}" ] && echo "VENDOR = ${vendor}"
16     [ "${soc}"    ] && echo "SOC    = ${soc}"
17     exit 0 ) > config.mk

include目录下生成config.mk,内容为:
ARCH   = arm
CPU    = armv7
BOARD  = smdkc100
VENDOR = samsung
SOC    = s5pc1xx

include目录下创建config.h

for i in ${TARGETS} ; do
i="`echo ${i} | sed ‘/=/ {s/=/ /;q; } ; { s/$/ 1/; }‘`"
echo "#define CONFIG_${i}" >>config.h ;
done
 ${TARGETS} 为空,所以以上for循环不会被执行。

01 echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
02 echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
03 echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h
04  
05 [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
06  
07 [ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h
08  
09 [ "${board}"  ] && echo "#define CONFIG_BOARDDIR board/$BOARDDIR" >> config.h
10 cat << EOF >> config.h
11 #include <config_cmd_defaults.h>
12 #include <config_defaults.h>
13 #include <configs/${CONFIG_NAME}.h>
14 #include <asm/config.h>
15 #include <config_fallbacks.h>
16 #include <config_uncmd_spl.h>
17 EOF
18  
19 exit 0
1 cat << EOF >> config.h表示以下内容追加到config.h中,直到出现EOF标记为止。

最终config.h内容为:

01 /* Automatically generated - do not edit */
02 #define CONFIG_SYS_ARCH  "arm"
03 #define CONFIG_SYS_CPU   "armv7"
04 #define CONFIG_SYS_BOARD "smdkc100"
05 #define CONFIG_SYS_VENDOR "samsung"
06 #define CONFIG_SYS_SOC    "s5pc1xx"
07 #define CONFIG_BOARDDIR board/samsung/smdkc100
08 #include <config_cmd_defaults.h>
09 #include <config_defaults.h>
10 #include <configs/smdkc100.h>
11 #include <asm/config.h>
12 #include <config_fallbacks.h>
13 #include <config_uncmd_spl.h>
时间: 2024-10-25 01:35:09

Uboot 2014.07 makefile分析 - 其他Cortex系列的相关文章

uboot移植之makefile分析

/* Name:uboot之makefile分析 Data:2015-3-3 Author:suj_un */ Uboot之makefile分析 编译uboot,内核或者其他软件只需要执行make命令就可以生成可执行文件.执行命令后是怎么工作的?要知道这个就要看makefile了.现在就来揭开这玩意神秘的面纱.其中会粘一些代码段来分析... VERSION = 2010 PATCHLEVEL = 03 SUBLEVEL = EXTRAVERSION = ifneq "$(SUBLEVEL)&qu

uboot主Makefile分析(t配置和编译过程详解)

1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_config  跳转执行mkconfig用来配置并生成config.mk(board/samsung/x210目录下为指定链接地址的与主uboot目录的config.mk不同) autuconfig.mk 2.框图 3.uboot主Makefile分析 3.1.uboot version确定(Make

Tiny4412 uboot Makefile 分析

* Build uboot a) 安装好toolchain (arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz)并设置好 环境变量PATH,保证可以正常使用.b) 解压 uboot_tiny4412-20130729.tgz 并进入相应的目录 tar xzf uboot_tiny4412-20130729.tgzc) 配置 uboot 并编译 cd uboot_tiny4412 make tiny4412_config maked) 编译 用于生成bl2 的工具 m

u-boot顶层Makefile分析

1.u-boot制作命令 make forlinx_nand_ram256_config: make all; 2.顶层mkconfig分析,参考 U-BOOT顶层目录mkconfig分析 mkconfig脚本执行后会生成以下3个文件,这些文件中提供的变量会在Makefile中其它地方使用. 116 # load ARCH, BOARD, and CPU configuration 117 include $(OBJTREE)/include/config.mk 118 export ARCH

u-boot的Makefile分析

由顶层Makefile文件,梳理U-Boot的编译流程. 小技巧: 在大型Makefile中,很多时候需要确定某个变量的值,一个小方法就是: $(shell echo "VARIABLE0_VAL = $(VARIABLE0_VAL)" > v_file.txt ) $(shell echo "VARIABLE1_VAL = $(VARIABLE1_VAL)" >> v_file.txt ) 1.首先,确定make过程中需要的变量(Makefile

U-Boot移植之前期分析(上)

老是看别人移植uboot,用别人移植好的uboot,今天终于下定决心自己移植一个uboot来玩玩,好歹我也是个软件开发人员啊. 第一步:去ftp://ftp.denx.de/pub/u-boot/网站下载个uboot工程源码,为了防止环境出问题,我决定用个老一点的,于是就下了:u-boot-1.1.6.tar.bz2. 第二步:解压源码:tar  jxvf  u-boot-1.1.6.tar.bz2. 第三步:建立source insight工程 好了完成以上三步之后,我们需要的前提条件都准备好

uboot移植——uboot源码目录分析

uboot移植(一)--uboot源码目录分析 本文分析的uboot是九鼎官方提供的,是对应s5pv210开发板x210bv3的uboot 一:uboot的概念及移植的原理. uboot就是在内核运行前的一段小程序,用来初始化硬件设备,建立内存空间映射图.从而将系统的软硬件带到合适的状态,主要功能就是为了启动内核,它将内核从flash中拷贝到ddr中,然后跳转到内核入口中,交由内核控制权,uboot严重依赖硬件,因此一个通用的uboot不太可能. 移植原理:uboot中有很多平行代码,各自属于各

E2 2014.07.01 更新日志

增加功能 完善功能 电话报修单,添加可以发短信通知客户和技术员选项 商品历程分析,增加按商品分类条件统计 修件库,增加可以按维修商条件过滤,以方便查询某维修商的返修件 维修中,备件转销售时,自动读取客户适用价格 修件库和服务维修明细表增加按客户电话查询条件 收款单和付款单中,如果实际收付款比结帐多,多出来的款项,增加到预收(付)款中. 收入单和支付单,增加欠款支持 修正BUG 修正快修中,存在销售商品,而且销售数量大于1时,如果非现场审核,则出现不能后期审核问题. 修正价格策略中,动态公式检查,

16.U-boot的工作流程分析-2440

16.U-boot的工作流程分析-2440 分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makefile: Uboot所支持的开发板,在顶层的Makefile中都会有一个配置选项.比如2440,在Makefile中的配置选项是smdk2440_config:在vim的命令模式按下/,然后输入smdk6410_config回车会定位到这里: 这是Makefile里的一个目标.这是来配置2440开发