一.一些概念
1.BootLoader
BootLoader不属于操作系统,采用汇编语言和C开发
2.BootLoader两种模式
交互模式:命令接口API
自启动模式:芯片上电后从固态固件加载操作系统到RAM。整个过程没有用户介入
3.核内寄存器:
CPU内部寄存器,没有地址只能通过汇编访问
arm有37个寄存器,有ARM七种模式,包括系统模式(SYS)、管理模式(SVC)、用户模式、快速中断模式(FIQ)、普通中断模式(IRQ)、数据访问中只模式、未定义指令模式
不论ARM处于那种工作模糊,智能访问16个寄存器+程序状态寄存器(CPSR ),SPSR是CPSR的影子寄存器。
4.MMU
MMU是内存管理单元,CPU在访问进程前先访问MMU,MMU访问进程的虚拟地址,链接真实的物理地址,进而CPU访问具体的物理地址
单片机没有MMU,所以不能进行进程调度,不能使用进程操作系统
5.高速缓存
将预先的指令加载到缓存处,CPU加载高速缓存的内容
6.重启
内核重启:reboot
uboot重启:reset
7.常见的BootLoader
BootLoader | 描述 | x86 | ARM | PowerPC |
LILO Linux | 磁盘引导程序 | 是 | 否 | 否 |
GRUB | GNU的LILO替代程序 | 是 | 否 | 否 |
Loadlin | 从DOS引导Linux | 是 | 否 | 否 |
ROLO | 从ROM引导Linux而不需要BIOS | 是 | 否 | 否 |
Etherboot | 通过以太网卡启动Linux系统的固件 | 是 | 否 | 否 |
LinuxBIOS | 完全替代BUIS的Linux引导程序 | 是 | 否 | 否 |
BLOB | LART等硬件平台的引导程序 | 否 | 是 | 否 |
U-boot | 通用引导程序 | 是 | 是 | 是 |
RedBoot | 基于eCos的引导程序 | 是 | 是 | 是 |
8.uboot遵循GPL(开源免费),支持多处理器架构(arch目录),支持多开发板(board)
二.uboot配置步骤
-
uboot压缩包进行解压:tar -xvf uboot_tiny4412-sdk1506.tar.bz2
-
顶层目录下的Makefile种包含了开发板的配置信息。从顶层目录开始递归地调用各级子目录下的Makefile,最后链接成u-boot映像。顶层目录下的Makefile负责u-boot整体配置和编译
-
uboot支持很多开发板,所以在顶层Makefile之前先选择对应开发板配置make tiny4412_config (在config有介绍)
-
编译:在顶层目录执行 make -j2(两个cpu参与make) 编译生成:
u-boot.map | u-boot映像的符号表 |
u-boot | u-boot映像的ELF格式 |
u-boot.bin | u-boot映像原始的二进制格式 |
u-boot.srec | u-boot映像的S-Record格式 |
5.烧录:uboot_tiny4412-sdk1506/sd_fuse/tiny4412目录下已经写好了u-boot的一键烧录脚本。 执行:/sd_fusing.sh /dev/sdb
(最终编译好的u-boot.bin大小为270K,远远大于BL2的14Kb,也就是说,u-boot是不能完整的存放在BL2中,在sd_fusing.sh一键烧录脚本中,先将u-boot.bin(前一部分)制作成BL2.bin。然后将BL1,BL2,u-boot一款烧录在SD卡中。CPU执行BL2的代码会将u-boot搬运到DDR中,然后跳转到DDR中去执行完整的u-boot代码。)
三、uboot的基本命令
1.help == ?
help cmd:查看命令帮助
2.环境变量命令
printenv(pri) | 查看环境变量 |
printenv+变量名 | 具体环境变量 |
setenv name value | 修改/增加现有环境变量 |
setenv | 删除环境变量 |
修改环境变量,只在内存中修改,修改后的值不会保存到固件存储器中。 | |
saveenv | 保存环境变量 |
baudrate=115200 //串口波特率
bootargs=noinitrd root=/dev/nfs nfsroot=192.168.10.106:/root…… //u-boot加载内核时,传递给内核的参数
bootcmd=movi read kernel 0 40008000;……//uboot倒计时结束之后自动执行的命令(自动加载内核)
bootdelay=3 //uboot倒计时时间
ethaddr=00:40:5c:26:0a:5b //uboot网卡物理地址
gatewayip=192.168.0.1 //网关
ipaddr=192.168.0.20 //ip 在网络通信起作用
netmask=255.255.255.0 //掩码
serverip=192.168.0.10 //服务器ip
注:以上网卡物理地址,网关,ip,掩码,服务器ip等环境变量无作用。
3.串口下载命令
loady [off] [baud]
off:要下载的RAM地址
baud:默认115200
第一步:执行loady 0x02023400
等待用户通过串口发送文件
第二步:使用软件的串口发送文件功能发送需要下载的文件
第三步:运行led.bin
go 0x02023400
4.fat文件系统命令
fatls <interface> <dev[:part]> [directory] :查看指定设备(某个存储设备)指定目录的文件列表
interface:接口可以是usb或mmc。mmc包括SD卡,MMC卡,eMMC
dev:开发板上的哪个存储设备。用数字表示,0表示启动设备,>0表示其他设备(1,2,3……)。
part:表示分区号,可选择。
directory:查看文件系统下的哪个目录
fatload <interface> <dev[:part]> <addr> <filename> [bytes]:从fat分区中加载文件到内存中
addr:下载到哪个地址(RAM中的地址)
filename:下载哪一个文件(led.bin)
bytes:文件的大小,不写就是下载全部
将SD卡中的led.bin下载到地址0x02023400并且运行
fatload mmc 0 0x02023400 led.bin
go 0x02023400
5.mmc命令
芯片开机的时候选择的默认启动方式就是0(相对而言的)
mmc list:列出当前的mmc设备
mmc rescan dev:重新扫描开发板上的mmc设备
mmc read <device num> addr blk# cnt 数据传输方向:FLASH->RAM
从设备号为device num的设备中,从第blk扇区,读取cnt个扇区内容到内存地址addr中
mmc write <device num> addr blk# cnt 数据传输方向:RAM->FLASH
将内存地址为addr的数据写入到设备号为device num的设备中,从第blk个扇区开始写,写cnt个扇区数据
6.查看内存数据
md [.b, .w, .l] address
b:一个字节显示
w:俩个字节显示
l:四个字节显示
注意:Ctrl+c结束
示例:md.b 0x02023400
7.USB下载命令
在u-boot中输入dnw + RAM 地址(此时开发板变为一个从设备,虚拟机编程主设备)
在虚拟机输入 dnw+filename
注:dnw使用前需要先下载文件并make,执行dnw命令需要指定路径
8.开机自启动命令
set bootcmd " fatload mmc 0 0x40008000 zImage;bootm 0x40008000" //go是加载SRAM,bootm解析内核的命令
0x40008000 :DRAM的建议开始位置
四.示例
1.fatload mmc 0 0x02023400 test.bin //从SD卡根目录(默认)读取test.bin写入SRAM的0x02023400
在uboot移植的时候14k内容是引导uboot开始搬运,当搬运完毕后,BL2空。此时在uboot(DRAM运行)输入上述命令,会将用户编写的程序放到SRAM运行
2.emmc open 1 //打开eMMC
3.mmc write 1 0x02023400 0 1 //将SRAM的数据从0x02023400写到第0扇区,写入大小1个扇区
4.emmc open 0 //关闭eMMC
5..mmc read 1 0x02023400 0 1 //从EMMC 第0扇区读取1个扇区大小放在SARM的0x02023400运行