全志Tina Linux 启动优化

本文转载自全志V853在线文档:https://v853.docs.aw-ol.com/soft/tina_boottime/

Tina Linux 启动优化

启动速度是嵌入式产品一个重要的性能指标,更快的启动速度会让客户有更好的使用体验,在某些方面还会节省能耗,因为可以直接关机而不需要休眠。

启动速度优化可提升产品的竞争力。对于某些系统来说,启动速度是硬性要求。

TinaLinux系统当前的启动流程如下:

brom --> boot0 --> (monitor/secure os) --> uboot --> rootfs --> app

brom 固化在 IC 内部,芯片出厂后就无法更改。

后续将从 boot0 开始分阶段介绍启动优化的方法。

BOOT0 启动优化

boot0 运行在SRAM ,主要功能是对 DRAM 进行初始化,并将 uboot 加载至DRAM

boot0 可优化的地方不多,可以做的是:

  • 关闭串口输出。

  • 减少检测按键和检测串口的等待时间。

  • 加载uboot的时候,不要先加载后搬运,直接加载到uboot的运行地址。

对于spinor的方案,还可以直接从boot0启动,只需要在boot0中加载好kerneldtb,不需要经过uboot,然后直接跳转到kernel运行,可节省一定的时间。

也可以开启双线/四线/DMA/Cache等优化储存器读取速度。

一般来说 boot0 占用的时间不多,基本不需要对其进行优化

Uboot启动优化

uboot 主要功能是引导内核、量产升级、电源管理、开机音乐/logo、fastboot刷机等。

提高 CPU 以及 flash 读取频率

可设置 uboot-board.dtssys_config.fex 中的 [target]boot_clock 来修改 uboot 运行时CPU频率(注:不能超过SPEC最大频率)。

对于 spinor/spinand,使用较高的时钟频率(一般是100M),使用四线模式或者双线模式(看硬件是否支持),提高加载速度。

关闭串口输出

可将 uboot-board.dtssys_config.fex 中的 [platform]debug_mode 设置为 0 来关闭 uboot 的串口输出。

可将 sys_config.fex 中的 [platform]debug_mode 设置为 0 来关闭 boot0 串口输出。

配置此项后,如果还有少量输出,有两个可能的原因:

  • 第一是这些输出是在获取 debug_mode 流程之前产生。

  • 第二是因为源码中直接使用了 puts 而没有使用 printf

对于这两者情况,需要修改源码来完全关闭串口输出。

修改 kernel 加载位置

如果 uboot 将内核加载到 DRAM 的地址与内核中 load address 不匹配,就需要将内核移动到正确位置,这样会浪费一定的时间。因此,可以直接修改 uboot 加载内核为正确的地址。

具体是修改 env.cfg 文件的 boot_normalboot_recovery 变量。

需要根据不同的内核镜像格式来设置不同的值

假设 kernelload address0x40008000

如果使用的是 uImage ,也就是在kernel的镜像前加了64字节,所以 uboot 应该将 kernel 加载到 0x40008000 - 0x40 = 0x40007fc0

#uImage/raw
boot_normal=sunxi_flash read 40007fc0 ${boot_partition};bootm 40007fc0
boot_recovery=sunxi_flash read 40007fc0 recovery;bootm 40007fc0

如果使用的是 boot.img,即 androidkernel 格式,其头部大小为 0x800 ,所以 uboot 应该将 kernel加载到 0x40008000 - 0x800 = 40007800

#boot.img/raw
boot_normal=sunxi_flash read 40007800 ${boot_partition};bootm 40007800
boot_recovery=sunxi_flash read 40007800 recovery;bootm 40007800

如果 uboot 加载 kernel 地址与 load address 不匹配,uboot 过程中串口输出可能会有:

Loading Kernel Image ... OK

如果是匹配的,uboot 过程中串口输出可能会有:

XIP Kernel Image ... OK

kernel 启动优化

通常来说,内核启动耗时较多,需要更深入的优化。

kernel 压缩方式

比较不同压缩方式的启动时间和flash占用情况,选择一种符合实际情况的。

此处给出某次测试结果供参考。实际优化的时候,需要重新测试,根据实际情况选择。

压缩方式内核大小/M加载时间/s解压时间/s总时间/s
LZO2.40.380.230.61
GZIP1.90.350.440.79
XZ1.50.252.172.42

加载位置

内核镜像可以由 kernel 自解压,也有 uboot 进行解压的情况。

对于 kernel 自解压的情况,如果压缩过的 kernel 与解压后的 kernel 地址冲突,则会先把自己复制到安全的地方,然后再解压,防止自我覆盖。这就需要耗费复制的时间。

比如对于运行地址为 0x80008000 的内核来说,bootloader 可以将其加载到0x81008000,当然其他位置也可以。

内核裁剪

裁剪内核,带来的加速是两个方面的。一是体积变小,加载解压耗时减少;二是内核启动时初始化内容变少。

裁剪要根据产品的实际情况来,将不需要的功能及模块都去掉。

具体是执行"make kernel_menuconfig",关闭不需要的选项。

initcall 优化

cmdline 中设置 initcall_debug=1 ,即可打印跟踪所有内核初始化过程中调用 initcall 的顺序以及耗时。

具体修改 env.cfg 配置文件, 新增一行"initcall_debug=1"

并在"setargs_*"后加入" initcall_debug=${initcall_debug}",如下所示。

setargs_nand=setenv bootargs console=${console} console=tty0 root=${nand_root} init=${init} loglevel=${loglevel} partitions=${partitions} initcall_debug=${initcall_debug}

加入后,内核启动时就会有类似如下的打印,对于耗时较多的initcall,可进行深入优化。

[    0.021772] initcall sunxi_pinctrl_init+0x0/0x44 returned 0 after 9765 usecs
[    0.067694] initcall param_sysfs_init+0x0/0x198 returned 0 after 29296 usecs
[    0.070240] initcall genhd_device_init+0x0/0x88 returned 0 after 9765 usecs
[    0.080405] initcall init_scsi+0x0/0x90 returned 0 after 9765 usecs
[    0.090384] initcall mmc_init+0x0/0x84 returned 0 after 9765 usecs

内核 module

需要考虑启动速度的界定,对于 内核module 的优化主要有两点:

  • 对于必须要加载的模块,直接编译进内核

  • 对于不急需的功能,可以编译成模块。

比如某个应用,会开启主界面联网,启动速度以出现主界面为准,那么可以考虑将disp编入内核,wifi编译成模块,后续需要时再动态加载。

rootfs 启动优化

initramfs

initramfs是一个内存文件系统,会占用较多DRAM。

部分产品可能会用到initramfs来过渡到rootfs,其优化思路大体与rootfs类似。可参考本节后续的优化方案。

rootfs类型以及压缩

存储介质、文件系统类型,压缩方式对rootfs挂载有很大影响。

此处给出某次测试结果供参考。实际优化的时候,需要重新测试,根据实际情况选择。

类型压缩介质总时间/s
squashfsgzipemmc0.12
squashfsxzemmc0.27
squashfsxznand0.26
ext4-emmc0.12

rootfs 裁剪

文件系统越小,加载速度越快。裁剪的主要思路是:删换压,即删除没有用到的,用小的换大的,选择合适的压缩方式。

指定文件系统类型

内核在挂载rootfs时,会有一个try文件系统类型的过程。可以在cmdline直接指定,节省时间。

具体是在cmdline中添加"rootfstype=<type>",其中type为文件系统类型,如ext4、squashfs等。

静态创建dev节点

对于dev下面的节点,事先根据实际情况创建好,而不是在系统启动后动态生成,理论上也可以节省一定的时间。

rootfs拆分

可以将rootfs拆分成两个部分,一个小的文件系统先挂载执行,大的文件系统根据需要动态挂载。

主应用程序启动优化
主应用程序主要是由用户开发,因此主导优化的还是用户,这里提一些优化措施:

  • 提升运行顺序。将应用程序放在init很前面执行。

  • 动态/静态链接。

  • 编译选项。

  • 暂时不使用的库采用dlopen方式。

  • 应用程序拆分。

开启Tina启动速度优化

在tina根目录下执行make menuconfig使能CONFIG_BOOT_TIME_OPTIMIZATION,具体如下所示

Tina Configuration
    └─> Target Images
        └─>[*] Boot Time Optimization

注:如果看不到该选项,使用?键搜索,会发现此项有一些依赖选项,使能依赖选项即可看到 Boot Time Optimization

实验结果

在某 norflash 方案上开启 CONFIG_BOOT_TIME_OPTIMIZATION 后,启动速度提升效果如下:

  • Linux内核镜像压缩方式从GZIP换成LZO,优化 > 0.2s。

  • rootfs从squashfs XZ压缩换成squashfs GZIP压缩,优化 > 0.15s。

  • 屏蔽boot0、uboot、kernel启动阶段控制台打印,优化 > 2s。

注:对于不同的方案,由于CPU运算速度、存储器类型、内核压缩及尺寸、根文件系统类型及尺寸、主应用等的不同,优化结果会有一定差异,请以实际优化结果为准。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值