目录
一、在UBoot命令行中依次测试使用CMD,记录调用过程,整理自己的理解。
本题作业详见链接:Uboot命令理解与实践
PS:整理成Markdown文档后转成pdf时,发现图片太小而无法清晰查看,因此将自己的整理发布于优快云平台。
二、参照第5章节内容在UBoot代码中添加⼀个CMD,并在UBoot命令行中完成该CMD的调用。命令实际执行内容自行设计。
添加了一个名为hello
的CMD,执行该命令时会向控制台输出“Welcome to Siflwoer!”
的欢迎提示语,如下图所示。
设计该命令时,主要参考了uboot/cmd
目录下的version.c
文件。以下是输入help
命令时,hello
命令的使用说明与详细信息。
Makefile
的更改如下所示。
hello.c
#include <common.h>
#include <command.h>
#include <version.h>
#include <linux/compiler.h>
#ifdef CONFIG_SYS_COREBOOT
#include <asm/arch/sysinfo.h>
#endif
const char __weak hello_string[] = "Welcome to Siflower!";
static int do_hello(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
printf("\n%s\n", hello_string);
return 0;
}
U_BOOT_CMD(
hello, 1, 1, do_hello,
"print a welcome message",
""
);
三、结合编译脚本和Makefile理解UBoot的编译流程,并进行整理记录。
以下是编译脚本的源码,添加了一些自己阅读时的注释。
#!/bin/sh
#1、通过传参对config、ver、flash、pcba进行初始化
config=sfa28_evb
ver=fullmask
flash="0"
pcba="0"
#$1 should be p10 or p20 p10m 86v
if [ -n "$1" ]; then
config=$1
fi
if [ -n "$2" ]; then
ver=$2
fi
if [ -n "$3" ]; then
flash=$3
fi
if [ -n "$4" ]; then# 如果传入了第4个参数,就赋给pcba
pcba=$4
fi
#2、根据当前的 Git 仓库状态来获取当前分支、版本号以及最新的提交哈希值
git branch > /dev/null 2>&1 #输出静默化,不在终端显示
if [ ! $? -eq 0 ] ; then #判断当前目录是否是一个 Git 仓库,如果不是则设置分支为 “default”,版本号为 “0.0”
echo "dose not exist git base"
tag="0.0"
branch="default"
else
# branch=`git branch -r | grep "\->" |awk -F "/" 'END{print $NF}'`
local_branch_name=`git branch -vv |grep "*" |awk '{print $2}'`# 获取本地当前分支的名称
# echo "local branch name $local_branch_name"
if [ "$local_branch_name" = "(no" ]; then
echo "branch set fail no local branch"
exit 1
fi
branch=`git branch -vv |grep "*" | awk -F "[][]" '{print $2}'| awk -F "[/:]" '{print $2}'` #获取当前分支的名称
echo "branch is $branch"
# handle release branch case release branch name is not release!!!
is_86v_release=$(echo $branch | grep "release.86v")
is_rep_release=$(echo $branch | grep "release.rep")
isrelease=$(echo $branch | grep "release")
if [ "$is_86v_release" != "" ];then
branch="release.86v"
elif [ "$is_rep_release" != "" ];then
branch="release.rep"
elif [ "$isrelease" != "" ];then
branch="release"
fi
# need to use tag for rep
is_rep_board=$(echo $config | grep "rep")
if [ "$is_rep_board" != "" ];then
tag=`git tag | grep "${branch}.rep-" | sort -V | awk 'END{print}'`
else
tag=`git tag | grep "${branch}-" | sort -V | awk 'END{print}'`
fi
if [ ! -n "$tag" ] ;then
#compatible with old version
tag=`git tag | grep -v "v" | sort -V | awk 'END{print}'`
version=$tag
else
version=`printf "$tag" | awk -F "[-]" '{print $2}'`
fi
echo "version is $version"
tag_commit=`git show $tag|grep ^commit | awk '{print substr($2,0,7)}'`
echo "tag commit $tag_commit"
last_commit=`git rev-parse --short HEAD`
echo "last commit $last_commit"
if [ $tag_commit != $last_commit ]; then
commit_suffix=$last_commit
fi
fi
echo "build config is $config"
# 根据pcba的值确定target_bin的路径
if [ "$pcba" = "1" ]; then
target_bin="sfax8/u-boot.img"
else
target_bin="sfax8/uboot_full.img"
fi
if [ "$pcba" = "1" ]; then
uboot_or_pcba=pcba
else
uboot_or_pcba=uboot
fi
# 3、构建生成文件的名称,并执行构建操作
if [ -n "$commit_suffix" ]; then
prefix=${uboot_or_pcba}_${branch}_${config}_${ver}_${version}_${commit_suffix}
else
prefix=${uboot_or_pcba}_${branch}_${config}_${ver}_${version}
fi
echo "branch=$branch config=$branch ver=$ver version=$version" #在这里貌似有点问题,为什么config的值还是$branch?
rm $target_bin -rf
./sf_make.sh cmd=clean prj=$config ver=$ver
./sf_make.sh prj=$config ver=$ver flash=$flash pcba=$pcba
if [ -f $target_bin ]; then
cp $target_bin ${prefix}.bin
else
echo "build fail, don't get target_bin"
fi
echo "build end"
在阅读uboot/cmd/Makefile
文件时候(如上图),发现其中主要有两类语句,如下。
obj-y += hello.o
obj-$(CONFIG_CMD_ZIP) += zip.o
当在Makefile
中编写这行代码时,它告诉构建系统将hello.o
添加到obj-y
变量所代表的目标文件列表中。在Makefile
中,目标文件列表通常用来指定要编译的源文件,最终生成可执行文件时所需的目标文件。obj-y
是在Makefile
中定义的一个变量,例如:obj-y := main.o foo.o bar.o
,这里的obj-y
变量包含了构建系统将要编译的目标文件。通过使用+=
运算符,可以将新的目标文件添加到变量中,例如:obj-y += hello.o
。这将在构建时将hello.o
包括在最终的目标文件列表中,使得hello.o
被编译并链接到可执行文件中。在构建过程中,如果obj-y 中的某个目标文件发生变化,系统将重新编译该文件,并重新生成最终的可执行文件。
obj-y
表示编译进内核,变量obj-y
表示需要编译到内核中的目标文件名集合obj-m
表示编译成模块,会生成一个独立的 “xxx.ko” 文件obj-$(CONFIG_PPC)
中$(CONFIG_PPC
表示一个变量
比如定义CONFIG_PPC=y
$(CONFIG_PPC)
就是y
obj-$(CONFIG_PPC)
就是obj-y
又比如定义CONFIG_PPC=m
$(CONFIG_PPC)
就是m
obj-$(CONFIG_PPC)
就是obj-m