启动LOG信息分析
uboot 启动后打印信息如下:
U-Boot 2016.03 (Dec 20 2021 - 22:57:51 +0800)
CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 39C
Reset cause: POR
Board: I.MX6U ALPHA|MINI
I2C: ready
DRAM: 512 MiB
NAND: 512 MiB
MMC: FSL_SDHC: 0
*** Warning - bad CRC, using default environment
Display: ATK-LCD-4.3-480x272 (480x272)
Video: 480x272x24
In: serial
Out: serial
Err: serial
Net: FEC1
Error: FEC1 address not set.
1.版本号打印信息“U-Boot 2016.03”.
2.编译时间 (Dec 20 2021 - 22:57:51 +0800)
3.芯片可达最大频率和目前使用频率 Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
芯片工业级温度 Industrial temperature grade (-40C to 105C) at 39C
4.开发板版本号 I.MX6U ALPHA|MINI
5.DDR大小 512 MiB
6 NAND大小 512 MiB
7. 复位类型 Reset cause:POR
8.MMC(指emmc或SD卡)相关的打印信息 FSL_SDHC: 0
9.U-Boot环境变量校验失败打印信息 Warning - bad CRC, using default environment (环境变量没保存造成,使用setenv解决)
U-Boot的环境变量可以保存在外部Flash(QSPI)设备中,当U-Boot启动的时候会首先从外部flash设备中读取环境变量把它拷贝到内存当中,在读取之前首先会校验,如果校验成功了,则表示flash设备中有保存的环境变量,如果校验实验,则表示flash设备中并没有保存环境变量,则使用默认的环境变量,默认的环境变量就是代码里边固定的那一份。
10. 屏幕输出信息:
Display: ATK-LCD-4.3-480x272 (480x272)
Video: 480x272x24
11.串口相关打印信息:
In: serial@e0000000 USB调试串口 stdin
Out: serial@e0000000 stdout
Err: serial@e0000000 stdierr
10.网络设备相关的打印信息: Net: FEC1
Error: FEC1 address not set.
常用命令介绍
环境变量操作命令
-
help => 打印当前U-boot 支持的命令 (或者使用 ? + enter)
-
?命令 => 查看帮助信息
-
bdinfo => 查看板子信息
-
pintf => 查看环境配置信息
-
setenv => 设置环境信息
-
saveenv => 保存环境信息
-
内存操作命令
1、 md 命令
作用:md 命令用于显示内存值
md[.b, .w, .l] address [# of objects]
命令中的[.b .w .l]对应 byte、 word 和 long,也就是分别以 1 个字节、 2 个字节、 4 个字节来显示内存值。 address 就是要查看的内存起始地址, [# of objects]表示要查看的数据长度。
输入命令:
md.b 80000000 10
md.w 80000000 10
md.l 80000000 10
2、 nm 命令
作用:nm 命令用于修改指定地址的内存值
nm [.b, .w, .l] address
nm 命令同样可以以.b、 .w 和.l 来指定操作格式,比如现在以.l 格式修改 0x80000000 地址的数据为 0x12345678。
输入命令:
nm.l 80000000
3、 mm 命令
作用:mm 命令也是修改指定地址内存值的,使用 mm 修改内存值的时候地址会自增,而使用命令 nm 的话地址不会自增。
4、 mw 命令
作用: 用于使用一个指定的数据填充一段内存。
mw [.b, .w, .l] address value [count]
mw 命令同样可以以.b、 .w 和.l 来指定操作格式, address 表示要填充的内存起始地址, value为要填充的数据, count 是填充的长度。
mw.l 80000000 0A0A0A0A 10
5、 cp 命令
cp 是数据拷贝命令,用于将 DRAM 中的数据从一段内存拷贝到另一段内存中,或者把 NorFlash 中的数据拷贝到 DRAM 中。
cp [.b, .w, .l] source target count
cp 命令同样可以以.b、 .w 和.l 来指定操作格式, source 为源地址, target 为目的地址, count为拷贝的长度。我们使用.l 格式将 0x80000000 处的地址拷贝到 0X80000100 处,长度为 0x10 个内存块(0x10 * 4=64 个字节),命令如下所示:
cp.l 80000000 80000100 10
6、 cmp 命令
cmp 是比较命令,用于比较两段内存的数据是否相等.
cmp [.b, .w, .l] addr1 addr2 count
cmp 命令同样可以以.b、 .w 和.l 来指定操作格式, addr1 为第一段内存首地址, addr2 为第二段内存首地址, count 为要比较的长度。我们使用.l 格式来比较 0x80000000 和 0X80000100 这两个地址数据是否相等,比较长度为 0x10 个内存块(16 * 4=64 个字节),命令如下所示:
cmp.l 80000000 80000100 10
网络操作命令
1. ping
开发板的网络能否使用,是否可以和服务器(Ubuntu 主机)进行通信,通过 ping 命令就可以验证,直接 ping 服务器的 IP 地址即可,比如我的服务器 IP 地址为 192.168.1.253,命令如下:
ping 192.168.1.104
2. dhcp
dhcp 用于从路由器获取 IP 地址,前提得开发板连接到路由器上的,如果开发板是和电脑直连的,那么 dhcp 命令就会失效。直接输入 dhcp 命令即可通过路由器获取到 IP 地址,如图所示:
从图 可以看出,开发板通过 dhcp 获取到的 IP 地址为 192.168.1.137。同时在图中可以看到“warning: no boot file name;”、“TFTP from server 192.168.1.1”这样的字样。这是因为 DHCP 不单单是获取 IP 地址,其还会通过 TFTP 来启动 linux 内核.
3. nfs
uboot 中的 nfs 命令格式如下所示:
nfs [loadAddress] [[hostIPaddr:]bootfilename]
准备好以后就可以使用 nfs 命令来将 zImage 下载到开发板 DRAM 的 0X80800000 地址处,
命令如下:
nfs 80800000 192.168.1.253:/home/user/linux/nfs/zImage
命 令 中 的 “ 80800000 ” 表 示 zImage 保 存 地 址 ,
“192.168.1.104:/home/user/linux/nfs/zImage”表示 zImage 在 192.168.1.253 这个主机中,
路径为/home/user/linux/nfs/zImage。
4. tftp
tftp 命令的作用和 nfs 命令一样,都是用于通过网络下载东西到 DRAM 中,只是 tftp 命令使用的 TFTP 协议, Ubuntu 主机作为 TFTP 服务器。因此需要在 Ubuntu 上搭建 TFTP 服务器,需要安装 tftp-hpa 和 tftpd-hpa,命令如下:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
和 NFS 一样, TFTP 也需要一个文件夹来存放文件,在用户目录下新建一个目录,命令如
下:
mkdir /home/user/linux/tftpboot -p
chmod 777 /home/user/linux/tftpboot
这 样 我 就 在 我 的 电 脑 上 创 建 了 一 个 名 为 tftpboot 的 目 录 ( 文 件 夹 ) , 路 径 为
/home/user/linux/tftpboot。注意!我们要给 tftpboot 文件夹权限,否则的话 uboot 不能从tftpboot 文件夹里面下载文件。
最后配置 tftp,安装完成以后新建文件/etc/xinetd.d/tftp, 如果没有/etc/xinetd.d 目录的话自行创建, 然后在里面输入如下内容:
server tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /home/zuozhongkai/linux/tftpboot/
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
完了以后启动 tftp 服务,命令如下:
sudo service tftpd-hpa start
打开/etc/default/tftpd-hpa 文件,将其修改为如下所示内容:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/xdh/linux/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"
TFTP_DIRECTORY 就是我们上面创建的 tftp 文件夹目录,以后我们就将所有需要通过TFTP 传输的文件都放到这个文件夹里面,并且要给予这些文件相应的权限。
最后输入如下命令, 重启 tftp 服务器:
sudo service tftpd-hpa restart
tftp 服务器已经搭建好了,接下来就是使用了。将 zImage 镜像文件拷贝到 tftpboot 文件夹中,并且给予 zImage 相应的权限,命令如下:
cp zImage /home/user/linux/tftpboot/
cd /home/user/linux/tftpboot/
chmod 777 zImage
boot 中的 tftp 命令格式如下:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
使用结果如下:
boot操作命令
1. bootz指令
uboot 的本质工作是引导 Linux,所以 uboot 肯定有相关的 boot(引导)命令来启动 Linux。常用的跟 boot 有关的命令有: bootz、 bootm 和 boot。
Linux 镜像文件和设备树都准备好了前提下,先通过网络启动 Linux,使用 tftp 命令将zImage下载到DRAM的0X80800000地址处,然后将设备树imx6ull-14x14-emmc-7-1024x600-c.dtb 下载到 DRAM 中的 0X83000000 地址处,最后之后命令 bootz 启动,命令如下:
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
bootz 80800000 - 83000000
上图就是我们通过 tftp 和 bootz 命令来从网络启动 Linux 系统。
2.bootm命令
bootm 和 bootz 功能类似,但是 bootm 用于启动 uImage 镜像文件。如果不使用设备树的话
启动 Linux 内核的命令如下:
bootm addr
addr 是 uImage 镜像在 DRAM 中的首地址。
如果要使用设备树,那么 bootm 命令和 bootz 一样,命令格式如下:
bootm [addr [initrd[:size]] [fdt]]
其中 addr 是 uImage 在 DRAM 中的首地址, initrd 是 initrd 的地址, fdt 是设备树(.dtb)文件
在 DRAM 中的首地址,如果 initrd 为空的话,同样是用“-”来替代。
3、 boot 命令
boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系
统, bootcmd 是一个很重要的环境变量!其名字分为“boot”和“cmd”,也就是“引导”和“命
令”,说明这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可
以修改的。比如我们要想使用 tftp 命令从网络启动 Linux 那么就可以设置 bootcmd 为“tftp
80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 -
83000000”,然后使用 saveenv 将 bootcmd 保存起来。然后直接输入 boot 命令即可从网络启动
Linux 系统,命令如下:
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb;
bootz 80800000 - 83000000'
saveenv
boot
在启动 Linux 内核的时候可能会遇到如下错误:
“Kernel panic – not Syncing: VFS: Unable to mount root fs on unknown-block(0,0)”
这个错误的原因是 linux 内核没有找到根文件系统,这个很正常,因为没有设置 uboot 的bootargs 环境变量,关于 bootargs 环境变量后面会讲解!此处我们重点是验证 boot 命令, linux内核已经成功启动了,说明 boot 命令工作正常。
其他常用命令
1. go命令
go 命令用于跳到指定的地址处执行应用,命令格式如下:
go addr [arg …]
addr 是应用在 DRAM 中的首地址,我们可以编译一下裸机例程的实验 13_printf,然后将编
译出来的 printf.bin 拷贝到 Ubuntu 中的 tftpboot 文件夹里面,注意,这里要拷贝 printf.bin 文件,
不需要在前面添加 IVT 信息,因为 uboot 已经初始化好了 DDR 了。使用 tftp 命令将 printf.bin
下载到开发板 DRAM 的 0X87800000 地址处,因为裸机例程的链接首地址就是 0X87800000,
最后使用 go 命令启动 printf.bin 这个应用,命令如下:
tftp 87800000 printf.bin
go 87800000
结果如图所示:
2.reset指令
reset 命令顾名思义就是复位的,输入“reset”即可复位重启,如图 30.4.10.1 所示:
3. mtest 命令
mtest 命令是一个简单的内存读写测试命令,可以用来测试自己开发板上的 DDR,命令格式如下:
mtest [start [end [pattern [iterations]]]]``
start是要测试的DRAM 开始地址, end 是结束地址,比如我们测试 0X80000000~0X80001000
这段内存,输入“mtest 80000000 80001000”,结果下图所示:
4.run命令
run 命令用于运行环境变量中定义的命令,比如可以通过“run bootcmd”来运行 bootcmd 中的启动命令,但是 run 命令最大的作用在于运行我们自定义的环境变量。在后面调试 Linux 系统的时候常常要在网络启动和 EMMC/NAND 启动之间来回切换,而 bootcmd 只能保存一种启动方式,如果要换另外一种启动方式的话就得重写 bootcmd,会很麻烦。这里我们就可以通过
自定义环境变量来实现不同的启动方式,比如定义环境变量 mybootemmc 表示从 emmc 启动,定义 mybootnet 表示从网络启动,定义 mybootnand 表示从 NAND 启动。如果要切换启动方式的话只需要运行“run mybootxxx(xxx 为 emmc、 net 或 nand)”即可。
例如:创建环境变量 mybootemmc、 mybootnet 和 mybootnand,命令如下
setenv mybootemmc 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-
14x14-emmc-7-1024x600-c.dtb;bootz 80800000 - 83000000'
setenv mybootnand 'nand read 80800000 4000000 800000;nand read 83000000 6000000
100000;bootz 80800000 - 83000000'
setenv mybootnet 'tftp 80800000 zImage; tftp 83000000imx6ull-14x14-emmc-7-1024x600-c.dtb;
bootz 80800000 - 83000000'
saveenv
创建环境变量成功以后就可以使用 run 命令来运行 mybootemmc
、 mybootnet 或 mybootnand
来实现不同的启动:
run mybootemmc
或
run mytoobnand
或
run mybootnet