========================= 基本常識 =========================
Linux系統基本啟動流程:
1、 CPU從ROM(如果有的話)的0x0地址開始讀取代碼,執行loader;
2、 Loader初始化ram,從rom中拷貝uboot或kernel的鏡像到ram的指定地址並執行;
3、 Uboot(如果有)拷貝kernel鏡像和dtb文件到ram的指定地址,並運行kernel;
4、 設置bootargs會被覆蓋,kernel啟動;
5、 Kernel自解壓;
6、 Kernel初始化;
7、 Kernel加載內置驅動程序,啟動硬件設備;
8、 加載文件系統,讀取並執行/etc/inittab.
========================= 快速啟動原理 =========================
一、 基本原理
1、 硬件IO時間;
2、 流程精簡;
3、 內核精簡;
二、 啟動流程分析
1、 0x0,一級loader,配置ram; à必須;
2、 拷貝uboot或kernel及dtb到ram; à必須,從ROM讀值,IO時間;
3、 Uboot(如果有)拷貝kernel和dtb; à可去除,直接跳過;
4、 設置bootargs,kernel啟動; à非必須,不占IO時間;
5、 Kernel自解壓; à可精簡,但會加長2的IO時間;
6、 Kernel初始化; à必須;
7、 Kernel加載內置驅動程序,啟動硬件設備; à可精簡,占大量IO時間;
8、 掃描ROM; à可去除;
9、 掛載文件系統; à必須,但為了8,可調整到2;
10、 讀取並執行/etc/inittab. à必須;
三、 基本思路
1、 Loader
- Loader存在的目的就是為了引導系統;
- 除非必要,不需要loader來驅動硬件,否則linux就沒有存在的必要;
2、 Kernel
- 必要的常識:Kernel的啟動只與CPU及ram有關;
- Kernel內嵌驅動,是為了應對固件掛載前必須要做的硬件IO操作;
3、 文件系統
- Kernel啟動時,文件系統不一定要從rom中讀取,也可以在ram中讀取;
- Rom在loader中已經能夠使用,可以趁這個時候把需要的東西一次性讀出,沒有必要占用kernel啟動的寶貴時間;
- 為了加速loader加載文件系統的速度,文件系統又可分為通用部分(<3mb)、固件部分,由kernel中的cramfs驅動加載啟動文件系統,先完成啟動任務,再從啟動文件系統中加載rom設備的驅動,再加載固件文件系統;
四、 調整后的啟動流程
1、 0x0,一級loader,配置ram;
2、 拷貝kernel(精簡),dtb,文件系統鏡像(精簡)到ram;
3、 設置bootargs,kernel啟動;
4、 Kernel自解壓;
5、 Kernel初始化;
6、 Kernel加載必須的驅動程序備;
7、 掛載通用文件系統;
8、 讀取並執行/etc/inittab;
9、 掛載固件,包括驅動程序、額外的應用軟件及LIB;
========================= 快速啟動配置 =========================
一、 精簡loader
思路:
1、 Loader的目的是為內核准備啟動的條件;
2、 Loader跳過准備運行環境的步驟,直接加載內核即可;
方法:
注:各大廠商的bootloader千差萬別,只能介紹大概的辦法
1、 如果官方工程有跳過uboot的方法,那么直接采用這種方法;
2、 若1不可取,則刪改uboot代碼,在進入uboot,硬件初始化結束后,不進行uboot用戶環境的初始化,直接使用源代碼加載和啟動鏡像;
效果:bootloader過程耗時減少;bootloader體積縮小;
二、 精簡kernel
思路:只保留啟動所必須的驅動程序即可,如cramfs的讀寫驅動,音頻驅動(開機音樂),其余驅動做成ko文件,放到文件系統中;
方法:
1、 make ARCH=arm menuconfig,砍掉不會用到的驅動;
2、 啟動時不需要的,但應用程序需要的驅動程序,設置為module,從內核剝離,;
3、 Busybox必須提供insmod功能;
效果:內核體積縮小,loadder加載kernel的時間縮短,kernel解壓縮時間縮短,kernel啟動到掛載文件系統的時間縮短;
三、 精簡rootfs(即制作通用部分)
思路:
只保留:1、busybox;2、通用的/etc配置文件;3、加載固件所需的驅動程序(rom相關);4、啟動任務所需要的文件(比如音頻播放器);5、相關運行庫;使用cramfs打包,體積約2.4mb;
效果:該文件系統可以直接在ram中運行,可以延遲加載rom驅動;
四、 制作固件
1、 剩余的所有文件全部封裝到固件系統中(ext4格式或ubi格式);
2、 但需要注意的是固件的/etc中需要有一個rc.local文件,當rootfs中定制的任務完成后,調用該文件啟動固件的任務;
3、 為了保持系統的正常運行,原/etc中的rcS文件在掛載固件后,要添加額外操作:
# 掛載固件
Mount /dev/*** /mnt
# 用固件的etc覆蓋通用的etc,應用固件的配置及恢復寫權限
Mount /mnt/etc /etc
# 用固件的var覆蓋通用的var,恢復讀寫權限
Mount /mnt/var /var
# 擴展lib搜索范圍到固件的/lib和/usr/lib,保證程序正常運行
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/lib:/mnt/usr/lib
# 執行固件的啟動配置腳本
/etc/init.d/rc.local
