linux下uboot编译和移植过程

一、获取u-boot源码

1、u-boot官方获取(DENX)
https://ftp.denx.de/pub/u-boot/
2、从芯片厂家获取
3、从开发板厂家获取
4、从部门主管获取
三星没有将S5p6818的硬件支持的源码开源到u-boot官方,
不可以从官方获取u-boot源码,

注:本次实验使用的是u-boot-2014.07版本 开发板是FS6818 芯片S5p6818

二、u-boot版本的选择

1、不选择太新
2、不选择太旧
3、选择稳定版本
rc:表示测试版

三、移植的准备工作

获取硬件平台的信息
cpu :Cortex-A53
arch:arm
SOC :S5P6818
vendor :samsung
board :FS6818 —》 参考三星S5P6818的公板

四、移植u-boot源码

1、准备u-boot源码
1)、拷贝u-boot源码到ubuntu中

2)、解压缩
tar -vxf u-boot-2014.07-netok.tar.bz2

3)、进入到u-boot源码目录
cd u-boot-2014.07

注:u-boot源码不要再共享目录或者windows下解压

2、分析u-boot源码的目录
平台相关代码:代码跟硬件相关
arch
board
平台无关代码:代码跟硬件无关
include
fs
lib
drivers

3、配置和编译u-boot源码
配置:配置u-boot源码支持S5P6818平台
编译:生成ubootpak.bin镜像文件

u-boot源码使用Makefile工具对工程进行配置和管理。

清除中间文件:
clean
distclean
编译u-boot源码:
all

make <board_name>_config 的作用
配置u-boot源码支持当前自己的硬件平台,
决定了最终哪些源码编译到ubootpak.bin镜像中,
哪些不编译到ubootpak.bin镜像中。

4、u-boot源码配置和编译过程详解

1)、 配置使用交叉编译器编译u-boot源码
在u-boot源码的顶层目录中指定交叉编译器。

 198 ifeq ($(HOSTARCH),$(ARCH))
 199 CROSS_COMPILE ?=                                                
 200 endif

修改为:

198 ifeq (arm,arm)
199 CROSS_COMPILE ?= arm-none-linux-gnueabi-
200 endif

2)、清除u-boot源码的中间文件
make distclean
3)、 配置u-boot源码支持FS6818开发板
make fs6818_config
回显一下信息表示成功:
Configuring for fs6818 board…
4)、 编译u-boot源码
make / make all
time make : 回显编译的时间
make -jn : 多线程编译

回显一下信息表示编译成功:
  LDS     u-boot.lds
  LD      u-boot
  OBJCOPY u-boot.srec
  OBJCOPY u-boot.bin
./tools/mk6818 ubootpak.bin nsih.txt 2ndboot u-boot.bin
NSIH : 188 line processed.
NSIH : 512 bytes generated.
Generate destination file: ubootpak.bin

五、分析make <board_name>_config命令执行过程详解

具备能力:Makefile Shell

1、打开u-boot源码顶层目录的Makefile文件,
搜索“<board_name>_config”
搜索“_config”,得到以下结果:

467 %_config:: outputmakefile                                        
468     /home/hqyj/porting/u-boot-2014.07/mkconfig -A fs6818
469     @cp net/x6818-eth.mk net/eth.o

解析:
去掉Makefile文件中的规则的命令前边的“@”符号
重新执行make fs6818_config得到以下信息:

/home/hqyj/porting/u-boot-2014.07/mkconfig -A fs6818

所以:
MKCONFIG = u-boot源码顶层目录的mkconfig文件
$(@:_config=):截取_config之前的字符串

通过file命令查看mkconfig文件,
file mkconfig

mkconfig: POSIX shell script, ASCII text executable

mkconfig是个脚本文件

2、打开mkconfig,分析

24 if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
25     # Automatic mode
26     line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
27     if [ -z "$line" ] ; then
28         echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
29         exit 1
30     fi               
31 
32     set ${line}
33     # add default board name if needed
34     [ $# = 3 ] && set ${line} ${1}
35 fi

解析:
$# : 执行脚本文件时,传递参数的个数
$srctree/boards.cfg : uboot源码目录下的boards.cfg文件
$0 !~ /^#/ : 不是#号开头
$7 ~ /^’"$2"’$/ : $7 = fs6818

line=Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 - 
   	  $1    $2    $3     $4      $5     $6      $7  $8

set ${line} : 重新设置mkconfig文件的参数
mkconfig Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 - 
         $1    $2    $3    $4       $5     $6      $7  $8

对变量进行赋值:

50 # Strip all options and/or _config suffixes
51  CONFIG_NAME="${7%_config}"
52 
53  [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"
54 
55  arch="$2"
56  cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
57  spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
58 
59  if [ "$cpu" = "-" ] ; then                     
60     cpu=
61  fi
62 
63  [ "$6" != "-" ] && board="$6"
64  [ "$5" != "-" ] && vendor="$5"
65  [ "$4" != "-" ] && soc="$4"

96  if [ "$options" ] ; then
97     echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
98  else  # 配置成功的打印信息
99     echo "Configuring for ${BOARD_NAME} board..."
100 fi

创建架构指令的头文件

102 #
103 # Create link to architecture specific headers
104 #
105 if [ -n "$KBUILD_SRC" ] ; then
106     mkdir -p ${objtree}/include
107     LNPREFIX=${srctree}/arch/${arch}/include/asm/
108     cd ${objtree}/include
109     mkdir -p asm
110 else # 头文件放在arch/arm/include目录下
111     cd arch/${arch}/include                                    
112 fi

创建Make工具使用的头文件

126 #
127 # Create include file for Make
128 #
129 ( echo "ARCH   = ${arch}"
130     if [ ! -z "$spl_cpu" ] ; then
131     echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
132     echo "CPU    = ${spl_cpu}"
133     echo "else"
134     echo "CPU    = ${cpu}"
135     echo "endif"
136     else
137     echo "CPU    = ${cpu}"
138     fi
139     echo "BOARD  = ${board}"
140 
141     [ "${vendor}" ] && echo "VENDOR = ${vendor}"
142     [ "${soc}"    ] && echo "SOC    = ${soc}"
143     exit 0 ) > config.mk  # 重定向到config.mk
144 
145 # Assign board directory to BOARDIR variable
146 if [ -z "${vendor}" ] ; then
147     BOARDDIR=${board}                               
148 else
149     BOARDDIR=${vendor}/${board}
150 fi

打开 vi include/config.mk

1 ARCH   = arm         
2 CPU    = slsiap
3 BOARD  = fs6818
4 VENDOR = s5p6818
5 SOC    = s5p6818

创建板子指定的头文件

153 # Create board specific header file
154 #
155 if [ "$APPEND" = "yes" ]    # Append to existing config file
156 then
157     echo >> config.h
158 else
159     > config.h      # Create new config file
160 fi
161 echo "/* Automatically generated - do not edit */" >>config.h
162 
163 for i in ${TARGETS} ; do
164     i="`echo ${i} | sed '/=/ {s/=/  /;q; } ; { s/$/ 1/; }'`"
165     echo "#define CONFIG_${i}" >>config.h ;
166 done
167 
168 echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
169 echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
170 echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h
171 
172 [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
173 
174 [ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h
175 
176 [ "${board}"  ] && echo "#define CONFIG_BOARDDIR board/$BOARDDIR" >> config.h
177 cat << EOF >> config.h
178 #include <config_cmd_defaults.h> 
179 #include <config_defaults.h> 
180 #include <configs/${CONFIG_NAME}.h> 
181 #include <asm/config.h> 
182 #include <config_fallbacks.h> 
183 #include <config_uncmd_spl.h>
184 EOF

打开 vi include/config.h

  1 /* Automatically generated - do not edit */
  2 #define CONFIG_SYS_ARCH  "arm"
  3 #define CONFIG_SYS_CPU   "slsiap"
  4 #define CONFIG_SYS_BOARD "fs6818"
  5 #define CONFIG_SYS_VENDOR "s5p6818"
  6 #define CONFIG_SYS_SOC    "s5p6818"
  7 #define CONFIG_BOARDDIR board/s5p6818/fs6818
  8 #include <config_cmd_defaults.h>
  9 #include <config_defaults.h>                                                    
 10 #include <configs/fs6818.h>
 11 #include <asm/config.h>
 12 #include <config_fallbacks.h>
 13 #include <config_uncmd_spl.h>

六、uboot官方源码 u-boot-2014.07.tar.bz2

​ exynos4412
​ cpu :Cortex-A9
​ arch:arm
​ SOC :Exynos4412
​ vendor :samsung
​ board :FS4412 —》 origen

七、制作windows下的win_ubootpak.bin

dd if=/dev/zero of=512B bs=1 count=512

或者

dd if=/dev/zero of=512B bs=512 count=1

执行下面两句

chmod 777 512B 
cat 512B ubootpak.bin > win_ubootpak.bin

八、将制作好的ubootpak.bin烧写到EMMC中,进行测试

【使用u-boot中的命令将u-boot的镜像烧写到Flash(EMMC)中】
1、 拷贝新编译生成ubootpak.bin镜像文件到tftpboot文件夹中
cp ubootpak.bin ~/tftpboot/

2、 启动开发板u-boot,进入u-boot的交互界面

3、使用tftp命令将ubootpan.bin文件烧写到内存中
FS6818# tftp 0x48000000 ubootpak.bin

4、使用update_mmc命令将内存中的ubootpak.bin文件烧写到EMMC中

FS6818# update_mmc 2 2ndboot 0x48000000 0x200 0x78000
打印以下信息表示成功:
head boot dev  = 2
update mmc.2 type 2ndboot = 0x200(0x1) ~ 0x78000(0x3c0): Done

5、测试是否烧写成功
开发板断电,设置开发板的启动方式为EMMC启动
开发板重新上电,即为EMMC启动

经过测试之后发现不支持loadb命令。
对于大多数的常用的命令,u-boot源码已经全部支持,
测试loadb命令不支持,可能原因u-boot源码没有
loadb命令对应的代码编译到ubootpak.bin镜像中

1)、搜索 grep “loadb” * -nR
common/cmd_load.c:389: * loadb command (load binary) included
common/cmd_load.c:1059: loadb, 3, 0, do_load_serial_bin,

2)、检查common目录下的Makefile文件,
检查是否将cmd_load.c文件进行编译

obj-y += cmd_load.o 说明cmd_load.c被编译

3)、在include/configs/fs6818.h文件中添加以下宏定义:
#define CONFIG_CMD_LOADB

4)、再次重新进行测试ubootpak.bin

九、ubnntu中的代码追踪工具:ctags

sudo apt-get install ctags

1、使用ctags命令生成tags符号文件
ctags -R

2、打开源码文件
要求:从tags文件开始进行打开
eg:
vi arch/arm/cpu/slsiap/s5p6818/start.S 正确

cd arch/arm/cpu/slsiap/s5p6818/ // 错误
vi start.S

3、追踪
将光标放到函数名的位置,
按ctrl + ] 既可以跳转到函数实现位置

按ctrl + t : 回到上一级

如果函数的调用和实现在同一个文件中,
建议使用搜索的方式。

十、uboot启动的过程中主要做了那些事?

u-boot主要作用(追踪uboot代码的执行过程)

两个阶段:
第一个阶段:汇编
构建异常向量表
禁止mmu和cache,禁止看门狗
硬件时钟的初始化,内存的初始化
清除bss段,
完成uboot代码的自搬移
初始化C代码运行的栈空间

第二个阶段:C
完成大部分硬件的初始化
串口的初始化
内存的进一步的初始化
电源的初始化
等等必要硬件的初始化
根据命令是否进入交互模式还自启动模式
获取uboot的环境变量,
执行bootcmd中的命令,
最终给内核传递参数(bootargs)。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值