/etc/rc.d/rc.sysinit 是 BSD 風格 init 系統中 **init 進程 (PID 1) 執行的第一個用戶空間腳本** (由 /etc/inittab 中 si::sysinit:/etc/rc.d/rc.sysinit 指定)。它在**切換到任何運行級別之前**運行,負責建立系統運行的最基本環境:文件系統可用、硬體可識別、時間同步、日誌就緒。無論進入單用戶 (1) 還是多用戶 (2/3/5),此腳本**必經且僅執行一次**。
echo "Mounting root device read-only..."
/bin/mount -n -o remount,ro /
ro 已將根 fs 以唯讀掛載。此處顯式 remount,ro 確保狀態一致。-n:不更新 /etc/mtab (此時根 fs 唯讀,寫入會失敗)。fsck 提供穩定、未被寫入的文件系統視圖。echo "Initializing swap partitions..."
/sbin/swapon -a
/etc/fstab 中類型為 swap 的條目並啟用。/sbin/fsck -A -a -C
# -A: 檢查 /etc/fstab 中所有 fs_passno > 0 的文件系統 (並行檢查不同磁碟)
# -a: 自動修復 (無需交互確認, 相當於 -y)
# -C: 顯示進度條 (針對 ext2/3/4)
if [ $? -gt 1 ]; then
# 返回碼 > 1 表示有錯誤已修復但需重啟, 或未修復的嚴重錯誤
echo "ERROR: Filesystem severely damaged. Manual fsck required."
PS1="(Repair filesystem)# "
export PS1
/sbin/sulogin # 進入單用戶 Shell 供管理員手動修復
/bin/umount -a -r # 只讀重掛載所有
/sbin/reboot -f # 強制重啟
fi
返回碼語義:0=無錯誤, 1=已修復錯誤, 2=需重啟, 4=未修復錯誤, 8=操作錯誤, 16=用法錯誤, 32=用戶取消, 128=共享庫錯誤。
echo "Remounting root device read-write..."
/bin/mount -n -v -o remount,rw /
echo "" > /etc/mtab
/bin/mount -f -o remount,rw /
mount -n -o remount,rw / 真正重掛載。echo "" > /etc/mtab 清空舊 mtab (舊系統用文件記錄掛載點,現代 systemd 用 /proc/self/mountinfo 替代)。mount -f -o remount,rw / 偽裝掛載,**僅更新 /etc/mtab 不實際調用系統調用**,補齊 mtab 記錄。echo "Mounting other local filesystems..."
/bin/mount -a -v -t nonfs
-a:掛載 /etc/fstab 中所有 noauto 未標記的項目。-t nonfs:排除網絡文件系統 (NFS/SMB),因網路尚未配置好。/home, /var, /opt 等分區可用。echo "Setting up hostname..."
/bin/hostname `cat /etc/HOSTNAME | cut -d . -f1`
/bin/domainname `cat /etc/HOSTNAME | cut -d . -f2-`
/etc/HOSTNAME (如 myserver.example.com)。cut -d . -f1 取第一段作主機名 (myserver)。cut -d . -f2- 取剩餘作域名 (example.com)。hostnamectl set-hostname 持久化,/etc/hostname 存主機名,域名由 DNS/搜索域決定。if [ -f "/etc/random-seed" ]; then
echo "Initializing random number generator..."
/bin/cat /etc/random-seed > /dev/urandom
rm -f /etc/random-seed
fi
rc.0 中 dd if=/dev/urandom of=/etc/random-seed) 寫入核心熵池。echo "Loading keymap..."
/usr/bin/loadkeys -d
-d 載入默認鍵盤映射 (通常為 defkeymap.map 或 us.map)。loadkeys /usr/share/kbd/keymaps/.../uk.map.gz。echo "Setting system time from hardware clock..."
/sbin/hwclock --hctosys --utc
--hctosys:Hardware Clock → System Time。--utc:假設 RTC 存儲 UTC 時間。**關鍵**:雙系統 (Windows/Linux) 環境下,Windows 預設 RTC 為本地時間,Linux 預設 UTC。需統一策略 (建議雙方皆用 UTC,或 Linux 設 --localtime),否則重啟時間漂移。echo "Starting system and kernel log daemons...."
/usr/sbin/syslogd
/usr/sbin/klogd -c3
syslogd:用戶空間日誌守護進程,接收應用/系統日誌,按 /etc/syslog.conf 寫入文件。klogd -c3:核心日誌守護進程,從 /proc/kmsg 讀取核心環形緩衝區日誌轉發給 syslogd。-c3 設定控制台日誌級別 (KERN_INFO=3,僅錯誤/警告輸出到控制台)。systemd-journald 統一接管,rsyslog/syslog-ng 作為後端轉發。# echo "Updating module dependencies..."
# /sbin/depmod -a
depmod -a 掃描 /lib/modules/$(uname -r)/ 建立 modules.dep 依賴索引,供 modprobe 使用。| rc.sysinit 階段 | Systemd 對應單元/機制 | 並行化優勢 |
|---|---|---|
| remount root ro | initrd 中完成,switch_root 前 | - |
| swapon -a | swap.target 引發 systemd-swap.service / fstab generator | 並行啟動 swap |
| fsck -A | systemd-fsck@.service (per-fs), fsck.target | **不同磁碟並行 fsck**,大幅縮短啟動時間 |
| mount -a nonfs | local-fs.target 依賴 .mount units (fstab generator) | 並行掛載獨立磁碟分區 |
| hostname | systemd-hostnamed, hostname.service (設定 /etc/hostname) | - |
| random-seed | systemd-random-seed.service (load/save) | - |
| loadkeys | systemd-vconsole-setup.service (vconsole.conf) | - |
| hwclock --hctosys | systemd-timesyncd / chronyd / ntpd (持續同步,非一次性) | 持續校準,非僅啟動時 |
| syslogd/klogd | systemd-journald.service (核心), rsyslog.service (兼容) | 日誌結構化、索引、轉發 |
| depmod | initramfs 打包時預執行,內核模組自動載入 (udev/kmod) | - |
rc.sysinit 以**線性串行邏輯**完成系統從「核心態」到「用戶態可用」的奠基工作。其核心價值在於:**嚴格的依賴順序 (ro根fs→fsck→rw根fs→本地fs→網路前置條件)、關鍵數據持久化 (隨機種子、硬體時鐘)、故障兜底 (fsck失敗進單用戶修復)**。Systemd 保留了這些邏輯依賴,但以**聲明式單元依賴圖**實現**最大化並行**,並引入 **Generator 機制** 自動將 fstab 轉換為 mount/swap/fsck 單元,實現了從「手寫腳本排序」到「自動拓撲構建」的躍遷。