嵌入式Linux 优化开机启动时间

1、 U-Boot快速启动优化。

修改延时bootdelay为0秒,可缩减bootdelay延时

bash 复制代码
bootdelay=0

2、关闭内核校验

uboot在启动内核前可能会校验内核镜像是否正确,如果内核镜像出错,在uboot阶段做不做校验,系统都会挂死,因此不做校验理论上不会出问题;

bash 复制代码
setenv verify n

2、修改random

由于random设备初始化太慢,应用程序调用random的函数时可能被阻塞,导致应用启动慢,因此可通过关闭crng_ready()功能从而缩短启动时间,关闭crng_ready()功能后启动时间可缩短2~3秒。

cpp 复制代码
drivers/char/random.c
/*
 * crng_init =  0 --> Uninitialized
 *      1 --> Initialized
 *      2 --> Initialized from input_pool
 *
 * crng_init is protected by primary_crng->lock, and only increases
 * its value (from 0->1->2).
 */
static int crng_init = 0; 
#define crng_ready() (likely(crng_init > 0))                                                                                                     
//#define crng_ready() (likely(crng_init > 1))

3、修改LPG

LPJ可以用来缩短每次启动时调用calibrate_delay()来校准loops_per_jiffy消耗的时间。这个时间开销与CPU频率无关,在典型的嵌入式硬件环境下会消耗300ms左右。LPJ值对于固定硬件平台应该是一致的,可以只计算一次,在后续的启动中就可以在启动参数中强制指定LPJ值,而跳过实际的计算过程。具体方法是:在正常启动后记录下内核启动信息中的"Calibrating Delay"数值,在启动参数中以"lpj=xxxxxx"的形式强制指定。

bash 复制代码
[    0.008286] Console: colour dummy device 80x25
[    0.012560] Calibrating delay loop (skipped), value calculated using timer frequency.. 24.00 BogoMIPS (lpj=120000)
[    0.022866] pid_max: default: 32768 minimum: 301
bash 复制代码
setenv bootargs rootwait console=ttyS0,115200 root=/dev/mmcblk1p1 lpj=120000

4、修改输出日志

在嵌入式设备中,调试口基本使用UART口,系统启动过程中,串口为同步输出,十分影响启动时间。例如115200,8N1(1位起始位,8位数据,无校验,1位停止位)的常用串口输出格式,有效数据速率为115200 / 10 = 11520 字节/秒。启动时串口每输出11K的字符,即需要消耗1秒的启动时间。减少启动串口的输出,能大大减少系统的启动时间。

4.1、减少内核日志输出

4.1.1、修改日志输出级别

bash 复制代码
setenv bootargs earlycon=nvt_serial,0x2f0280000 rootwait console=ttyS0,115200 libata.force=1.5 rootfstype=ext4 rw lpj=120000 loglevel=0

4.1.2、添加quiet输出

启动过程默认打开控制台输出启动消息,但是控制台尤其是基于帧缓冲的控制台会减慢启动速度。因此在嵌入式Linux产品中,将启动过程中的控制台设为静默状态,方法是在内核启动参数中加入"quiet"

bash 复制代码
setenv bootargs earlycon=nvt_serial,0x2f0280000 rootwait console=ttyS0,115200 libata.force=1.5 rootfstype=ext4 rw  lpj=120000 quiet

4.2、减少uboot日志输出

现在有些uboot会给出取消uboot日志输出的uboot指令。如果没有的话,我们可以直接修改uboot底层代码,取消uboot的日志输出。uboot的串口启动一般位于 drivers/serial, 根据时间情况修改即可

cpp 复制代码
drivers/serial/serial_ns16550.c
static void _serial_putc(const char c, const int port)
{
    if (uart_disable_anchor == 1)
        return; 

    NS16550_putc(PORT, c); 
}

5、内核修改

删除不需要的Uboot驱动和内核驱动配置,减少Uboot和内核的体积

6、文件系统修改

这一部分需要根据实际情况来修改。基本上需要优化的是内核加载文件系统到应用启动这一段的时间间隔,修改的方向大概是减少文件系统挂载的体积,修改挂载顺序,异步加载内核驱动,删除不必要的系统配置。

相关推荐
_upupup7 小时前
Linux的调试工具——gdb/cgdb
linux·服务器
JeJe同学7 小时前
Docker镜像导入、容器启动
linux·运维·docker
Jason_zhao_MR8 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
闲云野鹤在人间8 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
一个风轻云淡9 小时前
GCC 和 GDB命令简单解读
java·linux·前端
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
资料库0110 小时前
Linux 8个常见运维故障排查
java·linux·运维
零基础12310 小时前
Ubuntu 常用命令汇总
linux·运维·开发语言
Android系统攻城狮11 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
xiaoqiMikko11 小时前
Linux 实战(一):CentOS 7、Rocky 9、Ubuntu 24.04 三台真机实测 —— 认清系统、换源、装包的版本坑
linux·centos