正点原子STM32MP157学习——2.内核移植(V2.6版本TF-A原理及移植)

一、TF-A概述

        对传统ARM 处 理 而 言 , Linux 系 统 的 启 动 流 程 就 是 : 内部BootROM→Uboot→kernel→rootfs,整个启动过程是一个链式结构,启动过程其实是没有安全校验的。加入 TF-A 固件以后, TF-A 就可以对 uboot、 kernel进行校验,如果还要使用 TEE OS(Trusted Execution Environment, TEE),那么 TF-A 还要完成对TEE OS 的校验。

        STM32MP1 使用 ECDSA(Elliptic Curve Digital Signature,椭圆曲线数字签名算法)验证算法来完成鉴权,ECDSA 相比 RSA 效果好,而且秘钥更小,STM32MP1 使用 256 位的 ECDSA 秘钥。一共有两个算法用于计算 ECDSA:P-256 NIST 和 Brainpool 256。可以在 STM32MP1 头部信息中定义使用哪个算法,启动的时候,内部 Boot 代码会对 FSBL 进行鉴权,然后 FSBL 会对后续的内容进行鉴权,这个 FSBL 就是 TF-A。

        对于STM32MP1 而言, TF-A 一共有三部分:设备树、 BL2 和 BL32,外加一个头部文件。

二、Arm-v7工作模式

        其中Monitor和Hyp为新引入的工作模式。只有 User 模式处于 nonprivilege,也就是非特权级,剩下的 8 个模式都是 privilege(特权级)。系统启动以后应用软件都是运行在 User 模式,也就是非特权级,这个时候处理器对于敏感资源的访问是受限的,如果要访问这些敏感资源就需要切换到对应的工作模式下。

 三、Arm-v8工作模式

        ARMv8 没有 Privilege level 的概念,取而代之的是 Exception level(异常级别), 简称为 EL,
用于描述特权级别,一共有 4 个级别。

EL0:一般的应用程序
EL1: 操作系统,比如 Linux。
EL2:虚拟化(Hypervisor),虚拟机管理器。
EL3: 最底层的安全固件(安全监视器),比如 ARM Trusted Firmware(ARM 安全固件,TF-A)

在Arm-v8的AArch32模式下:

EL0: 对应 ARMv7 的 User 工作模式。
EL1: 对应 ARMv7 的 SVC、 ABT、 IRQ、 IRQ、 UND 和 SYS 这 6 中工作模式。
EL2: 对应 ARMv7 的 Hyp 工作模式。
EL3: 对应 ARMv7 的 Mon 工作模式。

所以 TF-A 主要工作在 EL3 下。

BL1:存储在核内固化的ROM中,上电时启动,加载到核内RAM中,用来初始化DDR、时钟等。

BL2:存储在外置Flash,被BL1一通操作然后加载到外置内存中。BL2将剩余的第三阶段镜像文件加载到指定的RAM中,完成启动。

BL31/BL32/BL33:BL31包含运行时固件(Runtime Firware),BL32包含安全操作系统(OP-TEE),BL33包含uboot。

四、移植ST官方TF-A

1.修改直接解压的ST官方TF-A源码包,将Makefile.sdk中的交叉编译链修改,之后进行编译。

此处编译遇到了一个问题,编译报错:

/bin/sh: 6: fiptool-stm32mp: not found

安装ST官网下载stm32的en.SDK-x86_64-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz工具包(名称可能会随版本更新有些许不同)再次编译报错:

Missing u-boot-stm32mp157a-dk1-trusted.dtb file in folder: '$FIP_DEPLOYDIR_UBOOT' or '$FIP_DEPLOYDIR_ROOT/u-boot'

解决办法:

1.在编译前使用export FIP_DEPLOYDIR_ROOT=****/stm32mp1-openstlinux-5.15-yocto-kirkstone-mp1-v22.06.15/sources/arm-ostl-linux-gnueabi/FIP_artifacts命令将FIP路径声明

2.安装官方推荐的arm-none-linux-guneabihf-交叉编译工具(不确定,为了排除不可控因素换的工具,可自行验证别的工具链),不要将TF-A的文件夹移到别的位置,直接在原目录下编译。可以少出很多错误,也可以节省很多步骤。

在此使用第二种,一劳永逸。

 五、官方TF-A修改

         官方的TF-A直接烧写会运行崩溃,需要针对板子做一些修改。

        此部分对V2.6版本TF-A的修改参考了ATK-DLMP157开发板的5.15内核的移植-OpenEdv-开源电子网的移植案例。

1.创建板子对应的设备树

        在xxx/tf-a-stm32mp-v2.6-stm32mp1-r1/fdts文件夹下的stm32mp157d-ev1.dts即为板子的设备树源文件,此源文件直接引用了stm32mp157d-ed1.dts,所以在此基础上直接使用,然后添加板子的相应信息即可。

#复制dts文件作为自己的模板
cp stm32mp157d-ed1.dts stm32mp157d-my.dts
#复制dtsi文件作为头文件引用
cp stm32mp15xx-edx.dtsi stm32mp157d-my.dtsi
#在*-my.dts中修改相关的.dtsi文件引用

cp stm32mp157d-ev1-fw-config.dts stm32mp157d-my-fw-config.dts 
#此文件和FIP相关不用修改直接可以使用

 2.修改设备树电源管理

        默认的电源芯片使用的是PMIC电源芯片,价格比较昂贵。在实际项目中使用分离电源设计,使用IIC接口来控制多个较廉价的电源芯片,所以需要修改对应的芯片接口。

        将stm32mp157d-my.dtsi中61行左右有关stpmic的代码删除(忘记此部分是否为i2c4节点的代码了,如果是,将i2c4节点全部删除),在21行左右的vin节点中添加自己使用的电源芯片信息。

        另外,在V2.6版本中此文件的末尾还有很多与电压有关的描述,直接参考上述的移植案例全部删除即可。

#描述 VDDCORE 电源,也就是 STM32MP157 的内核电源,最小为 1.2V,最大为 1.35V。
    vddcore: regulator-vddcore {
	compatible = "regulator-fixed";
	regulator-name = "vddcore";
	regulator-min-microvolt = <1200000>;
	regulator-max-microvolt = <1350000>;
	regulator-off-in-suspend;
	regulator-always-on;
	};
#描述 3.3V 电源,最小和最大都是 3.3V
	v3v3: regulator-3p3v {
	compatible = "regulator-fixed";
	regulator-name = "v3v3";
	regulator-min-microvolt = <3300000>;
	regulator-max-microvolt = <3300000>;
	regulator-off-in-suspend;
	regulator-always-on;
	};
#描述 VDD 电源,这是一个 3.3V 的电源,所以最小和最大都为 3.3V
	vdd: regulator-vdd {
	compatible = "regulator-fixed";
	regulator-name = "vdd";
	regulator-min-microvolt = <3300000>;
	regulator-max-microvolt = <3300000>;
	regulator-off-in-suspend;
	regulator-always-on;
	};
#描述 VDD_USB 电源,为 3.3V,所以最小和最大都为 3.3V
	vdd_usb: regulator-vdd-usb {
	compatible = "regulator-fixed";
	regulator-name = "vdd_usb";
	regulator-min-microvolt = <3300000>;
	regulator-max-microvolt = <3300000>;
	regulator-off-in-suspend;
	regulator-always-on;
	};

除此部分外,源码中还有一些关于pmic的描述代码,在源码目录中使用以下命令进行删除:

#在源码目录下使用此命令,把pmic相关的注册干掉
grep -rns fixed_regulator_register
#此文件的502行,干掉
gedit plat/st/stm32mp1/sp_min/sp_min_setup.c 
#此文件的351行的函数段,干掉
gedit plat/st/stm32mp1/bl2_plat_setup.c 

3.修改TF卡和EMMC设备树

继续操作 stm32mp157d-my.dtsi 这个文件,修改“sdmmc1”和“sdmmc2”节点。

&sdmmc1 {
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
	st,neg-edge;
	broken-cd;
	bus-width = <4>;
	vmmc-supply = <&v3v3>;
	status = "okay";
};

&sdmmc2 {
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
	non-removable;
	st,neg-edge;
	bus-width = <8>;
	vmmc-supply = <&v3v3>;
	vqmmc-supply = <&v3v3>;
	status = "okay";
};

4.修改USB OTG设备树

&usbotg_hs {
	phys = <&usbphyc_port1 0>;
	phy-names = "usb2-phy";
	usb-role-switch;
	status = "okay";
};

5.修改usbphyc节点

修改里面的“status”属性值,看起来就是向 stm32mp157d-my.dtsi文件里面添加了一个名为“usbphyc”的节点。文件中原本存在一个&usbphyc_port0和&usbphyc_port1节点,不做修改,直接添加上述新节点即可。

&usbphyc {
	status = "okay";
};

添加完成后直接在源码目录下编译。

编译命令:

make CROSS_COMPILE=arm-none-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 DTB_FILE_NAME=stm32mp157d-my.dtb STM32MP_SDMMC=1 STM32MP_EMMC=1 V=1 DEBUG=1

注:此部分不使用Makefile.sdk脚本,使用官方文档中推荐的编译命令。可以按照需求针对某一特定版本的设备进行编译,较少编译时长和输出结果。输出结果在:tf-a源码目录/build/stm32mp1/debug/下

        另外,参数中指定了SDMMC和EMMC,所以虽然只编译出来一个.stm32文件,但是在SD卡和EMMC中通用。另外V2.6版本对编译产物做了一些划分和精简,旧版本中tf-a-stm32mp157d-dk1.stm32和tf-a-stm32mp157d-dk1-truest.stm32为同一文件,仅修改了文件名。此版本中统一为tf-a-stm32mp157d-xxx.stm32,所以直接使用该文件烧写即可。

6.编译出xxx-serialboot.stm32

        在V2.6版本中,对serial boot模式的编译方式做了一些修改。serial boot模式有两种烧写方式:uart和usb口烧写。正点原子开发板使用的serial boot模式为usb模式,所以直接编译出usb模式的BL2镜像文件即可。

#清空原本的编译产物
make distclean
#编译USB模式的BL2镜像
make CROSS_COMPILE=arm-none-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 DTB_FILE_NAME=stm32mp157d-my.dtb  STM32MP_USB_PROGRAMMER=1  V=1 DEBUG=1

编译出的文件与之前的EMMC版本镜像同名,所以先将之前的.stm32移走,清空后重新编译。

至此,正点原子教程中的xxxx-serialboot.stm32和xxxx-atk.stm32镜像都编译完成

但是直接烧写后,启动时会出现如下错误,原因为对应版本的u-boot没有烧写,与正点原子使用的版本存在一些出入。后续编译出V2.6版本的U-Boot烧写即可。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值