第六章 Android SDK开发

本章向用户介绍如何对RK3568 Android SDK进行开发,包括u-boot开发、Linux内核开发、Android系统开发、Android应用开发;虽然本SDK目前适用于正点原子ATK-DLRK3568开发板,但是用户可以基于本SDK进行二次开发、定制,以适配自己的Android产品;基于本SDK,可以有效实现系统定制和应用移植开发,帮助用户快速开发、提高开发效率!

6.1 U-Boot开发

U-Boot源码在/u-boot目录,如下所示:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化

图6.1.1 U-Boot源码目录

RK提供了一份文档详细向用户介绍了Rockchip平台U-Boot所涉及到的知识点、技术点,包括Rockchip平台U-Boot基础简介、U-Boot架构、U-Boot启动流程、U-Boot系统模块、驱动模块、Kernel-DTB、AB系统、AVB安全启动、TPL、SPL、U-Boot快捷键等等,内容非常多,对U-Boot(Rockchip平台U-Boot)不太熟悉的用户建议一定要去看看;该文档的路径为:/RKDocs/common/u-boot/Rockchip_Developer_Guide_UBoot_Nextdev_CN.pdf。同样,ATK-DLRK3568开发板资料包中也有提供,路径为:开发板光盘A盘-基础资料08、RK官方文档Androidcommonu-bootRockchip_Developer_Guide_UBoot_Nextdev_CN.pdf。 6.1.1 U-Boot的设备树 U-Boot中,RK3568平台使用的设备树文件是/arch/arm/dts/rk3568-evb.dts,该设备树文件包含了rk3568.dtsi和rk3568-u-boot.dtsi,包含关系如下: rk3568-evb.dts rk3568.dtsi rk3568-u-boot.dtsi 原生的U-Boot只支持U-Boot自己的DTB,RK平台在原生U-Boot基础上增加了kernel DTB机制的支持,即U-Boot会使用kernel DTB去初始化外设。这样设计的目的主要是为了兼容外设板级差异,譬如power、clock、display等。 U-Boot设备树负责初始化存储、调试串口等基础外设;而kernel设备树初始化存储、调试串口之外的外设,譬如LCD显示、千兆网等。执行U-Boot代码时先用U-Boot的设备树完成存储、调试串口的初始化操作,然后从存储上加载kernel的设备树并转而使用这份设备树继续初始化其余外设。 所以用户一般不需要去修改U-Boot的设备树文件(除非更换调试串口)。 6.1.2 U-Boot编译  U-Boot源码目录下提供了一个编译脚本make.sh,可以直接使用该脚本编译U-Boot源码,譬如在U-Boot源码目录下执行如下命令编译U-Boot:

./make.sh rk3568

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_02

图6.1.2.1 编译U-Boot源码(1)

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化_03

图6.1.2.2 编译U-Boot源码(2)

编译完成后将会生成uboot.img和rk356x_spl_loader_v1.13.112.bin两个镜像文件。如下所示:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_04

图6.1.2.3 U-Boot编译后生成的镜像 当然,除了这两个镜像之外,还生成了很多的.bin镜像,譬如bl31_xxx.bin、tee.bin、u-boot.bin、u-boot-dtb.bin、u-boot-nodtb.bin等等,这些镜像都是中间产物,最终烧录到开发板只有uboot.img和rk356x_spl_loader_v1.13.112.bin,接下来讲一下这两个镜像文件。

  1. uboot.img镜像 前面提到过,uboot.img是由多个镜像合并而成,包括u-boot镜像、u-boot dtb以及trust镜像(ARM Trusted Firmware + OP-TEE)。uboot.img是一种FIT(flattened image tree)格式镜像,支持任意多个image打包和校验。使用file命令查看uboot.img,如下所示:

FIT使用its(image source file)文件来描述image的信息,最后通过mkimage工具生成itb(flattened image tree blob)镜像,那么这个itb镜像其实就是uboot.img镜像,uboot.img镜像通常含有多份itb镜像,如下所示:

uboot.img = uboot.itb * N(N一般是2) 这种设计也是为了避免如果第一份镜像启动失败、还可以尝试使用第二份镜像启动。 U-Boot编译成功后,U-Boot源码目录下会生成很多.bin镜像以及.dtb镜像:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_05

图6.1.2.4 U-Boot目录下的bin镜像

整理一下,如下表所示:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_06

表6.1.2.1 目录镜像介绍

uboot.img镜像最终由u-boot-nodtb.bin、u-boot.dtb、bl31_0x00040000.bin、bl31_0x00068000.bin、bl31_0x0006a000.bin、bl31_0xfdcc1000.bin、bl31_0xfdcce000.bin、bl31_0xfdcd0000.bin、tee.bin这些镜像合并而成。 uboot.img是FIT格式镜像,使用its文件来描述image的信息,最终通过/tools/mkimage工具生成itb镜像;its文件和生成的itb镜像都在/fit目录下:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_07

图6.1.2.5 fit目录下的文件 u-boot.its文件语法规则与设备树DTS的语法规则相同,非常灵活! u-boot.its文件中描述了有哪些镜像会参与合并成uboot.itb,以及这些镜像的路径等信息:

/dts-v1/;

/ {
        description = "FIT Image with ATF/OP-TEE/U-Boot/MCU";
        #address-cells = <1>;

        images {

                uboot {
                        description = "U-Boot";
                        data = /incbin/("u-boot-nodtb.bin");
                        type = "standalone";
                        arch = "arm64";
                        os = "U-Boot";
                        compression = "none";
                        load = <0x00a00000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-1 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0x00040000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0x00040000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-2 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0xfdcc1000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xfdcc1000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-3 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0x0006a000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0x0006a000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-4 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0xfdcd0000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xfdcd0000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-5 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0xfdcce000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xfdcce000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf-6 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("./bl31_0x00068000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0x00068000>;
                        hash {
                                algo = "sha256";
                        };
                };
                optee {
                        description = "OP-TEE";
                        data = /incbin/("tee.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "op-tee";
                        compression = "none";

                        load = <0x8400000>;
                        hash {
                                algo = "sha256";
                        };
                };
                fdt {
                        description = "U-Boot dtb";
                        data = /incbin/("./u-boot.dtb");
                        type = "flat_dt";
                        arch = "arm64";
                        compression = "none";
                        hash {
                                algo = "sha256";
                        };
                };
        };

        configurations {
                default = "conf";
                conf {
                        description = "rk3568-evb";
                        rollback-index = <0x0>;
                        firmware = "atf-1";
                        loadables = "uboot", "atf-2", "atf-3", "atf-4", "atf-5", "atf-6", "optee";

                        fdt = "fdt";
                        signature {
                                algo = "sha256,rsa2048";

                                key-name-hint = "dev";
                                sign-images = "fdt", "firmware", "loadables";
                        };
                };
        };
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
由此可知,its文件的语法规则与DTS是完全相同的,并无差别!详情可以参考<U-Boot>/doc/uImage.FIT/目录下的文档。
对于ARM Trusted Firmware以及OP-TEE,它们是闭源的,RK只提供了二进制镜像文件,并没提供源码。ARM Trusted Firmware固件对应<U-Boot>/bl31.elf、OP-TEE固件对应<U-Boot>/tee.bin,如下所示:
  • 1.
  • 2.

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_08

图6.1.2.6 ATF固件和OP-TEE固件

编译U-Boot源码之前,这两个镜像是不存在的,编译之后才会出现;实际上来自于/rkbin/bin/rk35/rk3568_bl31_v1.34.elf和/rkbin/bin/rk35/rk3568_bl32_v2.08.bin这两个镜像文件。打包uboot.itb的过程中,会将/rkbin/bin/rk35/rk3568_bl31_v1.34.elf拷贝到/bl31.elf,将/rkbin/bin/rk35/rk3568_bl32_v2.08.bin拷贝到/tee.bin。 bl31.elf固件并不是直接打包进uboot.itb,而是将bl31.elf分解成多个bl31_xxx.bin文件,最终将这些bl31_xxx.bin镜像打包进uboot.itb。

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_09

图6.1.2.7 bl31_xxx.bin固件

2. rk356x_spl_loader_v1.13.112.bin镜像 再来讲一下rk356x_spl_loader_v1.13.112.bin,这个镜像文件就是前面给大家介绍的MiniLoaderAll.bin镜像(由rk356x_spl_loader_v1.13.112.bin重命名而来)。前面给大家讲过,MiniLoaderAll.bin是运行在RK3568平台U-Boot之前的一段Loader代码(也就是比U-Boot更早阶段的Loader)。 MiniLoaderAll.bin由两部分构成:TPL(Tiny Program Loader) + SPL(Secondary Program Loader)构成。 TPL运行在SRAM中(片内内存),由rk3568芯片内部所固化的Maskrom代码引导启动;其作用是负责完成DRAM的初始化工作、并启动SPL;SPL运行在DDR,SPL的作用是负责完成系统的lowlevel初始化、完成uboot.img的加载和引导工作。 TPL、SPL分别有两种实现方案:开源版本和闭源版本。 闭源版本 RK向用户提供了tpl和spl的二进制镜像文件,不提供其对应的源码,其所在路径如下: /rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.13.bin ---------------> tpl /rkbin/bin/rk35/rk356x_spl_v1.12.bin -------------------------------> spl /rkbin/bin目录下存放了很多RK提供的二进制文件,这些二进制文件都是不开源的,所以只有二进制文件。 开源版本 tpl和spl镜像也可以通过u-boot源码编译出来,既然是U-Boot源码的一部分,自然是开源的。使用“./make.sh rk3568”命令编译完U-Boot源码后,除了会生成u-boot镜像之外,还会编译生成spl以及tpl镜像,spl镜像位于/spl目录下:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_10

图6.1.2.8 spl目录下的文件

该目录下也存在很多镜像文件: 镜像 说明 u-boot-spl elf格式的spl镜像 u-boot-spl.bin spl镜像,包含spl dtb u-boot-spl.dtb spl dtb u-boot-spl-dtb.bin spl镜像,包含spl dtb,与u-boot-spl.bin是一样的 u-boot-spl-nodtb.bin spl镜像,不包含spl dtb 表6.1.2.2 spl目录镜像介绍 tpl镜像位于/tpl目录下:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_11

图6.1.2.9 tpl目录下的文件

在RK的文档中,将RK提供的闭源TPL镜像/rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.13.bin称为ddr bin,将闭源SPL镜像/rkbin/bin/rk35/rk356x_spl_v1.12.bin称为miniloader。 rk356x_spl_loader_v1.13.112.bin镜像文件是由/tools/boot_merger工具制作而成,该工具由RK提供。使用boot_merger工具制作rk356x_spl_loader_v1.13.112.bin镜像时需要提供一个.ini文件,.ini文件用于描述image的信息;在/rkbin/RKBOOT/目录下有很多.ini文件,如下图所示:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化_12

图6.1.2.10 .ini文件

对于RK3568平台来说,它默认使用的是RK3568MINIALL.ini。文件内容如下: [CHIP_NAME] NAME=RK3568 [VERSION] MAJOR=1 MINOR=1 [CODE471_OPTION] NUM=1 Path1=bin/rk35/rk3568_ddr_1560MHz_v1.13.bin Sleep=1 [CODE472_OPTION] NUM=1 Path1=bin/rk35/rk356x_usbplug_v1.14.bin [LOADER_OPTION] NUM=2 LOADER1=FlashData LOADER2=FlashBoot FlashData=bin/rk35/rk3568_ddr_1560MHz_v1.13.bin FlashBoot=bin/rk35/rk356x_spl_v1.12.bin [OUTPUT] PATH=rk356x_spl_loader_v1.13.112.bin [SYSTEM] NEWIDB=true [FLAG] 471_RC4_OFF=true RC4_OFF=true FlashData指定了tpl镜像的路径;FlashBoot指定了spl镜像的路径。所以默认情况下,执行“./make.sh rk3568”命令生成的rk356x_spl_loader_v1.13.112.bin使用的是RK闭源的ddr bin(/rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.13.bin)和RK闭源的miniloader(/rkbin/bin/rk35/rk356x_spl_v1.12.bin)。 除了使用RK闭源的miniloader之外,还可以使用U-Boot编译出来的开源spl(注意,不能用U-Boot编译出来的tpl镜像,我测试过直接启动不了,估计是U-Boot TPL部分代码支持不够完善),执行如下命令可以用U-Boot生成的spl镜像(/spl/u-boot-spl.bin)替换RK闭源的miniloader去制作rk356x_spl_loader_v1.13.112.bin: ./make.sh --spl

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_13

图6.1.2.11 使用开源SPL生成MiniLoaderAll.bin

默认情况: MiniLoaderAll.bin = 闭源ddr bin + 闭源miniloader; 执行“./make.sh --spl”后:MiniLoaderAll.bin = 闭源ddr bin + 开源SPL。 make.sh脚本还支持很多其它的参数,执行“./make.sh -h”可以查看它的使用帮助信息,大家自己去捣鼓。

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_14

图6.1.2.12 make.sh脚本帮助信息 3. 镜像启动顺序 这里讲一下RK3568平台镜像的启动顺序。涉及到Trust,目前Rockchip的64位SoC平台上使用的是ARM Trusted Firmware + OP-TEE的组合来实现Trust,32位SoC平台上使用的是OP-TEE。 ARM Trusted Firmware的体系架构里将整个系统分成四种安全等级,分别为:EL0、EL1、EL2、EL3。将整个安全启动的流程阶段定义为:BL1、BL2、BL31、BL32、BL33,其中ARM Trusted Firmware自身的源代码里提供了BL1、BL2、BL31的功能。Rockchip平台仅使用了其中的BL31的功能;对于BL1和BL2,RK有自己的一套实现方案。所以在Rockchip平台上,我们一般也可以“默认”ARM Trusted Firmware指的就是BL31,而BL32使用的则是OP-TEE。 如果把上述这种阶段定义映射到Rockchip平台各级固件上,对应关系为:Maskrom(RK芯片内部固化的引导代码,BL1)、MiniLoaderAll.bin(BL2)、Trust(BL31:ARM Trusted Firmware + BL32:OP-TEE)、U-Boot(BL33)。 所以Linux系统的镜像启动顺序为: Maskrom MiniLoaderAll.bin uboot.img boot.img Android 还可以进行细分: Maskrom TPL(ddr bin) SPL(miniloader) Trust(ATF + OP-TEE) u-boot kernel Android 这个启动流程通过打印信息就可以分析出来,以下就是ATK-DLRK3568开发板上电启动时的打印信息:

执行ddr bin,对开发板的DDR进行初始化

DDR Version V1.13 20220218 In ddrconfig:15 DDR4, 324MHz BW=32 Col=10 Bk=4 BG=2 CS0 Row=16 CS=1 Die BW=16 Size=2048MB tdqss: cs0 dqs0: 24ps, dqs1: -48ps, dqs2: -96ps, dqs3: -96ps,

change to: 324MHz clk skew:0x87 PHY drv:clk:37,ca:37,DQ:37,odt:0 vrefinner:50%, vrefout:50% dram drv:34,odt:0

change to: 528MHz clk skew:0x87 PHY drv:clk:37,ca:37,DQ:37,odt:139 vrefinner:50%, vrefout:61% dram drv:34,odt:120

change to: 780MHz clk skew:0x87 PHY drv:clk:37,ca:37,DQ:37,odt:139 vrefinner:50%, vrefout:61% dram drv:34,odt:120

change to: 1560MHz(final freq) clk skew:0x87 PHY drv:clk:37,ca:37,DQ:37,odt:139 vrefinner:50%, vrefout:61% dram drv:34,odt:120 cs 0: the read training result: DQS0:0x32, DQS1:0x2c, DQS2:0x27, DQS3:0x30, min : 0xf 0xe 0xd 0x8 0x3 0x2 0x5 0x5 , 0x7 0x5 0x1 0x3 0x5 0x7 0x9 0x9 , 0x5 0x8 0x9 0x7 0x5 0x3 0x2 0x5 , 0xa 0x6 0x5 0x2 0x7 0xb 0x7 0x9 , mid :0x28 0x27 0x27 0x21 0x1b 0x1b 0x1e 0x1c ,0x1f 0x1d 0x19 0x1c 0x1e 0x1f 0x21 0x1e , 0x1d 0x20 0x20 0x1e 0x1d 0x1c 0x1a 0x1d ,0x23 0x1e 0x1e 0x1a 0x20 0x23 0x20 0x21 , max :0x41 0x41 0x41 0x3b 0x34 0x35 0x37 0x34 ,0x38 0x36 0x32 0x36 0x37 0x37 0x39 0x34 , 0x36 0x39 0x37 0x36 0x36 0x35 0x33 0x35 ,0x3c 0x37 0x38 0x32 0x39 0x3c 0x39 0x39 , range:0x32 0x33 0x34 0x33 0x31 0x33 0x32 0x2f ,0x31 0x31 0x31 0x33 0x32 0x30 0x30 0x2b , 0x31 0x31 0x2e 0x2f 0x31 0x32 0x31 0x30 ,0x32 0x31 0x33 0x30 0x32 0x31 0x32 0x30 , the write training result: DQS0:0x8b, DQS1:0x7e, DQS2:0x74, DQS3:0x74, min :0x76 0x76 0x7c 0x77 0x6b 0x6d 0x6f 0x6f 0x78 ,0x6d 0x6e 0x69 0x6e 0x6c 0x6e 0x74 0x6d 0x69 , 0x67 0x63 0x6a 0x69 0x64 0x5e 0x65 0x64 0x60 ,0x63 0x5e 0x63 0x5d 0x63 0x5f 0x61 0x67 0x61 , mid :0x8f 0x8e 0x93 0x8e 0x81 0x83 0x85 0x87 0x91 ,0x84 0x85 0x7d 0x84 0x83 0x85 0x88 0x84 0x7e , 0x7c 0x7d 0x7f 0x7d 0x7a 0x76 0x78 0x7a 0x78 ,0x79 0x74 0x78 0x71 0x79 0x78 0x78 0x7c 0x79 , max :0xa9 0xa7 0xab 0xa6 0x97 0x9a 0x9c 0xa0 0xaa ,0x9c 0x9c 0x92 0x9b 0x9b 0x9c 0x9c 0x9c 0x93 , 0x91 0x97 0x94 0x91 0x91 0x8e 0x8c 0x91 0x90 ,0x90 0x8b 0x8e 0x86 0x8f 0x91 0x90 0x91 0x91 , range:0x33 0x31 0x2f 0x2f 0x2c 0x2d 0x2d 0x31 0x32 ,0x2f 0x2e 0x29 0x2d 0x2f 0x2e 0x28 0x2f 0x2a , 0x2a 0x34 0x2a 0x28 0x2d 0x30 0x27 0x2d 0x30 ,0x2d 0x2d 0x2b 0x29 0x2c 0x32 0x2f 0x2a 0x30 , out

ddr bin结束,开始运行SPL(miniloader)代码

U-Boot SPL board init U-Boot SPL 2017.09-gaaca6ffec1-211203 #zzz (Dec 03 2021 - 18:42:16) unknown raw ID phN unrecognized JEDEC id bytes: 00, 00, 00 Trying to boot from MMC2 MMC error: The cmd index is 1, ret is -110 Card did not respond to voltage select! mmc_init: -95, time 10 spl: mmc init failed with error: -95 Trying to boot from MMC1 SPL: A/B-slot: _a, successful: 0, tries-remain: 7 Trying fit image at 0x4000 sector

Verified-boot: 0

Checking atf-1 0x00040000 ... sha256(6204b6f381...) + OK

Checking uboot 0x00a00000 ... sha256(08dca575f2...) + OK

Checking fdt 0x00b35800 ... sha256(56cff76c01...) + OK

Checking atf-2 0xfdcc1000 ... sha256(5563d929da...) + OK

Checking atf-3 0x0006a000 ... sha256(b04372ab0f...) + OK

Checking atf-4 0xfdcd0000 ... sha256(b46eaa95b8...) + OK

Checking atf-5 0xfdcce000 ... sha256(2f8839c803...) + OK

Checking atf-6 0x00068000 ... sha256(6e9d32ba23...) + OK

Checking optee 0x08400000 ... sha256(66bbd17352...) + OK

Jumping to U-Boot(0x00a00000) via ARM Trusted Firmware(0x00040000) Total: 236.326 ms

SPL结束(MiniLoaderAll.bin结束),跳转到了ATF和OP-TEE

INFO: Preloader serial: 2 NOTICE: BL31: v2.3():v2.3-365-gae7c295ca:derrick.huang NOTICE: BL31: Built : 15:37:13, May 17 2022 INFO: GICv3 without legacy support detected. INFO: ARM GICv3 driver initialized in EL3 INFO: pmu v1 is valid 220114 INFO: dfs DDR fsp_param[0].freq_mhz= 1560MHz INFO: dfs DDR fsp_param[1].freq_mhz= 324MHz INFO: dfs DDR fsp_param[2].freq_mhz= 528MHz INFO: dfs DDR fsp_param[3].freq_mhz= 780MHz INFO: Using opteed sec cpu_context! INFO: boot cpu mask: 0 INFO: BL31: Initializing runtime services INFO: BL31: Initializing BL32 I/TC: I/TC: OP-TEE version: 3.13.0-641-g4167319d3 #hisping.lin (gcc version 10.2.1 20201103 (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16))) #8 Wed Mar 16 15:14:56 CST 2022 aarch64 I/TC: Primary CPU initializing I/TC: Primary CPU switching to normal world boot INFO: BL31: Preparing for EL3 exit to normal world INFO: Entry point address = 0xa00000 INFO: SPSR = 0x3c9

进入到U-Boot,开始执行U-Boot代码

U-Boot 2017.09-gc2d9f80c05-220621 #tgg (Apr 10 2023 - 11:31:38 +0800)

Model: Rockchip RK3568 Evaluation Board PreSerial: 2, raw, 0xfe660000 DRAM: 2 GiB Sysmem: init Relocation Offset: 7d343000 Relocation fdt: 7b9f84e0 - 7b9fece0 CR: M/C/I Using default environment

dwmmc@fe2b0000: 1, dwmmc@fe2c0000: 2, sdhci@fe310000: 0

Bootdev(atags): mmc 0 MMC0: HS200, 200Mhz PartType: EFI DM: v1 boot mode: None …… ……

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_15

图6.1.2.13 TPL(ddr bin)运行过程

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化_16

图6.1.2.14 SPL运行过程

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_17

图6.1.2.15 Trust运行过程

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化_18

图6.1.2.16 U-Boot运行过程

6.1.3 U-Boot的配置 如果用户想要自己配置U-Boot,可以在U-Boot源码目录下执行如下命令对其进行配置: make rk3568_defconfig //选择配置文件 make menuconfig //打开图形化配置界面 运行结果如下所示:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_19

图6.1.3.1 menuconfig图形化配置 通过menuconfig图形化界面、用户可自行对U-Boot进行配置,配置完成后运行以下命令保存配置: make savedefconfig //把配置信息保存到defconfig文件中 cp defconfig configs/rk3568_defconfig //用defconfig文件替换rk3568_defconfig 保存配置后,我们可以直接在U-Boot源码目录下执行make.sh脚本编译U-Boot源码,也可以回到SDK根目录下执行build.sh脚本进行编译: ./make.sh rk3568 //在U-Boot源码目录下执行make.sh脚本编译 cd ../ && ./build.sh -U //在SDK根目录下执行build.sh脚本编译

6.1.4 defconfig配置文件

U-Boot中,RK3568平台使用的defconfig配置文件为:/configs/rk3568_defconfig,开发者基本不用去改动它,其实对于整个U-Boot来说,如果你的产品没什么特殊的需求,基本不用去动U-Boot源码。 如果不使用make.sh脚本,直接通过make命令配置U-Boot、然后编译U-Boot,可以这样做: make rk3568_defconfig -j24 make PYTHON=python2 CROSS_COMPILE=/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- all --jobs=24 表示SDK的目录,根据你自己的实际路径修改;编译内核、编译U-Boot用的都是这个交叉编译器/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-。

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_20

图6.1.4.1 配置U-Boot

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_21

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_22

图6.1.4.2 编译U-Boot

编译完成之后,并没有生成uboot.img和rk356x_spl_loader_v1.13.112.bin,因为这两个镜像属于pack打包镜像,需要通过专门的工具或脚本才能生成,make.sh脚本中已经添加了打包操作,所以使用make.sh脚本编译后会生成uboot.img和rk356x_spl_loader_v1.13.112.bin。 当然我们可以执行如下命令去打包生成这两个镜像: ./scripts/fit.sh --ini-loader ../rkbin/RKBOOT/RK3568MINIALL.ini --chip RK3568

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_Android_23

图6.1.4.3 执行打包操作(1)

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_初始化_24

图6.1.4.4 执行打包操作(2)

执行成功便会生成这两个镜像文件:

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_25

图6.1.4.5 uboot.img和MiniLoaderAll.bin

scripts/fit.sh脚本会调用tools/mkimage工具生成uboot.img、调用tools/boot_merger工具生成rk356x_spl_loader_v1.13.112.bin。还支持多种其它的用法,大家可以自己去摸索。 如果需要清理U-Boot源码工程,执行“make distclean”命令进行清理: make distclean

【正点原子K210连载】第六章 Android SDK开发 摘自【正点原子】DNK210使用指南-CanMV版指南_设备树_26

图6.1.4.6 清理U-Boot 6.1.5 快捷键 RK平台U-Boot支持通过串口组合键触发一些事件用于烧写、调试等操作。RK U-Boot运行后不会出现启动倒计时(启动内核的倒计时),它会直接启动内核,跳过倒计时。 当然,可以通过串口组合键“Ctrl + C”打断它启动内核、从而进入U-Boot命令行模式。RK U-Boot支持如下串口组合键(开机时长按): Ctrl + C:进入U-Boot命令行模式。 Ctrl + D:进入Loader烧写模式;除了2.9.1小节中介绍的进入Loader模式的方法之外,这也是一种进入Loader烧写模式的方法。 Ctrl + B:进入Maskrom烧写模式;除了2.9.1小节中介绍的进入Maskrom模式的方法之外,这也是一种进入Maskrom烧写模式的方法。 Ctrl + F:进入fastboot模式。 Ctrl + M:打印bidram/system的信息。 Ctrl + I:使能内核initcall_debug。 Ctrl + P:打印cmdline信息。 Ctrl + S:"Starting kernel..."之后进入U-Boot命令行。 大家可以自己测试下,这里不多说。 6.1.6 HW-ID DTB RK平台U-Boot支持检测GPIO或者ADC的硬件状态实现动态加载不同的kernel DTB,也就是说它可以根据GPIO或者ADC的硬件状态,从多份Kernel DTB文件中找到与当前硬件状态匹配的DTB进行加载;譬如说某个固定的ADC值、固定的某GPIO电平,RK将这种功能称为HW-ID DTB。 譬如正点原子ATK-DLRK3568开发板的MIPI屏接口支持5.5寸720p MIPI屏(正点原子5.5寸MIPI屏)、同样也支持5.5寸1080p MIPI屏(正点原子5.5寸MIPI屏),但是这两种屏的时序参数以及初始化参数都是不同的,两种MIPI屏就需要两个DTS文件分别进行配置,所以会导致出现这样一个情况:使用720p MIPI屏时,需要烧录720p MIPI屏对应的DTB,使用1080p MIPI屏时,需要烧录1080p MIPI屏对应的DTB。显得非常麻烦! 此时可以通过HW-ID DTB来解决这种麻烦,首先我们需要将720p MIPI屏的DTB文件和1080p MIPI屏的DTB文件全打包进同一个resource.img镜像中,U-Boot引导内核时会检测硬件状态(ADC或GPIO),从resource.img镜像中找出与当期硬件状态(某个固定的ADC值或某个GPIO的电平)相匹配的DTB、并加载。

  1. 硬件设计参考 目前支持检测ADC和GPIO两种硬件状态。 正点原子ATK-DLRK3568开发板MIPI屏接口处有设计一个SARADC_VIN2_LCD_ID引脚:

图6.1.6.1 MIPI屏接口