u-boot编译与烧录(二)

来源:互联网 发布:淘宝升级企业店铺好处 编辑:程序博客网 时间:2024/05/07 06:37
今天SD卡和TF卡都到手了,可以开始大干一场了,顺便结束掉在uboot上的纠缠。
这几天查了一些资料,也解决了上一篇博客里出现的一些疑问。


首先,superboot是友善独家制作的,可以写入nand作为bootloader,但是其源码不公开,也就是说除了友善的板子之外的板子无法使用superboot。superboot无法像uboot那样进入uboot模式,所以在批量刷机或者设计不涉及uboot、内核,从而不需要频繁烧写内核、uboot的上层应用制作中有优势,如果用来调试内核,一次次通过SD连minitools烧写是极度不方便的。


其次,Tiny210友善提供的就是superboot而没有uboot(我是指我的光盘里,网上tiny210的uboot也是很多的),所以我找不到uboot源码。


再次, 板子上电之后会有个等待时间,等待用户敲击键盘从而阻止内核加载,停留在uboot状态。之前疑惑个等待时间是怎么设定的,能不能不等待。其实这个是由uboot的环境变量所决定的。
进入uboot时,输入help可以查看所有uboot所支持的命令。
其中输入print可以查看所有的uboot环境变量:


iTOP-4412 # print
bootdelay=2
baudrate=115200
stdin=serial
stdout=serial
stderr=serial
bootcmd=movi read kernel 40008000;movi read rootfs 40df0000 100000;bootm 4000800
0 40df0000
Environment size: 160/16380 bytes
其中的bootdelay=2即表示uboot会等待两秒用户的反应,可以通过setenv修改
bootcmd即表示uboot反应时间过后执行的操作:这句话的意思就是将nand中的内核及文件系统读入内存,然后依次执行。


这里安利一个好方法,方便内核的调试,因为每次内核编译好后都通过烧写的办法是比较麻烦的,通过设置uboot的环境变量,利用uboot支持的tftp功能能很容易的调试编译好的内核:
首先,当然是要在虚拟机linux系统下搭建好tftp服务器,方法都大同小异,无非是下载所用的软件,然后写好环境变量,新建tftp服务器的路径,假定/tftp_space,重启服务,网上有很多资料,然后记住虚拟机的ip地址,假定192.168.1.2。


然后就是设置uboot的环境变量:


setenv ipaddr 192.168.1.10 //和服务器在同一网段
setenv server 192.168.1.2   //即服务器的ip地址
setenv bootcmd tftp c0008000 uImage \; bootm c0008000 //uboot起来后从tftp服务器获取uImage到内存c0008000的地址,然后运行这段内存里的内核
saveenv //保存环境变量到flash中


这里为了查看tftp设置好了没有可以在终端中使用ping指令,看看板子和虚拟机能否ping通,如果不能ping通,排除掉tftp设置及ip地址错误的基本原因之外,还有很多可能。
因为板子是通过网线和windows连接,然后window通过虚拟机连接,要确保每一层没有问题。
先将板子和window cmd下ping通 然后windows和虚拟机终端ping通,这两个没问题说明网络是通畅的
如果还是不行确保windows和虚拟机的防火墙关闭
最后还是不行的话,只能建议将pc和板子连在一个交换机上,这样可以排除最后的可能。


这样一来,每次编译出新的内核,只需把镜像文件放在之前建的/tftp_space下,上电后板子自动加载服务器的内核,就方便许多了。


有的时候在saveenv的时候会出现错误,我也不知道为什么,那么改了半天重启之后uboot的环境变量依然是老样子。
那么怎么办呢?我们可以尝试从源码直接修改uboot的环境变量,从而编译得到的uboot就具有希望的环境变量了:
在源码的common路径下的env_common.c中有这么一段:


#define XMK_STR(x) #x
#define MK_STR(x) XMK_STR(x)


uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
"ramboot=" CONFIG_RAMBOOTCOMMAND "\0"
#endif
#ifdef CONFIG_NFSBOOTCOMMAND
"nfsboot=" CONFIG_NFSBOOTCOMMAND "\0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(10) "\0"
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" MK_STR(CONFIG_BAUDRATE) "\0"
#endif
#ifdef CONFIG_LOADS_ECHO
"loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "\0"
#endif
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
#endif
#ifdef CONFIG_ETH1ADDR
"eth1addr=" MK_STR(CONFIG_ETH1ADDR) "\0"
#endif
#ifdef CONFIG_ETH2ADDR
"eth2addr=" MK_STR(CONFIG_ETH2ADDR) "\0"
#endif
#ifdef CONFIG_ETH3ADDR
"eth3addr=" MK_STR(CONFIG_ETH3ADDR) "\0"
#endif
#ifdef CONFIG_ETH4ADDR
"eth4addr=" MK_STR(CONFIG_ETH4ADDR) "\0"
#endif
#ifdef CONFIG_ETH5ADDR
"eth5addr=" MK_STR(CONFIG_ETH5ADDR) "\0"
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "\0"
#endif
#ifdef CONFIG_SYS_AUTOLOAD
"autoload=" CONFIG_SYS_AUTOLOAD "\0"
#endif
#ifdef CONFIG_PREBOOT
"preboot=" CONFIG_PREBOOT "\0"
#endif
#ifdef CONFIG_ROOTPATH
"rootpath=" MK_STR(CONFIG_ROOTPATH) "\0"
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) "\0"
#endif
#ifdef CONFIG_HOSTNAME
"hostname=" MK_STR(CONFIG_HOSTNAME) "\0"
#endif
#ifdef CONFIG_BOOTFILE
"bootfile=" MK_STR(CONFIG_BOOTFILE) "\0"
#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" MK_STR(CONFIG_LOADADDR) "\0"
#endif
#ifdef  CONFIG_CLOCKS_IN_MHZ
"clocks_in_mhz=1\0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
#endif
#ifdef  CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
"\0"
};
修改这样参数即可制定自己想要的环境变量了。


最后,关于上次编译的4412的uboot为什么错误呢,有几点原因:


首先,并没有制定编译器,现在用arm-linux-的4.4.1版本,如果编译的时候懒得制定,要在环境变量中修改:


在Ubuntu命令行中,执行下面命令: 
#cd /root 
#vim .bashrc 


然后在“.bashrc”文件中最后一行添加如下信息
export PATH=$PATH:/usr/local/arm/arm-2009q3/bin


修改完成后保存退出 执行下列命令,更新环境发量 
#source .bashrc
这样就可以选定4.4.1的交叉编译工具链了


其次,通过网上的资料可知完整的uboot由三部分组成,bl0.bin、bl1.bin、bl2.bin。其中bl0是固化在芯片中的。上回编译的uboot.bin只是uboot的一部分,当然是无法启动的。
卖家提供了一个create_uboot.sh的脚本,那么我们来看看脚本里写的是什么:


./build_uboot.sh clean


ls


sleep 2


#cp include/configs/tc4_plus_pop_android.h include/configs/tc4_plus_android.h


#cp include/configs/tc4_plus_no_charge_android.h include/configs/tc4_plus_android.h
if [ -z $1 ]
then
./build_uboot.sh
else
./build_uboot.sh $1
fi


ls
可见这个脚本不是重要部分,重要的是其启动的另一个脚本:build_uboot.sh:
#!/bin/sh


option1="tc4_ubuntu"


sec_path="../CodeSign4SecureBoot/"
CPU_JOB_NUM=$(grep processor /proc/cpuinfo | awk '{field=$NF};END{print field+1}')
ROOT_DIR=$(pwd)
CUR_DIR=${ROOT_DIR##*/}


case "$1" in
clean)
echo make clean
make mrproper
;;
*)

if [ ! -d $sec_path ]
then
echo "**********************************************"
echo "[ERR]please get the CodeSign4SecureBoot first"
echo "**********************************************"
return
fi


if [ -z $1 ]
                then
make itop_4412_android_config


elif [ $1 = $option1 ]
                then
make itop_4412_android_ubuntu_config
else
make itop_4412_android_config
fi

make -j$CPU_JOB_NUM

if [ ! -f checksum_bl2_14k.bin ]
then
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "There are some error(s) while building uboot, please use command make to check."
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
exit 0
fi

cp -rf checksum_bl2_14k.bin $sec_path
cp -rf u-boot.bin $sec_path
rm checksum_bl2_14k.bin

cd $sec_path

cat E4412_N.bl1.SCP2G.bin bl2.bin all00_padding.bin u-boot.bin tzsw_SMDK4412_SCP_2GB.bin > u-boot-iTOP-4412.bin
mv u-boot-iTOP-4412.bin $ROOT_DIR

rm checksum_bl2_14k.bin
#rm BL2.bin.signed.4412
rm u-boot.bin


echo 
echo 
;;

esac
这段代码并不难理解,就是先检测上级目录中有无的另一个路径/CodeSign4SecureBoot,
然后由传入的参数决定make的配置参数是 itop_4412_android_ubuntu_config 还是itop_4412_android_config
然后make config 然后make编译
之后将编译生成的 u-boot.bin和checksum_bl2_14k.bin拷贝到/CodeSign4SecureBoot路径下 
删除当前路径下编译出的文件
进入/CodeSign4SecureBoot路径
将E4412_N.bl1.SCP2G.bin bl2.bin all00_padding.bin u-boot.bin tzsw_SMDK4412_SCP_2GB.bin  拼接为u-boot-iTOP-4412.bin
然后将这个最终uboot移动到原路径下
删除编译产生文件,大功告成


知道了这个原理 于是重新编译了uboot.bin,用同样的方法手动产生u-boot-iTOP-4412.bin烧入板子中 没有问题。


关于210的uboot源码和uboot的原理,考虑再三,先不进行210uboot移植了,对当前的任务没有意义,用superboot麻烦了一点,当先4412的板子uboot也可以用,只知道参考教程修改修改uboot功能 如载入uboot的时候LCD显示logo之类的功能就足够了,uboot的移植还是等到以后有时间再慢慢研究吧。


温故而知新,解决了之前的疑惑,终于要操起SD卡来拯救两块变砖的开发板啦。




首先是4412板子的TF卡烧写:


1.制作可以烧写的TF卡
按照常理,应当先对TF进行分区,这样的话在就可以保留出不被uboot占用的空间,在win7下可以查看到空出来的盘符。
然而TF卡分区我所知道的办法要在uboot下,而现在板子已经变砖了,无法进入uboot,所以我们要将整张TF卡做成uboot启动盘。
首先虚拟机上输入df -l 查看挂接的设备
TF卡插入虚拟机中,(注意vmware的驱动正常,usb服务的启动)
再次输入df -l查看挂接的设备,如果TF卡已经接入虚拟机,则会多出一个/dev/sdx的设备,如果没有,则仔细检查驱动和服务。我的设备号是sdb1。
进入uboot源码的路径,拷贝u-boot-iTOP-4412.bin到该路径下,然后执行./mkuboot /dev/sdb(我的设备号是sdb1,但是我们要将整个卡制作,所以是sdb)
对于没有mkuboot.sh脚本的源码该怎么办呢?让我们来看看这个脚本:


#!/bin/bash


#
# This script will create a u-boot binary for movinand/mmc boot
#


chmod 777 sdfuse_q -R

echo "Fuse iTOP-4412 trustzone uboot file into SD card"
cd ./sdfuse_q


if [ -z $1 ]
then
./sd_fusing_exynos4x12.sh /dev/sdb u-boot-iTOP-4412.bin
else
./sd_fusing_exynos4x12.sh $1 u-boot-iTOP-4412.bin
fi


cd ..


显然,这个脚本的只是将参数/dev/sdb 和 u-boot-iTOP-4412.bin传入sd_fusing_exynos4x12.sh脚本:


#!/bin/sh
#
# Copyright (C) 2010 Samsung Electronics Co., Ltd.
#              http://www.samsung.com/
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
####################################
reader_type1="/dev/sd"
reader_type2="/dev/mmcblk0"


if [ -z $2 ]
then
    echo "usage: ./sd_fusing.sh <SD Reader's device file> <filename>"
    exit 0
fi


param1=`echo "$1" | awk '{print substr($1,1,7)}'`


if [ "$param1" = "$reader_type1" ]
then 
    partition1=$1"1"
    partition2=$1"2"
    partition3=$1"3"
    partition4=$1"4"


elif [ "$1" = "$reader_type2" ]
then 
    partition1=$1"p1"
    partition2=$1"p2"
    partition3=$1"p3"
    partition4=$1"p4"


else
    echo "Unsupported SD reader"
    exit 0
fi


if [ -b $1 ]
then
    echo "$1 reader is identified."
else
    echo "$1 is NOT identified."
    exit 0
fi


####################################
# format
umount $partition1 2> /dev/null
umount $partition2 2> /dev/null
umount $partition3 2> /dev/null
umount $partition4 2> /dev/null


echo "$2 fusing..."
dd iflag=dsync oflag=dsync if=../$2 of=$1 seek=1 && \
echo "$2 image has been fused successfully."


#<Message Display>
echo "Eject SD card"




其实这个脚本的作用就是调用sd_fuse.sh脚本,将引入的第二个参数的文件,烧写到第一个参数的设备中,即将uboot写入sd卡中。
执行它,Done。




2.用TF卡烧写uboot或者其他镜像
因为我们做的整张uboot的TF卡,所以在windows下是读不到盘符的,从而也没办法进行其他镜像的下载,但是我们通过uboot对TF卡分区后,那么空出来的部分就能用来放置其他要下载的镜像。这点后面会讲到,这里先说明从TF卡写uboot使板砖恢复为板子。
首先TF卡插入板子,板子设置从TF卡启动,如果之前的操作都是正确的,那么板子应该进入了uboot,uboot指示灯点亮,板子复活
首先要做的是对TF卡分区,一张卡放几k的uboot太奢侈了,在一个也为其他镜像烧写留出空间:
终端中执行命令:


fdisk -c 1 
fatformat mmc 1:1
ext3format mmc 1:2
ext3format mmc 1:3
ext3format mmc 1:4


如果是2G卡,将命令fdisk -c 1改为fdisk -c 1 300 300 300


终端中执行sdfuse flash bootloader u-boot-iTop-4412.bin 将uboot写入nand,到这里就可以断电了,板子可以从自身的nand启动了
这里要注意这时候的uboot虽然可以使用fastboot,但是不能真正将镜像写入到nand中,可能是因为TF卡启动的原因,不明


然后切换到nand启动板子,nand分区:
fdisk -c 1 1700 50 50 
 fatformat mmc 1:1
 ext3format mmc 1:2 
 ext3format mmc 1:3 
 ext3format mmc 1:4


之后在终端中输入fastboot,出现提示指导fastboot下载镜像,
之后,cmd进入win7 fastboot所在路径,常规下载镜像,如输入fastboot flash kernal zImage下载内核。
完成后fastboot -w 清除用户区
 fastboot reboot 重启
Done。


至于直接用TF卡下载镜像的方法,之前给TF卡分区的目的就是如此,但是不推荐这个办法,不如fastboot来的方便,如果没有OTG或者不喜欢用tftp可以尝试:
将TF卡插入win7,出现盘符,新建/sdupdate路径
在里面放入需要烧写的镜像
TF卡插回板子,TF启动,进入uboot
sdfuse flash A B 即可 A为烧写的部分(kernal,bootloader..)B为镜像的文件名
也可以sdfuse all 完全烧写。


tiny210的SD卡烧写方法


tiny210因为用的是superboot,很多东西都写死了,用起来就简单多了


1.制作SD卡:


SD卡插入win7,
用SD-Flasher.exe scan SD卡
relayout SD卡之后,
fuse入需要的superboot
在SD卡中建images文件夹
放入修改好参数的FriendlyARM.ini(重要),
新建镜像的路径(参照ini)放入镜像,superboot可直接放置在images中即可


2.用SD卡烧写镜像


插入SD到板子,ini中的USB_Mode=no时板子自动烧写SD卡中的镜像
USB_Mode=Yes, 配合minitools通过USB下载相关镜像即可


重申一次FriendlyARM.ini很重要,仔细修改其中的参数才能保证下载正确


贴出ini:


#This line cannot be removed. by FriendlyARM(www.arm9.net)


CheckOneButton=No 
Action = Install 
OS = Android 


LCD-Mode = No 
#LCD-Type = S70 


USB-Mode = no


LowFormat = Yes 
VerifyNandWrite = No 
CheckCRC32=No 


StatusType = Beeper | LED 
################### Android 4.0.3 #################### 
Android-BootLoader = Superboot210.bin 
Android-Kernel = Android/zImage 
Android-CommandLine = root=/dev/mtdblock4 console=ttySAC0,115200 init=/linuxrc androidboot.console=ttySAC0 ctp=3 skipcali=Yes
Android-RootFs-InstallImage = Android/rootfs_android.img 


################### Android 2.3.1 #################### 
#Android-BootLoader = Superboot210.bin 
#Android-Kernel = Android2.3.1/zImage 
#Android-CommandLine = root=/dev/mtdblock4 console=ttySAC0,115200 init=/linuxrc androidboot.console=s3c2410_serial0 skipeali=yes
#Android-RootFs-InstallImage = Android2.3.1/rootfs_android.img
 
################### Linux #################### 
Linux-BootLoader = Superboot210.bin 
Linux-Kernel = Linux/zImage 
Linux-CommandLine = root=/dev/mtdblock4 console=ttySAC0,115200 init=/linuxrc 
Linux-RootFs-InstallImage = Linux/rootfs_qtopia_qt4.img 


################### Windows CE6.0 #################### 
WindowsCE6-Bootloader = Superboot210.bin 
WindowsCE6-BootLogo = WindowsCE6\bootlogo.bmp 
WindowsCE6-InstallImage = WindowsCE6\NK.bin
WindowsCE6-RunImage = WindowsCE6\NK.bin


要注意的是:
CheckOneButton表示是否自动安装
USB-Mode SD卡下载还是USB下载
LowFormat 表示是否格式化flash 如果不想动文件系统可以no
ctp是电容屏的型号,具体查阅手册,电阻屏不需要
skipcali为跳过触摸屏的校准


到这里uboot也就告一段落了,毕竟uboot的功能很小,只要会下载,基本的调试修改,就可以使用开发板了,在这个上面耽搁太多时间就影响到内核的学习了。

0 0
原创粉丝点击