Ramdisk簡介
先簡單介紹一下ramdisk,Ramdisk是虛擬于RAM中的盤(Disk)。對于用戶來說,能把RAM disk和通常的硬盤分區(如/dev/hda1)同等對待來使用,例如:
redice # mkfs.ext2 /dev/ram0
mke2fs 1.38 (30-Jun-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2048 inodes, 8192 blocks
409 blocks (4.99%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
2048 inodes per group
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first.??Use tune2fs -c or -i to override.
redice # mount /dev/ram0 /mnt/rd
redice # ls /mnt/rd
lost+found
redice # mount
/dev/hda2 on / type ext3
proc on /proc type proc (rw)
/dev/ram0 on /tmp/xxx type ext2 (rw)
當然,Ramdisk和硬盤分區有其不同的地方,例如RAM disk不適合作為長期保存文件的介質,掉電后Ramdisk的內容會隨內存內容的消失而消失。Ramdisk的其中一個優勢是他的讀寫速度高,能被用作需要高速讀寫的文件。但在2.6版本后,Ramdisk的這一作用開始被tmpfs(Virtual memory file system support)取代。
回到上面的例子,我們格式化了一個ramdisk(/dev/ram0)并且將其mount到/mnt/rd目錄下,那么這個Ramdisk有多大呢?先看一下:
redice # df -h /dev/ram2
Filesystem????????????容量??已用 可用 已用% 掛載點
/dev/ram0?????????????7.8M??1.0K??7.4M???1% /mnt/rd
從上面的信息看出,ramdisk有大約7.8M的可用空間。我們再試一下另外的文件系統,重新格式化成minix分區并掛接試一下:
redice # umount /mnt/rd
redice # mkfs.minix /dev/ram0
2752 inodes
8192 blocks
Firstdatazone=90 (90)
Zonesize=1024
Maxsize=268966912
redice # mount /dev/ram0 /mnt/rd
redice # df -h /dev/ram0
Filesystem????????????容量??已用 可用 已用% 掛載點
/dev/ram0?????????????8.0M??1.0K??8.0M???1% /mnt/rd
目前看出來了,的確是8M(這同時說明,EXT2文件系統本身要占用一定的存儲空間,相比之下minix文件系統要少些),這個空間是在編譯核心時就確定下來了,在設置Ramdisk時,有一個叫?Default RAM disk size?的參數決定默認情況下Ramdisk的大小。能通過核心命令行參數(ramdisk_size)來改動這個值,例如要設置Ramdisk的大小為16M,在grub中能用:
# grub.conf -
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Redice Linux
????????root (hd0,0)
????????kernel /vmlinuz ro root=LABEL=/ hdc=ide-scsi ramdisk_size=16384
????????initrd /initrd
這樣,Ramdisk的大小就變成16M了。這個參數是Ramdisk直接編譯到核心時才能使用的,如果Ramdisk編譯為模塊,則應該使用模塊參數來設置Ramdisk的大小:
redice # insmod rd rd_size=16384
編譯到核心時,能通過下面的一些核心命令行參數來設置Ramdisk:
ramdisk_size - ramdisk的大小(Kbytes);
ramdisk - 和ramdisk_size的作用相同;
ramdisk_blocksize - ramdisk的塊大小,默認情況為1024;
當以模塊的形式譯時,模塊支持以下幾個加載參數:
rd_size - 同上面的ramdisk_size或ramdisk參數;
rd_blocksize - 同上面的ramdisk_blocksize;
initrd
上面已提到,Ramdisk需要先格式化然后理能使用。那么,如果核心希望使用ramdisk該怎么做呢?于是initrd產生了,initrd全稱是?initial RAM disk?,他提供一種讓核心能簡單使用Ramdisk的能力,簡單的說,這些能力包括:
格式化一個 Ramdisk;
加載文件系統內容到Ramdisk;
將Ramdisk作為根文件系統;
我們能將initrd形像的比作
Norton Ghost
備份的硬盤分區,而Linux啟動階段的Ramdisk相當于一個未格式化的硬盤分區,核心能直接將initrd的內容釋放到一個未初始化的Ramdisk里,這個過程和Ghost恢復一個分區的過程十分相似。于是,相應的內容被加載到相應的Ramdisk中,同時,這個Ramdisk也被格式化成某種由initrd格式所表達的分區格式。
initrd和Ghost備份的分區有許多相似之處,例如,他有一定的大小,包含分區上的文件系統格式等。initrd支持的格式包括:
Ext2文件系統;
Romfs文件系統;
cramfs文件系統;
minix文件系統;
如果核心選擇了Gzip支持(通常這是默認的,在init/do_mounts_rd.c中定義的BUILD_CRAMDISK宏)還能使用Gzip壓縮的initrd。相關的代碼能在核心源碼?drivers/block/rd.c:identify_ramdisk_image?中找到。
制作initrd
制作initrd傳統的作法是通過軟盤(顯然過時了,不介紹了)、ramdisk或loop設備(/dev/loop)。通過ramdisk來制作的方法比較簡單(以ext2文件系統為例):
redice # mkfs.ext2 /dev/ram0
redice # mount /dev/ram0 /mnt/rd
redice # cp _what_you_like_??/mnt/rd????# 把需要的文件復制過去
redice # dd if=/dev/ram0 of=/tmp/initrd
redice # gzip -9 /tmp/initrd
這個過程也最能夠解釋initrd的本質,對于Linux來說,Ramdisk的一個塊設備,而initrd是這個塊設備上所有內容的“克隆”(由命令dd來完成)而生成的文件。核心中加載initrd相關的代碼則用于完成將相反的過程,即將這一個文件恢復到Ramdisk中去。
通過loop設備來制作initrd的過程:
redice # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一個4M的空白文件
redice # losetup /dev/loop0 /tmp/initrd????????????????????# 映射到loop設備上;
redice # mkfs.ext2 /dev/loop0??????????????????????????????# 創建文件系統;
redice # mount /dev/loop0 /mnt/rd
redice # cp _what_you_like_ /mnt/rd????????????????????????# 復制需要的文件;
redice # umount /mnt/rd
redice # losetup -d /dev/loop0
redice # gzip -9 /tmp/initrd
不過,目前已有了一些更好的工具來完成這些工作,包括genromfs(uClinux里常用的工具),genext2fs,mkcramfs等。這些工具提供了一些方便研發的新特性,例如,不必上面煩索的過程,只要將文件復制到某個目錄中,將其作為根目錄,即可生成initrd;另一個重要的改進是,這些工具都能以普通用戶的身份來生成initrd。
未完,待續…(補充有關怎么加載|ARM中怎么使用initrd作為根文件系統等)
鏈接和參考文件
文件
?
原文:http://czdj2000.yo2.cn/articles/linux%E4%B8%AD%E7%9A%84ramdisk%E4%B8%8Einitrd.html