diff --git a/build.sh b/build.sh index 22aad82..842ffe4 100755 --- a/build.sh +++ b/build.sh @@ -84,6 +84,7 @@ echo "copying data into the image" populate_partitions $image_loop $initramfs_dir $rootfs_dir echo "cleaning up loop devices" +umount $rootfs_dir losetup -d $shim_loop losetup -d $image_loop echo "done" \ No newline at end of file diff --git a/build_rootfs.sh b/build_rootfs.sh index 96886a8..4669ab7 100755 --- a/build_rootfs.sh +++ b/build_rootfs.sh @@ -50,7 +50,7 @@ for mountpoint in $chroot_mounts; do mount --make-rslave --rbind "/${mountpoint}" "${rootfs_dir}/$mountpoint" done -chroot_command="DEBUG=${DEBUG} release_name=${release_name} packages=${packages} /opt/setup_rootfs.sh" +chroot_command="/opt/setup_rootfs.sh '$DEBUG' '$release_name' '$packages'" chroot $rootfs_dir /bin/bash -c "${chroot_command}" for mountpoint in $chroot_mounts; do diff --git a/build_squashfs.sh b/build_squashfs.sh index dc0863c..edd3d36 100755 --- a/build_squashfs.sh +++ b/build_squashfs.sh @@ -35,14 +35,16 @@ compile_unionfs() { local repo_url="https://github.com/rpodgorny/unionfs-fuse" local original_dir="$(pwd)" + local core_count="$(nproc --all)" rm -rf $working_path git clone $repo_url -b master --depth=1 $working_path cd $working_path - env LDFLAGS="-static" make + env LDFLAGS="-static" make -j$core_count local binary_path="$working_path/src/unionfs" cp $binary_path $out_path + cd $original_dir } rootfs_dir=$(realpath $1) @@ -67,7 +69,7 @@ rm -rf $kernel_dir mkdir $kernel_dir -p dd if=$kernel_loop of=$kernel_dir/kernel.bin bs=1M status=progress -echo "extracting initramfs from kernel" +echo "extracting initramfs from kernel (this may take a while)" extract_initramfs $kernel_dir/kernel.bin $kernel_dir $rootfs_dir rm -rf $rootfs_dir/init @@ -75,16 +77,12 @@ echo "mounting shim" make_mountable "${shim_loop}p3" safe_mount "${shim_loop}p3" $shim_rootfs -echo "extracting and compressing modules from shim" -extract_modules $modules_squashfs $shim_rootfs - echo "compressing old rootfs" mksquashfs $old_dir $root_squashfs -noappend -comp gzip echo "patching new rootfs" mv $unionfs_dir/unionfs $rootfs_dir/bin/unionfs -#cp -ar ./squashfs/* $rootfs_dir/ +cp -ar squashfs/* $rootfs_dir/ +chmod +x $rootfs_dir/bin/* -echo "cleaning up" -umount $shim_rootfs -losetup -d $shim_loop \ No newline at end of file +echo "done" \ No newline at end of file diff --git a/rootfs/opt/setup_rootfs.sh b/rootfs/opt/setup_rootfs.sh index fee86d0..6fda0a7 100755 --- a/rootfs/opt/setup_rootfs.sh +++ b/rootfs/opt/setup_rootfs.sh @@ -3,6 +3,10 @@ #setup the debian rootfs #this is meant to be run within the chroot created by debootstrap +DEBUG="$1" +release_name="$2" +packages="$3" + set -e if [ "$DEBUG" ]; then set -x @@ -23,13 +27,14 @@ END #install the patched systemd apt-get install -y ca-certificates apt-get update -apt-get upgrade -y +installed_systemd="$(dpkg-query -W -f='${binary:Package}\n' | grep "systemd")" +apt-get install --reinstall $installed_systemd #enable shimboot services systemctl enable kill-frecon.service #install desktop -apt-get install -y task-xfce-desktop cloud-utils zram-tools +apt-get install -y $packages cloud-utils zram-tools #set up zram tee -a /etc/default/zramswap << END diff --git a/shim_utils.sh b/shim_utils.sh index fe83aad..113b2bb 100755 --- a/shim_utils.sh +++ b/shim_utils.sh @@ -23,10 +23,3 @@ extract_initramfs() { rm -rf $output_dir cat $cpio_path | cpio -D $output_dir -imd --quiet } - -extract_modules() { - local output_path="$1" - local shim_rootfs="$2" - local modules_dir="$shim_rootfs/lib/modules" - mksquashfs $modules_dir $output_path -noappend -comp gzip -} \ No newline at end of file diff --git a/squashfs/bin/bootstrap.sh b/squashfs/bin/bootstrap.sh new file mode 100755 index 0000000..efb96c3 --- /dev/null +++ b/squashfs/bin/bootstrap.sh @@ -0,0 +1,68 @@ +#!/bin/busybox sh + +#mount the squashfs + unionfs and boot into it + +move_mounts() { + local base_mounts="/sys /proc /dev" + local newroot_mnt="$1" + for mnt in $base_mounts; do + mkdir -p "$newroot_mnt$mnt" + mount -n -o move "$mnt" "$newroot_mnt$mnt" + done +} + +boot_dir() { + local target="$1" + + echo "moving mounts to newroot" + move_mounts $target + + echo "switching root" + mkdir -p $target/oldroot + pivot_root $target $target/oldroot + + /bin/bash -c "mount -o bind /oldroot/lib/modules /lib/modules" + exec /sbin/init < "$TTY1" >> "$TTY1" 2>&1 +} + +mount_squashfs() { + mkdir -p /lib/modules /mnt/root_squashfs + mount /root.squashfs /mnt/root_squashfs + mount -o bind /mnt/root_squashfs/lib/modules /lib/modules +} + +#based on https://github.com/rpodgorny/unionfs-fuse/blob/master/examples/S01a-unionfs-live-cd.sh +mount_unionfs() { + local chroot_path="/tmp/unionfs" + local data_path="/data" + local mountpoint="/newroot" + local squashfs_path="/mnt/root_squashfs" + + local fuse_options="-o allow_other,suid,dev" + local unionfs_options="-o cow,chroot=$chroot_path,max_files=32768" + + mkdir -p $data_path + mkdir -p $mountpoint + mkdir -p $chroot_path/root + mkdir -p $chroot_path/rw + + mount -o bind $squashfs_path $chroot_path/root + mount -o bind $data_path $chroot_path/rw + + modprobe fuse + unionfs $fuse_options $unionfs_options /root=RO:/rw=RW /newroot +} + +main() { + echo "mounting squashfs" + mount_squashfs + + echo "mounting unionfs" + mount_unionfs + + echo "booting unionfs" + boot_dir /newroot +} + +main "$@" +sleep 1d diff --git a/squashfs/bin/init b/squashfs/bin/init new file mode 100755 index 0000000..2e16afc --- /dev/null +++ b/squashfs/bin/init @@ -0,0 +1,29 @@ +#!/bin/busybox sh + +#original: https://chromium.googlesource.com/chromiumos/platform/initramfs/+/refs/heads/main/factory_shim/init + +detect_tty() { + if [ -f "/bin/frecon-lite" ]; then + export TTY1="/dev/pts/0" + export TTY2="/dev/pts/1" + else + export TTY1="/dev/tty1" + export TTY2="/dev/tty2" + fi +} + +setup_environment() { + # Install additional utility programs. + /bin/busybox --install /bin || true +} + +main() { + setup_environment + detect_tty + # In case an error is not handled by bootstrapping, stop here + # so that an operator can see installation stop. + exec bootstrap.sh < "$TTY1" >> "$TTY1" 2>&1 || sleep 1d +} + +main "$@" +exit 1 \ No newline at end of file