F1C100S-BOOTROM与SPL阶段

BootROM支持的引导介质

默认的启动优先级

目前没有找到修改启动顺序的方式

序号 启动介质 注意事项
1st MicroSD Card/eMMC 只支持PF0 ~ PF5这六个脚复用为SDC0启动, 控制器支持到SD2.0和eMMC4.41,设备端可以使用主流的eMMC5.1(eMMC存储器可以向前兼容)
2nd SPI Nor/Nand Flash 只支持PC0 ~ PC3这四个脚复用为SPI0启动, 支持标准SPI和DOUT模式, BROM启动时SPI Nand固定为1024字节/页,SPI Nor无特殊限制
3rd BROM FEL Mode 以上介质都无启动代码时,自动运行芯片内部USB程序(FEL Mode)(USB Full-Speed@12Mbps),USB脚是固定的无其它复用功能

F1C100S手册未提及芯片启动顺序,但可以参考全志V3S的手册,F1C100S没有强制进入烧写模式的专用引脚,可以将SDC0_CMDSPI0_CS/SPI0_DOUT强制接地干扰已经固化在eMMC/Nor-Flash中的SPL启动,让芯片进入USB-FEL下载模式。

下图的SDC1_CMD实际上作为SPI0_DOUT功能

SDC0启动

硬件连线使用以下引脚,BootROM读取eMMC或SDCard中的SPL程序时,只使用了1bit-sdio,且最大速度限制在25MHz,因此正常启动最少需要接CMD、CLK、D0这三根线;
但eMMC或SDCard在启动完成后还可作为应用程序的存储器,为了提升传输速度建议CMD、CLK D0~D3这6根线都接上,F1C100S的SDIO控制器最大支持SDR-4bit@50MHz。

通过逻辑分析仪抓取BootROM读取eMMC中的SPL程序的过程,可以看到只使用了1bit模式。

SPL程序需要从eMMC UDA物理分区的第16个扇区(512字节/扇区)开始烧录,下图是eMMC UDA物理分区内的布局图:
前8KB(扇区0 ~ 扇区15)存放MBR分区表或者非标准的GPT分区表,扇区16开始存放SPL程序,BROM将从这里读取程序到SRAM并执行,扇区80开始可以存放用户的程序,如果是启动linux,这里可以存放uboot,如果是嵌入式系统或者裸机,这里直接存放应用程序。

对于使用GPT分区表的情况,前8KB的空闲空间只能存放56条分区信息,GPT规范要求至少留128条分区信息的空间,某些工具可能不会认可这样非标准的分区表,因此GPT分区表可以放在SPL程序后面。对于一般应用来说,MBR分区表最大支持4个分区已经可以满足需求。

在抓取BootROM与eMMC通信中,观察到了F1C100S的BootROM会写eMMC的1号扇区(待重复验证),建议前0~15扇区都空着,有分区表的话还是放在SPL程序后面。

SPI0启动

标准的4线SPI接口,最大速度是AHB总线时钟的2分频,AHB通常设置为200MHz,因此SPI的时钟最大为100MHz。
BootROM加载SPL程序时默认使用标准SPI,具体时钟速度忘记了,大概10MHz以内,这段启动时间是无法优化的。
SPL启动后,加载用户程序时,推荐使用DOUT模式,用带宽换时钟,降低SPI布线要求,100MHz的SPI读写Flash实测不是很稳定。

nor-flash和nand-flash需要从物理0地址(0号扇区0地址)开始烧录SPL程序。

spi nor-flash直接使用sunxi-fel工具烧录。

spi nand-flash有一个改版的sunxi-fel工具可用,目前大部分的spi nand-flash都是4K/扇区的,烧录的时候每扇区只使用前1K,剩下的空着(spi nand启动还未测试过)。

USB启动

当SDC0,SPI0都没有读取到SPL程序时,自动运行芯片固化的USB程序(FEL),此时可以通过该程序提供的API,通过USB对芯片下载程序或执行ARM汇编代码。

在usb-fel模式下,usb接口默认是全速的(12Mbps),F1C100S的usb也支持高速模式(480Mbps),因此在USB端口的ESD二极管等效电容尽可能小,推荐使用5pF左右的。
windows下需要使用zadig安装winusb(libusb)驱动,然后才能使用sunxi-fel工具进行nor-flash烧录,发送程序到DRAM执行等。

BOOTROM到SPL

以下是全志F1C100S参考手册的内存映射表:

以下是全志V3S参考手册的内存映射表:

先说结论:
关于BROM地址和SRAM地址,全志F1C100S手册描述有误,全志V3S手册描述部分适用于F1C100S,下面进行验证。

在没有片外启动介质的情况下,给F1C100S通电,按照F1C100S手册上描述,BROM在0x0 ~ 0x7FFF,这里直接从0地址开始,先读出64K内容查看:

从提取出的内容来看,并不是正常的可执行文件内容,因此可以断定,BROM并不在0x0地址起始处。

使用r命令复位CPU,并使用halt命令暂停CPU,可以看到CPU处于SVC模式,且不响应外部中断,PC是0,表示将从0地址取指。
PC: (R15) = 00000000, CPSR = 000000D3 (SVC mode, ARM FIQ dis. IRQ dis.)

那再次查看下0x00000000地址上的内容吧:
可以看到和上文一样是FF FF FF FF,由于ARM内核无法区分读到的内容是指令还是数据,读到的东西全部当成指令进行解析,那么全FF肯定不是正常的ARM指令,处理器执行到这里将会进入未定义指令异常

试着单步运行一下,果然出现了未定义指令异常,且PC指向了FFFF0004处,顺着PC值就找到了默认异常向量表的位置。
PC: (R15) = FFFF0004, CPSR = 000000DB (UNDEF mode, ARM FIQ dis. IRQ dis.)

因为未定义指令异常排在异常表的第二位,所以当前PC值是FFFF0004,那么异常向量表起始位置就是0xFFFF0000

通常ARM9异常向量表默认地址可以设置成两种:0x00xFFFF0000,可以通过访问CP15协处理器的C1寄存器来设置或者读取

继续进行单步操作,发现进入死循环:

0xFFFF0000处的异常向量表读出,发现其他7个异常都指向了while(1)

那么可以判断出,F1C100S上电后并不是通过0地址的指令异常向量跳转到BROM处的,BROM应该在其他地方。

对芯片拉低复位信号,复位CPU,但调试器不做任何操作,这样CPU可正常运行;经过硬复位,芯片的BROM正常运行,sunxi-fel工具也正确识别。

此时挂上调试器,可以看到正常运行时PC=0xffff012c,当前运行位置在默认异常表的后面。

使用r命令,halt命令复位并暂停CPU,手动将PC设置到0xFFFF0000处,使用s单步执行几次,经过2个跳转指令,最终跳转到了0xFFFF4000地址处。
那么基本可以断定,BROM处于0xFFFF4000地址。

使用g命令全速运行:

sunxi-fel工具也正确识别出了设备,此时暂停CPU查看PC寄存器,也与正常上电运行后再暂停CPU的PC寄存器值一致:

那么可以推断出F1C100S上电后,应该是从0xFFFF4000地址处启动,BROM异常向量在'0xFFFF0000'处。

F1C100S实际的BROM和SRAM地址表

Module Address Size 权限
SRAM 0x0000 - 0x9000 36KB rwx
SRAM1 0xB000 - 0xB600 1.5KB rwx
异常向量表 0xFFFF0000 - 0xFFFF001F 32 Bytes rx
FEL模式相关程序 0xFFFF0020 - 0xFFFF25AB 9612 Bytes rx
BROM 0xFFFF4000 - 0xFFFF62B7 8888 Bytes rx

同时也在在0xFFFF4000地址处发现了eGON.BRM文件头的固件,通过BRM大致可以猜出这是F1C100S的BOOTROM了,和全志二级引导的文件头eGON.BT0有点类似。

// 待完成...

参考文档:
挖坑网关于F1C100S SPI-NAND启动的讨论:
https://whycan.com/t_1658.html
https://whycan.com/t_649.html
github开源的spi-nand调试记录:
https://github.com/hcly/f1c100s
CSDN关于F1C100S制作SPI-NAND镜像:
https://blog.csdn.net/hclydao/article/details/103709642
linux-sunxi关于SD卡启动,实际上也适用于eMMC:
https://linux-sunxi.org/Bootable_SD_card
全志V3S手册:
https://linux-sunxi.org/images/2/23/Allwinner_V3s_Datasheet_V1.0.pdf
全志其他芯片的SPL:
https://github.com/allwinner-zh/bootloader/tree/master/basic_loader
linux-sunxi community:
https://linux-sunxi.org/Main_Page
F1C100S SRAM地址推测:
https://blog.csdn.net/qq446252221/article/details/122453469

其他:
全志F1C100S的芯片的开发代号为suniv。
https://openwrt.org/docs/techref/hardware/soc/soc.allwinner.sunxi
https://linux-sunxi.org/Allwinner_SoC_Family
f1c100s_brom_ffff0000.bin提取的0xFFFF0000地址处的BROM:
f1c100s_brom_0提取的0地址处的内容:
https://files.cnblogs.com/files/yanye0xff/f1c100s_brom.zip?t=1659198022

posted @ 2022-07-24 15:41  Yanye  阅读(3119)  评论(0编辑  收藏  举报