前言

[Zynq™ UltraScale+™ MPSoC]

在 Zynq™ UltraScale+™ MPSoC 中 Configuration and Security Unit 处理器会使用 BootRom 中的代码在这个配置阶段解释 boot header 来配置系统,并以安全或者非安全引导模式将 Processing System「PS处理系统」的 First-Stage-Boot-Loader「FSBL,第一阶段引导加载程序」加载到片上 RAM「OCM,on-chip RAM」;在启动过程中 CSU 会将 PMU FW 加载到 PMU RAM 中,与 PMU ROM 一起提供平台管理工作「P.S. 一般来说 FSBL 会在 PMU FW 前加载」;后加载 ATF,配置 DDR,最后将 u-boot 加载到 DDR 并启动 u-boot;u-boot 启动后可以选择加载 Hypervisor 并在上面运行 Linux 系统,也可直接使用 u-boot 加载 Linux 系统镜像到 DDR 并启动 Linux。

  • BootRom : 用于设备的初始化与启动
  • FSBL : 由 BootRom 加载到片上 ROM,用于配置 FPGA 和从非易失性Flash「SD/eMMC/NAND…」中加载裸机镜像或操作系统的第二阶段引导加载程序镜像到内存「DDR/OCM」
  • PMU : 用于控制系统的商店复位和监控系统内的资源
  • ATF : arm 的加密固件
  • Hypervisor: 略
  • Linux : 略

U-Boot

环境准备

  • U-Boot开发总结

  • 拉取 uboot-xln:

    1
    2
    3
    git clone https://github.com/Xilinx/u-boot-xlnx.git
    git checkout tags/xilinx-v2022.2
    git status
  • 设定工具链:

    • ZynqUS+:

      1
      2
      export CROSS_COMPILE=aarch64-linux-gnu-
      export DEVICE_TREE="zynqmp-zcu102-rev1.0"
    • Zynq:

      1
      2
      export CROSS_COMPILE=arm-linux-gnueabihf-
      export ARCH=arm
  • 建立ATF「ZynqUS+」:

    • 拉取 firmware

      1
      2
      git clone https://github.com/Xilinx/arm-trusted-firmware.git
      git checkout tags/xilinx-v2022.2
    • 编译 bl31.bin

      1
      make ARCH=aarch64 CROSS_COMPILE=aarch64-linux-gnu- DEBUG=1 RESET_TO_BL31=1 PLAT=zynqmp bl31
      • DEBUG=1. : 启用调试信息
      • RESET_TO_BL31: omit

      编译完成后会在 <PATH>/arm-trusted-firmware/build/zynqmp/release 目录生成 bl31.bin

  • 配置 u-boot 使用 BL31

    1
    2
    3
    export BL31=<PATH>/arm-trusted-firmware/build/zynqmp/release/bl31.bin
    make xxx_defconfig
    make

从 SD 卡启动 U-Boot

要将 u-boot 下载到 SD 卡并从 SD 卡启动需要以下步骤:

  • a. SD 卡格式化为 FAT32 文件系统

  • b. 生成 u-boot 映像文件:

    • u-boot.elf: u-boot 可执行文件
    • u-boot.img: u-boot 镜像文件
  • c. 生成固件「P.S. ZYNQMP 平台还需要 FSBL (First Stage Boot Loader) 和 PMUFW (Platform Management Unit Firmware) 等固件」

    • FSBL :
      • c.1 详见「[2.3 生成FSBL和PMUFW](#2.3 生成FSBL和PMUFW)」
      • P.S. 要让 u-boot 打印 log 信息需要在 fsbl_debug.h 中定义 FSBL_DEBUG_INFO (P.S. FSBL_DEBUG_DETAILED 输出最详细的信息)
    • PMUFW:
  • d. 合并生成 BOOT.bin 文件:通过 bootgen工具合成:

    • 制作 BOOT.bif 文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      //arch = zynqmp; split = false; format = BIN
      the_ROM_image:
      {
      [bootloader, destination_cpu = a53-0]fsbl_a53.elf
      [pmufw_image]pmu_fw.elf
      [destination_device=pl] design_1_wrapper.bit
      [destination_cpu = a53-0, exception_level = el-3]bl31.elf
      [destination_cpu = a53-0, exception_level = el-2]u-boot.elf
      // [offset=0x1E40000, load=0X10000000, destination_cpu=a53-0]image.ub
      }
      //pmu_fw.elf: pmu的配置文件
      //bl31.elf : arm的加密固件
      //pl.bit : FPGA端的bit配置文件,不是必须的
      //u-boot.elf: 必须
      //image.ub : ...
    • 使用 bootgen 工具生成 boot.bin 文件:

      1
      bootgen -image BOOT.bif -arch zynqmp -w -o i BOOT.BIN
    • 将生成的 boot.bin 文件复制到 SD 卡的根目录:

      1
      2
      3
      4
      sudo mount /dev/sdX1 /mnt
      sudo cp boot.bin /mnt
      sudo sync
      sudo umount /mnt
  • e. 启动开发板

    • e.1 将 SD 卡插入 ZynqMP-ZCU2CG 开发板的 SD 卡插槽
    • e.2 设置开发板为 SD 卡启动模式
    • e.3 上电启动开发板,U-Boot 应该会从 SD 卡启动

生成 FSBL 和 PMUFW

制作 FSBL (First Stage Boot Loader) 和 PMUFW (Platform Management Unit Firmware) 需要使用 Xilinx 提供的 Vivado 和 Vitis 工具。以下是详细的步骤:

2.3.1 创建硬件平台

首先,在Vivado中创建你的硬件设计并导出硬件描述文件「HDF/ XSA」。

  1. 打开Vivado并加载你的设计工程。
  2. 生成比特流文件「Bitstream」。
  3. 导出硬件描述文件「XSA」:
    • 选择 File > Export > Export Hardware。
    • 勾选 Include Bitstream。
    • 指定导出文件的路径并点击 OK。

生成 FSBL 和 PMUFW

接下来,在 Vitis 中使用导出的硬件描述文件来生成 FSBL 和 PMUFW。

打开 Vitis
  • 打开 Vitis 2022.2
  • 创建新的工作区
创建新的应用项目
  • FSBL: (blog_1,blog_2)

    • 选择 File > New > Application Project

    • 输入项目名称,如 zynqmp_fsbl

    • 选择你的硬件平台「在 Vivado 中导出的 XSA 文件」

    • 在 Templates 页面中,选择 Zynq MP First Stage Boot Loader 模板,然后点击 Finish,Vitis 将自动生成 FSBL 项目并编译生成 zynqmp_fsbl.elf 文件

    • 自定义硬件初始化: 根据硬件设计的需求,在FSBL启动过程中执行额外的初始化操作,比如初始化外设、设置I/O引脚、配置时钟等

      • 修改 xfsbl_board.c int XFsbl_BoardInit(void) 函数

        1
        // TODO
      • TODO

    • 自定义启动顺序 : 自定义的启动顺序,或者决定加载哪些额外的二进制文件(如bitstream、设备树等)

      • TODO (Non-Secure Boot跳过BL31启动)

        1
              
      • TODO

    • **调试和日志记录 : **添加调试信息来监视FSBL的执行过程

  • PMUFW

    • 选择 File > New > Application Project
    • 输入项目名称,如 zynqmp_pmufw
    • 选择你的硬件平台「在 Vivado 中导出的 XSA 文件」
    • 在 Templates 页面中,选择 Zynq MP PMU Firmware 模板,然后点击 Finish,Vitis 将自动生成 PMUFW 项目并编译生成 pmufw.elf 文件

ALTK-MPSOC-P4 Board 实战

[Altk MPSoC P4]

board 板级文件夹修改

board/xilinx/zynqmp 目录下新建一个 zynqmp-altk-p4 文件夹存放 P4 开发版的 PS init 文件,该文件不需要我们自己编写,vivado 导出的 xsa 文件解压即可得到。

开发板默认配置文件

因为 ALTK 的 MPSoC-P4 是参考 xilinx 的 zcu102 公板做的,所以可以参考 xilinx_zynqmp_virt_defconfig「设备树参考zynqmp-zcu102-revA」来修改我们的配置文件进行移植。

1
2
3
4
CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_altk_p4" // 指定开发板头文件
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-altk-p4" // 初始化文件(board/xilinx/zynqmp/CONFIG_DEFAULT_DEVICE_TREE)
CONFIG_OF_LIST="zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB"
CONFIG_BOOTCOMMAND="run default_bootcmd"

P.S. 以上仅展示修改的部份

开发板头文件

copy xilinx_zynqmp.h 进行修改

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
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Configuration for Xilinx ZynqMP
* (C) Copyright 2024 Theo Tsang <sihao.tsang@gmail.com>
*
* Based on Altk ZynqMP P4 platform
*/

#ifndef __XILINX_ZYNQMP_ALTK_P4_H
#define __XILINX_ZYNQMP_ALTK_P4_H

#include <configs/xilinx_zynqmp.h>

#if defined(CONFIG_ZYNQMP_GQSPI)
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x20000)
#else
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE
#endif

#undef BOOT_TARGET_DEVICES
#define BOOT_TARGET_DEVICES(func) \
BOOT_TARGET_DEVICES_JTAG(func) \
BOOT_TARGET_DEVICES_MMC(func) \
BOOT_TARGET_DEVICES_QSPI(func)

/* Initial environment variables */
#undef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
ENV_MEM_LAYOUT_SETTINGS \
BOOTENV
// "boot_image=BOOT.bin\0" \
// "loadbit_addr=0x100000\0" \
// "loadbootenv_addr=0x2000000\0" \
// "devicetree_size=0x20000\0" \
// "bootenv=uEnv.txt\0" \
// "loadbootenv=load mmc 1 ${loadbootenv_addr} ${bootenv}\0" \
// "uenvboot=" \
// "if run loadbootenv; then " \
// "echo Loaded environment from ${bootenv}; " \
// "run importbootenv; " \
// "fi; " \
// "if test -n $uenvcmd; then " \
// "echo Running uenvcmd ...; " \
// "run uenvcmd; " \
// "fi\0" \
// "sdboot=if mmcinfo; then " \
// "run uenvboot; " \
// "echo Copying Linux from SD to RAM... && " \
// "fi\0" \
// "default_bootcmd=run sdboot;\0" \
// "bootcmd=run sdboot;\0"
// // "bitstream_image=system_wrapper.bit.bin\0"

#endif /* __XILINX_ZYNQMP_ALTK_P4_H */

设备树

  • clone 设备树生成器插件

    1
    2
    git clone https://github.com/Xilinx/device-tree-xlnx.git
    git checkout xilinx_rel_v2022.2
  • 产生 DTS 文件

    • 运行 xsct 工具「工具版本需大于2015.1」:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      svivado
      xsct

      ****** xilinx Software Commandline Tool (XCST) v2022.2.0
      **** SW Build 0 on 2022-10-13-12:09:36
      ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved



      xsct% hsi open_hw_design system_wrapper.xsa
      xsct% hsi set_repo_path /home/theo/Tools/Vitis/2022.2/device-tree-xlnx-xilinx_v2022.2
      xsct% set procs [hsi get_cells -hier -filter {IP_TYPE==PROCESSOR}]<font></font>
      xsct% puts "List of processors found in XSA is $procs"<font></font>
      xsct% hsi create_sw_design device-tree -os device_tree -proc psu_cortexa53_0
      xsct% hsi generate_target -dir my_dts
      xsct% hsi close_hw_design [hsi current_hw_design]<font></font>
      xsct% exit
      • open xsa|hds 文件
      • 设定插件路径
      • Create SW design and setup CPU
      • Generate DTS/DTSI files to folder my_dts
      • Clean up

      P.S. 摘抄自 https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842279/Build+Device+Tree+Blob

  • 设备树文件详解

    • pcw.dtsi : ps 部分的设备树文件,在 zynqmp.dtsi 基础上生成的,使能相应的外设
    • pl.dtsi : pl 部分 IP 的设备树文件
    • system.dts :
    • system-top.dts : 设备树镜像文件 dtb 的核心文件
    • zynqmp-clk-ccf.dtsi: 芯片通用的时钟相关的设备树文件
    • zynqmp.dtsi : 芯片通用的 PS 部分的设备树文件
  • 修改 dts 文件:

  • 修改 arch/arm/dts/Makefile 添加开发板的设备树文件

Linux 内核移植

环境准备

website: https://www.kernel.org/,内核是操作系统的核心 ,其主要功能有:响应中断,执行中断服务程序;管理多个进程,调度和分享处理器的时间;管理进程地址空间的内存管理;网络和进程间通信等系统服务程序。

  • 版本号查询:

    Linux 的版本号分为两部分,即内核版本与发行版本。内核版本号由3个数字组成:A.B.C。各数字含义如下:

    A:内核主版本号。这是很少发生变化,只有当发生重大变化的代码和内核发生才会发生。如1994年的1.0及1996年的2.0。

    B:内核次版本号。是指一些重大修改的内核。偶数表示稳定版本;奇数表示开发中版本。

    C:内核修订版本号。是指轻微修订的内核。这个数字当有安全补丁,bug修复,新的功能或驱动程序,内核便会有变化。

    如:Linux theo-machine-vision 6.5.0-44-generic #44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jun 18 14:36:16 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

    第一个组数字:6, 主版本号

    第二个组数字:5, 次版本号,当前为稳定版本

    第三个组数字:0, 修订版本号

    第四个组数字:44,当前内核版本(6.5.0)的第44次微调patch

    generic: 当前内核版本为通用版本

  • 内核版本分类:

    mainline :主线版本

    stable :稳定版本

    longterm :长期支持版本

    linux-next:

拉取kernel

1
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.10.5.tar.xz