2009/02/22

把二進位內容放進 shell script

貼過一篇 把文字檔放進 C 執行檔中。記得曾貼過類似下面的文章將二進位內容放進 shell 中,有興趣的人請看舊作建立自解壓檔一文,現在再來貼一次作法類似的文章。

分兩個檔,一個叫 addpayload.sh, 一個叫 install.sh.in, 前者如下:


#!/bin/bash

# Check for payload format option (default is uuencode).
uuencode=1
if [[ "$1" == '--binary' ]]; then
binary=1
uuencode=0
shift
fi
if [[ "$1" == '--uuencode' ]]; then
binary=0
uuencode=1
shift
fi

if [[ ! "$1" ]]; then
echo "Usage: $0 [--binary | --uuencode] PAYLOAD_FILE"
exit 1
fi


if [[ $binary -ne 0 ]]; then
# Append binary data.
sed \
-e 's/uuencode=./uuencode=0/' \
-e 's/binary=./binary=1/' \
install.sh.in >install.sh
echo "PAYLOAD:" >> install.sh

cat $1 >>install.sh
fi
if [[ $uuencode -ne 0 ]]; then
# Append uuencoded data.
sed \
-e 's/uuencode=./uuencode=1/' \
-e 's/binary=./binary=0/' \
install.sh.in >install.sh
echo "PAYLOAD:" >> install.sh

cat $1 | uuencode - >> install.sh
fi


install.sh.in 是個樣本檔,template file, 最後會產生 install.sh 才是加了二進位內容的 shell script....原文有執行例,請自行前往觀看怎麼執行。


#!/bin/bash

uuencode=1
binary=0

function untar_payload()
{
match=$(grep --text --line-number '^PAYLOAD:$' $0 | cut -d ':' -f 1)
payload_start=$((match + 1))
if [[ $binary -ne 0 ]]; then
tail -n +$payload_start $0 | tar -tzvf -
fi
if [[ $uuencode -ne 0 ]]; then
tail -n +$payload_start $0 | uudecode | tar -tzvf -
fi
}

read -p "Install files? " ans
if [[ "${ans:0:1}" || "${ans:0:1}" ]]; then
untar_payload
# Do remainder of install steps.
fi

exit 0

2009/02/09

QEMU 與 VirtualBox 的影像檔互換

QEMU img to VirtualBox vdi
代碼:
VBoxManage convertdd qemu.img qemu.vdi

或是
代碼:
./vditool DD qemu.vdi qemu.img


VirtualBox vdi to QEMU img
代碼:
./vditool COPYDD virtualbox.vdi virtualbox.img

initrd 機制

這篇文章是因為他寫的好,有在看我的文章的會比較容易找到。

cpio-initrd 的處理流程

1. boot loader 把內核以及 initrd 文件加載到內存的特定位置。

2. 內核判斷initrd的文件格式,如果是cpio格式。

3. 將initrd的內容釋放到rootfs中。

4. 執行initrd中的/init文件,執行到這一點,內核的工作全部結束,完全交給/init文件處理。

image-initrd的處理流程

1. boot loader把內核以及initrd文件加載到內存的特定位置。

2. 內核判斷initrd的文件格式,如果不是cpio格式,將其作為image-initrd處理。

3. 內核將initrd的內容保存在rootfs下的/initrd.image文件中。

4. 內核將/initrd.image的內容讀入/dev/ram0設備中,也就是讀入了一個內存盤中。

5. 接著內核以可讀寫的方式把/dev/ram0設備掛載為原始的根文件系統。

6. .如果/dev/ram0被指定為真正的根文件系統,那麼內核跳至最後一步正常啟動。

7. 執行initrd上的/linuxrc文件,linuxrc通常是一個腳本文件,負責加載內核訪問根文件系統必須的驅動, 以及加載根文件系統。

8. /linuxrc執行完畢,常規根文件系統被掛載

9. 如果常規根文件系統存在/initrd目錄,那麼/dev/ram0將從/移動到/initrd。否則如果/initrd目錄不存在, /dev/ram0將被卸載。

10. 在常規根文件系統上進行正常啟動過程 ,執行/sbin/init。

cpio-initrd的製作方法更加簡單

cpio-initrd的製作非常簡單,通過兩個命令就可以完成整個製作過程

#假設當前目錄位於準備好的initrd文件系統的根目錄下
bash# find . | cpio -c -o > ../initrd.img
bash# gzip ../initrd.img


傳統initrd的製作過程比較繁瑣,需要如下六個步驟

#假設當前目錄位於準備好的initrd文件系統的根目錄下
bash# dd if=/dev/zero of=../initrd.img bs=512k count=5
bash# mkfs.ext2 -F -m0 ../initrd.img
bash# mount -t ext2 -o loop ../initrd.img /mnt
bash# cp -r * /mnt
bash# umount /mnt
bash# gzip -9 ../initrd.img