原创 NXP iMX8MP 处理器基于 Linux 关闭 Debug Console 输出

2025-1-7 14:52 91 0 分类: MCU/ 嵌入式

By Toradex 秦海

1). 简介

嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。

 

本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台

 

 

2. 准备

a). Verdin i.MX8MP ARM核心版配合Dahlia载板并连接Debug Console HDMI 显示器进行测试。

 

 

3). 测试流程

a). 参考这里说明下载Toradex Yocto Linux BSP7 对应 U-Boot 源码,根据如下 patch 文件修改编译配置后重新编译 U-Boot Image

-------------------------------

--- a/.config2024-12-27 14:52:26.151705541 +0800

+++ .b/.config2025-01-03 17:41:42.779299312 +0800

@@ -535,9 +535,13 @@

 # CONFIG_DISABLE_CONSOLE is not set

 CONFIG_LOGLEVEL=4

 CONFIG_SPL_LOGLEVEL=4

-# CONFIG_SILENT_CONSOLE is not set

-# CONFIG_SPL_SILENT_CONSOLE is not set

+CONFIG_SILENT_CONSOLE=y

+CONFIG_SPL_SILENT_CONSOLE=y

 # CONFIG_TPL_SILENT_CONSOLE is not set

+# CONFIG_SILENT_U_BOOT_ONLY is not set

+CONFIG_SILENT_CONSOLE_UPDATE_ON_SET=y

+CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC=y

+# CONFIG_SILENT_CONSOLE_UNTIL_ENV is not set

 # CONFIG_PRE_CONSOLE_BUFFER is not set

 CONFIG_CONSOLE_FLUSH_SUPPORT=y

 # CONFIG_CONSOLE_FLUSH_ON_NEWLINE is not set

@@ -644,7 +648,7 @@

 CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y

 CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x42200000

 CONFIG_SPL_SYS_MALLOC_SIZE=0x80000

-CONFIG_SPL_BANNER_PRINT=y

+# CONFIG_SPL_BANNER_PRINT is not set

 # CONFIG_SPL_DISPLAY_PRINT is not set

 CONFIG_SPL_SYS_MMCSD_RAW_MODE=y

 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y

-------------------------------

 

b). 参考这里说明重新组装Verdin i.MX8MP Boot Container,在编译 ATF Image 的时候参考如下命令来关闭 log 输出。

-------------------------------

$ make PLAT=imx8mp IMX_BOOT_UART_BASE=0x30880000 LOG_LEVEL=0 DEBUG=0bl31

-------------------------------

 

c). 从下面地址下载 Yocto linux BSP7 Minimal/Multimedia Image 并解压。

https://developer.toradex.cn/software/toradex-embedded-software/toradex-download-links-torizon-linux-bsp-wince-and-partner-demos/#bsp-quarterly-releases

 

d). 用上述步骤 b 生成的 flash.bin binary 文件重命名为 imx-boot并替换BSP Image 里面的 imx-boot文件。

-------------------------------

$ tar xvf /Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1.tar

$ $ cd /Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1/

$ cp /imx-mkimage/iMX8M/flash.bin /Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1/imx-boot

-------------------------------

 

e). 参考如下 patch 修改编译 BSP Image 中的环境变量定义文件。

-------------------------------

--- a/u-boot-initial-env-sd2024-10-01 21:50:32.000000000 +0800

+++ b/u-boot-initial-env-sd2024-12-27 16:28:20.000000000 +0800

@@ -19,7 +19,7 @@

bootcmd_mmc1=devnum=1; run mmc_boot

bootcmd_mmc2=devnum=2; run mmc_boot

bootdelay=1

-console=ttymxc2

+console=null

cpu=armv8

distro_bootcmd=setenv nvme_need_init; for target in ${boot_targets}; do run bootcmd_${target}; done

efi_dtb_prefixes=/ /dtb/ /dtb/current/

@@ -45,6 +45,7 @@

scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done

scriptaddr=0x50280000

soc=imx8m

+silent=1

update_uboot=askenv confirm Did you load flash.bin (y/N)?; if test "$confirm" = "y"; then setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200; mmc dev 2 1; mmc write ${loadaddr} 0x0 ${blkcnt}; fi

usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi

usb_ignorelist=0x1050:*,

-------------------------------

 

//当然,U-Boot 环境变量的修改也可以通过修改 U-boot 源代码中include/configs/verdin-imx8mp.h文件来修改,本文不做赘述。

 

// 如果只需要不显示部分 Kernel log 信息,则可以只设置增加如下环境变量即可,无需重新修改编译 U-Boot

-------------------------------

# setenv tdxargs '${tdxargs} quiet'

# saveenv

-------------------------------

 

f). 参考这里说明将修改的BSP Image 重新更新到 Verdin i.MX8MP 模块,启动后 Debug Console 输出如下,仅剩下 SPL 配合 ARM 处理器 BootRoM 启动的简单 log 信息输出,其他 U-Boot以及 Linux Kernel/Rootfs 等输出均已经不显示。同时此时测试在不进行任何其他优化的前提下,从按下载板 Power ON按键开机,到连接的HDMI 屏幕出现 Qt Cinama Demo 应用显示,一共是14s 时间。而正常不做任何修改的 Yocto Linux Multimedia BSP 同样情况启动时间在 17s - 18s

-------------------------------

DDRINFO: start DRAM init

DDRINFO: DRAM rate 4000MTS

Training FAILED

DDRINFO: start DRAM init

DDRINFO: DRAM rate 4000MTS

DDRINFO:ddrphy calibration done

DDRINFO: ddrmix config done

DDR configured as single rank

SEC0:  RNG instantiated

Normal Boot

WDT:   Started watchdog@30280000 with servicing every 1000ms (60s timeout)

Boot Stage: Primary boot

Find img info 0x4802d200, size 888

Need continue download 1024

Failed to find node!, err: -1!

Failed to find node!, err: -1!

-------------------------------

 

g). 通常情况上面保留 SPL BootROM 启动相关 log 打印即可满足需求,如果一定要完全去掉,就需要逐项查看对应的源代码,当前打印信息对应(BSP版本变更可能导致变化)以及修改 patch 请见如下,在对应源码中注释掉相关的 printf()/puts()打印log 输出代码重新编译即可,测试下来这样可以将启动时间缩短到 13.8s 左右。

./ ddr_init.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/ddr/imx/imx8m/ddr_init.c?h=toradex_imx_lf_v2024.04

-------------------------------

DDRINFO: start DRAM init

DDRINFO: DRAM rate 4000MTS

DDRINFO: start DRAM init

DDRINFO: DRAM rate 4000MTS

DDRINFO:ddrphy calibration done

DDRINFO: ddrmix config done

-------------------------------

./ ddrphy_utils.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/ddr/imx/phy/ddrphy_utils.c?h=toradex_imx_lf_v2024.04#n101

-------------------------------

Training FAILED

-------------------------------

./ spl.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/board/toradex/verdin-imx8mp/spl.c?h=toradex_imx_lf_v2024.04

-------------------------------

DDR configured as single rank

Normal Boot

-------------------------------

./ jr.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/crypto/fsl/jr.c?h=toradex_imx_lf_v2024.04#n937

-------------------------------

SEC0:  RNG instantiated

-------------------------------

./ wdt-uclass.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/watchdog/wdt-uclass.c?h=toradex_imx_lf_v2024.04#n143

-------------------------------

WDT:   Started watchdog@30280000 with servicing every 1000ms (60s timeout)

-------------------------------

./ spl_imx_romapi.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/arch/arm/mach-imx/spl_imx_romapi.c?h=toradex_imx_lf_v2024.04

-------------------------------

Boot Stage: Primary boot

Find img info 0x4802d200, size 888

Need continue download 1024

-------------------------------

./ spl.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/arch/arm/mach-imx/spl.c?h=toradex_imx_lf_v2024.04#n459

-------------------------------

Failed to find node!, err: -1!

Failed to find node!, err: -1!

-------------------------------

 

// 完整修改 patch 请见如下

-------------------------------

diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c

index d6664bf9103..a8ef680593b 100644

--- a/arch/arm/mach-imx/spl.c

+++ b/arch/arm/mach-imx/spl.c

@@ -456,7 +456,7 @@ int board_handle_rdc_config(void *fdt_addr, const char *config_name, void *dst_a

 

 node = fdt_node_offset_by_compatible(fdt_addr, -1, "imx8m,mcu_rdc");

 if (node < 0) {

-printf("Failed to find node!, err: %d!\n", node);

+//printf("Failed to find node!, err: %d!\n", node);

 ret = -1;

 goto exit;

 }

diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c

index 8b8d16d911f..fea293cb9ca 100644

--- a/arch/arm/mach-imx/spl_imx_romapi.c

+++ b/arch/arm/mach-imx/spl_imx_romapi.c

@@ -387,7 +387,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,

 }

 

 imagesize = img_info_size(phdr);

-printf("Find img info 0x%p, size %d\n", phdr, imagesize);

+//printf("Find img info 0x%p, size %d\n", phdr, imagesize);

 

 if (p - phdr < imagesize) {

 imagesize -= p - phdr;

@@ -463,11 +463,11 @@ int board_return_to_bootrom(struct spl_image_info *spl_image,

 if (ret != ROM_API_OKAY)

 goto err;

 

-printf("Boot Stage: ");

+//printf("Boot Stage: ");

 

 switch (bstage) {

 case BT_STAGE_PRIMARY:

-printf("Primary boot\n");

+//printf("Primary boot\n");

 break;

 case BT_STAGE_SECONDARY:

 printf("Secondary boot\n");

diff --git a/board/toradex/verdin-imx8mp/spl.c b/board/toradex/verdin-imx8mp/spl.c

index 73729a42b45..f6bf9260527 100644

--- a/board/toradex/verdin-imx8mp/spl.c

+++ b/board/toradex/verdin-imx8mp/spl.c

@@ -42,7 +42,7 @@ void spl_dram_init(void)

 

 lpddr4_single_rank_training_patch();

 if (!ddr_init(&dram_timing)) {

-puts("DDR configured as single rank\n");

+//puts("DDR configured as single rank\n");

 return;

 }

 puts("DDR configuration failed\n");

@@ -69,7 +69,7 @@ void spl_board_init(void)

 clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5));

 clock_enable(CCGR_GIC, 1);

 

-puts("Normal Boot\n");

+//puts("Normal Boot\n");

 }

 

 #define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE)

diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c

index 97b0cf83ae7..efb2544de02 100644

--- a/drivers/crypto/fsl/jr.c

+++ b/drivers/crypto/fsl/jr.c

@@ -934,7 +934,7 @@ init:

 return -1;

 }

 

-printf("SEC%u:  RNG instantiated\n", sec_idx);

+//printf("SEC%u:  RNG instantiated\n", sec_idx);

 }

 #if CONFIG_IS_ENABLED(OF_CONTROL)

 if (CONFIG_IS_ENABLED(DM_RNG)) {

diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c

index 91d963419d6..06ff6feaa09 100644

--- a/drivers/ddr/imx/imx8m/ddr_init.c

+++ b/drivers/ddr/imx/imx8m/ddr_init.c

@@ -316,7 +316,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

 unsigned int tmp, initial_drate, target_freq;

 int ret;

 

-printf("DDRINFO: start DRAM init\n");

+//printf("DDRINFO: start DRAM init\n");

 

 /* Step1: Follow the power up procedure */

 if (is_imx8mq()) {

@@ -339,7 +339,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

 

 initial_drate = dram_timing->fsp_msg[0].drate;

 /* default to the frequency point 0 clock */

-printf("DDRINFO: DRAM rate %dMTS\n", initial_drate);

+//printf("DDRINFO: DRAM rate %dMTS\n", initial_drate);

 ddrphy_init_set_dfi_clk(initial_drate);

 

 /* D-aasert the presetn */

@@ -409,7 +409,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

 tmp = reg32_read(DDRPHY_CalBusy(0));

 } while ((tmp & 0x1));

 

-printf("DDRINFO:ddrphy calibration done\n");

+//printf("DDRINFO:ddrphy calibration done\n");

 

 /* Step15: Set SWCTL.sw_done to 0 */

 reg32_write(DDRC_SWCTL(0), 0x00000000);

@@ -462,7 +462,7 @@ int ddr_init(struct dram_timing_info *dram_timing)

 

 /* enable port 0 */

 reg32_write(DDRC_PCTRL_0(0), 0x00000001);

-printf("DDRINFO: ddrmix config done\n");

+//printf("DDRINFO: ddrmix config done\n");

 

 board_dram_ecc_scrub();

 

diff --git a/drivers/ddr/imx/phy/ddrphy_utils.c b/drivers/ddr/imx/phy/ddrphy_utils.c

index 59a15764526..cddf270e594 100644

--- a/drivers/ddr/imx/phy/ddrphy_utils.c

+++ b/drivers/ddr/imx/phy/ddrphy_utils.c

@@ -98,7 +98,7 @@ int wait_ddrphy_training_complete(void)

 debug("Training PASS\n");

 return 0;

 } else if (mail == 0xff) {

-printf("Training FAILED\n");

+//printf("Training FAILED\n");

 return -1;

 }

 }

diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c

index 417e8d7eef9..7e4213858b8 100644

--- a/drivers/watchdog/wdt-uclass.c

+++ b/drivers/watchdog/wdt-uclass.c

@@ -140,9 +140,9 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)

 }

 }

 

-printf("WDT:   Started %s with%s servicing %s (%ds timeout)\n",

+/*printf("WDT:   Started %s with%s servicing %s (%ds timeout)\n",

        dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out",

-       str, (u32)lldiv(timeout_ms, 1000));

+       str, (u32)lldiv(timeout_ms, 1000));*/

 }

 

 return ret;

-------------------------------

 

h). 另外,U-Boot 默认的 countdown 功能虽然没有打印 log 了,但是还是依然存在,可以通过如下修改 u-boot-initial-env-sd 环境变量配置来忽略这个功能。设置后可以将启动时间缩短为 12s - 13s

-------------------------------

bootdelay=-2

// bootdelay variable description from U-Boot documentation

bootdelay: After reset, U-Boot will wait this number of seconds before it executes the contents of the bootcmd variable. During this time a countdown is printed, which can be interrupted by pressing any key.

Set this variable to 0 boot without delay. Be careful: depending on the contents of your bootcmd variable, this can prevent you from entering interactive commands again forever!

Set this variable to -1 to disable autoboot.

Set this variable to -2 to boot without delay and not check for abort.

-------------------------------

 

4). 总结

本文基于NXP i.MX8MP ARM 处理器平台测试了关闭 Debug Console 来增强安全和提高启动时间的流程。

 

参考文档

https://developer.toradex.com/software/development-resources/configuring-serial-port-debug-console-linuxu-boot/

作者: hai.qin_651820742, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1864768.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
0
关闭 站长推荐上一条 /1 下一条