正点原子嵌入式linux驱动开发——TF-A移植

news2024/11/26 13:45:39

经过了之前的学习,除了TF-A的详细启动流程仍待更新,TF-A的使用和其对应的大致启动流程已经进行过了学习。但是当我们实际做产品时,硬件平台肯定会和ST官方的有区别,比如DDR容量会改变,自己的硬件没有使用到官方EVK开发板所使用的PMIC芯片等等。因此就涉及到将半导体原厂提供的TF-A移植到我们的硬件上,本章就来讲解一下如何将ST官方提供的TF-A源码移植到正点原子的STM23MP157开发板上

编译ST官方TF-A源码

编译官方TF-A源码的原因

所谓的移植就是让半导体官方提供的软件在自己的硬件平台上运行起来,准确的说应该是将自己的硬件添加到官方软件包TF-A是ARM官方出品的一个软件包,半导体厂商会从ARM官方下载这个最正宗的TF-A软件包,然后将自己公司的SOC芯片添加进去,最终打包好提供给SOC用户,这个就是所谓的SDK包。我们在之前完成的对TF-A源码打的补丁就是ST编写的针对自家芯片的补丁文件,打完补丁以后的TF-A就支持了ST公司的芯片,所有使用ST芯片的厂商都会使用这个TF-A源码。打完补丁以后的TF-A能不能正常工作是需要验证的,也就是需要在一个硬件平台上运行测试,所有半导体厂商都会针对自家的芯片出一个或多个官方开发板。ST官方就有STM32MP157 EVK开发板,ST提供给用户的软件包都是在这个开发板上验证通过的,包括TF-A、uboot、linux kernel等。所有使用STM32MP157芯片的厂商都会在ST官方的开发板硬件基础上进行修改,制作自己的硬件,比如正点原子的 STM32MP157开发板就参考了 ST官方的STM32MP157 EVK开发板。

既然硬件参考了ST官方的开发板,那么软件肯定也是在官方提供的软件包基础上修改的,所以本章TF-A的移植就是在ST官方提供的TF-A源码上进行。首先肯定要先编译一下ST官方提供的 TF-A源码,目的如下:

  1. 掌握半导体官方软件编译方法
  2. 验证开发环境搭建是否正确,比如交叉编译器设置是否正确,所依赖的第三方库有没有安装等;
  3. 观察编译结果,比如编译完成以后的可执行文件保存在哪个目录下,都有哪些可执行文件及其区别等;
  4. 在自己的开发板上运行编译出来的可执行文件,所谓的移植就是改bug的过程,将编译出来的STM32MP157官方开发板可执行文件在自己的板子上运行,然后观察运行过程有没有错误,没错误最好,有错误就改,直到能在自己的开发板上正常运行,这就是移植过程。

编译TF-A

在之前的学习中已经准备好了ST官方的TF-A源码(按照之前的步骤完成打补丁之后再编译),可以另外新建一个名为“my-tfa”的目录来存放并编译ST官方的TF-A源码,如下图所示:
TF-A源码文件
上图中我们重点关注Makefile.sdk和tf-a-stm32mp-2.2.r1。Makefile.sdk是编译要用到的Makefile,其实Makefile.sdk主要是配置编译选项,最终是通过调用 tf-a-stm32mp-2.2.r1下的Makefile来完成具体编译过程的。tf-a-stm32mp-2.2.r1就是打完补丁后的ST官方TF-A源码文件,也就是我们要编译的。

修改Makefile.sdk

首先要修改上图中的Makefile.sdk,因为此文件定义编译选项,包括交叉编译器,要使用自己的交叉编译器,也就是已经安装的arm-none-linux-gnueabihf-gcc编译器。用VIM编辑器打开Makefile.sdk找到“CROSS_COMPILE”,将其改为“arm-none-linux-gnueabihf-”;修改完成后保存退出,进入到tf-a-stm32mp-2.2.r1目录下,然后进行编译,命令如下:

cd tf-a-stm32mp-2.2.r1/ //进入到 tf-a源码目录下
make -f ../Makefile.sdk all //编译

如果需要加快编译速度,可是使用多线程编译,线程数 最好和自己给虚拟机分配的物理核心一致,使用-j来指定线程数,命令如下:

make -f ../Makefile.sdk -j8 all //使用 8线程编译

编译完成以后会在tf-a-stm32mp-2.2.r1文件夹的上层目录 (也就是Makefile.sdk同级目录下)下生成一个名为“build”的文件夹,build文件夹下就是编译生成的所有可执行文件,进入到build目录下,有三个子目录,如下图所示:
编译结果
上图中有3个子目录:optee、serialboot和trusted,说明有3个版本的可执行文件,optee是针对 OP-TEE的,本教程没使用OP-TEE,所以optee目录和我们没关系。

serialboot看名字就知道是和串行启动有关的,也就是通过串口或者USB烧写系统的时候需要用到serialboot下的可执行文件,之前编写STM32CubeProgrammer所使用的Flashlayout文件(.tsv)的时候用到了一个名为“tf-a-stm32mp157d-atk-serialboot.stm32”的文件,此文件就是 serialboot目录下的。当然,上图中目前还没有“tf-a-stm32mp157d-atk-serialboot.stm32”这个文件。当把TF-A移植到自己开发板上以后就会在serialboot目录下生成我们板子对应的xxx-serialboot.stm32文件

trusted目录下的就是烧写到开发板中的TF-A镜像,进入 trusted目录,如下图所示:
TF-A镜像文件
从上图可以看出,编译出来了很多后缀为.bin、.elf、.ld、.stm32这样的文件, 以
前缀为“tf-a-stm32mp157d-ev1”的文件为例,相关的文件如下图所示:
使用STM32MP157D芯片的EV1开发板对应文件
从上图可以看出,这些文件都是针对使用STM32MP157D芯片的EV1开发板,同理,
其他的文件命名也是类似的,我们只需要选择和我们所使用开发板接近的文件就行了。比如正点原子 STM32MP157开发板使用的主控型号是STM32MP157DAA1,开发板硬件参考了ST官
方的STM32MP157 EVK开发板
,因此我们就需要使用上图中的这些文件,在移植的时候需要参考的对象就是stm32mp157d-ev1

另外,上图中的tf-a-stm32mp157d-ev1.stm32和tf-a-stm32mp157d-ev1-trusted.stm32这两个文件内容一模一样,后者只是前者的重命名版本,目的是为了和上一级optee和serialboot下的文件进行区分,我们在烧写的时候使用tf-a-stm32mp157d-ev1-trusted.stm32即可

在trusted目录下,还有一些其他的文件,比如单独的bl2和bl32对应的可执行文件:bl2.bin和bl32.bin。bl2和bl32编译过程中所有的.c源码文件对应的.o文件也都保存在bl2和bl32文件夹下。

烧写ST官方TF-A镜像

将编译出来的tf-a-stm32mp157d-ev1-trusted.stm32烧写到正点原子开发板EMMC里面,烧写方法在之前的笔记中有所讲解。烧写完成以后打开串口,设置好串口调试软件MobaXterm,设置开发板从EMMC启动,按下复位按键,观察MobaXterm软件接收到的log信息,如下图所示:
运行结果
上图代表着就是运行崩溃了,说明ST官方开发板对应的TF-A不能直接在正点原子的开发板上运行,需要进行修改。

TF-A移植

经过了上述的编译测试,ST官方的TF-A镜像并不能直接在正点原子的开发板上运行,所以需要进行移植操作。

注意,TF-A的移植全部是修改设备树,初学linux(这个文档在针对我,我就是初学者)肯定对设备树 (device tree)不了解,而设备树是一个系统的概念,会在后面的 linux驱动开发里面详解设备树的相关语法!所以初学的朋友直接根据接下来的教程修改就行了,不用深入研究其原理。或者,直接跳过TF-A的移植,直接使用正点原子移植好的。

新建开发板对应的设备树

创建板子对应设备树

设备树英文名字叫做Device tree,用来描述板子硬件信息,比如板子上的CPU有几个核、每个CPU核主频是多少,IIC、SPI这些外设的寄存器范围是多少,IIC接口下都挂了哪些设备等等。设备树文件是一种文本格式的文件,方便阅读与修改,文件后缀为.dts,设备树也有头文件,头文件后缀为.dtsi。和C语言一样,.dts可以引用头文件.dtsi,.dts经过编译以后生成.dtb文件,.dtb就是开发板要使用的。类似于我们将C语言的.c文件编译为.bin文件,然后在开发板上运行,将.dts编译为dtb的工具叫做DTC,并不是我们使用的gcc编译器

打开tf-a-stm32mp-2.2.r1\fdts目录,fdts目录下保存的就是所有开发板的设备树文件,其中就包括了STM32MP1系列的,如下图所示:
TF-A设备树文件
上图中的stm32mp157d-ev1.dts就是STM32MP157D EVK开发板所对应的设备树文件,同理还有STM32MP157其他型号的芯片,比如stm32mp157a、stm32mp157c等。我们以stm32mp157d-ev1.dts为蓝本,添加正点原子STM32MP157开发板对应的设备树文件

创建VScode工程,然后用VScode打开,打开stm32mp157d-ev1.dts文件,文件内容下图所示:
stm32mp157d-ev1.dts文件内容
上图中第8行引用了“stm32mp157d-ed1.dts”这样一个dts文件,注意,在设备树里面可以直接通过include引用另外一个.dts文件,不仅限于.dtsi文件,也就是说**.dts文件也可以作为头文件使用**。

可以看出stm32mp157d-ev1.dts文件非常简洁,主要原因是其引用了stm32mp157d-ed1.dts,主要工作都由 stm32mp157d-ed1.dts文件来完成了。所以可以把蓝本换成stm32mp157d-ed1.dts。复制一份stm32mp157d-ed1.dts,并命名为stm32mp157d-atk.dts,stm32mp157d-atk.dts就是为正点原子 STM32MP157开发板准备的设备树,命令如下:

cd fdts
cp stm32mp157d-ed1.dts stm32mp157d-atk.dts //复制

复制完成以后打开stm32mp157d-atk.dts文件,内容如下图所示:
stm32mp157d-atk.dts文件内容
第8-13行,头文件引用,其中第8-11行引用STM32MP15X芯片相关的dtsi头文件,这些全部保留即可

第12行,非常重要,“stm32mp15xx-edx.dtsi”,是edx系列开发板的通用头文件,适合具体板子有关的,很明显,板子不同其对应的板子头文件也不同。我们同样需要以stm32mp15xx-edx.dtsi为蓝本,创建正点原子开发板对应的板子头文件,一会再创建

第20行,stdout-path表示标准输出,也就是设置TF-A信息输出路径,这里设置为serial0,也就是串行接口0(注意,不是STM32MP157的串口 0),波特率为115200;

第24行,设置serial0对应STM32MP157的串口4,所以 TF-A会使用STM32MP157的串口4作为信息输出接口,在做板子的时候最好选择串口4作为通信接口

最后,需要以stm32mp15xx-edx.dtsi为蓝本,制作正点原子开发板对应的头文件,方法很简单,直接复制一份stm32mp15xx-edx.dtsi,然后将其重命名为“stm32mp157d-atk.dtsi”,命令如下:

cd fdts
cp stm32mp15xx-edx.dtsi stm32mp157d-atk.dtsi

拷贝完成以后就需要修改stm32mp157d-atk.dts,将第12行改为

#include "stm32mp157d-atk.dtsi"

修改以后的stm32mp157d-atk.dts文件内容如下(有缩减):
stm32mp157d-atk.dts文件内容

编译

设备树创建好以后编译一下,在编译之前要先修改以后Makefile.sdk,因此我们前面新建的stm32mp157d-atk.dts并没有添加到编译列表里面,直接编译的话并不会编译此文件。打开Makefile.sdk,在TFA_DEVICETREE配置项中添加“stm32mp157d-atk”,如下图所示:
修改后的TFA_DEVICETREE
修改完成以后保存退出,然后执行如下命令编译一下TF-A:

cd tf-a-stm32mp-2.2.r1/ //进入到 tf-a源码目录下
make -f ../Makefile.sdk all //编译

如果修改没有错误的话就会编译成功,编译完成以后进入build/trusted目录下,此时就会生成以“tf-a-stm32mp157d-atk”开头的相关文件,如下图所示:
编译生成的正点原子开发板TF-A固件
上图就是烧写的TF-A固件,其设备树(dtb)已经替换为上面新建的stm32mp157d-atk.dts了。但是由于并没有对TF-A源码做什么修改,所以tf-a-stm32mp157d-atk-trusted.stm32依旧是不可运行的,错误类型和之前的一样,可以自行烧写测试。

修改设备树电源管理

ST官方STM32MP157开发板用到了一颗PMIC芯片,型号为STPMIC1A,PMIC全称为Power Management IC,也就是集成电源管理芯片。我们在用单片机的时候,只需要给一个3.3V或5V电源即可, 使用起来很方便。但是随着芯片性能的提升,SOC对电源的要求越来越多,比如Cortex-A系列芯片主电源一般要求3.3V,但是芯片内核电压可能需要1.2V,而外扩的DDR3L芯片工作电压是1.35V,DDR3L芯片的端接电压要求0.65V,USB工作电压又要求5V等等,也就是说随着SOC功能越来越强大,所需要的的电源要求也越来越高,最直观的就是电源种类很多。另外,这些电源的上电顺序也是有要求的,也就是说,哪些电源先启动,哪些后启动等。

为此,SOC厂商为了简化硬件设计,都会针对自家的SOC芯片推出专用的PMIC芯片,PMIC芯片就是一个单进多出的电源芯片,比如输入5V,然后可以输出很多路电源,输出的这些电源可以配置输出电压。STPMIC1A就是ST专门为STM32MP1系列设计的专用PMIC,此PMIC芯片性能非常强大:

  • 输入电压 2.8V~5.5V;
  • 4路可调的通用LDO输出;
  • 1路 DDR3端接LDO电源;
  • 1路 USB PHY所使用的LDO电源;
  • 1路 DDR参考电压LDO电源;
  • 4路可调的BUCK开关电源;
  • 1路 5.2V/1.1A的BOOST开关电源;
  • 1路 500mA的USB OTG电源;
  • 1路 500mA/1000mA的通用电源;
  • 此芯片有一个IIC接口,主控通过IIC接口来配置电源芯片,设置每一路输出电源的输出电压,开启时间等。

STPMIC1A很好用但是性价比不高,STPMIC1A在ST官网报价1.9美金 /1K(2020/11/12日),也就是说1000片起的话,价格是1.9美金,换算成人民币就是12.5块钱。但是对于STM32MP157而言用不了这么多路电源,三四路就够了,所以可以采用分离电源,这样的话三四个电源芯片的价格远小于12.5块钱。难点就是分离电源很考验硬件工程师的设计功底,因为处理不同电源上电顺序,好在ST已经提供了分离电源设计手册

总之就是,因为采用ST提供的专用PMIC成本太高,因此大部分STM32MP157核心板都是采用分离电源设计的STPMIC1A是一个IIC器件,因此就涉及到驱动 问题,需要主控通过IIC接口来配置各路电源,所以ST官方提供的TF-A、uboot linux kernel等都会有PMIC驱动。但是正点原子的开发板并没有采用这个PMIC芯片,所以 TF-A默认的电源配置就会出问题,这里就需要我们修改相关的文件,取消掉这个PMIC的相关配置。

打开stm32mp157d-atk.dtsi文件,找到如下所以代码:
在这里插入图片描述
第45行,“i2c4”表示这段代码是和I2C4控制器有关的,在设备树中一个IIC接口下的所有设备都“打包”放到一个节点下,在这里就是描述 I2C4这个 IIC控制器下的所有 IIC器件。ST官方的STM32MP157开发板将STPMIC1A这个PMIC芯片挂到了I2C4下,所以STPMIC这个芯片的相关信息就会在“i2c4”这个节点下进行描述;

第54~281行,这一大段为STPMIC1A这颗芯片的描述信息,第54行是“pmic: stpmic@33”,即使我们没有学习过设备树,但是也能看出这是和PMIC有关的。在这一大段代码中,描述了STPMIC1A各输出电源应该如何配置,比如电压应该是多少,每路电源的功能是什么等

将上图中第54~281行的内容全部删除掉,也就是删除掉STPMIC1A芯片的相关描述,删除以后的 i2c4节点内容如下图所示:
删除pmic后的i2c4节点
由于我们上面把PMIC相关的信息都删除了,但是其他设备的电源信息还是要有的,只是不通过 PMIC来描述了。所以需要我们自己添加一些设备的电源描述信息,在stm32mp157d-atk.dtsi文件里面找到“vin”节点,如下图所示:
vin节点内容
将上图中的vin节点内容全部删除掉,也就是将 17~23行代码删除掉,替换为下面的代码:

vddcore: regulator-vddcore {
	compatible = "regulator-fixed";
	regulator-name = "vddcore";
	regulator-min-microvolt = <1200000>;
	regulator-max-microvolt = <1350000>;
	regulator-off-in-suspend;
	regulator-always-on;
};

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: 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: 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;
};

第17-24行,描述VDDCORE电源,也就是STM32MP157的内核电源,最小为1.2V,最
大为1.35V;

第26-33行,描述3.3V电源,最小和最大都是3.3V;

第35-42行,描述VDD电源,这是一个3.3V的电源,所以最小和最大都为3.3V;

第44-51行,描述VDD_USB电源,为3.3V,所以最小和最大都为3.3V。

修改完后如下图所示:
修改后电源信息
至此,电源管理修改完成了,不要编译,会报错。因为修改了电源设置,而USB OTG节点还是引用的以前相关电源设置,所以编译会报错,等修改好USB OTG设备节点以后就可以编译了

修改TF卡和EMMC设备树

继续操作stm32mp157d-atk.dtsi这个文件,找到“sdmmc1”和“sdmmc2”这2个节点,节点内容如下图所示:
sdmmc1和sdmmc2原节点内容
将上图中的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";
};

修改完成以后sdmmc1和sdmmc2如下图所示:
修改后的sdmmc1和sdmmc2节点
同样,不要编译,会报错,因为修改了电源,而USB OTG节点还是引用的以前相关电源设置,所以编译会报错,等修改好USB OTG设备节点以后就可以编译了。

修改USB OTG设备树

最后就是修改一下USB OTG对应的设备树节点,继续操作stm32mp157d-atk.dtsi,找到“usbotg_hs”这个节点,节点默认内容如下图所示:
usbotg_hs原内容
将上图中的usbotg_hs节点改为如下所示内容:

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

最后还需要修改“usbphyc”节点里面的“status”属性值,看起来就是向stm32mp157d-atk.dtsi文件里面添加了一个名为“usbphyc”的节点,内容如下:

&usbphyc {
	status = "okay";
};

修改完成以后的usbotg_hs和usbphyc这两个节点如下图所示:
修改后的usbotg_hs和usbphyc

编译测试

编译

设备树修改完成以后先编译一下TF-A,但是我们编译的时候默认会编译很多STM32MP1开发板的TF-A镜像,我们可以修改Makefile.sdk固件,只编译正点原子开发板对应的TF-A镜像。打开Makefile.sdk文件,将TFA_DEVICETREE修改为如下图所示内容:
修改后的TFA_DEVICETREE
上图中的TFA_DEVICETREE用于指定需要编译的板子对应的设备树,这里改为之编译stm32mp157d-atk,也就是正点原子开发板对应的设备树,也就是前面我们自己创建的stm32mp157d-atk.dts文件。

修改好以后重新编译TF-A,如下图所示,表示编译成功:
编译成功
上图中提示tf-a-stm32mp157d-atk.bin编译成功,而且也生成了tf-a-stm32mp157d-atk.stm32镜像文件。

烧写测试

使用STM32CubeProgrammer软件将上面编译出来 build/trusted/tf-a-stm32mp157d-atk.stm32烧写到开发板上的EMMC中并运行,运行log信息如下图所示:
TF-A运行log信息
从上图中可以看出TF-A运行成功,其中bl2和bl32(sp_min)都正常运行,bl2和sp_min的编译时间都为2020年11月23号,其中bl2编译时间为 9:18:37,sp_min的编译时间为9:18:48,bl2先编译,SP_MIN后编译。可以看出,bl2其实已经将 uboot加载到了0xc0100000地址处,这是因为拿到的开发板默认已经烧写了出厂系统,所以TF-A可以加载uboot(bl33)

这个时候uboot可能会启动,也可能不会启动,这里先不要管uboot能不能启动。

另外,由于正点原子的STM32MP157开发板出厂已经烧写系统,所以bl2可以加载uboot到DDR上,但是如果用的是全新的核心板,EMMC还没有烧写过任何系统,或者你把EMMC格式化过,因为 EMMC里面没有uboot镜像,所以bl2在加载uboot的时候就会失败,TF-A运行的log信息如下图所示:
TF-A运行错误
从上图中可以看出,TF-A提示没有找到ssbl分区 (ssbl分区用于存放uboot),因为是全新的 EMMC核心板,而烧写的时候也没有在FlashLayout中添加ssbl分区信息,所以会提示找不到ssbl分区,从而导致TF-A启动出问题。解决方法很简单,修改FlashLayout,然后在里面添加一个ssbl分区,但是ssbl分区不烧写任何文件,就相当于新建一个名为“ssbl”的分区打开之前已经创建的FlashLayout文件tf-a.tsv,在最后一行添加如下内容:
添加的ssbl信息
上面一行的“PE”表示不更新ssbl分区,但如果不存在ssbl分区就会进行创建ssbl分区。其实就是新建一个空的ssbl,添加完成后的tf-a.tsv如下图所示:
修改后的tf-a.tsv内容
上图中最后一行就是ssbl分区,**注意0x00080000后面的箭头表示TAB键,这个TAB键是必须要的!**因为最后面还有Binary列的内容,这里我们并没有给出 Binary列的镜像文件名,表示不烧写任何文件,但是位置得留出来,否则烧写的时候STM32CubeProgrammer会 tf-a.tsv语法错误。

修改完成以后使用新的tf-a.tsv来烧写TF-A镜像,烧写完成以后TF-A运行log信息如下图所示:
TF-A运行结果
从上图可以看出,此时没有再提示ssbl分区错误了,但是有另外一个错误,那就是在加载ID=5的镜像的时候加载错误,这个就是uboot镜像。因为全新的EMMC并没有uboot镜像,因此肯定加载不到,除非把uboot镜像也烧写进去,也就是烧写到上面的ssbl分区里面。

修改tf-a.tsv文件,在ssbl分区添加要烧写的uboot镜像即可,这里直接烧写正点原子官方出厂系统的uboot镜像即可,也就是u-boot.stm32,这个文件已经放到了我们烧写目录里面,修改后的tf-a.tsv文件如下图所示:
修改后的tf-a.tsv内容
上图中最后一行的Opt要改为‘P’,也就是更新ssbl分区中的文件,u-boot.stm32要和tf-a.tsv放在同一个目录下。修改完成以后使用新的tf-a.tsv烧写TF-A和uboot镜像到开发板的EMMC里面,烧写完成以后运行TF-A,运行过程的log信息如下图所示:
TF-A运行信息
从上图可以看出,TF-A运行正常,而且因为我们也烧写了uboot镜像,因此uboot也启动了,说明TF-A运行正常。

xxx-serialboot.stm32测试

在之前的TF-A初探中构建的系统烧写目录中,用到了正点原子出厂镜像中的stm32mp157d-atk-serialboot.stm32,前面讲了STM32CubeProgrammer首先通过USB或串口向开发板下载stm32mp157d-atk-serialboot.stm32,名字里面有个“serialboot”,翻译过来就是串行启动,此镜像主要用于初始化DDR,并且提供USB或串口功能,目的是为了进一步将uboot镜像下载到DDR的指定位置,最终通过uboot来向外部Flash设备烧写整个系统镜像

所以需要掌握自行编译stm32mp157d-atk-serialboot.stm32的方法,操作很简单。首先打开 Makefile.sdk,然后将EXTRA_OEMAKE_SERIAL改为如下内容

EXTRA_OEMAKE_SERIAL=$(filter-out STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_SPI_NOR=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1,$(EXTRA_OEMAKE)) STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1

修改完成后如下图所示:
修改后的EXTRA_OEMAKE_SERIAL配置
输入如下命令编译:

cd tf-a-stm32mp-2.2.r1/ //进入到 tf-a源码目录下
make -f ../Makefile.sdk clean //清除以前的编译
make -f ../Makefile.sdk TFA_DEVICETREE=stm32mp157d-atk TF_A_CONFIG=serialboot ELF_DEBUG_ENABLE='1' all //编译

编译完成以后就会在…/build/serialboot目录下生成tf-a-stm32mp157d-atk-serialboot.stm32,如下图所示:
编译生成的tf-a-stm32mp157d-atk-serialboot.stm32
用上图中的tf-a-stm32mp157d-atk-serialboot.stm32替换我们以前使用的正点原子出厂系统中的文件,替换完成以后的烧写目录如下图所示:
images目录
此时上图中的tf-a-stm32mp157d-atk-serialboot.stm32和tf-a-stm32mp157d-atk-trusted.stm32均为我们自行编译的,tf-a-stm32mp157d-atk-trusted.stm32经过测试运行正常,接下来就要测试一下tf-a-stm32mp157d-atk-serialboot.stm32是否能正常烧写系统

直接用STM32CubeProgrammer烧写测试即可,观察是否能正常烧写,烧写完成以后tf-a-stm32mp157d-atk-trusted.stm32是否能够正常启动。

注意!按照本小节讲解的方法编译生成tf-a-stm32mp157d-atk-serialboot.stm32以
后,…/build/trusted和 …/build/optee目录就没了,也就是说此本小节的方法只能编译tf-a-stm32mp157d-atk-serialboot.stm32。一旦编译成功并测试OK以后,就不要再去修改stm32mp157d-atk-serialboot.stm32了。如果想重新编译 tf-a-stm32mp157d-atk-trusted.stm32,那么就按照以前的编译命令即可,不用修改 Makefile.sdk文件!

至此,TF-A移植全部完成!!!

总结

TF-A的移植流程

整个TF-A的移植流程如下:

  • 正点原子的开发光盘中有ST官方TF-A的源码,当然可以官网下载,咱们就直接把他拖过来用就行,就是en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz;
  • 使用tar -xvf解压缩后,进入tf-a-stm32mp-2.2.r1-r0,继续tar -xvf解压缩tf-a-stm32mp-2.2.r1-r0.tar.gz,进入解压后的tf-a-stm32mp-2.2.r1之后,通过如下命令打补丁
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done //打补丁
  • 安装stm32wrapper4dgb,直接拖到Ubuntu之后unzip再make,然后复制到/usr/bin之中就可以了,复制命令如下:
sudo cp stm32wrapper4dbg /usr/bin
  • 在Makefile.sdk,将交叉编译器改为我们目前所使用的,找到CROSS_COMPILE,将其改为arm-none-linux-gnueabihf-
  • 进入tf-a-stm32mp-2.2.r1之后make
make -f ../Makefile.sdk -j8 all //使用 8线程编译
  • 打开tf-a-stm32mp-2.2.r1\fdts目录,复制stm32mp157d-ed1.dts并命名为stm32mp157d-atk.dts
  • 复制stm32mp15xx-edx.dtsi并命名为stm32mp157d-atk.dtsi,后在stm32mp157d-ed1.dts中12行改为
#include "stm32mp157d-atk.dtsi"
  • 正点原子MP157开发板没有PMIC这个电源管理芯片,所以按照教程完成电源的一系列配置,其操作均在stm32mp157d-atk.dtsi文件完成;
  • 配置TF卡和EMMC以及USB OTG设备树;
  • tf-a.tsv中添加uboot.stm32,添加代码如下:
P 0x06 ssbl Binary mmc1 0x00080000 u-boot.stm32
  • 自行编译stm32mp157d-atk-serialboot.stm32的方法,在Makefile.sdk中添加:
EXTRA_OEMAKE_SERIAL=$(filter-out STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_SPI_NOR=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1,$(EXTRA_OEMAKE)) STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1
  • 编译serial,命令如下:
make -f ../Makefile.sdk clean //清除以前的编译
make -f ../Makefile.sdk TFA_DEVICETREE=stm32mp157d-atk TF_A_CONFIG=serialboot ELF_DEBUG_ENABLE='1' all //编译
  • 以上编译的三个文件:tf-a-stm32mp157d-atk-serialboot.stm32,u-boot.stm32,tf-a-stm32mp157d-atk-trusted.stm32就此完成,放在同一个文件夹中,并创建一个FlashLayout的.tsv文件完成引导,内容如下:
#Opt Id Name Type Device Offset Binary
- 0x01 fsbl1-boot Binary none 0x0 tf-a/tf-a-stm32mp157d-atk-serialboot.stm32
- 0x03 ssbl-boot Binary none 0x0 uboot/u-boot.stm32
P 0x04 fsbl1 Binary mmc1 boot1 tf-a/tf-a-stm32mp157d-atk-trusted.stm32
P 0x05 fsbl2 Binary mmc1 boot2 tf-a/tf-a-stm32mp157d-atk-trusted.stm32
P 0x06 ssbl Binary mmc1 0x00080000 u-boot.stm32
  • 最后完成开发板接线连接PC,然后通过STM32CubeProgrammer完成烧写。

原理

TF-A在正点原子另一个国产的I.MX6ULL就是没有的,属于是ST公司处于产品的完整性来确保安全加进来的一个ARM可信固件

按照TF-A的原理和源码查看,可以分为bl1、bl2、bl31、bl32以及bl33五个部分,但是在STM32MP1系列芯片中,bl1在ROM内部代码中实现,bl31不是AArch32的,bl33就是uboot,所以其实只有两个部分
STM32MP1 TF-A启动流程

下一步

终于就进入了linux驱动开发的传统学习的uboot内容啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1056341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.HTML-标题排版

1.Vscode快速生成基本代码结构 !enter <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conte…

Acwing 908. 最大不相交区间数量

Acwing 908. 最大不相交区间数量 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 代码展示 #include <iostream> #include <algorithm>using namespace std;const int N 100010;int n;struct Range {int l, r;bool operator<(const Range …

【爬虫】用wget命令爬虫的简易教程

文章目录 1. 获取登录的请求2. 用postman模拟登录请求3. 用wget模拟登录请求并保存cookie4. 开始爬取网站5. 查看爬取结果6. 网站爬虫简易教程 爬取需要登录的网站的资源 背景&#xff1a;对于一些网站需要使用用户名和密码登录并且使用了https&#xff0c;我们如果不通过凭证将…

Arcgis提取玉米种植地分布,并以此为掩膜提取遥感影像

Arcgis提取玉米种植地分布上&#xff0c;并以此为掩膜提取遥感影像 一、问题描述 因为之前反演是整个研究区&#xff0c;然而土地利用类型有很多类&#xff0c;只在农田或者植被上进行反演&#xff0c;需要去除水体、建筑等其他类型&#xff0c;如何处理得到下图中只有耕地类…

世界前沿技术发展报告2023《世界信息技术发展报告》(六)网络与通信技术

&#xff08;六&#xff09;网络与通信技术 1. 概述2. 5G与光通讯2.1 美国研究人员利用电磁拓扑绝缘体使5G频谱带宽翻倍2.2 日本东京工业大学推出可接入5G网络的高频收发器2.3 美国得克萨斯农工大学通过波束管理改进5G毫米波通信2.4 联发科完成全球首次5G NTN卫星手机连线测试2…

springmvc-国际化中英文切换文件上传下载

1. 国际化 1.1 介绍 国际化(internationalization)&#xff0c; 简称国际化。一个产品支持国际化是指产品在无需做大的改变就能够适应不同的语言和地区的能力。i18n是指是一种让软件在开发阶段就支持多种语言的技术。 1.2 java.util.Locale 该类对象表示了特定的地理&#…

【算法学习】-【双指针】-【复写零】

LeetCode原题链接&#xff1a;1089. 复写零 下面是题目描述&#xff1a; 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 …

【word】从正文开始设置页码

在写报告的时候&#xff0c;会要求有封面和目录&#xff0c;各占一页。正文从第3页开始&#xff0c;页码从正文开始设置 word是新建的 分出三节&#xff08;封面、目录、正文&#xff09; 布局--->分割符--->分节符--->下一页 这样就能将word分为3节&#xff0c;分…

『RSSHub』搭建部署指南

前言 相信各位对推荐算法已经很熟悉了&#xff0c;平台基于推荐算法不断推送我们感兴趣的信息&#xff0c;但是身处推荐算法中心&#xff0c;有时我们可能感觉视野越来越闭塞&#xff0c;原来节约我们时间的推荐系统&#xff0c;这时却成了困住我们的信息茧房 那么也许 RSS&a…

想做网络安全但是没有任何证书可以吗

大家好&#xff0c;我是网络工程师成长日记实验室的郑老师&#xff0c;您现在正在查看的是网络工程师成长日记专栏&#xff0c;记录网络工程师日常生活的点点滴滴 有个同学说他打算做网络安全工程师。他问我说如果考这个软考的网络工程师或者信息安全这个工程师&#xff0c;到时…

基于SSM的公司项目管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

世界前沿技术发展报告2023《世界信息技术发展报告》(七)网络与信息安全技术

&#xff08;七&#xff09;网络与信息安全技术 1. 概述2. 网络安全关键技术2.1 美国特种作战司令部举办网络挑战赛以寻找边缘安全技术2.2 英国卡迪夫大学开发出在1秒内阻止网络攻击的方法2.3 国研究人员开发出检测恶意网页的新方法2.4 韩国仁川大学研发出一种基于5G的人工智能…

SpringBoot的全局异常拦截

在 Spring Boot 中&#xff0c;可以通过使用 ControllerAdvice 注解和 ExceptionHandler 注解来实现全局异常拦截。 RestControllerAdvice RestControllerAdvice 是 Spring Framework 提供的注解&#xff0c;用于定义全局异常处理类&#xff0c;并且结合 ExceptionHandler 注…

Python——ASCII编码与Unicode(UTF-8,UTF-16 和 UTF-32)编码

Python3 Python——ASCII编码与Unicode&#xff08;UTF-8&#xff0c;UTF-16 和 UTF-32&#xff09;编码 文章目录 Python3一、编码与编码格式二、ASCII编码与UTF-8编码&#xff08;UTF-16 和 UTF-32编码&#xff09;三、ASCII 字符串和 Unicode 字符串 最近看Python程序的文件…

C程序设计内容与例题讲解 -- 第四章--选择结构程序设计第二部分(第五版)谭浩强

前言:在前面我们学习了选择结构和条件判断&#xff0c;用if语句实现选择结构&#xff0c;关系运算符和关系表达式&#xff0c;逻辑运算符和逻辑表达式等知识。今天我们将接着上一篇未讲完的继续讲解。 鸡汤:种一棵树最好的时间是十年前&#xff0c;其次是现在&#xff01;加油各…

springmvc-controller视图层配置SpringMVC处理请求的流程

目录 1. 什么是springmvc 2.项目中加入springmvc支持 2.1 导入依赖 2.2 springMVC配置文件 2.3 web.xml配置 2.4 中文编码处理 3. 编写一个简单的controller 4. 视图层配置 4.1 视图解析器配 4.2 静态资源配置 4.2 编写页面 4.3 页面跳转方式 5. SpringMVC处理请求…

Vue3快速入门

简介 什么是Vue Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&…

【Go】go-es统计接口被刷数和ip访问来源

go-es模块统计日志中接口被刷数和ip访问来源 以下是使用go的web框架gin作为后端&#xff0c;展示的统计页面 背景 上面的数据来自elk日志统计。因为elk通过kibana进行展示&#xff0c;但是kibana有一定学习成本且不太能满足定制化的需求&#xff0c;所以考虑用编程的方式…

UART相关参数和Modbus协议

温湿度数据和风速风向数据的读取和计算方法 文章目录 温湿度数据和风速风向数据的读取和计算方法1 串行通信数据格式1.1 协议介绍1.2 UART相关参数1.3 UART通信过程 2 USB转串口模块的使用3 串口调试助手的使用3.1 串口控制区3.2 发送控制区3.3 接收控制区 4 GY-39气象信息模块…

基于SSM的微博系统网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…