自製LiveCD 簡要過程 - Linux

Mason avatar
By Mason
at 2017-07-29T11:52

Table of Contents

以下介紹讓livecd多些便利性的改進

LiveCD中的grub/custom.cfg 可以利用grub 的search指令
加入類似如下數行 可以找到另一顆hd上的*.cfg 在那裡做變化 可以增加未來彈性
如multiboot 或掛載hd上的OverlayFS 做為增修用cd 上的 squash用
可以等到穩定後 再將整個OverlayFS 存成新的squash 做成新的cd

=============
# hooks.cfg
device_label=overlayfs_rw
hook=boot/grub/grub_hook.cfg # 未來可以在這裡放multiboot, overlay 等等
search --label --set=HOOK_DEV $device_label
if [ -f ($HOOK_DEV)/$hook ]; then
source ($HOOK_DEV)/$hook
fi
=============

如果有用squashfs, grub也可用loopback這個指令 從裡面挖到vmlinuz,initrd
這樣就不用copy出來了 (以前不知道浪費好多時間)
配合前小段search的方法 假設找到boot device 為($BOOT_DEV)

=============
#inside some boot menu of the grub.cfg

insmod squash4
set loop_file=livecd.squashfs # your file name here
loopback some_name ($BOOT_DEV)/$loop_file
linux (some_name)/boot/vmlinuz-xxx.xxx.xx
initrd (some_name)/boot/initrd-xxx.xxx.xx

=============

然後 我想要grub也能從 OverlayFS中 挖到正確的新的vmlinuz與initrd 用來boot
因為之前要掛載overlayfs時 已經都參數化 由grub傳給initrd/linuxrc了
所以grub也能由這些參數挖到vmlinuz與initrd來boot

方法就是前兩小段的search+loopback指令
就是做些苦工把可能的地方 依照優先順序去找
找到後 存在$VMLINUX, $INITRD 這兩個變數中

先舉例用法, grub scripts 後列
set vmlinuz=vmlinuz-x.x.xx # 要用的版本
set initrd=initrd-x.x.xx
export vmlinuz
export initrd
set ovl_dev0=LIVECD # 假設grub能看得到device 只是要告訴它label name
set ovl_mnt0=/loops # 掛載點
set ovl_loopfile0=livecd.squashfs #cd 裡面的loopfile
set ovl_mnt0_sub=/lower # squash 掛載點
set ovl_dev1=overlay_rw # hd partition label
set ovl_mnt1=/rw # hd 掛載點
set ovl_loopfile1= # rw 也可以是hd 上的 loopfile
set ovl_mnt1_sub= # rw loopfile 掛載點
#參數設好後 用下面的function找
get_vmlinux_initrd "$ovl_dev0" "$ovl_mnt0" \
"$ovl_loopfile0" "$ovl_mnt0_sub" \
"$ovl_dev1" "$ovl_mnt1" \
"$ovl_loopfile1" "$ovl_mnt1_sub"
echo "vmlinux: $VMLINUX" # 找到後存在這
echo "initrd : $INITRD"
sleep 2
echo 'Loading vmLinux...'
linux $VMLINUX rootfstype=overlay \
ovl_dev0=LABEL=$ovl_dev0 ovl_mnt0=$ovl_mnt0 \
ovl_loopfile0=$ovl_mnt0/$ovl_loopfile0 \
ovl_mnt0_sub=/$ovl_mnt0_sub \
ovl_dev1=LABEL=$ovl_dev1 ovl_mnt1=$ovl_mnt1 \
root=overlay ro # mount_move init_opts=1
echo 'Loading initrd...'
initrd $INITRD # 用找到的地方boot, 其他一長串參數 請參看之前
# boot loop device 的po 文



以下是 get_vmlinux_initrd 函式列表
===========================
### BEGIN functions ###
set VMLINUX=''
set INITRD=''

function is_there {
echo is_there "${1}"
if [ -d "${1}" ]; then
if [ -z "$VMLINUX" -a -e "${1}/$vmlinuz" ]; then
set VMLINUX="${1}/$vmlinuz"
echo VMLINUX "${VMLINUX}"
export VMLINUX
fi
if [ -z "$INITRD" -a -e "${1}/$initrd" ]; then
set INITRD="${1}/$initrd"
echo INITRD "${INITRD}"
export INITRD
fi
echo
fi
sleep 1
}

#${1}
#ovl_dev0
#ovl_mnt0=/loops
#ovl_loopfile0=g-squash_mini/g-squash_mini.xz.squashfs
#ovl_mnt0_sub=/loops/g-squash_mini/lower
#ovl_dev1
#ovl_mnt1=/loops
#ovl_loopfile1=g-squash_mini/g-squash_mini.rw.ext2
#ovl_mnt1_sub=/loops/g-squash_mini/rw
function get_vmlinux_initrd_ovl {
echo
echo 'get_vmlinux_initrd_ovl'
echo "${1}, ${2}, ${3}, ${4}, ${5}, ${6}, ${7}, ${8}."
while [ -z "$VMLINUX" -o -z "$INITRD" ]; do
if [ -n "${5}" ]; then
search --no-floppy --label --set=OVL_DEV1 "${5}"
echo ovl_dev1 "$OVL_DEV1"
fi
if [ -n "$OVL_DEV1" ]; then
if [ -f "($OVL_DEV1)/${7}" ]; then
echo loopback loop1 "($OVL_DEV1)/${7}"
loopback loop1 "($OVL_DEV1)/${7}"
is_there "(loop1)/upper/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
else
if [ -z "$VMLINUX" -a -z "$INITRD" ]; then
loopback -d loop1
fi
fi
fi
if [ -n "${8}" ]; then
is_there '("$OVL_DEV1")/"${8}"/upper/boot'
fi
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "($OVL_DEV1)/upper/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
fi
if [ -n "${1}" -a "${1}" != '(LOOP_ENTRY)' ]; then
search --no-floppy --label --set=OVL_DEV0 "${1}"
echo ovl_dev0 "$OVL_DEV0"
fi
if [ -n "$OVL_DEV0" ]; then
if [ -f "($OVL_DEV0)/${7}" ]; then
echo loopback loop1 "($OVL_DEV0)/${7}"
loopback loop1 "($OVL_DEV0)/${7}"
is_there "(loop1)/upper/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
else
if [ -z "$VMLINUX" -a -z "$INITRD" ]; then
loopback -d loop1
fi
fi
fi
if [ -n "${8}" ]; then
is_there "($OVL_DEV0)/${8}/upper/boot"
fi
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "($OVL_DEV0)/upper/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
if [ -f "($OVL_DEV0)/${3}" ]; then
echo loopback loop0 "($OVL_DEV0)/${3}"
loopback loop0 "($OVL_DEV0)/${3}"
is_there "(loop0)/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
elif [ -n "${4}" -a -d "(loop0)/boot/${4}" ]; then
is_there "(loop0)/boot/${4}"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
else
is_there "(loop0)"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
if [ -z "$VMLINUX" -a -z "$INITRD" ]; then
loopback -d loop0
fi
fi
elif [ -n "${4}" ]; then
is_there "($OVL_DEV0)/${4}/lower/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
is_there "($OVL_DEV0)/${4}/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
is_there "($OVL_DEV0)/${4}"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
else
is_there "($OVL_DEV0)/lower/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
is_there "($OVL_DEV0)/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
is_there "($OVL_DEV0)"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
fi #[ -f "($OVL_DEV0)/${3}" ]
fi # [ -n "$OVL_DEV0" ]
if [ -f "${1}/${3}" ]; then
echo loopback loop_lower "${1}/${3}"
loopback loop_lower "${1}/${3}"
is_there "(loop_lower)/boot"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
elif [ -n "${4}" -a -d "(loop_lower)/boot/${4}" ]; then
is_there "(loop_lower)/boot/${4}"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
elif [ -z "$VMLINUX" -o -z "$INIDRD" ]; then
is_there "(loop_lower)"
if [ -n "$VMLINUX" -a -n "$INIDRD" ]; then
break;
fi
if [ -z "$VMLINUX" -a -z "$INITRD" ]; then
loopback -d loop_lower
fi
fi
fi
break
done
sleep 1
# play 240 440 1 524 1
}

#${1}
#loop_dev
#loop_dev_mnt
#loop_file
#loop_file_mnt
#ovl_dev0
#ovl_mnt0=/loops
#ovl_loopfile0=g-squash_mini/g-squash_mini.xz.squashfs
#ovl_mnt0_sub=/loops/g-squash_mini/lower
#ovl_dev1
#ovl_mnt1=/loops
#ovl_loopfile1=g-squash_mini/g-squash_mini.rw.ext2
#ovl_mnt1_sub=/loops/g-squash_mini/rw
function get_vmlinux_initrd {
echo
echo 'get_vmlinux_initrd'
echo "${1},${2},${3},${4}, ${5},${6},${7},${8}, ${9},${10},${11},${12}."
while [ -z "$VMLINUX" -o -z "$INITRD" ]; do
if [ -n "${1}" ]; then
search --no-floppy --label --set=LOOP_DEV "${1}"
echo loop_dev "$LOOP_DEV"
fi
if [ -n "$LOOP_DEV" ]; then
if [ -f "($LOOP_DEV)/${3}" ]; then
echo loopback LOOP_ENTRY "($LOOP_DEV)/${3}"
loopback LOOP_ENTRY "($LOOP_DEV)/${3}"
set _ovl_dev1="${9}"
if [ "$_ovl_dev1" = 'tmpfs' ]; then
_ovl_dev1=''
fi
get_vmlinux_initrd_ovl \
(LOOP_ENTRY) "${6}" "${7}" "${8}" \
"$_ovl_dev1" "${10}" "${11}" "${12}"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
elif [ -n "${4}" ]; then
is_there "(LOOP_ENTRY)/boot/${4}"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "(LOOP_ENTRY)/${4}/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "(LOOP_ENTRY)/${4}"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
fi
is_there "(LOOP_ENTRY)/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
else
if [ -z "$VMLINUX" -a -z "$INITRD" ]; then
loopback -d LOOP_ENTRY
fi
fi
elif [ -n "${4}" ]; then
is_there "(LOOP_DEV)/${4}/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "(LOOP_DEV)/${4}"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
is_there "(LOOP_DEV)/boot/${4}"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
elif [ -z "$VMLINUX" -o -z "$INITRD" ]; then
is_there "(LOOP_DEV)/boot"
if [ -n "$VMLINUX" -a -n "$INITRD" ]; then
break;
fi
fi
fi
break
done
sleep 1
}

### END functions ###

--
Tags: Linux

All Comments

Dinah avatar
By Dinah
at 2017-08-03T11:31
Yedda avatar
By Yedda
at 2017-08-03T16:21
推薦文章。
Jessica avatar
By Jessica
at 2017-08-05T19:23
這要給讚

請問要建構區域網路PC該從何開始?

Belly avatar
By Belly
at 2017-07-28T17:43
※ [本文轉錄自 hardware 看板 #1PUmQvcW ] 作者: allengx9900 (俏如來) 看板: hardware 標題: [請益] 請問要建構區域網路PC該從何開始? 時間: Fri Jul 28 17:41:11 2017 我想要透過主機板的LAN BOOT來進行伺服器的建置與維護 ...

centos6.9 雙網卡請教

Skylar Davis avatar
By Skylar Davis
at 2017-07-28T17:37
小弟是個 linux 新手, 由於先前維護的同事已經離職 老闆就找我手了 Orz 主機上有 eth0 對內區網 另有 wlan0 對外的 wifi 網路 我查了幾個網站, 說明如果要由wifi出去, 把 預設gateway 指向 wlan0 那個就好 小弟是這樣下的 /sbin/route add -ne ...

Canonical 在調查大家習慣使用的軟體

Freda avatar
By Freda
at 2017-07-28T15:39
Canonical 公司在調查 Linux 使用者平常習慣使用的各種軟體, 作為下一個 Ubuntu LTS 版本預設軟體的參考。 問卷分為 Browser、Email Cilent、 File Manager 等 14 種類別。 如果有些類別你沒有特別喜歡的軟體可以跳過; 可以提名多款軟體(用逗號 ...

建立yum server問題

Freda avatar
By Freda
at 2017-07-27T23:44
因單位內有很多linux server 版本不一 但是對外網路沒開 想要架設一台yum server給其他台更新 請教一下幾個問題 不知道有錯嗎 1.先讓yum server 通 mirror.centos.org port 80 後可yum之後讓client開通yum server 80 port ...

ubuntu 12裝xrdp 權限問題

Cara avatar
By Cara
at 2017-07-27T14:53
我是個linux 新手 我裝了xrdp用win7 用admin可登入 不過很多設定卻沒權限 像gui改網路 要在terminal下打sudo nm-connector-editor改有editor功能 用local登入是直接點右上角就可直接edit 請問我那設錯了 如何才能用xrdp登入有管理電腦的權限? ...