简介
星期六花了好半天时间学习u-boot。但是编译好u-boot以及kernel以后发现不能启动。因此需要分析u-boot的启动参数。
- 编译以后没有修改的u-boot参数
bootargs=noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200
bootcmd=nand read.jffs2 0x30007FC0 kernel; nand read.jffs2 32000000 device_tree; bootm 0x30007FC0 - 0x32000000
- 编译kernel时候得到的数据
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3444848 Bytes = 3364.11 kB = 3.29 MB
Load Address: 0x30008000
Entry Point: 0x30008000
过程分析
- 下载
uImage
的数据
Now, Downloading [ADDRESS:30000000h,TOTAL:3444922]
RECEIVED FILE SIZE: 3444922 (1121KB/S, 3S)
NAND erase: device 0 offset 0x80000, size 0x400000
Erasing at 0x460000 -- 100% complete.
OK
NAND write: device 0 offset 0x80000, size 0x3490b0
Writing data at 0x3c9000 -- 100% complete.
3444912 bytes written: OK
将uImage放置在 NAND 的 0x80000
地方。分配的区域是0x400000
。实际uImage大小为0x3490b0
。由于NAND最小擦除单位是页。因此写数据是页单位的整数倍0x3c9000
。
分析bootcmd
的数据
bootcmd=nand read.jffs2 0x30007FC0 kernel; nand read.jffs2 32000000 device_tree; bootm 0x30007FC0 - 0x32000000
发现读取了两个块区域出来。一个是有关于kernel
的镜像。一个是有关于设备树
的镜像。
再查看启动时显示的错误信息
## Booting image at 30007fc0 ...
Image Name: Linux-4.19.0-rc3
Created: 2019-04-27 6:42:27 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3444848 Bytes = 3.3 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
Bad magic of device tree at 0x32000000!
原来已经将kernel
识别出来了。显示的是没有识别出设备树
的镜像。
烧写设备树的镜像。
Now, Downloading [ADDRESS:30000000h,TOTAL:459]
RECEIVED FILE SIZE: 459 (0KB/S, 1S)
NAND erase: device 0 offset 0x40000, size 0x20000
Erasing at 0x40000 -- 100% complete.
OK
NAND write: device 0 offset 0x40000, size 0x1c1
Writing data at 0x40000 -- 100% complete.
449 bytes written: OK
设备树镜像的存放地址
0x40000~0x60000 size 0x20000
烧写完设备树以后启动设备
Creating 5 MTD partitions on "NAND":
0x000000000000-0x000000040000 : "bootloader"
0x000000040000-0x000000060000 : "device_tree"
0x000000060000-0x000000080000 : "params"
0x000000080000-0x000000480000 : "kernel"
0x000000480000-0x000010000000 : "rootfs"
一共有5个分区。除了熟知的
- kernel
- bootloader
- rootfs
- params
多出了一个 - device_tree
分析u-boot源代码
strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
run_command(cmd_buf, 0);
usbslave 1 0x30000000
命令
"usbslave - get file from host(PC)\n",
"[wait] [loadAddress]\n"
"\"wait\" is 0 or 1, 0 means for return immediately, not waits for the finish of transferring\n"
nand erase kernel
nand write.jffs2 0x30000000
nand write.jffs2 0x30000000 kernel $(filesize)
common\cmd_nand_legacy.c
common\cmd_nand.c
U_BOOT_CMD(nand, 5, 1, do_nand,
"nand - NAND sub-system\n",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
"nand read[.jffs2] - addr off|partition size\n"
"nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
"nand erase [clean] [off size] - erase `size' bytes from\n"
" offset `off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
"nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
"nand markbad off - mark bad block at offset (UNSAFE)\n"
"nand biterr off - make a bit error at offset (UNSAFE)\n"
"nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
"nand unlock [offset] [size] - unlock section\n");
原来.jffs2
这个可有可无。我就说为什么我安装的是yaffs的文件系统·怎么跑来一个jffs2的属性。原来可以去掉。