Include the FS filesystem as squashfs as second partition.
authorRalph Ronnquist <rrq@rrq.au>
Tue, 6 Feb 2024 09:24:16 +0000 (20:24 +1100)
committerRalph Ronnquist <rrq@rrq.au>
Tue, 6 Feb 2024 09:24:16 +0000 (20:24 +1100)
minbase-strap.sh

index 852e9cbc382b61a25d5619ebf97601ddfe6fd394..1da0179c9be1f01fcc8e6b2bfad9b49b81e6b47f 100755 (executable)
@@ -30,6 +30,11 @@ if [ -d "$FS" ] ; then
     [ "$REPLY" = 1 ] && DEBSTRAP=false
 fi
 
+stupid_links() {
+    mkdir -p $1/usr
+    for d in bin sbin lib ; do mkdir $1/usr/$d ; ln -s usr/$d $1/$d ; done
+}
+
 if $DEBSTRAP ; then
     ## Optionally add the stupid-links
     read -n 1 -p "prime $FS with stupid-links? [Yn]" x
@@ -37,13 +42,7 @@ if $DEBSTRAP ; then
 
     rm -rf "$FS" # remove if existin
 
-    if $USRMERGE ; then
-       mkdir -p "$FS"/usr
-       for d in bin sbin lib ; do
-           mkdir "$FS"/usr/$d
-           ln -s usr/$d "$FS"/$d
-       done
-    fi
+    $USRMERGE && stupid_links "$FS"
 
     ## bootstrap a filesystem, with exclusions
     echo "http_proxy=$http_proxy debootstrap ..."
@@ -65,15 +64,6 @@ if $DEBSTRAP ; then
 
 fi # End of $DEBSTRAP actions
 
-## (re)install /init
-echo "** Please select /init template"
-select INIT in none $(echo init*.template) ; do [ -n "$INIT" ] && break ; done
-if [ "$INIT" != none ] ; then
-    cp $INIT "$FS"/init
-    cp message.txt "$FS"/
-    chmod a+x "$FS"/init
-fi
-
 ## Pick boot kernel, if there are many
 LINUXES=( $(cd "$FS"/boot ; ls vmlinuz* 2>/dev/null) )
 if [ ${#LINUXES[@]} -gt 1 ] ; then
@@ -92,9 +82,62 @@ fi
 TMP=$(mktemp -d XXXX)
 trap "rm -r $TMP" 0 2 15
 
-( cd "$FS" && find -printf '%P\n' | cpio -o -H newc ) | \
+mkdir -p $TMP/prep/{proc,dev,tmp,sys,mnt,usr}
+stupid_links $TMP/prep
+
+# copy FS tree(s) in full into the TMP/prep tree
+copyFStree() {
+    local D
+    for D in $* ; do
+       tar cf - -C "$FS" $D \
+           | tar -xf - --skip-old-files --keep-directory-symlink -C $TMP/prep
+    done
+}
+
+# Copy FS binary(s) with all its libraries into the TMP/prep tree
+copyFSbin() {
+    local B BIN
+    for B in $* ; do
+       BIN="$(chroot "$FS" which "$B")"
+       tar cf - --dereference -C "$FS" ${BIN#/} \
+           $(chroot "$FS" ldd "$BIN" | grep -oE '/[^ ]*'|sed 's|/||')\
+           | tar -xf - --keep-directory-symlink -C $TMP/prep
+    done
+}
+
+INITRD="$FS"/boot/initrd.img${LINUX#*/vmlinuz}
+if [ -r "$INITRD" ] ; then
+    #select X in my FS ; do [ -n "$X" ] && break ; done
+    X=FS
+else
+    X=my
+fi
+case "$X" in
+    FS)
+       copyFStree lib/modules
+       zstdcat $INITRD | ( cd $TMP/prep && cpio -i )
+       ;;
+    my)
+       copyFStree lib/modules lib/udev
+       copyFSbin busybox sh cttyhack setsid mount mkdir
+       copyFSbin udevd udevadm modprobe modinfo kmod blkid
+       ;;
+esac
+
+## (re)install /init
+echo "** Please select /init template"
+select INIT in none $(echo init*.template) ; do [ -n "$INIT" ] && break ; done
+if [ "$INIT" != none ] ; then
+    mv $TMP/prep/init{,.FS}
+    cp $INIT $TMP/prep/init
+    chmod a+x $TMP/prep/init
+    cp message.txt $TMP/prep/message.txt
+fi
+
+( cd "$TMP/prep" && find -printf '%P\n' | cpio -o -H newc ) | \
     gzip > $TMP/initrd.gz
 cp $LINUX $TMP/vmlinuz
+rm -rf $TMP/prep
 
 #============================================================
 # Add syslinux boot equipment for bios boot under $TMP/syslinux
@@ -112,27 +155,43 @@ default menu.c32
 label linux
     kernel /vmlinuz
     append initrd=/initrd.gz init=/init console=ttyS0,115200 
+label rescue
+    kernel /vmlinuz
+    append initrd=/initrd.gz init=/init console=ttyS0,115200 rescue
 EOF
 
 #============================================================
 [ -e "$IMG" ] && read -p "** Will overwrite $IMG (or ^C here and now)" x
 rm -f "$IMG"
 
+# First partition sectors (round up to a Mb number
+DUM1=$(( ( $(du -sB1 $TMP | sed 's/\s.*//') / 1048576 + 2 ) ))
+DUM2=$(( $(stat -c %s FS.sqfs) / 1048576 + 2 ))
+
 # Estimate the required disk image size in Mib
-DUM=$(( $(du -sB1 $TMP | sed 's/\s.*//') / 1048576 + 3 ))
+DUM=$(( DUM1 + DUM2 + 1 ))
 
 # Create the image, with the partition marked as EFI parition and
 # bootable; acutal format is FAT{12,16,32}
 dd if=/dev/zero of="$IMG" bs=${DUM}M count=0 seek=1 status=none
-cat <<EOF | sfdisk -q "$IMG"
+cat <<EOF | tee -a /proc/self/fd/2 | sfdisk -q "$IMG"
 label: dos
 
-- - 0xef *
+2048 $(( DUM1 * 2048 )) 0xef *
+- - 0x83
 EOF
+PART=( $(fdisk -l -ostart,sectors $IMG | tail -n 2) )
+echo "${PART[*]}"
+
 # First sector is 2048 by default, which is byte address 1048576
-mkfs.fat --offset 2048 "$IMG" >/dev/null
+TMPIMG=$(mktemp XXXX)
+fusefile $TMPIMG $IMG/0+$(( ( ${PART[0]} + ${PART[1]} ) * 512 ))
+mkfs.fat --offset ${PART[0]} "$TMPIMG"  >/dev/null
+umount $TMPIMG
+rm $TMPIMG
 mcopy -i "$IMG@@1048576" -s $TMP/* ::/
 [ -z "$SUDO_USER" ] || chown $SUDO_USER: "$IMG"
+dd if=FS.sqfs of=$IMG seek=${PART[3]} conv=notrunc status=none
 
 #============================================================
 # Final syslinux bios boot image mastering