前言
本文主要介绍Orange PiPC2 的bootrom相关内容,包括启动过程中soc的行为。
bootrom
什么叫bootrom?
几乎每款soc都内部固话了一段bootrom代码,这段代码呢主要是用来防止设备变砖而存在的一小段代码,比如我们的uboot存在flash中,可以起来,但由于我的误操作,吧flash擦除了,那么设备就起不来了,这个时候bootrom,就会根据你目前的启动情况自动选择启动的介质(nand,nor,net,USB,uart,tf卡,emmc),有的soc提供boot select pin,通过拨码开关实现从不同的启动方式。而实现这一功能的代码就是soc中bootrom。 这段代码在设备出厂的时候就固话在soc内部,不可修改,soc一上电就执行这段代码。
sunxi的bootrom代码以开源,一顿汇编操作。
sunxi bootrom
sunxi的bootrom中大致的过程有这两个,一个是fel,一个是eGON 引导。
上电后,soc默认从0xffff0000获取指令,这个地方就是bootrom程序存储的地方。首先执行eGON
- 协处理器的设置
- disable 看门狗
- 设置时钟
- enable ahb apb的门控
- 设置堆栈
- 跳转uboot check
这块就有点意思了,通过设置某些寄存器然后检查fel引脚- 如果是低电平,立马进入fel模式
- 否则进行如下顺序进行挨个尝试
- sd0卡启动(emmc0) -》nand-》sdcard2(emmc2)-》nor-》fel
- 可以看到假如所有介质启动都失败了,又会进入fel模式。
- fel模式就是一个usb启动的方式。
在资料H5_User_Manual.pdf中也写道UBOOT_SEL 为0直接进入fel模式
normal 模式
security process
4.2.2.8. Fast Boot Security Process
When the system chooses to whether enter mandatory MP process, if the UBOOT_SEL(UBOOT signal) is detected to pulled to high level, then the system will jump to fast boot process. The fast boot process is illustrated below.
sunxi H5的uboot_sel管脚是w6,默认内部上拉,为0进入fel模式
sunxi-H5的UBOOT_SEL管脚是-----W6
在我的Orange pipc2的板子上就是这个脚
这个板子上没有接出来,默认直接拉高。
要记得是R124这颗电阻的靠H5 U1这边的点位碰下地就进入到fel模式
fel
在我们之前的尝鲜中Orange pi pc2 环境搭建 已经使用过通过usb otg将我们的uboot下载近板子中运行,这个就是利用了我们H5的fel功能。
sunxi-fel -v -p spl sunxi-h5-spl32-ddr3.bin write 0x44000 bl31uboot.bin write 0x4a000000 u-boot.bin reset64 0x44000
通过sunxi-fel工具与soc的fel模式进行数据通信,文件传输。
eGON
在上述eGON 启动过程中有对介质的判断,那么如何得知当前的介质是能起来还是不能起来,以及是否需要跳过选择下一个启动方式的条件是什么呢?
答案就是魔术字eGON.BRM,每当在存储介质中固定位置检查到这个字符串就认为这个是合法的,他就认为可以启动,所以有些时候为了搞破坏,不让他从当前介质起来就可以在固定的位置吧这个支付串擦除掉就可以跳过检查,跳过当前介质,因为没有检测到这个字符串,就认为当前介质启动失败。
这个魔术字符可以在uboot编译完成后查看二进制文件可以看出来。
相关的格式头EGON hander
我们可以看下h5的boot0镜像,其开始的地方有eGON的标识。
bootrom启动过程
几乎所有的soc平台启动过程都差不多,都是商店运行bootrom,然后拷贝存储介质中前一段代码(有的8K,有的4K)到sram中运行,这段代码我们叫boot0,这段代码做ddr的初始化,然后将完整的uboot拷贝到ddr中后再跳转到ddr中运行uboot,而我们的uboot代码叫boot1;
为什么这么操作,就是因为一开始ddr没有初始化,并不能使用,只能使用sram,而sram很小并不能运行完整的uboot(好几百K吧),所以刚开始只能跑一点点,而我们H5中这个boot0就是编译出来的spl文件。这个boot0一般很小,做的事情也不多。复杂的事情交给boot1去做。
nor启动
eGON 中对nor的处理
在bootrom的汇编文件里可以看到对nor的处理是这个函数
bootrom处理的代码
load_from_spinor
对于 SPI NOR 闪存引导,BROM 为 SPI0 设置 6 MHz时钟频率,然后发出一系列读取数据字节 (03h) 命令。第一条命令从地址 0 读取 256 字节。如果识别出有效的 eGON 标头,接下来会读2次,第一次从0 地址读2048字节,第二次,从2048地址一直读完整个boot0镜像。
那么他怎么知道我的boot0多大呢,这就得益于,boot0的头了,也就是第一次读到的信息里面获得。然后跳转到boot0去运行。
几乎能对上,但是这个plt信息有点对不上,不知道为啥。
eGON 中对tf的处理