前段時間因為嵌入式應用開發的需要,對linux進行了一次大幅度的裁減。由於是初次接觸linux啟動的核心部分,所以基本上還是對網上各種裁減 方案的拼湊和整理,包含自己理解的部分實在很少。總的來說效果不算理想,後面還有很長的路要走。
這裡就大致說說目前這個linux裁減方案的「雛形」吧。
1. 核心裁減
對linux核心部分的裁減主要根據實際需求進行了重編譯,去掉了大部分用不上的特性,以及實際硬體環境之外的裝置驅動。這一過程沒啥技術含量,就 不細說了。
2. initrd改造
常規的linux系統啟動過程中,initrd僅僅充當乙個臨時的rootfs,在載入實際的rootfs後即被解除安裝或轉移。出於精簡的考慮,我將 原rootfs併入了initrd,讓它直接充當rootfs,以節省啟動時間,並減小體積。(這個改造方案相對來說最簡單,也足以滿足實際需要)
改造的過程主要是基於原make install自動生成的initrd映象之上,進行以下「手術」:
(1) 用busybox的linuxrc替代原initrd中的初始化指令碼,並將原linuxrc指令碼中有用得上的初始化任務都合併至etc/inittab 中,以節省啟動時間。
(2) 因為要充當rootfs,所以還需為initrd新增linux啟動及執行所必須的一些資料夾和檔案(主要複製自原rootfs):
/dev
tty3 - tty10 終端會話裝置(console登入使用)
ttys0、ttys1 串列埠終端裝置(串列埠登入使用)
ptmx、pts 虛擬終端裝置(遠端登入使用)
/etc
fstab 載入裝置的配置檔案(後面詳述)
gettydefs 僅保留virtual console一項
group 僅保留root對應的項
hostname 包含本機的主機名
inittab 初始化指令碼(後面詳述)
issue 包含本機的全程登入歡迎文字
passwd 僅保留root對應的項
shadow 僅保留root對應的項
termcap 僅保留用於本地console及遠端登入的配置項
/etc/init.d
rcs 次級初始化指令碼(後面詳述)
/lib
libcrypt.so.1 登入認證(login)所需的庫檔案
/mnt
/proc
/sys
/tmp
/usr
/var
(3) 修改etc/fstab儲存裝置載入配置檔案,只包含下面四行:
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs size=512m 0 0
devpts /dev/pts devpts defaults 0 0
由於實際硬體環境的記憶體比較大,所以給臨時檔案系統分配的記憶體上限比較充裕
(4) 建立etc/inittab初始化指令碼。由於init模組採用了busybox的精簡版本,而它採用的inittab檔案格式較普通版本有一些區別,所以 特別按照busybox的格式重新編寫了。檔案較大,下面僅列舉其中的關鍵部分:
::sysinit:/bin/mount -a 載入etc/fstab中配置的所有儲存裝置
::sysinit:/bin/mkdir /dev/shm/var 在tmpfs中劃分用作var的部分
::sysinit:/bin/mkdir /dev/shm/tmp 在tmpfs中劃分用作tmp的部分
::sysinit:/bin/chmod 1777 /dev/shm/var 修改var為合適的許可權
::sysinit:/bin/chmod 1777 /dev/shm/tmp 修改tmp為合適的許可權
::sysinit:/bin/mount --bind /dev/shm/var /var 將/var繫結到tmpfs中
::sysinit:/bin/mount --bind /dev/shm/tmp /tmp 將/tmp繫結到tmpfs中
::sysinit:/bin/hostname -f /etc/hostname 從etc/hostname中讀取並設定主機名
::sysinit:/sbin/ifconfig lo 127.0.0.1 up 配置ip環迴介面
::sysinit:/sbin/telnetd 啟動telnet daemon
::sysinit:/etc/init.d/rcs 呼叫次級初始化指令碼(完成不能在inittab中進行的初始化任務)
::sysinit:/bin/mkdir /var/log 建立日誌資料夾
::sysinit:/bin/touch /var/log/messages 建立日誌檔案
::respawn:/sbin/syslogd -n -m 30 -c 載入迴圈緩衝模式的系統日誌daemon
::respawn:/sbin/klogd -n
::askfirst:/bin/login 在console建立登入程序
tty2::askfirst:/bin/login 在tty2-tty6上建立額外的登入程序
tty3::askfirst:/bin/login
...ttys0::respawn:/sbin/getty -l ttys0 115200 vt100 在串列埠com1上建立登入程序
tty10::respawn:/sbin/logread -f 將所有日誌列印輸出到tty10
(5) 建立etc/init.d/rcs次級初始化指令碼,包含以下內容:
注:由於試驗的方便,生成的initrd採用了ext2檔案系統。在實際應用中考慮換為cramfs(壓縮rom映象檔案系統),以進一步縮減映象 檔案體積並提高讀取效率。
3. boot loader修改
由於這個裁減方案僅僅使用了核心映象及initrd,保持了與標準引導方式的高度相容,因此適用於幾乎任何boot loader。由於裁減實驗中需要頻繁替換核心和initrd映象,因此使用了便於控制的grub,以提高實驗效率。如果最終方案採取flash作為映象 載體,則建議使用lilo,以提高相容性並節省空間。
為了與本方案中以initrd作為rootfs保持一致,boot loader的配置檔案中需要修改引導引數,指定「root=/dev/ram0」,無需其它額外的引數。
經過上述裁減,整個linux的啟動時間已經縮短到10s以內。核心+initrd的映象大小也不足3m,基本達到了預期的目標。後續會針對啟動的 各個環節作進一步的分析和優化,以期進一步縮短啟動時間。
嵌入式應用Linux裁減的初次嘗試
前段時間因為嵌入式應用開發的需要,對linux進行了一次大幅度的裁減。由於是初次接觸linux啟動的核心部分,所以基本上還是對網上各種裁減方案的拼湊和整理,包含自己理解的部分實在很少。總的來說效果不算理想,後面還有很長的路要走。這裡就大致說說目前這個linux裁減方案的 雛形 吧。1.核心裁減 對l...
嵌入式linux訊息佇列應用
在核心空間開闢一片區域,乙個程序將資料傳到另乙個程序,需要完成2次資料複製。第一次,將乙個程序的資料複製到核心中,即從使用者態轉到核心態。第二次,將核心的資料複製到另乙個程序,即從核心態轉到使用者態。與管道相比,簡化了對檔案的操作。第一步 建立乙個物件,msgget。需要定義佇列的鍵值,相當於ipc...
嵌入式系統應用
不論是日常生活中經常使用的家庭自動化產品 家用電器 手提 自動櫃員機 atm 還是各行各業的辦公裝置 現代化醫療裝置 航空電子 計算機網路裝置 用於工業 自動化和監測的可程式設計邏輯控制器 plc 甚至是娛樂裝置的固定遊戲機和可攜式遊戲機 等,都屬於嵌入式系統。歸納起來,嵌入式系統的應用領域可以包括...