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_CMD
或SPI0_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异常向量表默认地址可以设置成两种:0x0
和0xFFFF0000
,可以通过访问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