更新 添加kernel不识别sd卡的修正过程
最近RISC-V开发板降价,芯片是阿里的TH1520,4*C910 +16GB RAM+128GB ROM的板子卖480元,附带两个协处理器C906和E902实时核,附带NPU,可玩性超高。开发板标配的固件和各种第三方系统默认从eMMC启动,且没有给SD卡Boot的信息。我想从SD卡启动U-Boot并引导Linux,可是没有找到th1520的BootROM文档。
经过摸索,th1520的启动管脚配置为SD卡,芯片上电后BootROM会尝试从0扇区读取SPL,并用串口输出内容
如此一来,只需把SPL写入0扇区,BootROM->SPL->U-Boot的启动链便完成了
把SPL、U-Boot、openSBI打包写入SD卡扇区:dd if=u-boot-with-spl.bin of=/dev/mmcblk1 conv=fsy nc
但GPT分区类型的SD卡,前34个分区有特殊用途,0扇区是保护性MBR(PMBR),1~33扇区是分区表,把SPL写入0扇区会覆盖GPT 分区 表
第一步 修改uboot代码, 开启 日志
1.修改GPT解析驱动(disk/part_ ef i.c)
打开源码目录下的disk/part_efi.c。在文件的第1行(必须在所有的#include之前),加 上这 句代码:
#defi ne DEBUG
2.修改块设备/分区核心接口(dis k/ part.c)
同样地,打开disk/part.c, 在第 1行加上:
#d ef ine DEBUG
3. 修改MMC核心驱动(driver s/ mmc/mmc.c)
第二步:通过menuco nfi g提高全局日志级别
make -j 15 CROSS_COMPILE=riscv64-linux-gnu- O=/dev/shm light_lpi4 a_1 6g_defconfig
make -j 15 CROSS_COMPILE=riscv64-linux-gnu- O=/de v/s hm menuconfig
make -j 15 CROSS_COMPILE=riscv64-linu x-g nu- O=/dev/shm
rm -r build && mkdir -p build && cp /dev /sh m/u-boot* build
在include/common.h中 打 开调试开关#define DEBU G
调整menuc onf ig,
Plaintext
Device Drivers —>
Logging —>
[*] Enable logging f or U-Boot (CONFIG_LOG=y)
(7) Maximum log level to recor d ( CONFIG_LOGLEVEL=7或8)
Level 7是LOGL_DEBUG,Le vel 8是LOGL_DEBUG_CON T ENT
编 译完成后写入eMMC开机测试
获得日志
Lig ht LPI4A 16G# part list mmc 1
blk_get_devnum_by_typename: if_type=6, devnum =1: sdhci@ffe7080000.blk, 6, 0
blk_get_devnum_by_typename: if_type=6, de vnu m=1: sd@ffe7090000.blk, 6, 1
blk_get_devnum_by_typena me: Device desc 00000000ffa27 9a0
miss: start 0, count 1
blk_find_device: if_type=6, de vnu m=1: sdhci@ffe7080000.blk, 6, 0
blk_find_device: if_type=6 , d evnum=1: sd@ffe7090000.blk, 6 , 1
fill: s tart 0, count 1
part_init: try ‘EFI’: ret=- 1 ← EFI (GPT)驱动尝试解析,直 接返回 -1 (失败)
hit: start 0, count 1
## Unknown partition table type 0
在这整个过程中,U-Boot的底层驱动自始至终只读取了LBA 0(第0扇区),它根本就没有去读LBA 1( 主G PT所在位置),更别提去读SD卡尾部的Backup GPT了!
为什么会这样?这就涉及到了U-Boot EFI驱动的“前置防御机制”。
在U-Boot的源码 disk/ part_efi.c中,test_part_efi()函数是这样写的:
/* Read legacy MBR from block 0 and check it */
if ((blk_drea d(dev_ desc, 0, 1, (ulong *)legacymbr) != 1) ||
(is_ pmbr _v alid (leg acy mbr) != 1)) {
return -1;
}
真相大白:
标准的GPT规范要求在0扇区必须有一个“保护性MBR(Pro tectiv e MBR)”,它的特征是结尾有55 AA,且包含一个类型为0xEE的假分 区。
但0扇区早就被uboot-with-spl.bin的RISC-V机器码填满了!
因此,当EFI驱动读取LBA 0后,is_pmbr_valid(legacymbr)返回了False。E FI 驱动一看0扇区连保护性MBR都没有,直接当场宣判“这不是GPT磁盘”,返回了-1。
它根本懒得去管 你LBA 1有没有数据,也根本 不会 触发后续去SD卡尾部寻找Backup GPT的容错回退逻辑!
修改U-Boot源码
打开disk/part_efi.c。
第一步: 找到检测函数
在文件中搜索i n t test_part_efi或者is_pmbr_valid。
第二步:注 释掉PMBR校验逻辑
将那段严格的检测逻辑修改掉,让它即使发现0扇区被破坏,也强制继 续往下走 。
static int part_test_efi(struct blk_desc *dev_desc)
{
ALLOC_CAC HE_A LIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blk sz );
/* Read legacy MBR from block 0 and validate it * /
if ((blk_dread(dev_desc, 0, 1, (ulong * )legacy mbr) != 1)
|| (i s_pmbr_vali d(le g acym br) != 1)) {
return -1;
}
re tu r n 0;
}
static int part_test_efi(struct blk_desc *dev_desc)
{
ALL OC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc- >b lksz);
/* Read legacy MBR from block 0 and don’t valida te it */
if (( blk_drea d(dev_de sc, 0, 1 , (u lo ng * )legac ymb r) ! = 1)) {
return -1;
}
return 0;
}
重新编译后烧录
日 志
Light LPI4A 16G# part list mmc 1
## Testing fo r valid EFI partition ##
Partition Map for MMC device 1 – Partition Type: EFI
GUID Partition Table Header signature is wrong: 0x 2529730529073 != 0x5452415020494645
fi nd_valid_g pt: *** ERROR: Invalid GPT * **
find _valid_gpt : *** Using Backup GP T ***
Part S tart LBA End LBA Name
Attribu tes
Type GUID
Partit ion GUID
1 0x00001000 0x00032fff “”
attrs: 0x00 00000000000 000
type: 0fc63daf-8483-4772-8 e79-3d69d84 77de4
type: linux
guid: 63f6d427-7e5 e-417f-98c6 -ad6e83bb84fd
2 0x00033000 0x03a527ff “”
attrs: 0x00000000 00000000
type: 0fc63daf-8483-4 772-8e79-3 d69d8477d e4
type: linux
guid: e6a7b680-8df5-4c52-9931-65063190a2fc
uboot可以正常识别sd卡了
上面内容只是实现th1520芯片从sd卡启动uboot和kernel,进入userland时可能出现挂载分区失败的问题
所以,还需要修改以下内容
Uboot代码,修改后重新编译,用dd写入sd卡0扇区
include/configs/light-c910.h中的uboot环境变量信息,编译时会把变量写入bin,uboot启动时根据变量启动kernel,这些变量包括加载协处理器固件、设置kernel内存地址、启动分区uuid,kernel参数等信 息
/boot分区内核启动参数,分区UUID,需要和sd卡分区uuid 匹配
/etc/fstab挂载分区需要和sd卡分区uuid 匹配
重启,kenel不认识gpt分区表损坏的SD卡,panic了
[ 4.696074] Waiting for root device /dev/mmcblk 1p2…
[ 4.698327] mmc1: new ultra high speed SDR104 SDHC card at addre ss 0001
[ 4.708489] mmcblk1: mmc1:0001 SD 29.2 GiB
[ 4.730525] /dev/root: Can’t open blockdev
[ 4.734672] VFS: Cannot open root device “/dev/mmcblk1p2” or unknown-block(179,770) : error -6
[ 4.743208] Please append a correct “root=” boot option; here are the available partitions:
[ 4.751572] b300 12213 8624 mmcblk0
[ 4.751579] d river: mmcblk
[ 4.758391] b301 2031 mmcblk0p1 13bff422-9836-4617-929 c-bef34845ad26
[ 4.758397]
[ 4.767371] b302 512000 mmcblk0p2 363dfde9-7b99-4085-b cfd-f9573f728f60
[ 4.767376]
[ 4.776346] b303 4194304 mmcblk0p3 5ebcaaf0-e098-43b9 -beef-1f8deedd135 e
[ 4.776351]
[ 4.785323] b304 117430255 mmcblk0p4 80a5a8e9-c744-49 1a-93c1-4f4194fd6 90a
[ 4.785328]
[ 4.794308] 0b3:00100 4096 mmcblk0boot0
[ 4.794313] (driver?)
[ 4.801116] 0b3:00200 4096 mmcblk0boot1
[ 4.801120] (driver?)
[ 4.807930] 0b 3:00300 30578688 mmcblk1
[ 4.807935] driver: mmcblk
[ 4.814743] L ist of all bdev filesys tems:
[ 4.818758] ext3
[ 4.818762 ] ext2
[ 4 .820685] ext4
[ 4.822613]
[ 4.826039] th1520-event soc: th1520-event: set rebootmode:0x22
[ 4.831878] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,770)
[ 4.840489] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.6.119 -th1520 #2025.12.24.18.43+2a44b04d6
[ 4.849274] Hardwar e name: Sipeed Lichee Pi 4A 1 6G (DT)
[ 4.854497] Call Trace:
[ 4.856944] [] dump_backtrace+0x28/0x30
[ 4.862354] [< ffffffff80a36a3c>] show_stack+0x38/0x44
[ 4.867408] [] dump_stack_lvl+0x44/0x5c
[ 4.872810] [] dump_stack+0x18/0x20
[ 4.8778 62] [] panic+0x13a/0x322
[ 4.882654] [] mount_root_generic+0x210/0x2be
[ 4.888576] [] mount_root+0x16e/0x186
[ 4.893802] [] prepare_namespace+0x20c/0x262
[ 4.899635] [] kernel_init_freeable+0x2fa/0x326
[ 4.9057 31] [] kernel_init+0x2a/0x158
[ 4.910 957] [] ret_from_fork+0xe/0x 1c
[ 4.916185] SMP: stopping secondary CPUs
[ 4.920112] [panic_cpufreq_notifier_ call]Match the clock sw status to the hw after rst
[ 4.928188] —[ end Kernel panic - not syncing: VFS: Una ble to mount root fs on unknown-block(179,770) ]—
继续修改,内核参数添加init=/bin/bash gpt
setenv bootargs “root=/dev/mmcblk1p2 rw console=ttyS0,115200 rootwait rw earlycon clk_ignore_unused loglevel=7 eth= rootrwo ptions=rw,noatime rootrwreset=yes init=/bin/bash gpt”
再次启动,截取日志片 段,kernel使用备份的GPT识别到两个分区并成功启动,可以看到sd卡中的archlinux
[ 5.4853 15] Freeing unused kernel image (initmem) m emory: 2752K
[ 5.491 327] Run /init as init process
Loading, please wait…
[ 5.528013] m mc1: new ultra high speed SDR104 SDHC card at ad dress 0001
[ 5.535636] mmcblk1: mmc1:0001 SD 29.2 GiB
[ 5.548432] Primary GPT is in valid , using alternate GPT.
[ 5.553961] mmcblk1: p1 p2

