loading linux img2a,嵌入式Linux中initrd的应用--浅析ramdisk、ramfs、initrd和initramfs
看到這樣的一句話很讓我費解,因為似乎我理解為這樣做能夠提高一點嵌入式linux啟動速度,我對此是非常地感興趣
自此,就開始了我的解惑之旅
首先需要知道的是ramdisk和ramfs
http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/Introducing-initramfs-a-new-model-for-initial-RAM-disks/
或者內(nèi)核源碼/Documentation/filesystems/ramfs-rootfs-initramfs.txt
從上述文章,大致可以了解到
ramdisk是一種基于ram的塊設(shè)備,ramfs是一種基于ram的文件系統(tǒng),開發(fā)ramfs的目的是因為ramdisk浪費了太多的內(nèi)存cache頁,ramfs是基于tmpfs的一個實例
順理成章,initrd是init ramdisk的縮寫,initramfs是init ramfs的縮寫
名稱里加了init前綴,代表它們具有了引導(dǎo)內(nèi)核啟動的功能
ramfs比ramdisk更加高效,自然initramfs也更加優(yōu)秀,是2.6內(nèi)核新加入的推薦使用的機(jī)制,雖然可能pc中g(shù)rub使用的內(nèi)核cmd
line參數(shù)是
kernel /vmlinuz-2.6.25-14.fc9.i686 ro
root=UUID=11d7ac51-2b45-489e-8a48-8d2a28e2c04e rhgb quiet
initrd /initrd-2.6.25-14.fc9.i686.img
,實際上使用的是initramfs,可以靠文件格式來區(qū)分。initrd是gziped的,initramfs是cpio的
剩下的部分就只說initrd了
首先是initrd的作用:內(nèi)核鏡像要盡可能小,所以不應(yīng)該靜態(tài)包含進(jìn)太多驅(qū)動模塊。但是Linux內(nèi)核啟動最后一步,創(chuàng)建init內(nèi)核線程,需要執(zhí)行的init程序或者腳本并不在內(nèi)核鏡像中,而在根文件系統(tǒng)中。根文件系統(tǒng)可能在硬盤、磁盤陣列、nfs、flash上,同時根文件系統(tǒng)的格式也是五花八門。此時,實在不想包含這么多驅(qū)動到鏡像的話,可以使用initrd作為一個過渡。
initrd本身的內(nèi)容就是一個精簡的根文件系統(tǒng),包含必備的目錄和程序,甚至也有一個init腳本或程序linuxrc
一切的一切,因為linux的高可定制性,一切隨你便。在pc上通常是后者
以pc上的為例,首先拷貝一個initrd-2.6.25-14.fc9.i686.img,防止破壞了它開不了機(jī)
然后將其備份改名為gz,解壓縮
[root@localhost boot]# mkdir /tmp/initrd
[root@localhost boot]# cp initrd-2.6.25-14.fc9.i686.img
/tmp/initrd/
[root@localhost boot]# cd /tmp/initrd/
[root@localhost initrd]# mv initrd-2.6.25-14.fc9.i686.img
initrd-2.6.25-14.fc9.i686.gz
[root@localhost initrd]# gunzip initrd-2.6.25-14.fc9.i686.gz
[root@localhost initrd]# ls
initrd-2.6.25-14.fc9.i686
[root@localhost initrd]# file initrd-2.6.25-14.fc9.i686
initrd-2.6.25-14.fc9.i686: ASCII cpio archive
(SVR4 with no CRC)
繼續(xù)解壓縮,查看其根目錄下的init腳本,其重要的地方都用加粗了
#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
echo Mounting sysfs filesystem
mount -t sysfs /sys /sys
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mkdir /dev/pts
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
mkdir /dev/shm
mkdir /dev/mapper
echo Creating initial device nodes
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mknod /dev/systty c 4 0
mknod /dev/tty c 5 0
mknod /dev/console c 5 1
mknod /dev/ptmx c 5 2
mknod /dev/tty0 c 4 0
mknod /dev/tty1 c 4 1
mknod /dev/tty2 c 4 2
mknod /dev/tty3 c 4 3
mknod /dev/tty4 c 4 4
mknod /dev/tty5 c 4 5
mknod /dev/tty6 c 4 6
mknod /dev/tty7 c 4 7
mknod /dev/tty8 c 4 8
mknod /dev/tty9 c 4 9
mknod /dev/tty10 c 4 10
mknod /dev/tty11 c 4 11
mknod /dev/tty12 c 4 12
mknod /dev/ttyS0 c 4 64
mknod /dev/ttyS1 c 4 65
mknod /dev/ttyS2 c 4 66
mknod /dev/ttyS3 c 4 67
echo Setting up hotplug.
hotplug
echo Creating block device nodes.
mkblkdevs
echo "Loading ehci-hcd module"
modprobe -q ehci-hcd
echo "Loading ohci-hcd module"
modprobe -q ohci-hcd
echo "Loading uhci-hcd module"
modprobe -q uhci-hcd
mount -t usbfs /proc/bus/usb /proc/bus/usb
echo "Loading ext3 module"
modprobe -q ext3
echo "Loading scsi_mod module"
modprobe -q scsi_mod
echo "Loading sd_mod module"
modprobe -q sd_mod
echo "Loading libata module"
modprobe -q libata
echo "Loading ata_generic module"
modprobe -q ata_generic
echo "Loading pata_acpi module"
modprobe -q pata_acpi
echo Waiting for driver initialization.
stabilized --hash --interval 250 /proc/scsi/scsi
echo "Loading ata_piix module"
modprobe -q ata_piix
echo Waiting for driver initialization.
stabilized --hash --interval 250 /proc/scsi/scsi
echo "Loading dm-mod module"
modprobe -q dm-mod
echo "Loading dm-mirror module"
modprobe -q dm-mirror
echo "Loading dm-zero module"
modprobe -q dm-zero
echo "Loading dm-snapshot module"
modprobe -q dm-snapshot
echo Making device-mapper control node
mkdmnod
modprobe scsi_wait_scan
rmmod scsi_wait_scan
mkblkdevs
echo Scanning logical volumes
lvm vgscan --ignorelockingfailure
echo Activating logical volumes
lvm vgchange -ay --ignorelockingfailure VolGroup00
resume /dev/VolGroup00/LogVol01
echo Creating root device.
mkrootdev -t ext3 -o defaults,ro
/dev/VolGroup00/LogVol00
echo Mounting root filesystem.
mount /sysroot
echo Setting up other filesystems.
setuproot
loadpolicy
echo Switching to new root and running init.
switchroot
echo Booting has failed.
sleep -1
首先,這里使用的是nash,不是bash、csh等常見shell。nash是專門為了init設(shè)計的,因為體積小。
pc機(jī)上的initrd不過只是一個過渡,所以在加載完了硬盤、ext3等驅(qū)動后,就迫不及待地要重新設(shè)置根文件系統(tǒng)了
首先mkrootdev指定最終的根目錄,參數(shù)跟grub的內(nèi)核啟動參數(shù)一致。接著mount
/sysroot將最終的根目錄先掛在到/sysroot
,setuproot開始將initrd中的/proc /dev /sys 中的資料轉(zhuǎn)移到
/sysroot ,
switchroot會開始轉(zhuǎn)換/sysroot
為最終的根文件系統(tǒng),完成后順便將initrd之前在ram中的一切清空。
(如果有/initrd 目錄的話就會把initrd掛載到該目錄下)
好了,扯了半天,終于能解釋最開始的疑惑了
initrd,或者initramfs,無論在pc還是嵌入式,都是可以選擇的,分3種情況
1 完全不要initrd
2 initrd作為最終的根文件系統(tǒng)
3 initrd作為過渡,由initrd的init來加載最終的根文件系統(tǒng)
(本文作者deep_pro http://hi.baidu.com/deep_pro/ 轉(zhuǎn)載請注明出處)
情況1,比如嵌入式linux靜態(tài)包含了nand flash驅(qū)動和jffs2驅(qū)動,指定內(nèi)核啟動參數(shù)
root=/dev/mtdblock2 rootfs=jffs2 rw console=ttySAC0,115200
init=/linuxrc
(使用busybox作為根文件系統(tǒng))
情況2,將根文件系統(tǒng)做成ramdisk鏡像,使用ubbot下載到0x30800000,內(nèi)核啟動參數(shù)
root=/dev/ram rw init=/linuxrc
initrd=0x30800000,8M console=ttySAC0,115200
注意,一旦使用了ramdisk作為內(nèi)核命令行參數(shù)root的參數(shù),root=/dev/ram那么就直接把
initrd當(dāng)做最終的根文件系統(tǒng)
情況3,pc常見,嵌入式linux也可見這樣的啟動參數(shù)
console=ttySAC0,115200 root=nfs nfsroot=192.168.1.9:/source/rootfs
initrd=0x10800000,0x14af47
也屬于情況3
對于arm平臺,如果bootloader不支持裝入initrd的話,可以使用bootpImage,這種復(fù)合鏡像會把內(nèi)核和initrd直接連接到一起。
現(xiàn)在看來,initrd作為最終的根文件系統(tǒng),將花費時間將initrd從flash讀入ram,同時對文件系統(tǒng)的讀寫不會寫入falsh
完全不要initrd,根文件系統(tǒng)一直存在于flash,如果根文件系統(tǒng)可寫,也將寫入flash
至于性能上的比較,還是經(jīng)驗不足啊
總結(jié)
以上是生活随笔為你收集整理的loading linux img2a,嵌入式Linux中initrd的应用--浅析ramdisk、ramfs、initrd和initramfs的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle安装 衍生进程已退出,lin
- 下一篇: c语言如何关闭线程,如何用C语言实现多线