2023-10-02 15:23:01 -05:00
|
|
|
#!/bin/bash
|
|
|
|
|
2023-10-02 15:53:11 -05:00
|
|
|
create_loop() {
|
|
|
|
local loop_device=$(losetup -f)
|
2024-05-03 14:20:09 -05:00
|
|
|
if [ ! -b "$loop_device" ]; then
|
|
|
|
#we might run out of loop devices, see https://stackoverflow.com/a/66020349
|
|
|
|
local major=$(grep loop /proc/devices | cut -c3)
|
|
|
|
local number="$(echo "$loop_device" | grep -Eo '[0-9]+' | tail -n1)"
|
|
|
|
mknod $loop_device b $major $number
|
|
|
|
fi
|
2023-10-02 15:53:11 -05:00
|
|
|
losetup -P $loop_device "${1}"
|
|
|
|
echo $loop_device
|
|
|
|
}
|
|
|
|
|
2023-10-03 12:20:41 -05:00
|
|
|
#set required flags on the kernel partition
|
|
|
|
make_bootable() {
|
|
|
|
cgpt add -i 2 -S 1 -T 5 -P 10 -l kernel $1
|
|
|
|
}
|
|
|
|
|
2023-10-02 15:23:01 -05:00
|
|
|
partition_disk() {
|
2024-01-25 15:19:25 -06:00
|
|
|
local image_path=$(realpath -m "${1}")
|
2023-10-02 15:23:01 -05:00
|
|
|
local bootloader_size=${2}
|
|
|
|
|
2023-10-02 15:53:11 -05:00
|
|
|
#create partition table with fdisk
|
2023-10-02 15:23:01 -05:00
|
|
|
(
|
|
|
|
echo g #new gpt disk label
|
|
|
|
|
|
|
|
#create 1MB stateful
|
|
|
|
echo n #new partition
|
|
|
|
echo #accept default parition number
|
|
|
|
echo #accept default first sector
|
|
|
|
echo +1M #partition size is 1M
|
|
|
|
|
|
|
|
#create 32MB kernel partition
|
|
|
|
echo n
|
|
|
|
echo #accept default parition number
|
|
|
|
echo #accept default first sector
|
|
|
|
echo +32M #partition size is 32M
|
|
|
|
echo t #change partition type
|
|
|
|
echo #accept default parition number
|
|
|
|
echo FE3A2A5D-4F32-41A7-B725-ACCC3285A309 #chromeos kernel type
|
|
|
|
|
|
|
|
#create bootloader partition
|
|
|
|
echo n
|
|
|
|
echo #accept default parition number
|
|
|
|
echo #accept default first sector
|
|
|
|
echo "+${bootloader_size}M" #set partition size
|
|
|
|
echo t #change partition type
|
|
|
|
echo #accept default parition number
|
|
|
|
echo 3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC #chromeos rootfs type
|
|
|
|
|
|
|
|
#create rootfs partition
|
|
|
|
echo n
|
|
|
|
echo #accept default parition number
|
|
|
|
echo #accept default first sector
|
|
|
|
echo #accept default size to fill rest of image
|
2023-10-03 19:29:55 -05:00
|
|
|
echo x #enter expert mode
|
|
|
|
echo n #change the partition name
|
|
|
|
echo #accept default partition number
|
|
|
|
echo "shimboot_rootfs:default" #set partition name
|
|
|
|
echo r #return to normal more
|
2023-10-02 15:23:01 -05:00
|
|
|
|
|
|
|
#write changes
|
|
|
|
echo w
|
2023-10-20 15:51:56 -05:00
|
|
|
) | fdisk $image_path > /dev/null
|
2023-10-02 15:23:01 -05:00
|
|
|
}
|
|
|
|
|
2023-10-02 15:53:11 -05:00
|
|
|
safe_mount() {
|
2024-05-03 14:20:09 -05:00
|
|
|
local source="$1"
|
|
|
|
local dest="$2"
|
|
|
|
local opts="$3"
|
|
|
|
|
|
|
|
umount $dest 2> /dev/null || /bin/true
|
|
|
|
rm -rf $dest
|
|
|
|
mkdir -p $dest
|
|
|
|
if [ "$opts" ]; then
|
2024-05-13 13:03:17 -05:00
|
|
|
mount $source $dest -o $opts
|
2024-05-03 14:20:09 -05:00
|
|
|
else
|
|
|
|
mount $source $dest
|
|
|
|
fi
|
2023-10-02 15:53:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
create_partitions() {
|
2024-01-25 15:19:25 -06:00
|
|
|
local image_loop=$(realpath -m "${1}")
|
|
|
|
local kernel_path=$(realpath -m "${2}")
|
2023-10-02 15:53:11 -05:00
|
|
|
|
|
|
|
#create stateful
|
|
|
|
mkfs.ext4 "${image_loop}p1"
|
|
|
|
#copy kernel
|
|
|
|
dd if=$kernel_path of="${image_loop}p2" bs=1M oflag=sync
|
2023-10-03 12:20:41 -05:00
|
|
|
make_bootable $image_loop
|
2023-10-02 15:53:11 -05:00
|
|
|
#create bootloader partition
|
|
|
|
mkfs.ext2 "${image_loop}p3"
|
|
|
|
#create rootfs partition
|
|
|
|
mkfs.ext4 "${image_loop}p4"
|
|
|
|
}
|
|
|
|
|
|
|
|
populate_partitions() {
|
2024-01-25 15:19:25 -06:00
|
|
|
local image_loop=$(realpath -m "${1}")
|
|
|
|
local bootloader_dir=$(realpath -m "${2}")
|
|
|
|
local rootfs_dir=$(realpath -m "${3}")
|
2024-01-30 15:13:03 -06:00
|
|
|
local quiet="$4"
|
2023-10-02 15:53:11 -05:00
|
|
|
|
|
|
|
#mount and write empty file to stateful
|
|
|
|
local stateful_mount=/tmp/shim_stateful
|
|
|
|
safe_mount "${image_loop}p1" $stateful_mount
|
|
|
|
mkdir -p $stateful_mount/dev_image/etc/
|
2023-11-09 15:13:59 -06:00
|
|
|
mkdir -p $stateful_mount/dev_image/factory/sh
|
2023-10-02 15:53:11 -05:00
|
|
|
touch $stateful_mount/dev_image/etc/lsb-factory
|
|
|
|
umount $stateful_mount
|
|
|
|
|
|
|
|
#mount and write to bootloader rootfs
|
|
|
|
local bootloader_mount=/tmp/shim_bootloader
|
|
|
|
safe_mount "${image_loop}p3" $bootloader_mount
|
|
|
|
cp -r $bootloader_dir/* $bootloader_mount
|
|
|
|
umount $bootloader_mount
|
|
|
|
|
2023-10-06 23:28:40 -05:00
|
|
|
#write rootfs to image
|
2023-10-20 07:04:19 -05:00
|
|
|
local rootfs_mount=/tmp/new_rootfs
|
2023-10-02 15:53:11 -05:00
|
|
|
safe_mount "${image_loop}p4" $rootfs_mount
|
2024-01-30 15:13:03 -06:00
|
|
|
if [ "$quiet" ]; then
|
|
|
|
rsync --archive --human-readable --hard-links --quiet --sparse $rootfs_dir/ $rootfs_mount/
|
|
|
|
else
|
|
|
|
rsync --archive --human-readable --hard-links --info=progress2 --sparse $rootfs_dir/ $rootfs_mount/
|
|
|
|
fi
|
2023-10-20 07:04:19 -05:00
|
|
|
umount $rootfs_mount
|
2023-10-02 15:53:11 -05:00
|
|
|
}
|
|
|
|
|
2023-10-02 15:23:01 -05:00
|
|
|
create_image() {
|
2024-01-25 15:19:25 -06:00
|
|
|
local image_path=$(realpath -m "${1}")
|
2023-10-02 15:23:01 -05:00
|
|
|
local bootloader_size=${2}
|
|
|
|
local rootfs_size=${3}
|
|
|
|
|
|
|
|
#stateful + kernel + bootloader + rootfs
|
|
|
|
local total_size=$((1 + 32 + $bootloader_size + $rootfs_size))
|
2023-10-20 15:51:56 -05:00
|
|
|
rm -rf "${image_path}"
|
|
|
|
fallocate -l "${total_size}M" "${image_path}"
|
2023-10-02 15:23:01 -05:00
|
|
|
|
|
|
|
partition_disk $image_path $bootloader_size
|
2023-12-21 00:09:41 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
patch_initramfs() {
|
2024-01-25 15:19:25 -06:00
|
|
|
local initramfs_path=$(realpath -m $1)
|
2023-12-21 00:09:41 -06:00
|
|
|
|
|
|
|
rm "${initramfs_path}/init" -f
|
|
|
|
cp -r bootloader/* "${initramfs_path}/"
|
|
|
|
|
|
|
|
find ${initramfs_path}/bin -name "*" -exec chmod +x {} \;
|
2024-05-13 13:03:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#clean up unused loop devices
|
|
|
|
clean_loops() {
|
|
|
|
local loop_devices="$(losetup -a | awk -F':' {'print $1'})"
|
|
|
|
for loop_device in $loop_devices; do
|
|
|
|
local mountpoints="$(cat /proc/mounts | grep "$loop_device")"
|
|
|
|
if [ ! "$mountpoints" ]; then
|
|
|
|
losetup -d $loop_device
|
|
|
|
else
|
|
|
|
echo "warning: not removing $loop_device because it is still mounted"
|
|
|
|
fi
|
|
|
|
done
|
2023-10-20 21:30:02 -05:00
|
|
|
}
|