Include initial init script and build script

This commit is contained in:
jumperfly 2016-11-16 19:19:01 +00:00 committed by Sam Liddell
parent 80724147e4
commit 08a85a5acc
4 changed files with 191 additions and 1 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
target
busybox-cache

View file

@ -1,2 +1,36 @@
# initramfs-overlay
Initramfs focussed on mounting a read only image with writeable overlay using overlayfs
Initramfs focussed on mounting a read only image with writeable overlay using overlayfs.
## Disk partitions
The following disk partitions are expected, currently located by label:
* The image partition (ext4,LABEL=img): Contains the OS squashfs image to mount and boot.
* The overlay partition (ext4,LABEL=overlay): Writeable partition overlaid with the OS image, cleared each boot.
* The boot partition (vfat,LABEL=boot): Optional for initframfs, contains the kernel plus squashfs module (if not in kernel).
* The new image partition (ext4,LABEL=newimg): Optional, can be used to provide an updated OS image.
### The boot partition
If the partition is detected, the squashfs module will be loaded from /modules/<kernel-version>/squashfs.ko if the module existed. Otherwise it is assumed the kernel has build-in support for squashfs.
### The overlay partition
This is used as the writeable area of the overlay and consists of three directories which are created if not preset:
* /upper: Used for the 'upperdir' of the overlayfs. This is where all deleted/modified/created files are stored. This is cleared on each boot.
* /work: Used for the 'workdir' of the overlayfs.
* /persistent: Used as an additional 'lowerdir' of the overlayfs. As the 'upperdir' is cleared, this read-only lower dir allows customisations to be made compared to the read-only OS image.
### The image partition
This must contain a single file, root-squashfs.img which contains the full operating system.
### The new image partition.
If the partition is detected and contains an image file with the same name as the one that will be mounted from the image partition it will be moved into the image partition. The previous image will be renamed <name>-old.img
## Project structure
The build.sh script will generate two initramfs files per architecture into a 'target' directory.
* init-<version>-<arch>.gz - The 'standard' initramfs. This should be used in most cases.
* init-<version>-<arch>-debug.gz - The 'debug' initramfs. This will load a shell before booting to allow any checks to made, type 'exit' to boot. Also it will load a shell if an error occurs, rather than exiting immediately resulting in a shutdown.
Currently three architectures are built:
* armv6l
* i686
* x86_64
The build will include all files under 'src' in the intramfs. A busybox binary (cached into 'busybox-cache') is also placed under /bin/busybox and corresponding symlinks for all commands supported by busybox.

61
build.sh Executable file
View file

@ -0,0 +1,61 @@
#!/bin/bash
set -e
PROJECT_VERSION="0.1.0"
BUSYBOX_VERSION="1.21.1"
BUSYBOX_BASE_URL="https://busybox.net/downloads/binaries/$BUSYBOX_VERSION"
declare -A BUSYBOX_MD5=(
["armv6l"]="d9b9d2245c2df526a8e373340f1e3b5a"
["i686"]="130e3ccda88aa313faee5be1af8ec21b"
["x86_64"]="d1a32f63fef8e639a63d85e46753c0ae" )
function verifyBusybox {
arch=$1
md5=($(md5sum busybox-cache/busybox-$arch))
if [[ $md5 != ${BUSYBOX_MD5[$arch]} ]]; then
return 1
fi
}
# Clean
if [ -e target ]; then
rm -rf target
fi
mkdir target
mkdir -p busybox-cache
# Build image for each arch
for arch in ${!BUSYBOX_MD5[@]}; do
# Download/verify busybox binaries
if ! verifyBusybox $arch; then
echo "File busybox-$arch does not exist or failed checksum validation, downloading..."
wget $BUSYBOX_BASE_URL/busybox-$arch -O busybox-cache/busybox-$arch
if ! verifyBusybox $arch; then
echo "Checksum validation failed for busybox-$arch" >&2
exit 1
fi
fi
# Create base
INIT_DIR=target/$arch
mkdir -p $INIT_DIR/{boot,bin,dev,etc,lib,mnt,proc,sbin,sys,tmp}
cp -rf src/* $INIT_DIR
cp -f busybox-cache/busybox-$arch $INIT_DIR/bin/busybox
chmod 755 $INIT_DIR/bin/busybox
for bbcmd in $($INIT_DIR/bin/busybox --list); do
ln -s busybox $INIT_DIR/bin/$bbcmd
done
cd $INIT_DIR
find . | cpio -H newc -o | gzip > ../init-$PROJECT_VERSION-$arch.gz
cd ../..
# Create debug (start shell before switching root, start shell on error instead of exiting)
cp -r $INIT_DIR $INIT_DIR-debug
INIT_DIR=$INIT_DIR-debug
sed -i -r '/# End mounting OS filesystems/a sh' $INIT_DIR/init
sed -i -r 's/exit 1/sh/' $INIT_DIR/init
cd $INIT_DIR
find . | cpio -H newc -o | gzip > ../init-$PROJECT_VERSION-$arch-debug.gz
cd ../..
done

92
src/init Executable file
View file

@ -0,0 +1,92 @@
#!/bin/busybox sh
MAX_WAIT=10
BOOT_DEVICE="LABEL=boot"
IMG_DEVICE="LABEL=img"
NEWIMG_DEVICE="LABEL=newimg"
OVERLAY_DEVICE="LABEL=overlay"
OS_IMAGE="root-squash.img"
### Begin creating mount points
for dir in root img newimg lower overlay; do
mkdir -p /mnt/$dir
done
### End creating mount points
### Begin mounting special fs
mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
### End mounting special fs
### Begin mounting OS file systems
# Wait for devices to become available
ATTEMPTS=0
while [[ $ATTEMPTS -lt $MAX_WAIT ]] && ! findfs $OVERLAY_DEVICE > /dev/null; do
sleep 1
let ATTEMPTS=ATTEMPTS+1
done
if [[ $ATTEMPTS -eq $MAX_WAIT ]]; then
echo "***** Boot device not detected: $OVERLAY_DEVICE *****" >&2
echo "Exiting..." >&2
sleep 5
exit 1
fi
# Mount device containing updated image (if any)
mount -t ext4 $NEWIMG_DEVICE /mnt/newimg
if [[ -e /mnt/newimg/$OS_IMAGE ]]; then
# Mount device containing current image RW and replace with updated image
mount -t ext4 $IMG_DEVICE /mnt/img
mv -f /mnt/newimg/$OS_IMAGE /mnt/img/$OS_IMAGE-new
mv -f /mnt/img/$OS_IMAGE /mnt/img/$OS_IMAGE-old
mv /mnt/img/$OS_IMAGE-new /mnt/img/$OS_IMAGE
umount /mnt/img
fi
umount /mnt/newimg
# Mount device containing current image RO
mount -t ext4 -o ro $IMG_DEVICE /mnt/img
# Mount boot device and load squashfs module if present
mount -t vfat -o ro $BOOT_DEVICE /boot
if [[ -e /boot/modules/$(uname -r)/squashfs.ko ]]; then
insmod /boot/modules/$(uname -r)/squashfs.ko
fi
umount /boot
# Mount OS image
mount -t squashfs -o ro /mnt/img/root-squash.img /mnt/lower
# Load overlay module if present on OS image
if [[ -e /mnt/lower/lib/modules/$(uname -r)/kernel/fs/overlayfs/overlay.ko ]]; then
insmod /mnt/lower/lib/modules/$(uname -r)/kernel/fs/overlayfs/overlay.ko
fi
# Mount device for writeable overlay and workdir
mount -t ext4 $OVERLAY_DEVICE /mnt/overlay
# Clear upper overlay dir
if [[ -e /mnt/overlay/upper ]]; then
rm -rf /mnt/overlay/upper
fi
# Create base directories if not present
for dir in persistent upper work; do
mkdir -p /mnt/overlay/$dir
done
# Mount root file system (overlay)
mount -t overlay -o ro,lowerdir=/mnt/overlay/persistent:/mnt/lower,upperdir=/mnt/overlay/upper,workdir=/mnt/overlay/work overlay /mnt/root
### End mounting OS filesystems
### Begin unmounting special fs
umount /proc
umount /sys
umount /dev
### End mounting special fs
### Begin switching root
exec switch_root /mnt/root /sbin/init
### End switching root