diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b031379 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.largeFileOptimizations": true +} \ No newline at end of file diff --git a/builder/bins/cgpt.x86-64 b/builder/bins/cgpt.x86-64 new file mode 100755 index 0000000..16f8fa0 Binary files /dev/null and b/builder/bins/cgpt.x86-64 differ diff --git a/builder/bins/sfdisk.x86-64 b/builder/bins/sfdisk.x86-64 new file mode 100755 index 0000000..ddda90a Binary files /dev/null and b/builder/bins/sfdisk.x86-64 differ diff --git a/builder/bootstrap/bin/bash b/builder/bootstrap/bin/bash new file mode 100644 index 0000000..fc60c9b Binary files /dev/null and b/builder/bootstrap/bin/bash differ diff --git a/builder/lib/extract_initramfs.sh b/builder/lib/extract_initramfs.sh index 4209e63..240c7a3 100644 --- a/builder/lib/extract_initramfs.sh +++ b/builder/lib/extract_initramfs.sh @@ -10,7 +10,6 @@ run_binwalk() { fi } -#extract the initramfs from a kernel image extract_initramfs() { local kernel_bin="$1" local working_dir="$2" @@ -76,7 +75,8 @@ copy_kernel() { local shim_loop=$(create_loop "${shim_path}") local kernel_loop="${shim_loop}p2" #KERN-A should always be p2 dd if=$kernel_loop of=$kernel_dir/kernel.bin bs=1M status=none - losetup -d $shim_loop + dd if=$kernel_loop of="/tmp/kernel.bin" bs=1M status=none + # losetup -d $shim_loop } #copy the kernel image then extract the initramfs @@ -99,6 +99,7 @@ extract_initramfs_full() { extract_initramfs $kernel_dir/kernel.bin $kernel_dir $rootfs_dir fi + if [ "$kernel_bin" ]; then cp $kernel_dir/kernel.bin $kernel_bin fi diff --git a/builder/lib/rootfs_utils.sh b/builder/lib/rootfs_utils.sh index 829fdc3..09a7cd1 100644 --- a/builder/lib/rootfs_utils.sh +++ b/builder/lib/rootfs_utils.sh @@ -2,6 +2,35 @@ # Code was borrowed from the SH1mmer repo, credits to them # https://github.com/MercuryWorkshop/sh1mmer +get_sector_size() { + "$SFDISK" -l "$1" | grep "Sector size" | awk '{print $4}' +} + +get_final_sector() { + "$SFDISK" -l -o end "$1" | grep "^\s*[0-9]" | awk '{print $1}' | sort -nr | head -n 1 +} + +# create_stateful(){ +# local final_sector=$(get_final_sector "$loopdev") +# local sector_size=$(get_sector_size "$loopdev") +# # special UUID is from grunt shim, dunno if this is different on other shims +# "$CGPT" add "$loopdev" -i 1 -b $((final_sector + 1)) -s $((state_size / sector_size)) -t "9CC433E4-52DB-1F45-A951-316373C30605" +# partx -u -n 1 "$loopdev" +# mkfs.ext4 -F "$loopdev"p1 +# sync +# } + +create_stateful(){ + local image="$1" + fdisk "$image" << EOF > /dev/null 2>&1 +n +1 + ++${state_size}M +w +EOF +} + is_ext2() { local rootfs="$1" local offset="${2-0}" @@ -48,7 +77,7 @@ disable_rw_mount() { shrink_partitions() { local shim="$1" - fdisk "$shim" < /dev/null 2>&1 d 12 d @@ -69,7 +98,6 @@ shrink_partitions() { 4 d 1 - p w EOF } @@ -80,11 +108,11 @@ truncate_image() { local final_sector=$(get_final_sector "$1") local end_bytes=$(((final_sector + buffer) * sector_size)) - log "Truncating image to $(format_bytes "$end_bytes")" - truncate -s "$end_bytes" "$1" + echo "Truncating image to $(format_bytes "$end_bytes")" + truncate -s "$end_bytes" "$1" > /dev/null 2>&1 # recreate backup gpt table/header - suppress sgdisk -e "$1" 2>&1 | sed 's/\a//g' + sgdisk -e "$1" 2>&1 | sed 's/\a//g' > /dev/null 2>&1 } format_bytes() { @@ -92,24 +120,29 @@ format_bytes() { } shrink_root() { - log "Shrinking ROOT-A Partition" + loopdev="$@" + echo "$@" + echo "$1" + echo "Shrinking ROOT-A Partition" - enable_rw_mount "${LOOPDEV}p3" - suppress e2fsck -fy "${LOOPDEV}p3" - suppress resize2fs -M "${LOOPDEV}p3" - disable_rw_mount "${LOOPDEV}p3" + echo $loopdev - local sector_size=$(get_sector_size "$LOOPDEV") - local block_size=$(tune2fs -l "${LOOPDEV}p3" | grep "Block size" | awk '{print $3}') - local block_count=$(tune2fs -l "${LOOPDEV}p3" | grep "Block count" | awk '{print $3}') + enable_rw_mount "${loopdev}p3" + e2fsck -fy "${loopdev}p3" + resize2fs -M "${loopdev}p3" + disable_rw_mount "${loopdev}p3" - local original_sectors=$("$CGPT" show -i 3 -s -n -q "$LOOPDEV") + local sector_size=$(get_sector_size "$loopdev") + local block_size=$(tune2fs -l "${loopdev}p3" | grep "Block size" | awk '{print $3}') + local block_count=$(tune2fs -l "${loopdev}p3" | grep "Block count" | awk '{print $3}') + + local original_sectors=$("$CGPT" show -i 3 -s -n -q "$loopdev") local original_bytes=$((original_sectors * sector_size)) local resized_bytes=$((block_count * block_size)) local resized_sectors=$((resized_bytes / sector_size)) echo "Resizing ROOT from $(format_bytes ${original_bytes}) to $(format_bytes ${resized_bytes})" - "$CGPT" add -i 3 -s "$resized_sectors" "$LOOPDEV" - partx -u -n 3 "$LOOPDEV" + "$CGPT" add -i 3 -s "$resized_sectors" "$loopdev" + partx -u -n 3 "$loopdev" } \ No newline at end of file diff --git a/builder/picoshim.sh b/builder/picoshim.sh index 52981e6..bf891d1 100644 --- a/builder/picoshim.sh +++ b/builder/picoshim.sh @@ -27,43 +27,84 @@ fi source lib/extract_initramfs.sh source lib/detect_arch.sh +source lib/rootfs_utils.sh echo "PicoShim builder" -echo "requires: binwalk, fdisk" +echo "requires: binwalk, fdisk, cgpt, mkfs.ext2, numfmt" SHIM="$1" initramfs="/tmp/initramfs_path" -ROOTFS_MNT="/tmp/picoshim_rootmnt" +rootfs_mnt="/tmp/picoshim_rootmnt" loopdev=$(losetup -f) -STATE_SIZE=$((1 * 1024 * 1024)) + +# gets the initramfs size, e.g: 6.5M, and rounds it to the nearest whole number, e.g: 7M +# we're giving it 5 extra MBs to allow the busybox binaries to be installed +initramfs_size=$(($(du -sb "$initramfs" | awk '{print $1}' | numfmt --to=iec | awk '{print int($1) + ($1 > int($1))}') + 2)) +kernsize=$(fdisk -l ${loopdev}p2 | head -n 1 | awk '{printf $3}') + +# size of stateful partition in MiB +state_size="1" + + rm -rf $initramfs # cleanup previous instances of picoshim, if they existed. mkdir -p $initramfs -rm -rf $ROOTFS_MNT # cleanup previous instances of picoshim, if they existed. -mkdir -p $ROOTFS_MNT +rm -rf $rootfs_mnt # cleanup previous instances of picoshim, if they existed. +mkdir -p $rootfs_mnt if [ -f "$SHIM" ]; then + shrink_partitions "$SHIM" losetup -P "$loopdev" "$SHIM" else exit 1 fi arch=$(detect_arch $loopdev) -extract_initramfs_full "$SHIM" "$initramfs" ""$loopdev"p2" "$arch" +extract_initramfs_full "$loopdev" "$initramfs" "/tmp/shim_kernel/kernel.img" "$arch" +dd if="${loopdev}p2" of=/tmp/kernel-new.bin bs=1M oflag=direct status=none + +fdisk "$loopdev" < /dev/null 2>&1 +d +3 +p +d +2 +p +n +3 + ++${initramfs_size}M +n +2 + ++${kernsize}M +p + +w +EOF +dd if=/tmp/kernel-new.bin of="${loopdev}p2" bs=1M oflag=direct status=none echo "creating new filesystem on rootfs" -echo "y" | mkfs.ext4 "$loopdev"p3 -L ROOT-A +echo "y" | mkfs.ext2 "$loopdev"p3 -L ROOT-A > /dev/null 2>&1 echo "mounting & moving files from initramfs to rootfs" -mount "$loopdev"p3 "$ROOTFS_MNT" -mv "$initramfs"/* "$ROOTFS_MNT"/ -umount "$loopdev"p3 +mount "$loopdev"p3 "$rootfs_mnt" +mv "$initramfs"/* "$rootfs_mnt"/ -shrink_root +create_stateful "$loopdev" +echo "adding kernel priorities" +"$CGPT" add "$loopdev" -i 2 -t kernel -P 1 +"$CGPT" add "$loopdev" -i 3 -t rootfs + echo "cleaning up" losetup -D -rm -rf $initramfs -rm -rf $ROOTFS_MNT + +truncate_image "$SHIM" + + +rm -rf $initramfs +rm -rf $rootfs_mnt +umount "$loopdev"p3