工控網(wǎng)首頁(yè)
>

應(yīng)用設(shè)計(jì)

>

NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源

NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源

簡(jiǎn)介

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

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

系統(tǒng)初始化與啟動(dòng)系統(tǒng)控制器通信電源管理資源管理引腳配置定時(shí)器中斷處理

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

當(dāng) AP 核和 M4 核在同一個(gè)分區(qū)時(shí),AP 上的 Linux 雖然可以通過(guò) reserved memory 方式不去使用相關(guān) RAM 區(qū)域,但是直接物理地址訪問(wèn)的方式仍起作用。這對(duì)于 M4 端也是如此。使用 SCU 的分區(qū),可以從底層規(guī)避該問(wèn)題。除此之外,AP 和 M4 使用獨(dú)立 Power Domain,在隔離分區(qū)情況下,對(duì)于 M4 的實(shí)時(shí)關(guān)鍵任務(wù)和 AP 上基于富操作系統(tǒng) Linux 的應(yīng)用獨(dú)立運(yùn)行提供可能。 NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源792.png

在剛啟動(dòng)時(shí),系統(tǒng)會(huì)劃分三個(gè)分區(qū)。

SCU:包含所有運(yùn)行 SCFW 固件所需的 Pads、外設(shè)和內(nèi)存區(qū)域SECO:Security Controller 運(yùn)行所需的相關(guān)資源Boot:系統(tǒng)剩余的所有資源如 Pads、外設(shè)和內(nèi)存區(qū)域都將會(huì)劃分到該分區(qū)

當(dāng)系統(tǒng)繼續(xù)啟動(dòng)時(shí),如果不做進(jìn)一步的分區(qū),默認(rèn)情況下 AP 和 M4 核都將運(yùn)行在 Boot 分區(qū)中,它們之間只能通過(guò)軟件的方式隔離各自的資源。為了實(shí)現(xiàn) AP 和 M4 之間的硬件隔離,可以采用下面分區(qū)。

NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源1022.png

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

分區(qū)的創(chuàng)建和資源劃分在 SCU 的固件 SCFW 中調(diào)整。

SCU 固件 SCFW

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

在 platform/board/mx8qm_apalis/board.c 中配置分區(qū)和資源。宏定義 PARTITION_NAME 命令系統(tǒng)啟動(dòng)時(shí)的設(shè)置三個(gè)分區(qū)名字。

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

檢測(cè)標(biāo)志位判斷是否需要?jiǎng)?chuàng)建 AP0、MCU0、MCU1 和 Shared 分區(qū)。

  if (alt_config != SC_FALSE)   {

在需要進(jìn)行分區(qū)時(shí),PARTITION_NAME 設(shè)置相應(yīng)分區(qū)的名稱。

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

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

  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 分區(qū)所使用的引腳范圍。

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

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

NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源2638.png

sc_rm_mem_list_t 配置了包括 RAM 在內(nèi)的可使用存儲(chǔ)空間。

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

rm_partition_create 使用上面配置的所有資源創(chuàng)建 MCU0 分區(qū)。

  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 來(lái)啟動(dòng)系統(tǒng)。啟動(dòng)時(shí)除了加載 SCFW,它還可以加載 ATF 和 U-Boot,以及直接加載 M4 核的固件。Boot Container 組裝方法參考 Specifics: Build U-Boot for NXP i.MX 8/8X-based SoMs。默認(rèn)情況下,如網(wǎng)頁(yè)描述,使用下面命令組裝 Boot Container。該方法生成的 flash.bin 文件中并不包含 M4 核的固件,并且 AP 和 M4 在同一個(gè)分區(qū)。M4 的固件在 U-Boot 啟動(dòng)時(shí),使用 bootaux 命令從 eMMC 上加載后運(yùn)行。

make SOC=iMX8QM flash_b0

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

make SOC=iMX8QM flash_regression_linux_m4

編譯目標(biāo)來(lái)自 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 在啟動(dòng)時(shí)將會(huì)創(chuàng)建 AP0、MCU0、MCU1 和 Shared 的分區(qū)。

  if (alt_config != SC_FALSE)   {

sc_fw_port.pdf 中說(shuō)明了 Bit 21 SCFW_SC_BD_FLAGS_ALT_CONFIG 為更改 SCFW 配置的位,對(duì)應(yīng) 0x00200000。

NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源4417.png

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

如下修改 U-boot 源碼中 U-boot/cmd/booti.c,重新編譯后將 u-boot.bin 復(fù)制到 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 更新

接下來(lái)的演示中,我們?cè)?M4 上使用 multicore_examples/rpmsg_lite_pingpong_rtos 作為演示,在 AP 上的 Linux 系統(tǒng)中也需要開(kāi)啟 rpmsg 節(jié)點(diǎn)并加載驅(qū)動(dòng)。針對(duì) Apalis iMX8 BSP 7 的 imx8qm-apalis-v1.1-ixora-v1.2.dtb 需要打該補(bǔ)丁。

更新 Boot Container 文件

上面命令執(zhí)行成功后生成的 flash.bin,需要更新到 Apalis iMX8 模塊上的 eMMC 上。對(duì)于使用 Toradex Easy Installer 進(jìn)行批量燒寫(xiě)或者重裝系統(tǒng),可以將 flash.bin 重名為 imx-boot,替換原來(lái)的燒錄文件中 imx-boot。在開(kāi)發(fā)期間,使用 U-Boot 直接更新 flash.bin 會(huì)更加方便,免于重裝整個(gè)系統(tǒng)鏡像。

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

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

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

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

測(cè)試 在 U-Boot 中配置啟動(dòng)時(shí)加載的 device tree 文件。 Apalis iMX8 # setenv fdtfile imx8qm-apalis-v1.1-ixora-v1.2.dtb Apalis iMX8 # saveenv Apalis iMX8 # reset 啟動(dòng)后可以在 Linux 和兩個(gè) M4 的調(diào)試串口上看到啟動(dòng)內(nèi)容。NXP iMX8QM 通過(guò) SCFW 隔離 AP_M4 核資源6306.png Linux 中進(jìn)入 kernel modules 驅(qū)動(dòng)目錄 kernel/drivers/rpmsg,加載 imx_rpmsg_pingpong.ko。兩個(gè) M4 上的固件在發(fā)現(xiàn) rpmsg 通道后,自動(dòng)向 Linux 發(fā)送消息。# 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! 總結(jié)

文章介紹了如何使用 SCU 劃分不同的分區(qū),將 AP 和 M4 之間做硬件隔離,并使用 SCFW 直接加載 M4 的固件,不僅提高系統(tǒng)可靠性,也將 M4 運(yùn)行提前到 U-Boot 之前,加快啟動(dòng)速度。更多關(guān)于 SCU 的高級(jí)高級(jí)功能,可以參考 SCFW 的說(shuō)明文檔。

審核編輯(
王靜
)
投訴建議

提交

查看更多評(píng)論
其他資訊

查看更多

上手測(cè)試 Hailo:在 Toradex 模塊上加速邊緣 AI

Yocto Linux 量產(chǎn) BSP 鏡像定制

ARM 處理器平臺(tái) eMMC Flash 存儲(chǔ)磨損測(cè)試示例

NXP iMX8MP 處理器基于 Linux 關(guān)閉 Debug Console 輸出

ARM 處理器平臺(tái) Ethernet Compliance 測(cè)試流程示例