做者:張華 發表於:2013-01-27 ( http://blog.csdn.net/quqi99 )html
運行一個linux系統須要三項內容:
1,kernel, 內核,一些核心的代碼塊,如進程管理,它要求體積很小。
2,initrd, 進入系統所需預告加載的硬件驅動module的一個最小集。當GRUB加載kernel時,kernel會在內存中將initrd文件mount到rootfs上激活,而後kernel照着initrd中的init一步一步地加載驅動。在initrd文件中所放入的模塊,必須是與操做系統同一版本kernel所編譯的模塊。init腳本的工做流程是:
initrd的參考文檔可見:
1) Linux initial RAM disk (initrd) overview, http://www.ibm.com/developerworks/linux/library/l-initrd/index.html
2) NTTdocomo-openstack / baremetal-initrd-builder, https://github.com/NTTdocomo-openstack/baremetal-initrd-builder
2.1, nash指令(一個文件小,內置了一些實用的指令)
2,2 掛載主要的文件系統, 並創建設備文件所需的文件系統
mount -t proc /proc /proc
mount -t sysfs /sys /sys
2.2.1,procfs映射着內存中的一個虛擬目錄,用於提供硬件、進程的實時信息,會隨時變更。linux爲保證穩定性,不容許訪問/proc下的文件,root用戶也不例外。
2.2.2, sysfs也映射着內存中的一個虛擬目錄,用於硬件信息的分類, sys目錄的每個文件都只有一個字符爲內容來作開關的。
2.2.3, tmpfs也映射着內存中的一個虛擬目錄,內存中的文件系統。想要速度快時,能夠選擇在內存創建tmpfs類型的文件系統,由於它都將建在內存中。
例如在內存中創建了一個tmpfs分區並掛載到/mnt/tmpfs目錄 :mount -t tmpfs -o size=50M tmpfs /mnt/tmpfs/
[root@zhanghua proc]# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 50M 0 50M 0% /mnt/tmpfs
2.2.4, /dev/shm,它是tmpfs的一種變種,tmpfs全部的內容所放在內存中,而/dev/shm在內存與文件系統有個映射,硬盤和內存中都會有這內容。
速度快,能存大於內存的文件,但重啓以後,內容會消失。
下面顯示在/dev/shm中創建文件與在普通ext4文件系統建文件的速度比較:
[root@zhanghua proc]# time dd if=/dev/zero of=/dev/shm/test.file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.0395221 s, 2.7 GB/s
real 0m0.075s
user 0m0.001s
sys 0m0.041s
[root@zhanghua proc]# time dd if=/dev/zero of=/bak/test.file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.0647526 s, 1.6 GB/s
real 0m0.090s
user 0m0.001s
sys 0m0.066s
2.2.5,devfs, 全部的device都會在/dev目錄創建一個對應的設備文件.
缺點是例如即便打印機沒連在計算機上,/dev/printer文件也會存在,這樣會形成在intrd階段的設備過多,因此devfs正在被udev所取代
例如要用光驅時,需先在linux與光驅之間經過 mount /dev/cdrom /mnt/命令作關聯
2.2.6, udev, udev能夠放在/sys目錄下,不須要將全部未使用的文件創建設備文件,再也不須要major number和minor number,當硬件被加載時可執行用戶設置的script。
例如,若是/dev/cdrom是被udev創建的,而非devfs,那麼當光驅被撥除時,/dev/cdrom文件就會消失。
2.2.7,/proc/PID文件,第一個進程都會對應這要閏個文件
2.2.8,/proc/partitions用來表示檢測到的硬盤信息, major字段表示SCSI controller的slot ID,minor字段表示分區ID。
#[root@zhanghua proc]# cat /proc/partitions
major minor #blocks name
8 0 488386584 sda
8 1 82051956 sda1
2.2.9, /sys/block,塊設備
#[root@zhanghua proc]# cat /sys/block/
loop0/ loop1/ sda/ sr0/
2.2.10, /dev/pts ( pseudo terminal slave) 副虛擬終端,其目錄的文件都是由ptmx(主虛擬終端)產生的,它們是父子關係。當用ssh聯機到localhost本地端以後,就會在
/dev/pts目錄下產生一個叫作"0"的文件,當別的console也利用ssh聯到這臺機器時,就會出現「1「.
[root@zhanghua proc]# ps -ef|grep ssh
hua 11186 3068 0 16:01 pts/0 00:00:00 ssh hua@localhost
hua 11195 11187 0 16:01 ? 00:00:00 sshd: hua@pts/3
如上,當一個用戶以ssh登陸以後,該用戶就分到一個ptmx所賦予的pts資源(pts/3),因此說ssh使用的是虛擬終端,不是真正的tty接口。telnet用的則是真正的tty接口。
2.2.11, /dev/mapper,若是使用LVM後,linux要和硬盤打交道時再也不直接使用/proc/partitions下的硬盤設備,而是使用/dev/mapper下的設備再去中轉。
# ls -l /dev/mapper/*
brw-rw---- 1 root disk 253, 0 jan 27 16.16 /dev/mapper/vg0-lv0
# cat /proc/partitions
major minor #blocks name
8 0 17528 sda
253 0 1111 dm-0
3,創建最初所需使用的設備文件
設備文件使用mknod指令創建,mknod指令用來創建字符(character)或塊(block)文件。
例:mknod /dev/tty1c41, 創建一個名爲tty1的設備文件,c表示是字符文件,major=4, minor=1
4,加載相關模塊
5,切入image所指示的硬盤中實體操做系統. (rescue mode是直接經過kernel加載initrd進入單純的內存開機的虛擬操做系統)
5.1, mkrootdev -t ext4 -o defaults.ro hda1, 即nash指令會將GRUB中所設備的root=xxx中的xxx路徑先創建好
5.2, mount /sysroot, 將GRUB中的root路徑mount到initrd中的/sysroot下。
5.3, switchroot這個nash指令將initrd中的/sysroot文件系統切換成/rootfs,從而切換到了硬盤中的文件系統。
3,image, 操做系統的image文件系統,當initrd被加載後,必須爲用戶與文件系統牽線。
4, init進程,在切入到用戶操做系統以後,首先執行linux的init進程(pid=1), init進程再去加載/etc/rc.d/init.d/functions從而啓動服務。
關於啓動級別與init進程的事兒,也可參見個人另外一博文件,Linux的運行級別與解決開機故障一例 ( by quqi99 ), http://blog.csdn.net/quqi99/article/details/7436926
5, 系統管理
5.1, 查看CPU信息 cat /proc/cpuinfo
5.2, 查看內存, cat /proc/meminfo 或者 free -m
5.3, 查看usb, lsusb
5.4, 查看PCI, lspci
5.5, 查看開機日誌, dmesg |grep -i error
本文講的是如何編譯kernel,接下來也會研究如何製做initrd與image.
最好使用普通用戶執行下面全部操做。
1,下載內核源碼
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
用git tag查看版本,將並代碼切換到v3.8-rc5下, git checkout v3.8-rc5
2,配置內核(有點相似於./configure), 配置前先安裝一個依賴包, sudo yum install ncurses-devel,
make menuconfig
說明一下,內核的配置項是三選一,yes, no, 或module。yes, no意味着直接將該特性編譯或不編譯到內核中,module意味着以模塊形式編譯,模塊意味着你開機會能夠通modprobe命令動態加載或卸載。
我在這裏選擇的默認配置,生成的配置位於根目錄下的.config文件之中。
若是你在一個老的配置文件上更改配置的話,能夠用make oldconfig命令比較與以前的配置文件的差別來驗證你配置的正確性。
3,執行make命令編譯,
make
說明一下,這條命令實際上已經包括了下面的命令:
1)肯定依賴性 make dep
2)清理編譯中間文件,make clean
3)編譯內核, make bzImage
4)生成模塊, make modules
4, 安裝模塊,下列命令會將模塊自動安裝到/lib/modules/3.8.0-rc5/目錄下.
sudo make modules_installlinux
5, 安裝內核及initrd,人工將arch/x86/boot/bzImage的內核文件拷到/boot目錄便可。
sudo cp arch/x86_64/boot/bzImage /boot/vmlinuz-3.8.0-rc5
sudo chmod a+x vmlinuz-3.8.0-rc5git
sudo update-initramfs -u -k version github
sudo update-grub -o /boot/grub/grub.cfg
注意:以vmlinuz-<version>這樣命名它。算法
上述三步等價於make install, 但make install在自動執行update grub命令時有時候會破壞你的grub文件,特別對於進行PGP加密過的硬盤。ubuntu
6,「可選」,安裝符號表,只有調試時才須要用到。符號表System.map用以將內核符號和它們的起始地址對應起來,調試的時候,若是須要把內存地址翻譯成容易理解的函數名和以及變量名,就會頗有用。vim
sudo cp System.map /boot/System.map-3.8.0-rc5
7, 創建initrd文件
sudo mkinitrd --with=ntfs -o /boot/initrd-linux3.8.0-rc5.img 3.8.0-rc5
以上mkinitrd命令是參照現有系統的/etc/modprobe.conf和/etc/fstab文件建立一個全新的initrd, 用--with=ntfs會從/lib/modules/3.8.0-rc5目錄將ntfs模塊也作到initrd裏去。
那如何要從頭開始作一個initrd呢?
1) 能夠用 sudo zcat initrd-linux3.8.0-rc5.img | cpio -id 命令解壓 ( initrd文件是以ext2做爲文件系統中,因此能夠用mount -o loop initrd.img /mnt命令加載.)
2) 而後將模塊ntfs.ko加到相應的目錄,如lib/modules/3.8.0-rc5/kernel/fs/ntfs目錄
3) 將ntfs.ko模塊加到init腳本
4) 從新壓縮,find | cpio -co | gzip -9 > initrd-new.img
8, 更新grub, 編譯/etc/grub/grub.conf文件,添加下面內容,注意千成不要用update grub命令來更新grub哦,這可能會致使你的雙系統沒法用。
menuentry 'Fedora,Linux 3.8.0' --class fedora --class gnu-linux --class gnu --class os {
set root='(hd0,msdos9)'
linux /boot/vmlinuz-3.8.0-rc5 root=/dev/sda10 ro quiet splash
initrd /boot/initrd-linux3.8.0-rc5.img
}
也能夠在開機時按e進入grub編輯模式,再按e一次進入kernel的設置界面:
grub> root (hd0,msdos9)
grub> kernel /boot/vmlinuz-3.8.0-rc5 ro root=/dev/sda9 acpi=off (注意,kernel在前的grub>光標後必定要空一行)
grub> initrd /boot/initrd-linux3.8.0-rc5.imgcentos
grub> bootbash
9, 下面講一下用於裸機的image的製做過程,須要將虛擬機磁盤系統(raw, qcow2, vhd等)往Linux識別的ext4格式轉換。架構
create raw disk
sudo kvm-img create -f raw /bak/kvmimages/ubuntutemplate.img 8G
install kvm virtual machine
sudo kvm -m 728 -cdrom/bak/kvmimages/ubuntu-11.04-desktop-i386.iso -drivefile=/bak/kvmimages/ubuntutemplate.img -boot d -nographic -vnc :0
use vnc to see: vncviewer192.168.99.100:5900
啓動虛機以後安裝一些如SSH,cloud-init等軟件
sudo apt-get install kvm-pxe
sudo kvm -m 728 -drivefile=/bak/kvmimages/ubuntutemplate .img -boot c -nographic -vnc :0
sudo apt-get install openssh-servercloud-init
sudo rm -rf/etc/udev/rules.d/70-persistent-net.rules #刪它,防止添加其餘網口
sudo shutdown -h now
調整鏡像, 由於openstack只接受ext4文件系統格式,故需將raw格式轉化成ext4
root@zhhua:/bak/kvmimages# sudo losetup -f --show /bak/kvmimages/ubuntucapture.img
root@zhhua:/bak/kvmimages# sudo losetup -a
/dev/loop0: [0809]:5770371(/bak/kvmimages/nova.img)
/dev/loop1: [0809]:5770373(/bak/kvmimages/ubuntucapture .img)
root@zhhua:/bak/kvmimages# sudo fdisk-l /dev/loop1
Disk /dev/loop1: 8589 MB, 8589934592bytes
255 heads, 63 sectors/track, 1044cylinders, total 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes/ 512 bytes
Disk identifier: 0x0009d391
Device Boot Start End Blocks Id System
/dev/loop1p1 * 2048 15286271 7642112 83 Linux
/dev/loop1p2 15288318 16775167 743425 5 Extended
/dev/loop1p5 15288320 16775167 743424 82 Linux swap
顯示分區是從扇區(sector)2048開始的,每一個扇區是512個字節,因此是從2048 x 512 = 1048576個字節開始的。記住這個1048576,下面會用到
卸載loop後從新從1048576字節開始掛載:
sudo losetup -d /dev/loop1
sudo losetup -f -o 1048576 /bak/kvmimages/ubuntucapture.img
把這整個分區拷貝到一個新文件就是一個咱們要的ext4文件系統鏡像
sudo dd if=/dev/loop1 of=/bak/kvmimages/ubuntutemplate.img
用完loop後記得卸載,sudo losetup -d /dev/loop1
掛載剛建立的ext4根文件系統,修改分區加載表(/etc/fstab),註釋或刪除之前的,加上「LABEL=my-rootfs / ext4 defaults 0 0」一行,
最後,別忘了運行下列命令將塊設備的卷標修改爲咱們上面設置的my-rootfs, sudo tune2fs -L my-rootfs /bak/kvmimages/ubuntutemplate.img:
sudo mount -o loop /bak/kvmimages/ubuntutemplate.img /mnt
sudo vi /mnt/etc/fstab
#UUID=98a4bc39-82a9-4d20-abf8-4aef654c1268 / ext4 errors=remount-ro 0 1
UUID=my-rootfs / ext4 defaults 0 0
# swapwas on /dev/sda5 during installation
UUID=3afdd9f7-7e1e-4172-ae32-7407b0559c51none swap sw 0 0
把內核(vmlinuz)和initrd文件拷貝出來以便後面和虛擬機鏡像一塊兒發佈到OpenStack雲裏。使用完虛擬機鏡像後記得卸載(unmount):
sudo cp /mnt/boot/vmlinuz-2.6.38-8-generic /bak/kvmimages/boot/
sudo cp /mnt/boot/initrd.img-2.6.38-8-generic /bak/kvmimages/boot/
sudo umount /mnt
整個過程是,initrc或者initramfs都是一個運行在內存的小根文件系統,它有一個叫init的腳本,作完一些準備工做以後,如加載硬件的驅動,而後會切換到鏡像所在的新根文件系統上,下面就是一個intramfs中init腳本的例子:
#!/bin/sh
mount -vt proc proc /proc #不少工具都讀proc的數據,故先加載
mount -vt sysfs sysfs /sys #加載內核文件系統
insmod scsi_mod #要切換到鏡像的新根文件系統,固然要先加載硬件用的scsi驅動模塊
insmod libata
insmod ata_piix
insmod sd_mod
mdev -s 或者echo /sbin/mdev > /proc/sys/kernel/hotplug #可使用busybox的mdev生成動態的udev文件,也可使用hotplug技術在加載模塊的時候再加載相應的設備
mount /dev/sda /mnt #加載硬盤,或者直接加到根目錄/中
exec switch_root /mnt /sbin/init #經過exec會讓鏡像中的init進程徹底替換initramfs中的init進程的空間來切換根文件分區
/bin/sh #若是上述切換根文件分區失敗,還可使用initramfs的sh進程,不然會panic
因此說,這個鏡像應該是linux內核直接能夠認的文件系統格式,如ext4, 直虛機使用的文件格式像raw, qrow2等須像如上方式轉換到ext4等格式。這樣也就能夠直接經過dd命令將鏡像拷到/dev/sda硬盤中了(gunzip -c /mnt/sda1/hda.img.gz | dd of=/dev/hda conv=sync,noerror bs=64K)
想把整個硬盤備份到外部存儲移動硬盤中的話:
1,加載移動硬盤,mount -t vfat /dev/sda1 /mnt/sda1
2,dd備份,dd if=/dev/hda conv=sync,noerror bs=64K | gzip -c > /mnt/sda1/hda.img.gz
3, 恢復,gunzip -c /mnt/sda1/hda.img.gz | dd of=/dev/hda conv=sync,noerror bs=64K
顯然, dd的缺點是備份整個硬盤分區,無論它是否是真用了。有個叫再生龍的工具(Clonezilla)就是來克服這個缺點的。下面是它的介紹:
Clonezilla是一個很好的系統克隆工具,它基於Partimage,吸收了Norton Ghost和Partition Image的優勢。即不只支持對整個系統進行克隆,並且也能夠克隆單個的分區,這種靈活性可能更能適應備份者的須要.支持GNU/Linux的文件系統 ext二、ext三、reiserfs、xfs、jfs和Windows的FAT、FAT3二、NTFS文件系統.Clonezilla支持使用 PXEBoot來進行Multicast克隆.這對於須要克隆大量系統的用戶極爲有用. Clonezilla 比起Ghost For Linux(簡稱G4L)有一個很顯著的優點就是Clonezilla支持的文件系統格式比G4L多之外Clonezilla只備份數據,而G4L卻將整個分區都備份了(即包含空數據),因此G4L將比Clonezilla佔用更多的用於存放備份鏡像的空間。
或者咱們使用另外一種方式製做OpenStack鏡像(即根文件系統),例如linux-0.2.img是一個採用kvm虛機安裝的raw格式的鏡像,如今將它轉成linux內核認識的ext4格式的根文件系統。
1, sudo mkdir -p /mnt/{raw,ext4} && sudo mount -o loop linux-0.2.img /mnt/raw
2, dd if=/dev/zero of=linux-0.2.ext4 bs=1M count=22
mkfs.ext4 linux-0.2.ext4
sudo mount -o loop linux-0.2.ext4 /mnt/ext4
3, sudo cp -r /mnt/raw/* /mnt/ext4/
直接用raw格式的作鏡像也是能夠的,那樣就不須要轉換了,glance add name="CentOS-6.4-x86_64" is_public=true container_format=ovf disk_format=raw < CentOS-6.4-x86_64.img
最後,現看一下如何掛載raw和qcow2格式的KVM硬盤鏡像
raw格式
對於未分區鏡像文件直接使用loop:
mount -o loop image.img /mnt/image
已分區的鏡像文件:
若是已知分區的起始位置
mount -o loop,offset=32256 image.img /mnt/image
或者使用losetup + kpartx
losetup /dev/loop0 image.img
kpartx -a /dev/loop0
mount /dev/mapper/loop0p1 /mnt/image
kpartx命令的做用,是讓Linux內核讀取一個設備上的分區表,而後生成表明相應分區的設備。
kpartx -l imagefile 能夠查看一個映像文件中的分區,使用 kpartx -a imagefile 命令後,就能夠經過 /dev/mapper/loop0pX (其中X是 分區號)來訪問映像。
qcow2格式
對於qcow2格式須要使用qemu-nbd這個工具
modprobe nbd max_part=63
qemu-nbd -c /dev/nbd0 image.img
mount /dev/nbd0p1 /mnt/image
若是是LVM格式的鏡像:
vgscan
vgchange -ay
mount /dev/VolGroupName/LogVolName /mnt/image
最後使用結束需釋放資源:
umount /mnt/image
vgchange -an VolGroupName
killall qemu-nbd
kpartx -d /dev/loop0
losetup -d /dev/loop0
initrd 的英文含義是 boot loader initialized RAM disk,就是由 boot loader 初始化的內存盤。在 linux內核啓動前,boot loader 會將存儲介質中的 initrd 文件加載到內存,內核啓動時會在訪問真正的根文件系統前先訪問該內存中的 initrd 文件系統。在 boot loader 配置了 initrd 的狀況下,內核啓動被分紅了兩個階段,第一階段先執行 initrd 文件系統中的"init or linuxrc",完成加載驅動模塊等任務,第二階段纔會執行真正的根文件系統中的 /sbin/init, Linux2.6既支持cpio-initrd,也支持image-initrd,可是cpio-initrd有着更大的優點,在使用中咱們應該優先 考慮使用cpio格式的initrd.
Initrd 的主要用途
linux 發行版必須適應各類不一樣的硬件架構,將全部的驅動編譯進內核是不現實的,initrd 技術是解決該問題的關鍵技術。Linux 發行版在內核中只編譯了基本的硬件驅動,在安裝過程當中經過檢測系統硬件,生成包含安裝系統硬件驅動的 initrd,是一種便可行又靈活的解決方案。
1.解壓 initrd
# file initrd.`uname –r`.img (察看格式,不一樣的linux操做系統,這個文件格式也有不一樣,這個文件格式多是cpio 也多是ext2)
若是是cpio格式 :
# mkdir /mnt/tmp
# cd /mnt/tmp
# cpio -idmv </tmp/initrd.`uname -r`.img
2 壓縮initrd
2.1 mkinitrd
#cd /lib/modules/`uname -r`
#mkinitrd /tmp/initrd.`uname -r`.img `uname -r`
#cd /tmp
#mv initrd.`uname –r`.img initrd.`uname –r`.img.gz
(initrd使用gzip壓縮,若是不更名字的話,後面沒法解壓縮) #gunzip initrd.`uname -r`.img.gz
2.2 cpio
#假設當前目錄位於準備好的initrd文件系統的根目錄下
第一種方式,老的-c選項,用的是ascii碼備份方式.
# find . | cpio -c -o > ../initrd.img
# gzip ../initrd.img
第二種方式,新的.已經測試可用的方式.
#cd /root/busybox-1.15.3/rootfs9260
#find . | cpio -H newc -o > ../initrd_cpio.img
#cd ../
#cp initrd_cpio.img initrd_cpio_bk.img -f
#gzip initrd_cpio.img -f
#/home/u-boot-1.1.5/tools/mkimage -A arm -T ramdisk -C none -O linux -a 0x600000 -e 0x600000 -d initrd_cpio.img.gz /home/ramdisk.uboot
#ls /home/ramdisk.uboot -al
上面cpio命令的 -H 選項指定打包文件的具體格式,要生成initramfs,只能用newc 格式,若是使用其餘格式,
內核會打出這樣的出錯信息:Unpacking initramfs...<0> kernel panic - not syncing: no cpio magic
或者出現:Unpacking initramfs...<0>Kernel panic - not syncing: bad gzip magic numbers。 若是採用了-c舊的ascii碼備份方式,則內核會按照ramdisk的方式加載根文件系統。
若是你在編譯內核時選上了RAM block device support (在device drivers -> block devices裏),
也能夠啓動成功,但這就失去了cpio-initrd的意義了!。
再就是注意cpio-initrd的初始進程是 「/init」,ramdisk方式初始進程是"/linuxrc"。
另外若是採用cramfs格式的根文件系統,也需在編譯內核時選上RAM block device support。
2.3 gen_init_cpio
獲取 gen_init_cpio,工具 ,gen_init_cpio是編譯內核時獲得的,
在內核源代碼的 usr 目錄下,咱們能夠經過 如下步驟獲取它,進入內核源代碼 執行 :
# make menuconfig
# make usr/
這樣即編譯好gen_init_cpio,
gen_initramfs_list.sh 在內核源代碼的 script 目錄下,
將這兩個 文件 copy 到 /tmp 目錄下,/tmp/initrd 爲 解壓好的 initrd 目錄,執行如下命令 製做initrd :
#製做initrd :
# gen_initramfs_list.sh initrd/ > filelist
# gen_init_cpio filelist >initrd.img
# gzip initrd.img
# mv initrd.img initrd-'uname –r’.img
只有用這個方式壓縮的initrd ,在Linux系統重啓的時候才能 一正確的文件格式 boot 起來,也能夠用
這種方式修改安裝光盤的initrd文件 而後 進行系統安裝。
3. 如何在 initrd 中添加新的驅動,以 ahci.ko 爲例
3.1 gen_init_cpio
# cp initrd-‘uname –r‘.img /tmp/initrd;cd /tmp/initrd
# cpio –ivdum < initrd-‘uname –r’.img;
# mv initrd-‘uname –r’.img ../
# cd /tmp/initrd
# vim init加上一行 insmod /lib/ahci.ko
# cp ahci.ko lib/
# cd /tmp
# gen_initramfs_list.sh initrd/ > filelist
# gen_init_cpio filelist >initrd.img
# gzip initrd.img
# mv initrd.img initrd-‘uname –r’.img
至此,新的initrd文件initrd-‘uname –r’.img中就包含了ahci的驅動程序了 ,這種方式是最簡單有效的。
3.2 mkinitrd
(1) Add 「alias scsi_hostadapter ahci」 at /etc/modprobe.conf
(2) copy ahci.ko to 「/lib/module/$(kernel-version)」/kernel/drivers/scsi」
(3) mkinitrd initrd.img ‘uname -r’
至此,新的initrd文件initrd-‘uname –r’.img中就包含了ahci的驅動程序了 .
#釋放cpio格式的initrd:
mv initrd.img imitrd.img.gz
gunzip initrd.img.gz
cpio -i --make-directories < initrd.img
#釋放centos6.2系統的initramfs.img
1."gunzip initrd.img-2.6.27-7-generic.gz",獲得一個未壓縮的initrd.img-2.6.27-7-generic
2. 」cpio -iv <initrd.img-2.6.27-7-generic",提取成功
#製做cpio格式的initrd(新2012年使用過的)
# cd /root/busybox-1.15.3/rootfs9260 # find . | cpio -H newc -o > ../initrd_cpio.img
#製做cpio格式的initrd(2009年製做的LFS的方式):
dd if=/dev/zero of=/tmp/rootfs bs=1k count=35000
losetup /dev/loop0 /tmp/rootfs
mkfs.ext2 –F –i 2000 /tmp/rootfs
mkdir /tmp/loop
mount –o loop /tmp/rootfs /tmp/loop
#而後將剛纔創建的基本系統拷貝到/tmp/loop
cp /lfs/* /tmp/loop –arfp
find . | cpio –o –H newc | gzip –c > /tmp/initrd.img
紅帽(Red Hat)從Enterprise Server 6.2 開始,啓動鏡像文件initrd.img 開始改用xz 工具進行壓縮,這與以往版本是有區別的。
1、啓動鏡像initrd.img 文件
類RedHat 系統從vmlinuz 核心引導後,會讀取initrd.img 啓動鏡像。該文件中包含驅動模塊等信息,是很是重要的文件。不一樣版本使用的格式不一樣。
1.RHEL 4.0 版本
採用ext2 文件格式鏡像,再經過gzip 壓縮:
2.RHEL 5.0 版本
採用cpio 打包鏡像,再經過gzip 壓縮:
3.RHEL 6.2 版本
RHEL 6.0 - 6.2 都採用與RHEL 5.0 相同的格式進行打包,但從6.2版本開始,改用LZMA 進行壓縮。詳見:Release Notes for Red Hat Enterprise Linux 6.2 Edition 2。
以下:
※ 注意,若在低於RHEL 6.2 版本下執行file 命令,可能沒法識別LZMA 壓縮格式:
這時,可把file 軟件包升級到5.04-13.el6 便可。
2、xz 工具簡介
xz 工具是LZMA 壓縮算法的一個實現。具體可見:Wikipedia
可見,Windows 下可以使用7-Zip 打開.xz 文件。LZMA 算法比Gzip 算法壓縮率更高。幾個參數:
3、手動修改initrd.img 文件
解壓:
壓縮:
3、補充tar.lzma
因爲LZMA 具備優秀的壓縮率及佔用資源少的特色,愈來愈多的工具採用lzma進行打包,後綴名爲:tar.lzma。
對於Fedora 11 及之後的版本,可使用下面的命令操做:
壓縮
解壓:
若是是CentOS 5.3 等老版本,須要安裝獨立的lzma 工具或用xz 進行:
壓縮:
解壓(兩個方式均可以):
光盤中的initrd.img
位置isolinux/initrd.img
1 解壓縮
file後發現是xz文件
將initrd.img更名,更名爲Initrd.img.xz
爲何要更名?由於不更名xz會叫喚,說你胡塞給我什麼文件啊?我不解壓縮
file initrd.img
mv initrd.img initrd.img.xz
unxz initrd.img.xz
解壓縮完成。
結果:生成一個initrd.img,和原始文件比,這個文件是個cpio後的文件
2 cpio解出來
file initrd.img(第一步解壓縮出來的名字)
發現是cpio
cpio -i -d < initrd.img
結果:生成全部文件系統,主要是usr, etc, lib等目錄
2.6內核中的initrd.img採用cpio壓縮,再也不是2.4內核使用的ext2格式,沒法使用mount -o loop 掛載。須要使用gunzip解壓縮,而後再使用cpio解包
cp /boot/initrd-***.img initrd.img.gz
gunzip initrd.img.gz
mkdir initrd
mv initrd.img initrd
cd initrd
cpio -ivmd ../initrd.new.img
gzip ../initrd.new.img
再將其更名拷貝至/boot目錄,重啓就能夠觀察修改後的效果。重啓後沒法成功引導。這是由於生成的initrd.img不對。解決以下:
生成initrd
find . | cpio -o -H newc | gzip > /mnt/sda1/boot/initrd.img-2.6.18-4-686
(注:-H newc 是必須的,不然內核會認爲是ramdisk,而不是initramfs)
Extract
gunzip < /boot/initrd.img | cpio -i –make-directories
Repack
find ./ | cpio -H newc -o > initrd.cpio
gzip initrd.cpio
mv initrd.cpio.gz initrd.img
Uncompress:
mkdir initrd
cd initrd zcat ../initrd.img | cpio -idmv
Compress:
find . | cpio -o -c | gzip -9 > ../initrd.img
initrd.img解壓:
[root@CentOS5 ~]# mkdir /usr/src/initrd
[root@CentOS5 ~]# cp /boot/initrd-2.6.18-308.el5.img /usr/src/initrd
[root@CentOS5 ~]# cd /usr/src/initrd
[root@CentOS5 initrd]# ls
initrd-2.6.18-308.el5.img
[root@CentOS5 initrd]# mv initrd-2.6.18-308.el5.img initrd-2.6.18-308.el5.img.gz
[root@CentOS5 initrd]# gunzip initrd-2.6.18-308.el5.img.gz
[root@CentOS5 initrd]# cpio -i -d < initrd-2.6.18-308.el5.img
[root@CentOS5 initrd]# rm -rf initrd-2.6.18-308.el5.img
[root@CentOS5 initrd]# ls
bin dev etc init lib proc sbin sys sysroot
initrd.img打包:
[root@CentOS5 initrd]# find . -print|cpio -o -H newc > ../initrd-2.6.18-308.el5.img
[root@CentOS5 initrd]# cd ..
[root@CentOS5 src]# gzip -9 initrd-2.6.18-308.el5.img
[root@CentOS5 src]# mv initrd-2.6.18-308.el5.img.gz initrd-2.6.18-308.el5.img
[root@CentOS5 src]# ls
initrd-2.6.18-308.el5.img
*initrd.img打包也可採用以下命令:
[root@CentOS5 initrd]# find . | cpio --quiet -H newc -o | gzip -9 -n > ../initrd-2.6.18-308.el5.img.gz
[root@CentOS5 src]# mv initrd-2.6.18-308.el5.img.gz initrd-2.6.18-308.el5.img
[root@CentOS5 src]# ls
initrd-2.6.18-308.el5.img
Ubuntu的initrd.img能夠在/boot中找到,一般文件名後面還跟有很長的一串版本號。
爲了保險起見,不直接操做原文件,而是把它複製到本身的家目(home)錄中。若是你是用root賬號登陸的,家目錄就在/root中,若是是用wsxx登陸的,家目錄通常就在/home/wsxx中,一般登陸以後自動就到了家目中。咱們把initrd.img複製但家目中進行解壓:
cp /boot/initrd.img-2.6.15-ubuntu-r6 ./initrd.img.gz
上面這個命令把/boot區中的文件複製到當前目錄,並改名爲initrd.img.gz。一方面改爲短文件名好一點好操做,另外一方面加上gz的後綴更清楚代表它本來就是一個gzip壓縮出來的文件。http://www.ccthere.com/article/825480
而後解壓:
gunzip initrd.img.gz
也能夠:http://www.ccthere.com/article/825480
gzip -d initrd.img.gz
二者結果是相同的,都是在當前目錄獲得一個解壓後的initrd.img,原來的initrd.img.gz被刪除掉了(這也許是linux整潔的優勢)。
如今這個更大的initrd.img要用cpio解開,成爲一系列目錄和文件。爲了避免與當前目錄中現有的文件搞混,咱們有必要新建一個目錄,把initrd.img解壓到新目錄中去。未來把裏面的文件修改好以後,還要把全部的目錄文件再打包起來:http://www.ccthere.com/article/825480
mkdir initrd #創建目錄
cd initrd #進入目錄
cpio -i -d < ../initrd.img #解開上層目錄中的initrd.img http://www.ccthere.com/article/825480
由於已經進入到initrd中,../initrd.img表示上層目錄中的initrd.img。
如今就能夠看到initrd中各目錄中有不少新的目錄和文件了。在這裏咱們能夠窺視到ubuntu是如何裝配起來的。能夠對其中的內容進行修改了。
http://www.ccthere.com/article/825480
修改文本文件沒有什麼好多說的了。
修改以後,就是壓縮回去,用它來啓動,檢驗是否能夠正常啓動,是否達到預期的修改目的。先用cpio打包:
http://www.ccthere.com/article/825480
find . | cpio -o -H newc > ../myinitrd.img #打包當前目錄中的全部目錄和文件,到上層目錄中的myinitrd.img
cd .. #回到上層目錄
gzip -9 myinitrd.img #gzip的最高級壓縮http://www.ccthere.com/article/825480
獲得的myinitrd.img.gz就是新的Ubuntu啓動文件了。
作到這裏,要有必要停下來看看一看,比較一下從新壓縮以後的文件,是否和原來的initrd.img.gz差很少大小?都應該是4M多的文件。若是文件大小相差太多,可能就有問題。我用Ubuntu文件解壓後在壓縮回來,用不一樣的文件名,最後比較,大小徹底一致,內心就踏實了。
http://www.ccthere.com/article/825480
再用Gentoo的initramfs文件進行一樣方法的操做,2M多的文件解壓再壓縮回來,只剩下不到1K了,本身也不相信這是對的。
==================== End