1990 年代:前因——“硬盤太慢、驅動太多”
- 背景:早期 Linux 根文件系統要么在軟盤、要么在 IDE 硬盤,內核把對應的軟盤/IDE 驅動編進去即可順利掛載。
- 矛盾出現:隨著 SCSI、PCMCIA、USB、RAID 控制器等百花齊放,如果把所有可能的驅動都靜態編進內核,內核體積會爆炸;如果把驅動當模塊放在 /lib/modules,又陷入“掛載根文件系統需要根文件系統里的模塊”的雞與蛋問題。
- 解決思路:在內存里先偽造出一個“小硬盤”(ramdisk),把必備驅動、工具、甚至 fsck 都塞進這個內存盤;內核只要能識別內存本身,就能先掛 ramdisk,再從 ramdisk 里加載真正的存儲驅動,最后 pivot 到真正的根文件系統 。
這就是 ramdisk 技術誕生的直接原因——啟動階段的“驅動跳板”。
1995:首次實現——rd.c 與 ramdisk 的誕生
- 1995 年左右的內核 1.x/2.0,出現了最早的 rd.c;它把一段連續的物理內存注冊成塊設備 /dev/ramX,再通過 mke2fs 格式化就能當磁盤用。
- 特點:
– 大小在編譯時固定(默認 4 MB,最多 16 個設備);
– 需要完整走塊設備層,先格式化再掛載,浪費內存和 CPU;
– 掉電即失,只能放啟動時一次性數據 。
1999-2002:initrd 標準化——壓縮 cramfs/ext2 鏡像
- 為了解決早期 ramdisk 浪費內存的問題,社區把 ramdisk 做成壓縮鏡像(ext2、cramfs、romfs),由 bootloader 一次性讀入內存,內核解壓后掛載為臨時根文件系統。
- 這就是我們今天說的 initrd(initial ramdisk)。
- 啟動流程變為:
- bootloader 把內核 + initrd.gz 讀進內存;
- 內核啟動→解壓 initrd→掛載為 /→執行 /linuxrc 或 /init;
- /init 加載 udev、驅動、建立 /dev 節點→掛載真正的根文件系統→switch_root 。
- 局限性:鏡像大小固定,需要事先估算;解壓后仍占用整塊內存;腳本維護復雜。
2004-2006:initramfs 興起——ramfs/tmpfs 取代塊設備
- 內核 2.4/2.6 引入 initramfs,技術上基于 ramfs/tmpfs,而非塊設備。
- 區別:
– 不再是塊設備,而是直接利用 page cache 當文件系統,省掉一次格式化/緩存復制;
– 大小可變,按需增長,可回收;
– 使用 cpio 格式打包,可無縫嵌入內核鏡像(CONFIG_INITRAMFS_SOURCE);
– 啟動腳本統一為 /init,接口更簡單 。 - 結果:initrd 退出主流,initramfs 成為各大發行版的默認啟動機制。
2007-至今:brd 模塊、tmpfs 日常化
- 傳統 ramdisk 塊設備演化為 brd(block ramdisk,drivers/block/brd.c),仍保留在源碼,用于:
– 無盤機、嵌入式系統需要真正“磁盤”語義的場景;
– 測試塊層、文件系統完整性校驗等。 - 日常使用中,tmpfs 全面接管“內存當磁盤”的需求:
– /tmp、/run、/dev/shm 默認掛載 tmpfs;
– 讀寫速度 1 GB/s 以上,空間隨用隨還;
– 不再掉坑“固定大小、雙份緩存” 。
副作用與經驗教訓
- 掉電即失:曾有人把 MySQL 數據目錄放在 ramdisk 以求極速,結果斷電訂單歸零 。
- 內存是昂貴資源:ramdisk 占用不可回收的連續內存,tmpfs 則可用 swap、可回收,性價比更高。
- 安全場景:ramdisk 的易失性反而成為“解密后即焚”的理想場所,例如高安全級別下的臨時解密盤 。
一句話總結
ramdisk 最初是“為了啟動而偽造的磁盤”,后來變成“為了速度而犧牲容量”的利器,最終被 initramfs + tmpfs 取代——它完成了“啟動跳板”的使命,也留給我們一條寶貴經驗:內存不是保險箱,速度和安全必須權衡。