如何定制Linux外圍文件系統?
一般來說,我們所說的 Linux系統
指的是各種基于 Linux Kernel
和 GNU Project
的操作系統發行版。為了掌握 Linux
操作系統的使用,了解 Linux
操作系統的運作過程,理解內核與外圍支撐系統的關系,加深對開源操作系統的認識,我決定造個輪子——自己定制一個 Linux
文件系統。
這里有兩種實現方法:
- 直接自己實現
init**\*(M1)***
加載bios 的硬件信息-> 讀取MBR –>執行Grub ->加載kernel–> 加載驅動–> init –> 執行bash
- 利用系統
/sbin/init**\*(M2)***
加載bios 的硬件信息-> 讀取MBR –>執行Grub ->加載kernel–> 加載驅動–> init –> /sbin/init -> 取得run-level信息 -> /etc/rc.d/rc.sysinit -> services –> /etc/rc.d/rc.local –> mingetty –> login
我們先選擇 *M1 *。
思路
- 利用原有系統復制必備部件到新存儲器
- 利用
initrd.img
機制在RAM Disk
中測試 - 搭配原文件內核和模塊啟動
Step1:獲得shell版本的initrd.img
首先,我們可以寫一個腳本 init
,使得內核用該文件系統啟動后能夠直接獲得一個 Bash
。
創建腳本 init
其中: /bin
目錄下是常用命令, init
是自己寫的腳本, /lib64
目錄下是應用程序所依賴的動態庫。
init 內容
現在我們需要使用命令行,創建 bin
和 sbin
目錄,向其中添加 bash
、 ls
、 rm
、 cp
、 mv
、 echo
、 cat
、 less
等基礎命令。由于這些命令需要依賴 /lib64
等目錄下的一些動態鏈接的共享庫,所以需要將依賴的庫拷貝到小系統對應的目錄下,用 ldd
命令查詢應用程序及其依賴的動態庫。完成之后,執行:
find . | cpio -H newc -o | gzip > /boot/initrd.img
將根文件系統打包成 initrd.img
放到 /boot
目錄下。啟動時系統會自動執行 initrd.img
中的 init
。
費了這么大勁生成 initrd.img
,如何測試新建的 initrd.img
呢,需要在 grub
啟動配置文件當中增加一個入口用于測試。
title CentOS 6 Mini
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64
initrd /initrd.img
這樣重啟之后就會出現啟動選項了。
Step2:完成掛載原系統能力
為了能掛載原系統,必須在 initrd.img
中加載原系統運行所必須的驅動模塊,比如 ext4
文件系統的驅動、 scsi
設備的相關驅動等, /sbin/modinfo
配合 /sbin/insmod
,驅動放到 /module
Step3:完成擁有管理設備能力(udev)
利用管理、監控主機設備的服務程序udevd來自動加載所需的驅動模塊,比我們自己實現更加可靠。 udevd
的規則文件在 /lib/udev/
目錄下,配置文件在 /etc/udev/
目錄下,同時還需要 /etc/nsswitch.conf
配置的名稱服務交換,其依賴的庫為 /lib
目錄下以 libnss
開頭的文件,將上述文件拷貝到我們的目錄下,然后使用 /sbin/start\_udev
命令可以啟動 udevd
服務。( udevd
需要調用一些其他的系統命令,如 /sbin/modprobe
,可用 strace
進行跟蹤獲取)。
小系統的目錄文件
其中: /dev
目錄下是系統存放可用設備的目錄, /log
是使用 strace
命令生成的 log
記錄文件。
Step4:完成擁有login登錄能力
由于 login
的機制比較復雜,涉及進程管理機制和進程組、控制臺等許多方面,因此我們采用 *M2 *,將 /sbin/init
命令拷到小系統目錄下, init
腳本改為
#!/bin/bash
exec /sbin/init
將控制權交給 /sbin/init
之后,系統啟動時就必須等到它完成一系列調用之后,進入 login
界面,用戶才能重新獲得控制權。
/sbin/init
的過程大致分為三塊:***塊是udevd加載驅動模塊、文件系統檢查和根切換,相關配置在 /etc/rc.sysinit
中;第二塊是啟動各項服務,相關配置在 /etc/rc.d/
目錄下;第三塊是登錄部分,需要調用 /sbin/mingetty
和 /bin/login
等命令。將上述所涉及的命令及文件拷貝到小系統對應的目錄下,并對配置進行修改。
由于小系統啟動之后 initrd.img
作為臨時根文件系統直接在內存中運行,而我們小系統不需要進行根切換,故將 /etc/rc.sysinit
中 remount\_needed()
函數體注釋掉,這樣就不會根切換了。
由于系統采用了全新的 Upstart
啟動方式( /sbin/init
程序已經改由 upstart
軟件包提供),將與 Upstart
啟動相關的配置文件拷貝至小系統目錄下:
/etc/inittab 配置默認運行級別
/etc/init/rcS.conf 加載rc.sysinit腳本,完成系統初始化任務
/etc/init/rc.conf 兼容腳本,負責各運行級別的調用處理
/etc/init/rcS-sulogin.conf 為單用戶模式啟動/sbin/sushell環境
/etc/init/control-alt-delete.conf 控制終端下的Ctrl+Alt+Del熱鍵操作
/etc/init/start-ttys.conf 配置tty終端的開啟數量、設備文件
/etc/sysconfig/init 控制tty終端的開啟數量、終端顏色方案
/etc/init/tty.conf 控制tty終端的開啟
將 bootmini/etc/inittab
的運行優先級改為2,那么系統啟動時 /sbin/init
將執行 bootmini/etc/rc.d/rc2.d/
目錄下以 S
開頭的文件,將一些不需要開啟的服務文件名改為 K
開頭。
在 bootmini/etc/rc.d/rc.local
文件中可以加入用戶需要系統開機啟動后自動執行的操作。
login
程序基于認證體系 PAM
, 配置文件在 /etc/pam.d/
目錄下,相關庫文件有 /lib64/security/
及其依賴的庫文件; login
還涉及用戶組管理 /bin/chgrp
、 /bin/chown
、 /bin/chmod
等,保存用戶名的文件 /etc/passwd
、 /etc/group
,用戶密碼文件為 /etc/shadow
。其他一些涉及的文件可通過 strace
來幫助分析。
可在真機上運行的完整版小系統
部分目錄文件:
/etc
/bin
/sbin
/usr/bin
/usr/sbin
至此,文件系統算是可以跑了。