以下技术在盈鹏飞嵌入式的A40I/T3核心板(CoM-X40I)和主控板(SBC-X40I)上经过验证,欢迎 交流! CoM-X40I核心板和SBC-X40I主板见下图:
前言
此优化是基于全志V系列编码产品的启动优化,纯linux平台;
目标: 开机视频第一帧在3s内
启动优化主要分为以下几个部分:
- 时间统计
- 模块优化
(1)uboot
(2)linux内核
(3)linux驱动
(4)文件系统rootfs
(5)中间件
(6)应用程序
- 常规优化
时间统计
做这部分工作时,首先需要花一段时间分析linux系统开机启动整体流程,
包括按键响应、uboot启动、uboot到kernel切换、kernel启动、应用程序启动等;
这里就不详细分析这里的启动流程,主要分析耗时部分
1. uboot启动
这部分优化空间也不大,主要是可以裁剪不需要模块;
另外可以去掉开机动画模块,这个耗时比较大
2. init进程初始化
1、init进程到进入rcS | 1.19s | ||
a、run_init_process(execute_command) | 0.38s | ||
b、main.c进到init进程 | 0.767s | ||
2、udev | 0.59s |
这里耗时的原因是内核解压,数据拷贝导致的。
在init进程中加打印方法:
直接在output/build/busybox/init/init.c中加打印是不行的
必须将lichee\buildroot\dl\busybox-1.18.3.tar.bz2解压出来,修改init.c文件,再压缩之后mklichee
3. 统计驱动耗时模块
打开这个宏initial_debug,每个驱动的初始化起始时间和结束时间都打印出来了。有了这个时间,基本就可以确定哪些部分需要优化了。我的做法是只关注耗时10000us以上的驱动。
打开方法:linux-3.10\init\main.c中do_one_initcall函数中,将initcall_debug=1即可
统计如下:
驱动耗时模块(大于10000us) | ||||
vin_init | 摄像头 | 0.7775 s | ||
dm_init | 0.5887 s | |||
ohci_hcd_mod_init | 0.3747 s | |||
ehci_hcd_init | usb | 0.2895 s | ||
disp_module_init | 显示 | 0.1660 s | ||
init_kprobes | 0.1091 s | |||
sunxi_ion_module_init | ion | 0.0977 s | ||
sunxi_spi_init | spi | 0.0898 s | ||
init_module | 0.0648 s | |||
sunxi_wlan_driver_init | 网络 | 0.0619 s | ||
sunxi_mmc_driver_init | mmc | 0.0512 s | ||
customize_machine | 0.0488 s | |||
aw_pm_init | 0.0488 s | |||
inet_ini | 0.0430 s | |||
event_trace_init | 0.0420 s | |||
sunxi_uart_init | 0.0395 s | |||
chr_dev_init | 0.0318 s | |||
dm_bufio_init | 0.0303 s | |||
initcall bt_init | bt | 0.0293 s | ||
logger_init | 0.0253 s | |||
sunxi_internal_codec_driver_init | 0.0243 s | |||
init_sunrpc | 0.0226 s | |||
brd_init | 0.0223 s | |||
sunxi_bt_driver_init | bt | 0.0213 s | ||
ahci_sunxi_driver_init | 0.0208 s | |||
sunxi_budget_cooling_driver_init | 0.0195 s | |||
usb_init | 0.0195 s | |||
axp22_i2c_init | 0.0195 s | |||
axp22_regulator_initcall | 0.0195 s | |||
userscene_lock_init | 0.0195 s | |||
axp22_charger_initcall | 0.0187 s | |||
sunxi_sram_driver_init | 0.0182 s | |||
sunxi_keyboard_driver_init | 0.0143 s | |||
usb_serial_module_init | 0.0143 s | |||
nf_tproxy_init | 0.0140 s | |||
loop_init | 0.0133 s | |||
sunxi_rtc_driver_init | 0.0139 s | |||
tun_init | 0.0127 s | |||
hidp_init | 0.0119 s | |||
sun4i_mdio_driver_init | 0.0118 s | |||
hid_init | 0.0111 s | |||
ipgre_init | 0.0105 s |
模块优化
1. uboot
boot0 | 0.241 | 0.241 |
uboot | 3.714 | 0.803 |
uboot的优化空间也不大,不需要的模块已经被裁剪;
这里主要是对开机logo进行优化,暂时不开启bootlogo功能
2. linux内核
由上面时间统计数据可以看到,大部分耗时是在kernel解压部分,这里主要有几个方式进行优化:
(1)减少kernel大小
将不需要的驱动模块裁剪掉,减小kernel大小就会是使解压时间更快;
另外可将不是在启动阶段必须加载的驱动模块留在文件系统后面加载,减少kernel的运行和加载时间;
内核裁决可以参考之前写的帖子:
https://blog.csdn.net/jzwjzw19900922/article/details/103808476
https://blog.csdn.net/jzwjzw19900922/article/details/103822645
(2)使用Image替换zImage
zImage是压缩后的内核镜像文件,所以使用Image就省去的加载时的解压所消耗的时间(大概可以节省2~3秒的启动时间)。但若使用Image则应考虑NandFlash的空间是否够用
(3)提高spi传输效率
由于内核解压拷贝,都是通过SPI进行传输的,所以可以提升SPI传输效率;
例如: 将SPI单线模式改为双线模式,或者四线模式
测试效果: 可以提升几百ms时间
3. linux驱动
(1)耗时最多的视频输入模块
编译成模块放在后面加载
(2)裁剪不需要的驱动模块
(3)裁剪无线模块
WLAN和BT在menuconfig取消之后还有,只要把Network support中的wrieless取消掉之后,就可以彻底取消掉了
vin_init | 摄像头 | 编译ko加载 | 0.7775 s |
dm_init | 去掉 | 0.5887s | |
ohci_hcd_mod_init | 0.3747 s | ||
ehci_hcd_init | usb | 0.2895 s | |
disp_module_init | 显示 | 0.1660 s | |
init_kprobes | 断点调试 | 去掉 | 0.1091 s |
sunxi_ion_module_init | ion | 0.0977 s | |
sunxi_spi_init | spi | 0.0898 s | |
clocksource_done_booting | 0.0098 s | ||
init_module | 0.0648 s | ||
sunxi_wlan_driver_init | 网络 | 去掉 | 0.0619 s |
sunxi_mmc_driver_init | mmc | 0.0512 s | |
customize_machine | 0.0488 s | ||
aw_pm_init | 0.0488 s | ||
inet_init | 0.0430 s | ||
event_trace_init | 0.0420 s | ||
sunxi_uart_init | 串口 | 0.0395 s | |
chr_dev_init | 0.0318 s | ||
dm_bufio_init | 0.0303 s | ||
bt_init | bt | 去掉 | 0.0293 s |
logger_init | 0.0253 s | ||
sunxi_internal_codec_driver_init | 0.0243 s | ||
init_sunrpc | 0.0226 s | ||
brd_init | 0.0223 s | ||
sunxi_bt_driver_init | bt | 去掉 | 0.0213 s |
ahci_sunxi_driver_init | 0.0208 s | ||
sunxi_budget_cooling_driver_init | 0.0195 s | ||
usb_init | 0.0195 s | ||
axp22_i2c_init | 0.0195 s | ||
axp22_regulator_initcall | 0.0195 s | ||
userscene_lock_init | 0.0195 s | ||
axp22_charger_initcall | 0.0187 s | ||
sunxi_sram_driver_init | 0.0182 s | ||
sunxi_keyboard_driver_init | 0.0143 s | ||
usb_serial_module_init | 0.0143 s | ||
nf_tproxy_init | 0.0140 s | ||
loop_init | 0.0133 s | ||
sunxi_rtc_driver_init | 0.0139 s | ||
tun_init | 0.0127 s | ||
hidp_init | 0.0119 s | ||
sun4i_mdio_driver_init | 0.0118 s | ||
hid_init | 去掉 | 0.0111 s | |
ipgre_init | 0.0105 s |
4. 文件系统rootfs
这部分优化主要涉及到rootfs裁剪,可以查看之前的帖子
https://blog.csdn.net/jzwjzw19900922/article/details/103833615
5. 中间件
这部分由于涉及系统框架,优化可能会影响系统稳定性,所以不做优化
6. 应用程序
应用程序优化,主要包括以下几个部分
a. 出图程序逻辑优化,优先出图其它先不管
b. 编译优化,减小应用程序大小