2025-1-7 14:52
320 次阅读|
0 个评论
B y 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=0 bl31 ------------------------------- 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-sd 2024-10-01 21:50:32.000000000 +0800 +++ b/u-boot-initial-env-sd 2024-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) fsp_msg .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", 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/