tiny4412 uboot 2020.10版本移植系列(二)——下载uboot及对uboot移植的构想和准备工作
一、uboot下载
这个网站提供所有uboot版本的下载:ftp://ftp.denx.de/pub/u-boot/
我下载了最新版本的uboot:u-boot-2020.10.tar.bz2
二、uboot启动流程分析
uboot源码根目录下的README是一个好文件,里面会告诉你很多关于uboot源码怎么使用的信息,仔细阅读会带来很多便利。
uboot的启动流程可以参见README文件Board Initialisation Flow: 下面的信息。
这里进行一些简略的记录:
uboot源码可以配置编译成两份镜像,一份称为u-boot-spl.bin, 一份称为u-boot.bin。
SPL:Secondary Program Loader,即辅助程序加载器,主要作用是在有限空间的内部RAM中,启用uboot较少的功能,把完整的uboot加载到外部大空间的DRAM中,并跳转到DRAM对应的地址运行uboot。
u-boot-spl.bin:即基于SPL生成的仅有部分功能的uboot,编译完放在spl/目录下。占用空间小。
u-boot.bin:即完整的uboot镜像,编译完放在源码根目录下,占用空间相对较大。
两个镜像的启动流程基本一样:start.S-->lowlevel_init()-->board_init_f()-->board_init_r()
这里不详细讲述,以免重复,可参阅其他博客,或者uboot本身的README的详细记录。
三、对tiny4412 uboot移植的构想及准备工作:
3.1. exynos 4412 CPU芯片的启动过程如下:
(参见SEC_Exynos4412_Users Manual_Ver.1.00.00.pdf P91 5.2.1Block Diagram)
Soc即Exynos 4412Soc芯片。集成了内部ROM(iROM)和内部SRAM(iRAM)。
iROM里面的固化程序开机即启动,根据OM引脚的值决定从Nand/SD卡/eMMC/USB获取BL1的镜像,并加载到iRAM0x02021400处,并运行BL1程序。
BL1镜像为三星提供的bin文件,没有源代码,不清楚里面的具体实现。但通过数据手册知道BL1会加载BL2到iRAM的0x02023400位置,并运行BL2镜像。
由于iRAM空间有限,无法容纳完整的uboot镜像,所以我们用u-boot-spl.bin通过处理成bl2需要的格式(具体参考下面3.3节),变为BL2镜像。
BL2运行之后, 初始化时钟,初始化外部DRAM,然后把u-boot.bin镜像加载到外部DRAM上,并跳转到DRAM运行完整的uboot。
3.2. 镜像在SD卡与eMMC的布局
参见数据手册:Android_Exynos4412_iROM_Secure_Booting_Guide_Ver.1.00.00.pdf
P24
SD卡启动时,布局如上,第0块(512字节)为保留块,1-16块(8K字节)为BL1, 17-48块(16K字节)为BL2,之后的空间可以自由发挥,可以先规划一个环境变量存放区,然后在规划一个uboot存放区,一个linux kernel 存放区等。
eMMC布局如上,与SD卡区别在于没有前面第0块512字节的保留区。
这里还需要注意,提供给sd或者mmc的时钟必须为20MHz, 否则可能加载uboot到DRAM会失败。如数据手册上面的警告:
3.3. sd卡的烧录及用到的软件
sd卡烧录要用到三星提供的sd_fuse软件包。
这个软件包可以通过友善之臂提供的uboot源码包中获取。也可以到github获取https://github.com/friendlyarm/uboot_tiny4412
sd_fuse目录结构如下:
.
├── Makefile
├── mkbl2
├── sd_fdisk
├── sd_fdisk.c
├── tiny4412
│ ├── bl2.bin
│ ├── E4412_N.bl1.bin
│ ├── E4412_tzsw.bin
│ ├── fast_fuse.sh
│ └── sd_fusing.sh
└── V310-EVT1-mkbl2.c
用法说明:
Makefile使得sd_fdisk.c和V310-EVT1-mkbl2.c编译为sd_fdisk和mkbl2。
sd_fdisk我并没有用到;
mkbl2用来把u-boot-spl.bin修改为一个16KB大小bl2.bin,原来代码提供的功能仅能处理大于16KB的u-boot-spl.bin,但我的u-boot-spl.bin总比16KB小,所以需要修改一下V310-EVT1-mkbl2.c代码,让其功能更完整。具体可参考我写的《关于tiny4412开发板烧录uboot时不成功的一个原因可能是mkbl2造成的》这篇博客,这里不再累撰。
sd_fusing.sh脚本把E4412_N.bl1.bin,bl2.bin,u-boot.bin, E4412_tzsw.bin按照上面3.2节说的布局烧录到sd卡里面。
fast_fuse.sh脚本仅烧录bl2.bin,u-boot.bin两个镜像到sd卡里面。
E4412_N.bl1.bin——即BL1镜像
bl2.bin——u-boot-spl.bin通过mkbl2软件处理生成的BL2镜像
u-boot.bin——uboot镜像
E4412_tzsw.bin——与芯片TrustZone功能相关的镜像。这个镜像的烧录通过各种方式获知,它应该烧录到uboot镜像之后的空间里。但却不知道到底怎么去读它,在什么地方调用上面的功能,网上并没有过多的解释。仅仅是烧录在uboot后面。如果谁知道,请告诉我。万分感谢。
我对TrustZone的一些理解来自数据手册SEC_Exynos4412_Users Manual_Ver.1.00.00.pdf P903
信任区域保护控制器 (TZPC) 在信任区设计中为安全系统中的保护位提供软件接口。它将每个内存区域配置为安全或不安全。
我认为E4412_tzsw.bin存放的是一些与读取信任区数据有关的函数,但没有找到源代码,也无法深入了解,只能暂时搁置对TrustZone的研究。
通过我的实践,发现其实E4412_tzsw.bin这个镜像并不一定非要烧录到sd卡或者eMMC里面。你只要在uboot不对TZPC进行初始化,似乎一切正常。反而如果初始化有问题,可能uboot根本就没法加载到DRAM指定的位置,只给你显示0xffffffff。而加载函数的返回值却显示成功,让你根本不知道到底哪里出问题了,让人一脸困惑。
所以对TrustZone我简单地摒弃掉了,不烧录E4412_tzsw.bin,也不初化TZPC,留到以后有空再进行研究。
作者水平有限,如有错误,请不吝指出,必虚心接纳。
本文参考众多技术博客及资料,如:
https://www.cnblogs.com/pengdonglin137/tag/TINY4412/
https://www.cnblogs.com/LoTGu/category/872380.html
等,对其作者表示感谢。他们的引领,让我少走很多弯路。