1.1 Uboot概述
U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。U-Boot的作用是系统引导。U-Boot从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是根据相应的Linux内核源程序进行简化而形成的,尤其是一些设备的驱动程序
1.2 uboot目录结构
1.3 工作模式
U-Boot的工作模式有启动加载模式和下载模式。
启动加载模式是Bootloader的正常工作模式,嵌入式产品发布时,Bootloader必须工作在这种模式下,Bootloader将嵌入式操作系统从FLASH中加载到SDRAM中运行,整个过程是自动的。
下载模式就是Bootloader通过某些通信手段将内核映像或根文件系统映像等从PC机中下载到目标板的FLASH中。用户可以利用Bootloader提供的一些命令接口来完成自己想要的操作。
1.4 Uboot启动流程
大多数BootLoader都分为stage1和stage2两大部分,U-boot也不例外。依赖于cpu体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
1、 stage1(start.s代码结构)
U-boot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:
(1) 定义入口。由于一个可执行的image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在rom(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
(2)设置异常向量(exception vector)。
(3)设置CPU的速度、时钟频率及中断控制寄存器。
(4)初始化内存控制器 。
(5)将rom中的程序复制到ram中。
(6)初始化堆栈 。
(7)转到ram中执行,该工作可使用指令ldrpc来完成。
2、 stage2(C语言代码部分)
lib_arm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:
(1)调用一系列的初始化函数。
(2)初始化flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有nand设备,则初始化nand设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写ip,c地址等。
(7)进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
1.5 常用的bootloader
U-Boot
U-Boot(Universal BootLoader)是遵循GPL条款的开放源码项目,是在PPCBoot以及ARMBoot的基础上逐步发展和演化而来,现在U-Boot已经能够支持PowerPC、ARM、X86、MIPS等体系结构的上百种开发板,已经成为功能最多、灵活性最强,并且开发最积极的开放源码的BootLoader。
vivi
vivi是由韩国Mizi公司开发的一种BootLoader,专门针对ARM9处理器而设计,支持S3C2410x处理器。和所有的BootLoader一样,vivi有两种工作模式,即启动加载模式和下载模式。当vivi处于下载模式时,它为用户提供一个命令行接口,通过该接口可以使用vivi提供的一些命令。
Blob
Blob(BootLoader Object)是由Jan-Derk Bakker和Erik Mouw发布,专为StrongARM构架下的LART设计的BootLoader。
Blob支持SA1100的LART主板,但用户也可以自行修改移植。Blob也提供两种工作模式,在启动时处于正常的启动加载模式,但是它会延时10秒等待终端用户按下任意键而将Blob 切换到下载模式。如果在10秒内没有用户按键,则Blob继续启动Linux内核。
ARMboot
ARMboot是一个ARM平台的开源固件项目,它严重依赖于PPCBoot。ARMboot支持的处理器构架有StrongARM,ARM720T,PXA250等,是为基于ARM或者StrongARM CPU的嵌入式系统所设计的。ARMboot的目标是成为通用的、容易使用和移植的引导程序,非常轻便地运用于新的平台上。总得来说,ARMboot介于大、小型BootLoader之间,相对轻便,基本功能完备,缺点是缺乏后续支持。ARMboot发布的最后版本为ARMboot–1.1.0,2002年终止了ARMboot的维护,其发布网址为:http://sourceforge.net/projects/armboot。
Redboot
RedBoot是标准的嵌入式调试和引导解决方案,是一个专门为嵌入式系统定制的引导工具,最初由Redhat开发,是嵌入式操作系统eCos的一个最小版本,是随eCos发布的一个BOOT方案,是一个开源项目。现在交由自由软件组织FSF管理,遵循GPL。集BootLoader、调试、Flash烧写于一体。支持串口、网络下载、执行嵌入式应用程序。既可以用在产品的开发阶段(调试功能),也可以用在最终的产品上(Flash更新、网络启动)。
RedBoot支持的处理器构架有ARM、MIPS、PowerPC、x86等,是一个完善的嵌入式系统BootLoader。
交叉编译器:在宿主机上编译出能够在目标机上运行的代码的工具。咱们的压缩包为arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz。
2.1 解压交叉编译器工具
[root@itcast tools]# tar -xzvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz
2.2 创建arm目录
[root@itcast tools]# mkdir /usr/local/arm
[root@itcast tools]#
2.3 拷贝对应的文件到arm目录
[root@itcast tools]# cp opt/FriendlyARM/toolschain/4.5.1/ /usr/local/arm/ -rf
[root@itcast tools]#
2.4 设置环境变量
[root@itcast /]# vim ~/.bash_profile
PATH=$PATH:$HOME/bin
# 新增加的内容如下
PATH=/usr/local/arm/4.5.1/bin:$PATH
2.5 注销系统
Ctrl + Alt + BackSpace 重新登录
2.6 测试交叉编译器
#输入arm-linux- 按两下tab键 如果出现如下内容表示环境已经设置好
[root@itcast tools]# arm-linux-
arm-linux-addr2line arm-linux-cpp arm-linux-gprof arm-linux-populate
arm-linux-ar arm-linux-g++ arm-linux-ld arm-linux-ranlib
arm-linux-as arm-linux-gcc arm-linux-ldd arm-linux-readelf
arm-linux-c++ arm-linux-gcc-4.5.1 arm-linux-nm arm-linux-size
arm-linux-cc arm-linux-gccbug arm-linux-objcopy arm-linux-strings
arm-linux-c++filt arm-linux-gcov arm-linux-objdump arm-linux-strip
3.1 解压uboot
[root@itcast tools]# tar -xjvf uboot_tiny4412-master.tar.bz2
3.2 配置uboot
[root@itcast tools]# cd uboot_tiny4412-master
[root@itcast uboot_tiny4412-master]# make tiny4412_config
awk '(NF && $1 !~ /^#/) { print $1 ": " $1 "_config; $(MAKE)" }' boards.cfg > .boards.depend
Configuring for tiny4412 board...
[root@itcast uboot_tiny4412-master]#
3.3 编译uboot
[root@itcast uboot_tiny4412-master]# make -j4
....
arm-linux-ld: warning: creating a DT_TEXTREL in object.
arm-linux-objcopy -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
3.4 生成对应工具
[root@itcast sd_fuse]# ls
Makefile sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
[root@itcast sd_fuse]# make
gcc -o mkbl2 V310-EVT1-mkbl2.c
gcc -o sd_fdisk sd_fdisk.c
[root@itcast sd_fuse]#
4.1 解挂SD卡
[root@itcast /]# umount /media/*
[root@itcast /]#
4.2 格式化SD卡
[root@itcast /]# dd if=/dev/zero of=/dev/sdb bs=1024 count=1024
记录了1024+0 的读入
记录了1024+0 的写出
1048576字节(1.0 MB)已复制,1.79304 秒,585 kB/秒
[root@itcast /]#
4.3 烧写Uboot到SD卡
[root@itcast tiny4412]# pwd
/home/tools/uboot_tiny4412-master/sd_fuse/tiny4412
[root@itcast tiny4412]# ./sd_fusing.sh /dev/sdb
/dev/sdb reader is identified.
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192字节(8.2 kB)已复制,0.0816119 秒,100 kB/秒
---------------------------------------
BL2 fusing
记录了28+0 的读入
记录了28+0 的写出
14336字节(14 kB)已复制,0.255752 秒,56.1 kB/秒
---------------------------------------
u-boot fusing
记录了540+1 的读入
记录了540+1 的写出
276932字节(277 kB)已复制,4.6861 秒,59.1 kB/秒
---------------------------------------
TrustZone S/W fusing
记录了184+0 的读入
记录了184+0 的写出
94208字节(94 kB)已复制,2.49234 秒,37.8 kB/秒
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.
[root@itcast tiny4412]#
到此,uboot已经烧写到SD中。
在Linux平台我们使用minicom作为串口调试工具。
5.1 安装minicom(如果没有安装minicom的话)
[root@itcast sd_fuse]# yum install minicom.x86_64
5.2 设置minicom
[root@itcast sd_fuse]# minicom -s
# 选择第三个选项 按下回车
按下回车
备注:
115200 波特率
8N1: 8数据位 N 奇校验 1停止位
保存为默认配置,下次启动就不需要配置。
5.3 启动minicom
此时板子上电,从SD卡启动,输出如下信息
[root@itcast /]# minicom
U-Boot 2010.12 (Jun 04 2020 - 17:01:06) for TINY4412
CPU: S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
APLL = 1400MHz, MPLL = 800MHz
Board: TINY4412
DRAM: 1023 MiB
vdd_arm: 1.2
vdd_int: 1.0
vdd_mif: 1.1
BL1 version: N/A (TrustZone Enabled BSP)
Checking Boot Mode ... SDMMC
REVISION: 1.1
MMC Device 0: 7580 MB
MMC Device 1: 3728 MB
MMC Device 2: N/A
*** Warning - using default environment
Net: No ethernet found.
Hit any key to stop autoboot: 0
TINY4412 #
此时uboot已经启动了。
6.1 问题一 没有那个文件或目录
[root@itcast uboot_tiny4412-master]# arm-linux-gcc -v
bash: /usr/local/arm/4.5.1/bin/arm-linux-gcc: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录
[root@itcast uboot_tiny4412-master]#
解决办法:
[root@itcast uboot_tiny4412-master]# yum install glibc.i686
[root@itcast uboot_tiny4412-master]# arm-linux-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gcc
6.2 问题二:找不到libz.so动态库
编译过程中
解决办法
[root@itcast uboot_tiny4412-master]# yum install zlib*.i686
7.1 arm-linux-gcc下载:arm-linux-gcc-4.5.1-v6-vfp-20120301.tar.gz
7.2 uboot下载:uboot_tiny4412-master.tar.gz