上一篇文章主要讲到了TDA4的启动流程,可以查看《J721E TDA4系列——启动流程》
本文主要梳理TDA4的SD卡和emmc启动方式。
目录
1、SD卡启动
Linux SDK在<SDK INSTALL DIR> / bin 目录中包含一个名为mksdboot.sh的脚本。该脚本的目的是通过对SD卡进行分区和格式化来创建可引导的SD卡,以便目标可以使用引导映像和文件系统来引导。以下命令(需root权限):
sudo <SDK INSTALL DIR>/bin/mksdboot.sh --device /dev/sdX --sdk <SDK INSTALL DIR>
#Replace the /dev/sdX with appropriate device name
也可使用如下命令:
#格式化SD卡分区
sudo passwd #添加root权限密码
su root #切换root用户
df -h #查看SD卡分区 eg: /dev/sdb1 30G 80K 30G 1% /media/schling/88B0-7548
umount -l /dev/sdb1 #先强制卸载SD卡
sudo ./mk-linux-card.sh /dev/sdb #执行脚本格式化,sdb而不是sdb1
sudo ./install_to_sd_card.sh #用途:将该脚本旁边的文件系统压缩包直接拷贝到/media/USER/BOOT和/media/USER/rootfs中,此时该卡就可以启动了。
#如果该命令无法执行,提示找不到目录,可将SD卡重新插拔一次即可
至此,SD卡分区(BOOT和rootfs分区)及烧写已完成,启动前将拨码调至SD卡启动即可。
上述用到的脚本文件:
2、emmc启动
2.1 根文件系统rootfs分区制作
以下步骤将使用SD卡rootfs文件系统的副本对eMMC设备进行分区,格式化和填充。
- 将mksdboot.sh从主机<PATH_TO_INSTALLER> /bin/mksdboot.sh复制到目标文件系统。
- 确保脚本具有执行权限。
chmod +x mksdboot.sh
- 确保该板使用uenv.txt.base引导,以便SD和eMMC设备都可用于内核。
- SD(mmcblk1)和eMMC(mmcblk0)均可用时的示例输出
root@j7-evm:~# ls -l /dev/mmcblk*
brw-rw---- 1 root disk 179, 0 Jul 18 22:49 /dev/mmcblk0
brw-rw---- 1 root disk 179, 32 Jul 17 22:37 /dev/mmcblk0boot0
brw-rw---- 1 root disk 179, 64 Jul 17 22:37 /dev/mmcblk0boot1
crw------- 1 root root 242, 0 Jul 17 22:37 /dev/mmcblk0rpmb
brw-rw---- 1 root disk 179, 96 Jul 17 22:37 /dev/mmcblk1
brw-rw---- 1 root disk 179, 97 Jul 17 22:37 /dev/mmcblk1p1
brw-rw---- 1 root disk 179, 98 Jul 17 22:37 /dev/mmcblk1p2
- 从根内核卸载eMMC分区
umount /dev/mmcblk0*
- 停止udev守护程序,以避免在格式化eMMC时自动挂载分区
udevadm control -s
- 使用mksdboot.sh脚本对eMMC设备进行分区,如下所示:
root@j7-evm:~# ./mksdboot.sh --device /dev/mmcblk0
./mksdboot.sh: line 83: [: too many arguments
-- Main device is: /dev/mmcblk1p2
************************************************************
* THIS WILL DELETE ALL THE DATA ON /dev/mmcblk0 *
* *
* WARNING! Make sure your computer does not go *
* in to idle mode while this script is *
* running. The script will complete, *
* but your SD card may be corrupted. *
* *
* Press <ENTER> to confirm.... *
************************************************************
ls: /dev/mmcblk0?: No such file or directory
1024+0 records in
1024+0 records out
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x02f86286.
Command (m for help): Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): Partition number (1-4, default 1): First sector (2048-31080447, default 2048): Last sector, +secto[87597.744275] mmcblk0: p1 p2
rs or +size{K,M,G,T,P} (2048-31080447, default 31080447):
Crea[87597.750177] mmcblk0: p1 p2
ted a new partition 1 of type 'Linux' and of size 62 MiB.
Partition #1 contains a vfat signature.
Command (m for help): Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): Partition number (2-4, default 2): First sector (129024-31080447, default 129024): Last sector, +sectors or +size{K,M,G,T,P} (129024-31080447, default 31080447):
Created a new partition 2 of type 'Linux' and of size 14.8 GiB.
Command (m for help): Partition number (1,2, default 2): Hex code (type L to list all codes):
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help): Partition number (1,2, default 2):
The bootable flag on partition 1 is enabled now.
Command (m for help): The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Formating /dev/mmcblk01 ...
mkfs.fat 4.1 (2017-01-24)
mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows
mke2fs 1.44.3 (10-July-2018)
64-bit filesystem support is not enabled. The larger fields afforded by this feature enable full-strength checksumming. Pass -O 64bit to rectify.
Discarding device blocks: done
Creating filesystem with 3868928 4k blocks and 967232 inodes
Filesystem UUID: a5586362-272d-4fb2-a0cc-56458dfc4b64
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
Partitioning and formatting completed!
root@j7-evm:~# [87602.674595] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
- 现在,将SD卡rootfs分区的内容复制到eMMC设备rootfs分区。在目标上逐一运行以下命令。
umount /run/media/*
mkdir /mnt/sd-rootfs
mount /dev/mmcblk1p2 /mnt/sd-rootfs
mkdir /mnt/emmc-rootfs
mount /dev/mmcblk0p2 /mnt/emmc-rootfs
cp -r /mnt/sd-rootfs/* /mnt/emmc-rootfs
sync
umount /mnt/*
- 重新启动板后,Infotainment虚拟机可以使用eMMC中的rootfs。
2.2 BOOT分区制作
上述的mksdboot.sh脚本其实已对emmc进行分区:BOOT和rootfs,并且将SD的rootfs拷贝至emmc的rootfs中,但是并没有对BOOT分区进行烧写。
1) 根据TI SDK的操作
eMMC设备通常在出厂时没有任何分区表。我们利用U-Boot中的GPT支持将GPT分区表写入eMMC。在这种情况下,我们需要在主机上使用uuidgen程序来创建用于磁盘和每个分区的UUID。(实际操作并不可行,gpt写入失败,故本人使用的是上述2.1中的分区方法)
$ uuidgen
...first uuid...
$ uuidgen
...second uuid...
U-Boot # printenv partitions
uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
U-Boot # setenv uuid_gpt_disk ...first uuid...
U-Boot # setenv uuid_gpt_rootfs ...second uuid...
U-Boot # gpt write mmc 1 ${partitions}
从eMMC引导分区引导tiboot3.bin,tispl.bin和u-boot.img
基于K3的处理器支持从eMMC引导分区引导。可以使用以下命令从SD卡下载tiboot3.bin,tispl.bin和u-boot.img,并将它们写入相应地址的eMMC boot0分区。
=> mmc dev 0 1
=> fatload mmc 1 ${loadaddr} tiboot3.bin
=> mmc write ${loadaddr} 0x0 0x400
=> fatload mmc 1 ${loadaddr} tispl.bin
=> mmc write ${loadaddr} 0x400 0x1000
=> fatload mmc 1 ${loadaddr} u-boot.img
=> mmc write ${loadaddr} 0x1400 0x2000
=> fatload mmc 1 ${loadaddr} sysfw.itb
=> mmc write ${loadaddr} 0x3600 0x800
要使ROM访问引导分区,必须首次使用以下命令:
=> mmc partconf 0 1 1 1
=> mmc bootbus 0 2 0 0
mmc partconf命令可参考:https://blog.csdn.net/shalan88/article/details/92774956
上述操作实际测试并没有成功写进mmc的BOOT分区,具体原因尚不清楚,目前暂时采用如下第二种方式烧录。
2)BOOT分区拷贝
如同rootfs拷贝一样,通过挂载分区的方式将SD卡BOOT分区中的内容拷贝至emmc的BOOT分区。
umount /run/media/*
mkdir /mnt/sd-boot
mount /dev/mmcblk1p1 /mnt/sd-boot
mkdir /mnt/emmc-boot
mount /dev/mmcblk0p1 /mnt/emmc-boot
cp -r /mnt/sd-boot/* /mnt/emmc-boot
sync
umount /mnt/*
通过以上过程,可以将emmc进行分区并填充和SD分区相同的内容,下一步就是如何从emmc启动的问题。
2.3 从emmc启动
1)rootfs从emmc加载
进入uboot命令行:
通过mmc info:可查看当前mmc设备的信息;
mmc list:列出当前的mmc设备;
mmc part:当前mmc设备的分区;
fatls mmc 0:1 :列出mmc0设备分区1中的目录和文件,针对fat32格式,ext4ls针对ext4格式;
fstype mmc 0:1:mmc0设备分区1的格式类型;
下面是关键的一个操作,将根文件系统设置为emmc的rootfs分区启动。
set bootpart 0:2 #emmc0,第2个分区,即rootfs分区
设置完之后,可以使用 cat /proc/cmdline命令查看根文件系统的uuid,同时与mmc part命令显示的uuid对比,即可知道rootfs是从哪个分区加载的。
2)BOOT从emmc分区加载
拨码开关拨到emmc启动对应的设置即可。
3、HyperFlash启动
3.1 HyperBus和HyperFlash
HyperBus是主机系统与一个或多个从机接口之间的低信号计数,高性能双倍数据速率(DDR)总线接口。其8位数据总线(DQ [7:0])具有读写数据选通(RWDS)信号和单端时钟(3.0V)或差分时钟(1.8V)。通过片选选择b/w多个从机。在总线级别,它遵循HyperBus规范中描述的单独协议。
HyperFlash是HyperBus上基于NOR flash的存储设备。HyperFlash遵循与现有并行NORs相似的CFI AMD / Fujitsu扩展命令集(0x0002)。由于Hyperbus是x8 DDR总线,因此等效于每clk x16并行NOR flash wrt位。但是Hyperbus的运行频率很高。
TI的J721E EVM上的HyperFlash已连接到HyperBus内存控制器,该控制器支持对闪存的内存映射IO访问。MTD框架支持HyperFlash,并且U-Boot的标准MTD命令可用于访问HyperFlash。
支持的设备 -J721E EVM
列出检测到的HyperFlash设备:
=> mtd list
List of MTD devices:
* nor0
- type: NOR flash
- block size: 0x40000 bytes /* Each erase sector size is of 256KB */
- min I/O: 0x1 bytes
- 0x000000000000-0x000004000000 : "nor0" /* Detected 64MB devices labeled as "nor0" */
注:在J721E EVM上,应将SW3.1设置为ON位置以选择HyperFlash。
以下示例展示如何从U-Boot提示符下擦除不同的启动映像并将其写入HyperFlash。(擦除必须是擦除扇区大小的倍数)
=> mtd erase nor0 0 0x40000 /* Erase from offset 0 to 256KB of HyperFlash labeled nor0 */
Erasing 0x00000000 ... 0x0003ffff (1 eraseblock(s))
=> fatload mmc 1 0x82000000 tiboot3.bin /* Load an img from SD into DDR to flash into HyperFlash */
180932 bytes read in 10 ms (17.3 MiB/s)
=> mtd write nor0 0x82000000 0x0 $filesize /* Write the loaded image into HyperFlash labeled nor0 */
Writing 180932 byte(s) at offset 0x00000000
=>
下面示例展示如何回读数据
=> mtd read nor0 0x82000000 0x0 0x40000 /* Read from offset 0 to 0x4000 to DDR address 0x82000000 from nor0 */
Reading 262144 byte(s) at offset 0x00000000
3.2 将镜像刷入HyperFlash
可以使用以下命令在tftp上下载tiboot3.bin,tispl.bin和u-boot.img,然后将其刷入到相应地址的HyperFlash中。
=> mtd erase nor0 0 0x800000
=> tftp ${loadaddr} tiboot3.bin
=> mtd write nor0 $loadaddr 0x0 $filesize
=> tftp ${loadaddr} tispl.bin
=> mtd write nor0 $loadaddr 0x80000 $filesize
=> tftp ${loadaddr} u-boot.img
=> mtd write nor0 $loadaddr 0x280000 $filesize
=> tftp ${loadaddr} sysfw.itb
=> mtd write nor0 $loadaddr 0x6C0000 $filesize
HyperFlash的Flash分布
下面是HyperFlash从HyperFlash引导的分布:
0x0 +----------------------------+
| hbmc.tiboot3(512K) |
| |
0x80000 +----------------------------+
| hbmc.tispl(2M) |
| |
0x280000 +----------------------------+
| hbmc.u-boot(4M) |
| |
0x680000 +----------------------------+
| hbmc.env(128K) |
| |
0x6C0000 +----------------------------+
| hbmc.sysfw(1M) |
| |
0x7C0000 +----------------------------+
| padding (256k) |
0x800000 +----------------------------+
| hbmc.rootfs(UBIFS) |
| |
+----------------------------+
J721E EVM的引导模式开关设置
写入镜像后,将EVM上的启动模式开关更改为以下模式,以便以83MHz的频率从HyperFlash启动: