目錄
一、vmlinux、vmlinuz、zImage、bzImage、uImage
二、initrd 和 initramfs
1、initrd(Initial RAM Disk)
2、initramfs(Initial RAM Filesystem)
3、initrd vs. initramfs 對比
4. 如何查看和生成 initramfs
三、SystemV 和 SystemD 的區別
一、vmlinux、vmlinuz、zImage、bzImage、uImage
vmlinux
是編譯出來的最原始的內核文件,未經壓縮的原始Linux內核可執行文件(ELF格式),包含調試符號,體積非常大。
主要用于內核調試(如用GDB分析崩潰),不直接用于啟動系統。
vmlinuz
vmlinux
的壓縮版本(名稱中的?z
?表示壓縮),去除了調試符號,體積更小,是bzImage/zImage文件的拷貝或指向bzImage/zImage的鏈接
實際用于系統啟動的通用內核文件名稱(如?/boot/vmlinuz-<version>
)
zImage
使用gzip壓縮的小型內核鏡像(適用于老式引導器),大小限制在約512KB
bzImage
Big zImage
,同樣壓縮但支持更大內核(現代x86系統的標準格式)
大多數x86架構系統的標準啟動文件(如?/boot/bzImage-<version>
)
uImage
uboot
專用的內核鏡像格式,在zImage/bzImage
前添加U-Boot頭(包含加載地址等信息)
嵌入式系統中使用U-Boot引導時必需的文件(如ARM開發板)
二、initrd 和 initramfs
initrd
(Initial RAM Disk)和?initramfs
(Initial RAM Filesystem)都是 Linux 內核在啟動過程中使用的臨時根文件系統,用于在掛載真正的根文件系統之前提供必要的驅動、工具和腳本。盡管它們的目的一致,但實現方式不同。以下是它們的區別、工作原理及使用場景:
1、initrd(Initial RAM Disk)
-
基于塊設備:
initrd
?是一個壓縮的磁盤映像(通常是?gzip
?壓縮的?ext2
?或?cramfs
?文件系統),由引導加載器(如 GRUB)加載到內存。 -
需要掛載:內核將其視為一個塊設備(如?
/dev/ram0
),并掛載為臨時根文件系統(/
)。 -
固定大小:需要預先分配固定大小的內存,可能導致資源浪費或空間不足。
工作流程
(1)引導加載器(如 GRUB)加載內核(vmlinuz
)和?initrd
?到內存。
(2)內核解壓?initrd
?并掛載為臨時根文件系統(/
)。
(3)initrd
?中的?/linuxrc
?或?/init
?腳本執行,加載必要的模塊(如磁盤驅動、LVM、加密等)。
(4)腳本掛載真正的根文件系統(如?/dev/sda1
),并切換根目錄(pivot_root
?或?chroot
)。
(5)真正的?init
?進程(如?systemd
?或?SysVinit
)接管,initrd
?被卸載。
由于其基于塊設備,效率較低。且大小固定不夠靈活,因此現代 Linux 系統已逐漸淘汰initrd,改用initramfs。
2、initramfs(Initial RAM Filesystem)
-
基于 tmpfs(內存文件系統):initramfs是一個?
cpio
?歸檔文件(通常用?gzip
?壓縮),直接解壓到內核的內存文件系統(tmpfs
)。 -
無需掛載:內核直接將其解壓到根文件系統,無需額外的塊設備驅動。
-
動態大小:按需使用內存,更高效靈活。
-
現代標準:從 Linux 2.6 開始成為默認機制。
工作流程
-
引導加載器?加載內核(
vmlinuz
)和?initramfs
?到內存。 -
內核將?
initramfs
?解壓到?tmpfs
?并作為初始根文件系統(/
)。 -
/init
(通常是 shell 腳本或?systemd
)執行,加載必要的驅動和工具。 -
掛載真正的根文件系統,并切換根目錄(
pivot_root
)。 -
真正的?
init
?進程接管,initramfs
?被釋放。
更快的啟動速度(無需掛載塊設備)。動態調整大小,節省內存。支持更復雜的早期用戶空間(如?
systemd
?在 initramfs 中運行)。
3、initrd vs. initramfs 對比
特性 | initrd | initramfs |
---|---|---|
存儲方式 | 塊設備(如?/dev/ram0 ) | tmpfs (內存文件系統) |
格式 | 磁盤映像(ext2 +gzip ) | cpio ?歸檔(gzip ?壓縮) |
掛載方式 | 需要掛載為塊設備 | 直接解壓到內存 |
大小 | 固定大小 | 動態調整 |
性能 | 較慢(需塊設備訪問) | 更快(直接內存訪問) |
現代使用 | 已淘汰(舊系統可能使用) | 現代 Linux 默認機制 |
4. 如何查看和生成 initramfs
(1)查看 initramfs 內容
lsinitramfs /boot/initramfs-$(uname -r).img
# 或
unmkinitramfs /boot/initramfs-$(uname -r).img /tmp/initramfs
(2)生成initramfs
# Debian/Ubuntu(使用 update-initramfs)
update-initramfs -u -k $(uname -r)# RHEL/CentOS(使用 dracut)
dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
(3)手動創建 initramfs
# 1. 創建一個簡單的 initramfs 目錄結構
mkdir -p initramfs/{bin,dev,proc,sys}
# 2. 復制必要的工具(如 busybox)
cp /bin/busybox initramfs/bin/
# 3. 創建 init 腳本(必須是可執行的)
echo -e '#!/bin/sh\nmount -t proc proc /proc\nexec /bin/sh' > initramfs/init
chmod +x initramfs/init
# 4. 打包成 cpio.gz
(cd initramfs && find . | cpio -H newc -o | gzip > ../initramfs.cpio.gz)
三、SystemV 和 SystemD 的區別
SystemV 和 SystemD 是 Linux 系統中兩種不同的初始化(init)系統,用于管理系統的啟動和服務。
特性 | SystemV?(SysV) | SystemD |
---|---|---|
啟動方式 | 順序執行腳本(串行) | 并行啟動服務 |
運行級別 | 0-6(如 runlevel3=多用戶模式) | 使用?target (如?multi-user.target ) |
服務管理 | /etc/init.d/ ?腳本 +?service /chkconfig | systemctl ?+?.service ?單元文件 |
日志管理 | 依賴?syslog | 內置?journalctl |
依賴管理 | 手動定義啟動順序 | 自動依賴解析 |
默認配置文件 | /etc/inittab | /etc/systemd/system/default.target |
根據Linux內核驅動流程,在架構有關的匯編代碼完成特定初始化后,會調用start_kernel開始內核的初始化工作;
- start_kernel函數中有關根文件系統掛載的簡要執行流程概述如下:
start_kernel→ vfs_caches_init()→ mnt_init()→ init_rootfs() // 注冊rootfs→ init_mount_tree() // 掛載rootfs到/→ rest_init()→ kernel_init()→ do_basic_setup()→ populate_rootfs() // 處理initramfs/initrd→ 檢查/init是否存在?→ 是:執行init_post() // 用戶空間接管→ 否:prepare_namespace()→ mount_root() // 掛載真實根文件系統→ sys_mount(".", "/", MS_MOVE) // 切換根目錄
- 其中,rest_init函數中依次創建了三個進程,idle進程,init進程以及kthreadd進程;
- kernel_init函數中調用do_basic_setup函數,解壓釋放initramfs類型文件系統到rootfs的根目錄,其中就必須包括
/init
可執行文件;
對于采用SystemV管理的系統
在系統啟動過程中,/init可執行文件通常是init程序本身,在制作initramfs根文件系統時,需要將init程序打包進去,并確保/init指向這個init程序。init程序啟動后,會讀取/etc/inittab文件來確定系統的默認運行級別,并執行相應的腳本。
具體步驟如下:
- 制作initramfs根文件系統時,將init程序打包進去。
- 創建/init到init程序的軟鏈接。
- init程序啟動后,讀取/etc/inittab文件,確定系統的默認運行級別。
- 根據運行級別,init程序會執行/etc/rc.d/rc script,該腳本會進一步調用/etc/rc.d/rc<number>腳本(其中<number>是運行級別)。
- /etc/rc.d/rc<number>腳本會啟動或停止相應的服務,以完成系統的初始化過程。
對于采用SystemD管理的系統,
- 實際上
/init
可執行文件是systemd的符號鏈接,所以在init_post函數中執行的用戶進程即為systemd; - 在制作initramfs根文件系統時,將systemd程序也打包進去,創建
/init
到systemd的軟鏈接,即可啟動systemd; - systemd啟動后,完成后續的linux操作系統加載過程。