Slack/mem-slack
メモリ領域でSlackwareを動かす
はじめに
使い慣れたPC環境をどこでも使えるようにしたい.ノートPCを持ち歩けば良いが,軽量ノートでも1kg近くはあり鞄が重くなってしまう. PC利用する場所としてはオフィスやネカフェ,旅先のホテル,帰省先などあるが,何かしらPC端末があるのでこれを利用できるようにしたい.
他人のPCであり勝手にOSやアプリをインストールできないので,PCメモリ領域をストレージ空間にして、 そこへ予め用意した自環境(OS,アプリ)を起動時に展開する.起動DiskはUSBメモリを利用.
基本設計と事前準備
ストレージ効率化
ストレージ領域を圧迫するkernelモジュール,firmwareはブートDiskに所持し,必要時にマウントして使う
/
|-EFI
|-BOOT
| |-bootx64.efi
| |-elilo.conf
| |-syslinux.cfg
|
|-slack15
|-vmlinuz
|-initrd.gz
|-root.tgz # root領域アーカイブ
|-firmware.sfs # firmwareアーカイブ
|-mod-kernel.sfs # kernelモジュールアーカイブ
USBメモリの準備
- EFI領域(vfat)だけ作成する.10G程度.
- UUIDも確認しておく.⇒「89AB-CDEF」
# fdisk -l /dev/sda .... Disklabel type: gpt # GPTテーブルで作成 .... Device Boot Start End Sectors Size Type /dev/sda1 2048 20973568 20971520 10G EFI System # ls -l /dev/disk/by-uuid | grep sda1 lrwxrwxrwx 1 root root 10 Oct 8 20:01 89AB-CDEF -> ../../sda1 # mkfs.vfat -F32 /dev/sda1 # mount UUID=89AB-CDEF /usb/ # mkdir /usb/EFI /usb/EFI/BOOT /usb/EFI/slack15 # cp /boot/vmlinuz-huge-5.15.19 /usb/EFI/slack15/vmlinuz # 作業マシンのイメージを利用
アーカイブの作成
超基本部分だけで作成してみる
[a]パッケージ
$ grep ":ADD" ISO:/slackware64/a/tagfile | sed 's/:ADD/-*.t?z/g' > a
- 内容:あまり使わないパッケージもありそう
$ grep ":ADD" ISO:/slackware64/a/tagfile | sed 's/:ADD/ /g' | tr -d '\n' | fmt -w 140 aaa_base aaa_glibc-solibs aaa_libraries acl attr bash bin bzip2 coreutils cpio cracklib dcron devs e2fsprogs elvis etc eudev exfatprogs findutils floppy gawk glibc-zoneinfo gptfdisk grep gzip hdparm hostname hwdata infozip kernel-firmware kernel-huge kernel-modules kmod less libgudev libpwquality lilo logrotate lzip mlocate nvi openssl-solibs pam pkgtools procps-ng reiserfsprogs sdparm sed shadow sharutils smartmontools sysklogd syslinux sysvinit sysvinit-scripts tar usb_modeswitch usbutils util-linux xz
- kernelは作業マシンのイメージを使うので不要
$ vi a kernel-huge-*.t?z # <- 行を削除
[l]パッケージ
- [a]パッケージのみだとライブラリがないと怒られるので,必要最小限のライブラリパッケージを追加
- ちなみに起動はするが,ncursesのライブラリが無いとログインできない(実はライブラリはあるがリンクがないだけ)
$ cat > l ncurses-*.t?z pcre-*.t?z gmp-*.t?z zstd-*.t?z zlib-*.t?z
インストール(パッケージ展開)
- 作成したパッケージリストに基づいてインストールを実行
# mkdir root
# for d in a ap l
do cat "${d}" | \
while read f
do /sbin/installpkg --terse --root root /mnt/cdrom/slackware64/${d}/"${f}"
done
done
- 不要(きっと使わない)ファイルを削除
# rm -rf root/usr/{doc,info,include,man}
# cd root/usr/share/zoneinfo; ls --ignore Asia | xarg rm -r
# cd root/usr/share/zoneinfo/Asia; ls --ignore Tokyo | xarg rm -r
# cd root/usr/share/locale; ls --ignore "ja" --ignore "en*" | xarg rm -r
- 必要な設定を行う
# vi root/etc/fstab # vi root/etc/HOSTNAME <-Host名 # vi root/etc/hosts <-Host名 # vi root/etc/passwd <-ユーザアカウント追加 # vi root/etc/group <-グループ追加 # ln -s /usr/share/zoneinfo/Asia/Tokyo root/etc/localtime <-TimeZone設定 ...
インストール(アーカイブ配置)
- kernelモジュール(mod-kernel.sfs)のアーカイブ作成
# cd root/lib/modules/5.15.19/ # mksquashfs kernel /usb/EFI/slack15/mod-kernel.sfs # rm -f kernel/*
- firmwareのアーカイブ作成
# cd root/lib # mksquashfs firmware /usb/EFI/slack15/firmware.sfs # rm -f firmware/*
- root領域のアーカイブ作成
# cd root # tar cvfz /usb/EFI/slack15/root.tgz *
OS起動ロジックの作成
initrdの作成
雛形の作成.USBホストドライバは使いそうなものを選定
# mkinitrd -s ./tree -o /usb/EFI/slack15/initrd.gz
-m loop # fileマウント用のモジュール (sfsファイル)
:usb-storage:uas # USBストレージドライバ
:xhci-hcd:xhci-pci:xhci-plat-hcd:xhci-pci-renesas # USB3.0ホストドライバ
:ohci-hcd:ohci-pci:ohci-platform # USB1.0/1.xホストドライバ
:uhci-hcd # USB1.xホストドライバ
:ehci-hcd:ehci-pci:ehci-platform # USB2.0ホストドライバ
スクリプトの編集
rootデバイスをマウントするあたり(322行あたり)を改造
# vi ./tree/init
# Switch to real root partition:
/sbin/udevadm settle --timeout=10
echo 0x0100 > /proc/sys/kernel/real-root-dev
#### begin ###############################################################################
# mount -o ro${ROOTFLAGS:+,$ROOTFLAGS} -t $ROOTFS $ROOTDEV /mnt # コメントアウト
mkdir /boot
mount -o ro -t $ROOTFS $ROOTDEV /boot # USBメモリをマウント
mount -t tmpfs tmpfs /mnt # メモリ空間にroot領域を作成
PKGROOT=/boot/EFI/slack15
tar xfz $PKGROOT/root.tgz -C /mnt # rootイメージを展開
# link oneoff directories
mkdir /kernel
mount -o ro,loop $PKGROOT/mod-kernel.sfs /kernel # kernelモジュールをマウント
mkdir /firmware
mount -o ro,loop $PKGROOT/firmware.sfs /firmware # firmwareをマウント
mount -o move /boot /mnt/boot # USBメモリを/bootとしてリマウント
mount -o move /kernel /mnt/lib/modules/$(unamr -r)/kernel
mount -o move /firmware /mnt/lib/firmware
# add chip to fstab
cat <<EOF >> /mnt/etc/fstab # USBメモリのマウントポイントをfstabへ追記しておく
# USB Chip
$ROOTDEV /boot vfat noauto,user,rw 0 0
$PKGROOT/mod-kernel.sfs /lib/modules/$(uname -r)/kernel squashfs noauto,user,ro 0 0
$PKGROOT/firmware.sfs /lib/firmware squashfs noauto,user,ro 0 0
EOF
mount -n -o remount,ro /mnt
############################################################################################
if [ ! -r /mnt/sbin/init ]; then
echo "ERROR: No /sbin/init found on rootdev (or not mounted). Trouble ahead."
initrdの再作成
# mkinitrd -s ./tree -o /usb/EFI/slack15/initrd.gz # モジュールは省略可(tree内にある)
-f vfat # 上記スクリプトの${ROOTFS}
-w 5 # USBデバイスの認識待ち時間(s).適当.
ブート設定
- UEFI起動の設定
# cp /boot/elilo-x86_64.efi /usb/EFI/BOOT/bootx64.efi # 名前の変更が必要?
# vi /usb/EFI/BOOT/elilo.conf
image=/EFI/slack15/vmlinuz
label=slackware
initrd=/EFI/slack15/initrd.gz
root=UUID=89AB-CDEF # USBデバイスのUUIDを設定
read-only
- MBR起動の設定
# /sbin/sgdisk -A 1:set:2 /dev/sda # /dev/sda1 の属性を(legacy BIOS bootable)に設定 # dd if=/usr/share/syslinux/gptmbr.bin of=/dev/sda # GPTテーブル用のMBRを転記 # syslinux -i /dev/sda1 -d /EFI/BOOT # syslinuxをインストール
起動
- いろいろ怒られる(kernelモジュールが無いとか)けど一応起動
- メモリ消費は170M程度,USBメモリは500M程度
Welcome to Linux 5.15.19 x86_64 (tty1) mem-slack15 login: root Linux 5.15.19. root@mem-slack15:~# df -h Filesystem Size Used Avail Use% Mounted on tmpfs 32M 132K 32M 1% /run devtmpfs 8.0M 0 8.0M 0% /dev /dev/sda1 498M 457M 42M 92% /boot tmpfs 985M 170M 815M 18% / /dev/loop0 55M 55M 0 100% /lib/modules/5.15.19/kernel /dev/loop1 327M 327M 0 100% /lib/firmware tmpfs 985M 0 985M 0% /dev/shm cgroup_root 8.0M 0 8.0M 0% /sys/fs/cgroup
追加パッケージ
後で必要になったパッケージを動的に追加できるようにしてみる
作成方法と置き場所
tmuxとdiffを任意ディレクトリへインストールしてsquashfs圧縮する
# mkdir app
# /sbin/installpkg --terse --root app /mnt/cdrom/slackware64/ap/diffutils-3.8-x86_64-1.txz
# /sbin/installpkg --terse --root app /mnt/cdrom/slackware64/ap/tmux-3.2a-x86_64-1.txz
# cd app
# rm -rf usr/{doc,info,include,man} # 不要なファイルを削除(メモリ節約するため)
# mksquashfs ../app.sfs * # パッケージファイル(app.sfs)完成
置き場所はusbメモリのslack15/sfsとする
/
|-EFI
|-slack15
|-sfs
|-app.sfs # 追加アプリパッケージ
|-etc.sfs # etc追加設定を集めたパッケージとかもいける
パッケージ利用選択
kernelへの追加パラメータで選ぶようにしてみる
# vi EFI/BOOT/elilo.conf
prompt
timeout=50
image=/EFI/slack15/vmlinuz
label=slackware
initrd=/EFI/slack15/initrd.gz
root=UUID=89AB-CDEF
read-only
image=/EFI/slack15/vmlinuz
label=slackware+app
initrd=/EFI/slack15/initrd.gz
root=UUID=89AB-CDEF
apped=sfs=app.sfs,etc.sfs # 追加パッケージを指定
read-only
パッケージの適用
initrdの中でパッケージの展開と適用を行う まずはcommand lineからsfs値を取得
# vi tree/init
waitforroot=*|rootdelay=*)
WAIT=$(echo $ARG | cut -f2 -d=)
;;
###追加部分###############################
sfs=*)
SFS=$(echo $ARG | cut -f2 -d=)
;;
##########################################
esac
次にsfsファイルを展開し,root領域へ適用
# vi tree/init
mount -t tmpfs tmpfs /mnt
tar xfz $PKGROOT/root.tgz -C /mnt
##パッケージ展開&適用########################
mkdir /sfs
for s in ${SFS//,/}
do
f=$PKGROOT/sfs/${s}
if [ -e "${f}" ]; then
echo "expand: ${f}"
mount -o ro,loop "${f}" /sfs #↓OS領域のrsyncコマンドとライブラリを使う
LD_LIBRARY_PATH=/mnt/lib64:/mnt/usr/lib64 /mnt/usr/bin/rsync -avH /sfs/* /mnt/ > /dev/null 2>&1
umount /sfs
fi
done
###############################################
# link oneoff directories
mkdir /kernel
---
update at 2024/12/02 10:09:14
※注:当サイトは特定環境において確認できた事象のみを記述しています。他の環境での動作は一切保証しません。