• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 博客專欄

    EEPW首頁 > 博客 > NXP iMX8QM 通過 SCFW 隔離 AP_M4 核資源

    NXP iMX8QM 通過 SCFW 隔離 AP_M4 核資源

    發布人:toradex 時間:2025-03-21 來源:工程師 發布文章

    By Toradex 胡珊逢

    簡介

    Apalis iMX8QM 使用了 NXP 的 iMX8 Quad Max 處理器。該 CPU 提供 A72 和 A53 Application Processor 和 M4 MCU。文章將介紹如何在硬件層面上隔離 AP 和 MCU 的資源,從而提高系統的可靠性。


    System Controller Unit (SCU)System Controller Unit 是 iMX8 Quad Max 處理器上的一個專用 M4 核,連接 PMIC 和控制處理器上的子系統,為處理器的硬件功能提供抽象接口,供子系統使用。其主要管理以下功能和資源:


    系統初始化與啟動系統控制器通信電源管理資源管理引腳配置定時器中斷處理


    默認情況下,AP 核和 M4 核均能夠使用 Apalis iMX8QM 的所有資源,包括 DDR RAM。SCU 可以通過分區 partition 的方式,將 AP 和 M4 之間,以及兩個 M4 核之間所使用的資源從硬件上隔離開。一個分區中除了處理器核心外,還可以有外設、引腳 Pads 和內存區域。處理器核只能訪問位于同一個分區內的資源。如果嘗試訪問其他分區的資源,則會返回總線錯誤。


    當 AP 核和 M4 核在同一個分區時,AP 上的 Linux 雖然可以通過 reserved memory 方式不去使用相關 RAM 區域,但是直接物理地址訪問的方式仍起作用。這對于 M4 端也是如此。使用 SCU 的分區,可以從底層規避該問題。除此之外,AP 和 M4 使用獨立 Power Domain,在隔離分區情況下,對于 M4 的實時關鍵任務和 AP 上基于富操作系統 Linux 的應用獨立運行提供可能。

    在剛啟動時,系統會劃分三個分區。

    SCU:包含所有運行 SCFW 固件所需的 Pads、外設和內存區域SECO:Security Controller 運行所需的相關資源Boot:系統剩余的所有資源如 Pads、外設和內存區域都將會劃分到該分區

    當系統繼續啟動時,如果不做進一步的分區,默認情況下 AP 和 M4 核都將運行在 Boot 分區中,它們之間只能通過軟件的方式隔離各自的資源。為了實現 AP 和 M4 之間的硬件隔離,可以采用下面分區。


    AP0:擁有運行 U-boot,Linux 的分區MCU0 和 MCU1:兩個 Cortex-M4 核各自運行的分區Shared:共享資源的分區,例如將一段用于 rpmsg 通信的 RAM 區域劃分到其中,AP 和 M4 就能夠相互發送消息

    分區的創建和資源劃分在 SCU 的固件 SCFW 中調整。


    SCU 固件 SCFW


    SCFW 的下載和編譯方法參考Build Custom i.MX 8/8X System Controller Firmware (SCFW)。接下來將針對上面使用 AP0、MCU0、MCU1 和 Shared 分區案例進行說明。按照上面方法下載的 SCFW 源碼中,mx8qm_apalis/board.c 已經包含上面分區的實現代碼,所以無需額外的修改。在組裝 Boot Container 時傳入特定的 Flags 值可以啟用。

    在 platform/board/mx8qm_apalis/board.c 中配置分區和資源。宏定義 PARTITION_NAME 命令系統啟動時的設置三個分區名字。

      PARTITION_NAME(SC_PT, "SCU");
      PARTITION_NAME(SECO_PT, "SECO");
      PARTITION_NAME(pt_boot, "BOOT");


    檢測標志位判斷是否需要創建 AP0、MCU0、MCU1 和 Shared 分區。

      if (alt_config != SC_FALSE)
      {


    在需要進行分區時,PARTITION_NAME 設置相應分區的名稱。

      PARTITION_NAME(pt_boot, "AP0");
      ...
      PARTITION_NAME(pt_m4_0, "MCU0");
      ...
      PARTITION_NAME(pt_m4_1, "MCU1");
      ...
      PARTITION_NAME(pt, "Shared");


    這里以 MCU0 分區為例,rsrc_list中包含了劃分到 MCU0 分區的資源,如 M4 中斷、Message Unit、定時器等。

      static const sc_rsrc_t rsrc_list[7U] =
      {
          SC_R_SYSTEM,
          SC_R_IRQSTR_M4_0,
          SC_R_MU_5B,
          SC_R_MU_7A,
          SC_R_MU_8B,
          SC_R_GPT_4,
          SC_R_SECO_MU_4
      };


    pad_list 中包含 MCU0 分區所使用的引腳范圍。

      static const sc_pad_t pad_list[2U] =
      {
          RM_RANGE(SC_P_M40_I2C0_SCL, SC_P_M40_GPIO0_01)
      };


    結合 sc_fw_api_qm_b0.pdf 文檔,index 7~10 的引腳都將在劃分到 MCU0 分區。

    sc_rm_mem_list_t 配置了包括 RAM 在內的可使用存儲空間。

      static const sc_rm_mem_list_t mem_list[2U] =
      {
          {0x088000000ULL, 0x0887FFFFFULL},
          {0x008081000ULL, 0x008180FFFULL}
      };


    rm_partition_create 使用上面配置的所有資源創建 MCU0 分區。

      BRD_ERR(rm_partition_create(pt_boot, &pt_m4_0, SC_FALSE,
          SC_TRUE, SC_FALSE, SC_TRUE, SC_FALSE, SC_R_M4_0_PID0,
          rsrc_list, ARRAY_SIZE(rsrc_list),
          pad_list, ARRAY_SIZE(pad_list),
          mem_list, ARRAY_SIZE(mem_list)));


    組裝 Boot Container

    NXP i.MX 8QuadMax 處理器使用前面提到的 SCU 來啟動系統。啟動時除了加載 SCFW,它還可以加載 ATF 和 U-Boot,以及直接加載 M4 核的固件。Boot Container 組裝方法參考 Specifics: Build U-Boot for NXP i.MX 8/8X-based SoMs。默認情況下,如網頁描述,使用下面命令組裝 Boot Container。該方法生成的 flash.bin 文件中并不包含 M4 核的固件,并且 AP 和 M4 在同一個分區。M4 的固件在 U-Boot 啟動時,使用 bootaux 命令從 eMMC 上加載后運行。

    make SOC=iMX8QM flash_b0


    為了使用上面 SCFW 中劃分的分區,使用下面命令組裝 Boot Container。

    make SOC=iMX8QM flash_regression_linux_m4


    編譯目標來自 imx-mkimage/iMX8QM/soc.mak 中的定義。flash_regression_linux_m4: $(MKIMG) $(AHAB_IMG) \
    scfw_tcm.bin u-boot-atf.bin m4_image.bin m4_1_image.bin \
      ./$(MKIMG) -soc QM -rev B0 -append $(AHAB_IMG) \
      -c -flags 0x00200000 -scfw scfw_tcm.bin \
      -ap u-boot-atf.bin a53 0x80000000 \
      -p3 -m4 m4_image.bin 0 0x34FE0000 \
      -p4 -m4 m4_1_image.bin 1 0x38FE0000 \
      -out flash.bin


    -flags 0x00200000向 SCFW 的 board.c 傳遞,SCU 在啟動時將會創建 AP0、MCU0、MCU1 和 Shared 的分區。

      if (alt_config != SC_FALSE)
      {


    sc_fw_port.pdf 中說明了 Bit 21 SCFW_SC_BD_FLAGS_ALT_CONFIG 為更改 SCFW 配置的位,對應 0x00200000。

    上面命令中 m4_image.bin 和 m4_1_image.bin 為兩個 M4 各自的固件,從各自的 TCML 運行。因此,在執行上面命令前,需要把兩個 M4 的固件復制到 imx-mkimage/iMX8QM 目錄下。

    如下修改 U-boot 源碼中 U-boot/cmd/booti.c,重新編譯后將 u-boot.bin 復制到 imx-mkimage/iMX8QM 目錄下。

      if (dest < gd->ram_base || dest > gd->ram_top) {
          puts("kernel_comp_addr_r is outside of DRAM range!\n");
          //return -EINVAL;
      }


    Linux device tree 更新


    接下來的演示中,我們在 M4 上使用 multicore_examples/rpmsg_lite_pingpong_rtos 作為演示,在 AP 上的 Linux 系統中也需要開啟 rpmsg 節點并加載驅動。針對 Apalis iMX8 BSP 7 的 imx8qm-apalis-v1.1-ixora-v1.2.dtb 需要打該補丁。


    更新 Boot Container 文件

    上面命令執行成功后生成的 flash.bin,需要更新到 Apalis iMX8 模塊上的 eMMC 上。對于使用 Toradex Easy Installer 進行批量燒寫或者重裝系統,可以將 flash.bin 重名為 imx-boot,替換原來的燒錄文件中 imx-boot。在開發期間,使用 U-Boot 直接更新 flash.bin 會更加方便,免于重裝整個系統鏡像。

    將 flash.bin 復制到的一臺 TFTP 服務器的下載目錄中。然后在 U-Boot 中配置 Apalis iMX8 和 TFTP 服務器 IP 地址。

    Apalis iMX8 # setenv ipaddr 192.168.3.181
    Apalis iMX8 # setenv serverip 192.168.3.196
    Apalis iMX8 # saveenv


    使用 tftpboot 和 mmc 命令將 flash.bin 下載并寫入到 eMMC 上。mmc write $loadaddr 0 0x973中最后的數值是寫入的 block 數量。tftpboot 在下載時會顯示文件大小,例如這里為 1238016 字節。需要寫入的 block = (1238016+511)/512,計算結果向上取整,并轉為十六進制數值。

    Apalis iMX8 # tftpboot $loadaddr flash.bin
    Using ethernet@5b040000 device
    TFTP from server 192.168.3.196; our IP address is 192.168.3.181
    Filename 'flash.bin'.
    Load address: 0x95400000
    Loading: ##################################################  1.2 MiB
    3.4 MiB/s
    done
    Bytes transferred = 1238016 (12e400 hex)


    Apalis iMX8 # mmc dev 0 1
    Apalis iMX8 # mmc write $loadaddr 0 0x973


    測試
    在 U-Boot 中配置啟動時加載的 device tree 文件。
    Apalis iMX8 # setenv fdtfile imx8qm-apalis-v1.1-ixora-v1.2.dtb
    Apalis iMX8 # saveenv
    Apalis iMX8 # reset
    啟動后可以在 Linux 和兩個 M4 的調試串口上看到啟動內容。
    Linux 中進入 kernel modules 驅動目錄 kernel/drivers/rpmsg,加載 imx_rpmsg_pingpong.ko。兩個 M4 上的固件在發現 rpmsg 通道后,自動向 Linux 發送消息。# insmod imx_rpmsg_pingpong.ko
    ...
    [   67.386427] get 91 (src: 0x1f)
    [   67.389556] get 101 (src: 0x1e)
    [   67.392707] imx_rpmsg_pingpong virtio1.rpmsg-openamp-demo-channel.-1.30: 
    goodbye!
    [   67.401771] get 93 (src: 0x1f)
    [   67.406364] get 95 (src: 0x1f)
    [   67.410982] get 97 (src: 0x1f)
    [   67.415594] get 99 (src: 0x1f)
    [   67.420212] get 101 (src: 0x1f)
    [   67.423388] imx_rpmsg_pingpong virtio3.rpmsg-openamp-demo-channel-1.-1.31: 
    goodbye!

    總結

    文章介紹了如何使用 SCU 劃分不同的分區,將 AP 和 M4 之間做硬件隔離,并使用 SCFW 直接加載 M4 的固件,不僅提高系統可靠性,也將 M4 運行提前到 U-Boot 之前,加快啟動速度。更多關于 SCU 的高級高級功能,可以參考 SCFW 的說明文檔。


    *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。




    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 唐海县| 建昌县| 保靖县| 武穴市| 五莲县| 罗山县| 易门县| 宁津县| 阳城县| 宝清县| 汉沽区| 通道| 江门市| 临泉县| 孙吴县| 泰来县| 岳西县| 阜新市| 靖远县| 博罗县| 阜平县| 富蕴县| 许昌县| 自贡市| 额济纳旗| 商洛市| 常州市| 白沙| 靖州| 内江市| 长岛县| 澄城县| 赣州市| 辽宁省| 曲松县| 武义县| 马边| 富阳市| 房山区| 越西县| 新余市|