在眺望电子TW-IMX6DL-EVM开发板上优化linux系统启动时间。
编译环境及开发包: 主机:ubuntu18.04
交叉编译器:arm-linux-gnueabihf-gcc
QT5.12.8:qt-everywhere-opensource-src-5.12.8
开发板:TW-IMX6DL-EVM
Linux:Linux-4.1.15
注意:本文章的所有命令涉及到的路径均为眺望电子官方环境路径,需根据自身实际环境改变。本文所演示的平台来自于眺望电子 iMX6 ARM嵌入式平台,这是一个基于NXP iMX6 ARM处理器,支持单核/双核Cortex-A9的核心板。
解决方案:
NXP i.MX6系列平台可以通过修改u-boot默认配置、裁剪内核以及修改文件系统三个方面来优化启动时间。
1.u-boot优化u-boot主要可以通过以下几个方案进行优化:
- 去掉不必要的串口信息;
- 去掉启动延迟时间;
- 去掉不必要的驱动;
- 去掉用不到的命令。
u-boot启动通常会打印以下消息:
U-Boot 2014.04-gdec7a05-dirty (Mar 16 2020 - 10:34:39) CPU: Freescale i.MX6DL rev1.3 at 792 MHz CPU: Temperature 33 C, calibration data: 0x59751969 Reset cause: POR Board: MX6-SabreSD I2C: ready DRAM: 2 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2 No panel detected: default to Hannstar-XGA Display: Hannstar-XGA (1024x768) In: serial Out: serial Err: serial Found PFUZE100 deviceid=10,revid=11 mmc2(part 0) is current device Net: FEC [PRIME] Warning: failed to set MAC address Card did not respond to voltage select! mmc1(part 0) is current device Card did not respond to voltage select! ** Bad device mmc 1 ** Card did not respond to voltage select! ** Bad device mmc 1 ** Normal Boot Saving Environment to MMC... Writing to MMC(2)... done Have env flag, ignore inner env Hit any key to stop autoboot: 0 mmc2(part 0) is current device reading boot.scr ** Unable to read file boot.scr ** reading zImage 6709816 bytes read in 172 ms (37.2 MiB/s) Booting from mmc ... reading imx6dl-sabresd.dtb 44928 bytes read in 18 ms (2.4 MiB/s) Kernel image @ 0x12000000 [ 0x000000 - 0x666238 ] ##Flattened Device Tree blob at 18000000 Booting using the fdt blob at 0x18000000 Using Device Tree in place at 18000000, end 1800df6b switch to ldo_bypass mode! Starting kernel ...
可以通过在include/configs/mx6sabre_common.h文件中添加以下选项来屏蔽打印信息:
#define CONFIG_EXTRA_ENV_SETTINGS "silent=1 " #define CONFIG_SILENT_ConSOLE 11.2启动延迟时间修改
默认出厂固件会有1秒钟的延迟,可以通过修改include/configs/mx6sabre_common.h文件来取消延迟。
#define CONFIG_BOOTDELAY 0 #define CONFIG_ZERO_BOOTDELAY_CHECK1.3去掉不必要的驱动
可以根据实际情况去掉不必要的驱动来优化启动时间,例如SPI、USB、HDMI等。去掉SPI驱动可以修改include/configs/mx6sabre_common.h文件:
#if defined(CONFIG_ENV_IS_IN_MMC) #define CONFIG_ENV_OFFSET (8 * 64 * 1024) #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_ENV_SECT_SIZE (64 * 1024) //#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS //#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS //#define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE //#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED #elif defined(CONFIG_ENV_IS_IN_FLASH)
如果无需使用网络,也可以去掉相关驱动,同样是修改include/configs/mx6sabre_common.h文件:
//#define CONFIG_FEC_MXC //#define CONFIG_MII //#define IMX_FEC_base ENET_base_ADDR //#define CONFIG_FEC_XCV_TYPE RGMII //#define CONFIG_ETHPRIME "FEC" //#define CONFIG_FEC_MXC_PHYADDR 1 //#define CONFIG_PHYLIB //#define CONFIG_PHY_ATHEROS
同样可以选择去掉USB的驱动,修改如下:
#if 0 #define CONFIG_CMD_USB #define CONFIG_USB_EHCI #define CONFIG_USB_EHCI_MX6 #define CONFIG_USB_STORAGE #define CONFIG_EHCI_HCD_INIT_AFTER_RESET #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX #define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) #define CONFIG_MXC_USB_FLAGS 0 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif1.4去掉用不到的命令
在配置文件include/configs/mx6sabre_common.h文件中可以去掉用不到的命令,这里以去掉网络相关的命令为例。
//#define CONFIG_CMD_PING //#define CONFIG_CMD_DHCP //#define CONFIG_CMD_MII //#define CONFIG_CMD_NET2.内核修改
内核层面主要通过裁剪内核来实现启动时间优化,为了减少启动时间,可以在arch/arm/configs/imx_v7_defconfig文件中去掉caam(i.MX6硬件加密加速模块)模块的支持:
#CONFIG_CRYPTO_ANSI_CPRNG is not set #CONFIG_CRYPTO_DEV_FSL_CAAM=y #CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y #CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y #CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
根据实际情况去掉其它用不到的驱动模块,例如A9平台默认没有使用flash,可以去掉该驱动模块的支持:
#CONFIG_MTD=y
对于需用到的模块,可以可以编译成KO文件,等待系统启动后再加载,或者在需调用时再加载。
另外对于初始化中小于10 ms的sleep,可由msleep改为mdelay,因为msleep会让出CPU的占用,而A9上CPU调度频率是100hz,也就是最快调度一次也要大于10ms,所以用mdelay会更快些。
内核启动过程中同样会在串口打印相关信息,所以关闭打印时间以及将printk的打印级别调高,减少打印的信息也可以在一定程度上对启动时间进行优化:
#CONFIG_PRINTK_TIME=n #define DEFAULT_CONSOLE_LOGLEVEL 43.文件系统修改
文件系统占用启动时间较多的地方主要有:
- 拷贝文件系统到内存;
- udev或者mdev等自动创建设备节点;
- 系统自启动服务;
- 相关的自启程序。
相对应的优化方法有:
- 裁剪文件系统
- 用mknod创建设备节点
- 关闭不使用的服务
- 取消不必要的自启程序
需根据自身需求进行裁剪,去掉文件系统中不必要的库文件、logo图片、测试程序等,在虚拟机上先对文件系统进行解包,裁剪完成后再进行打包,对应的命令为:
tar zxvf rootfs.tar.gz –C ./ /* 解包 * / tar zcvf rootfs.tar.gz ./rootfs /* 打包 * /3.2用mknod创建设备节点
创建设备节点一般有两种方法,第一种是自动创建,利用udev(mdev)来实现设备文件的自动创建,这种比较占用启动时间。第二种是使用mknod手动创建,可以减少启动时间,使用cat /proc/devices查看申请到的设备名,设备号,然后使用以下命令创建设备节点:
mknod filename type major minor3.3关闭不使用的服务
系统默认会自启很多种服务,结合自身需求取消用不到的服务同样可以优化启动时间。这里以取消几种服务为例:
rm /etc/init.d/oprofileui-server /* 系统性能 * / rm /etc/init.d/bootlogd /* 日志 * / rm /etc/init.d/ofono /* 电话 * / rm /etc/init.d/neard3.4取消不需要的自启程序
init进程会调用/etc/rcS.d目录下Sxxxx之类的脚本文件(S是开头,然后是数字,之后是名称)从而实现开机自启程序的目的。可以将不需要的脚本文件直接删掉,也可以节省不少启动时间。



