diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 32f2688..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,4 +0,0 @@ -include: - - project: serge/pi-gen - ref: ci - file: 'pi-gen.yml' diff --git a/README.md b/README.md index 604c7ce..c255d8d 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,8 @@ ChillcraftOS is a custom Raspberry Pi OS built using a system based on `pi-gen`. This build system is specifically designed to create **ChillcraftOS** images, not general Raspberry Pi OS images. **Important Notes:** -- The 32-bit versions of ChillcraftOS are based on Raspbian. -- The 64-bit versions of ChillcraftOS are based on Debian. -- For building 32-bit images, use the `master` branch. -- For building 64-bit images, use the `arm64` branch. +- The 32-bit versions of ChillcraftOS are based on Raspbian. +- The 64-bit versions of ChillcraftOS are based on Debian. ## Dependencies diff --git a/build.sh b/build.sh index 8e8c7a8..1643d5f 100755 --- a/build.sh +++ b/build.sh @@ -6,17 +6,50 @@ run_sub_stage() log "Begin ${SUB_STAGE_DIR}" pushd "${SUB_STAGE_DIR}" > /dev/null for i in {00..99}; do - if [ -f "${i}-debconf" ]; then + if [ -f "${i}-debconf-${ARCH}" ]; then + log "Begin ${SUB_STAGE_DIR}/${i}-debconf-${ARCH}" + on_chroot << EOF +debconf-set-selections < /dev/null + if [ "${CLEAN}" = "1" ]; then + rm -rf .pc + rm -rf ./*-pc + fi + QUILT_PATCHES="${SUB_STAGE_DIR}/${i}-patches-${ARCH}" + SUB_STAGE_QUILT_PATCH_DIR="$(basename "$SUB_STAGE_DIR")-pc" + mkdir -p "$SUB_STAGE_QUILT_PATCH_DIR" + ln -snf "$SUB_STAGE_QUILT_PATCH_DIR" .pc + quilt upgrade + if [ -e "${SUB_STAGE_DIR}/${i}-patches-${ARCH}/EDIT" ]; then + echo "Dropping into bash to edit patches..." + bash + fi + RC=0 + quilt push -a || RC=$? + case "$RC" in + 0|2) + ;; + *) + false + ;; + esac + popd > /dev/null + log "End ${SUB_STAGE_DIR}/${i}-patches-${ARCH}" + elif [ -d "${i}-patches-arm-only" ]; then + log "Begin ${SUB_STAGE_DIR}/${i}-patches-arm-only" + pushd "${STAGE_WORK_DIR}" > /dev/null + if [ "${CLEAN}" = "1" ]; then + rm -rf .pc + rm -rf ./*-pc + fi + QUILT_PATCHES="${SUB_STAGE_DIR}/${i}-patches-arm-only" + SUB_STAGE_QUILT_PATCH_DIR="$(basename "$SUB_STAGE_DIR")-pc" + mkdir -p "$SUB_STAGE_QUILT_PATCH_DIR" + ln -snf "$SUB_STAGE_QUILT_PATCH_DIR" .pc + quilt upgrade + if [ -e "${SUB_STAGE_DIR}/${i}-patches-arm-only/EDIT" ]; then + echo "Dropping into bash to edit patches..." + bash + fi + RC=0 + quilt push -a || RC=$? + case "$RC" in + 0|2) + ;; + *) + false + ;; + esac + popd > /dev/null + log "End ${SUB_STAGE_DIR}/${i}-patches-arm-only" + elif [ -d "${i}-patches" ]; then log "Begin ${SUB_STAGE_DIR}/${i}-patches" pushd "${STAGE_WORK_DIR}" > /dev/null if [ "${CLEAN}" = "1" ]; then @@ -64,12 +169,28 @@ EOF popd > /dev/null log "End ${SUB_STAGE_DIR}/${i}-patches" fi - if [ -x ${i}-run.sh ]; then + if [ -x ${i}-run-${ARCH}.sh ]; then + log "Begin ${SUB_STAGE_DIR}/${i}-run-${ARCH}.sh" + ./${i}-run-${ARCH}.sh + log "End ${SUB_STAGE_DIR}/${i}-run-${ARCH}.sh" + elif [ -x "${i}-run-arm-only.sh" ] && [[ "${ARCH}" == "arm64" || "${ARCH}" == "armhf" ]]; then + log "Begin ${SUB_STAGE_DIR}/${i}-run-arm-only.sh" + ./${i}-run-arm-only.sh + log "End ${SUB_STAGE_DIR}/${i}-run-arm-only.sh" + elif [ -x ${i}-run.sh ]; then log "Begin ${SUB_STAGE_DIR}/${i}-run.sh" ./${i}-run.sh log "End ${SUB_STAGE_DIR}/${i}-run.sh" fi - if [ -f ${i}-run-chroot.sh ]; then + if [ -f ${i}-run-chroot-${ARCH}.sh ]; then + log "Begin ${SUB_STAGE_DIR}/${i}-run-chroot-${ARCH}.sh" + on_chroot < ${i}-run-chroot-${ARCH}.sh + log "End ${SUB_STAGE_DIR}/${i}-run-chroot-${ARCH}.sh" + elif [ -f "${i}-run-chroot-arm-only.sh" ] && [[ "${ARCH}" == "arm64" || "${ARCH}" == "armhf" ]]; then + log "Begin ${SUB_STAGE_DIR}/${i}-run-chroot-arm-only.sh" + on_chroot < ${i}-run-chroot-arm-only.sh + log "End ${SUB_STAGE_DIR}/${i}-run-chroot-arm-only.sh" + elif [ -f ${i}-run-chroot.sh ]; then log "Begin ${SUB_STAGE_DIR}/${i}-run-chroot.sh" on_chroot < ${i}-run-chroot.sh log "End ${SUB_STAGE_DIR}/${i}-run-chroot.sh" @@ -177,7 +298,7 @@ export PI_GEN=${PI_GEN:-pi-gen} export PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen} export PI_GEN_RELEASE=${PI_GEN_RELEASE:-Raspberry Pi reference} -export ARCH=arm64 +export ARCH="${ARCH:-arm64}" export RELEASE=${RELEASE:-bookworm} export IMG_NAME="${IMG_NAME:-chillcraftos-$RELEASE-$ARCH}" @@ -190,20 +311,11 @@ export SCRIPT_DIR="${BASE_DIR}/scripts" export WORK_DIR="${WORK_DIR:-"${BASE_DIR}/work/${IMG_NAME}"}" export DEPLOY_DIR=${DEPLOY_DIR:-"${BASE_DIR}/deploy"} -# DEPLOY_ZIP was deprecated in favor of DEPLOY_COMPRESSION -# This preserve the old behavior with DEPLOY_ZIP=0 where no archive was created -if [ -z "${DEPLOY_COMPRESSION}" ] && [ "${DEPLOY_ZIP:-1}" = "0" ]; then - echo "DEPLOY_ZIP has been deprecated in favor of DEPLOY_COMPRESSION" - echo "Similar behavior to DEPLOY_ZIP=0 can be obtained with DEPLOY_COMPRESSION=none" - echo "Please update your config file" - DEPLOY_COMPRESSION=none -fi export DEPLOY_COMPRESSION=${DEPLOY_COMPRESSION:-xz} export COMPRESSION_LEVEL=${COMPRESSION_LEVEL:-6} export LOG_FILE="${WORK_DIR}/build.log" -export TARGET_HOSTNAME=${TARGET_HOSTNAME:-raspberrypi} - +export TARGET_HOSTNAME=${TARGET_HOSTNAME:-chillcraftos} export FIRST_USER_NAME=${FIRST_USER_NAME:-system} export FIRST_USER_PASS export DISABLE_FIRST_BOOT_USER_RENAME=${DISABLE_FIRST_BOOT_USER_RENAME:-0} diff --git a/build_amd64 b/build_amd64 new file mode 100644 index 0000000..92ac6f4 --- /dev/null +++ b/build_amd64 @@ -0,0 +1 @@ +ARCH=amd64 diff --git a/build_arm64 b/build_arm64 new file mode 100644 index 0000000..c6b56f9 --- /dev/null +++ b/build_arm64 @@ -0,0 +1 @@ +ARCH=arm64 diff --git a/export-image/mk-img.sh b/export-image/mk-img.sh index 796c77e..d562500 100755 --- a/export-image/mk-img.sh +++ b/export-image/mk-img.sh @@ -14,23 +14,25 @@ ROOT_SIZE=$(du -x --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/ # All partition sizes and starts will be aligned to this size ALIGN="$((4 * 1024 * 1024))" -# Add this much space to the calculated file size. This allows for -# some overhead (since actual space usage is usually rounded up to the -# filesystem block size) and gives some free space on the resulting -# image. ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 400 * 1024 * 1024) / 1" | bc)" +# Recovery partition fixed size: 256MB +RECOVERY_SIZE="$((256 * 1024 * 1024))" + BOOT_PART_START=$((ALIGN)) BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN)) ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE)) -ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) -IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE)) +ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) +RECOVERY_PART_START=$((ROOT_PART_START + ROOT_PART_SIZE)) +RECOVERY_PART_SIZE=$(((RECOVERY_SIZE + ALIGN - 1) / ALIGN * ALIGN)) +IMG_SIZE=$((RECOVERY_PART_START + RECOVERY_PART_SIZE)) truncate -s "${IMG_SIZE}" "${IMG_FILE}" parted --script "${IMG_FILE}" mklabel msdos parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))" parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))" +parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${RECOVERY_PART_START}" "$((RECOVERY_PART_START + RECOVERY_PART_SIZE - 1))" echo "Creating loop device..." cnt=0 @@ -48,12 +50,13 @@ done ensure_loopdev_partitions "$LOOP_DEV" BOOT_DEV="${LOOP_DEV}p1" ROOT_DEV="${LOOP_DEV}p2" +RECOVERY_DEV="${LOOP_DEV}p3" ROOT_FEATURES="^huge_file" for FEATURE in 64bit; do -if grep -q "$FEATURE" /etc/mke2fs.conf; then - ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES" -fi + if grep -q "$FEATURE" /etc/mke2fs.conf; then + ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES" + fi done if [ "$BOOT_SIZE" -lt 134742016 ]; then @@ -64,6 +67,7 @@ fi mkdosfs -n bootfs -F "$FAT_SIZE" -s 4 -v "$BOOT_DEV" > /dev/null mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null +mkfs.ext4 -L recovery -O "$ROOT_FEATURES" "$RECOVERY_DEV" > /dev/null mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4 mkdir -p "${ROOTFS_DIR}/boot/firmware" @@ -71,3 +75,5 @@ mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot/firmware" -t vfat rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot/firmware "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/" rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/firmware/" "${ROOTFS_DIR}/boot/firmware/" + +echo "Image created with boot, rootfs, and 256MB recovery partition." \ No newline at end of file diff --git a/export-image/mk-iso.sh b/export-image/mk-iso.sh index c057626..683dea2 100755 --- a/export-image/mk-iso.sh +++ b/export-image/mk-iso.sh @@ -5,32 +5,33 @@ ISO_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.iso" unmount_image "${ISO_FILE}" rm -f "${ISO_FILE}" - rm -rf "${ROOTFS_DIR}" mkdir -p "${ROOTFS_DIR}" -BOOT_SIZE="$((512 * 1024 * 1024))" +BOOT_SIZE=$((512 * 1024 * 1024)) +RECOVERY_SIZE=$((256 * 1024 * 1024)) # 256MB recovery partition ROOT_SIZE=$(du -x --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot/firmware --block-size=1 | cut -f 1) -# All partition sizes and starts will be aligned to this size -ALIGN="$((4 * 1024 * 1024))" -# Add this much space to the calculated file size. This allows for -# some overhead (since actual space usage is usually rounded up to the -# filesystem block size) and gives some free space on the resulting -# image. +ALIGN=$((4 * 1024 * 1024)) ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)" BOOT_PART_START=$((ALIGN)) BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN)) + ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE)) -ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) -IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE)) +ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) + +RECOVERY_PART_START=$((ROOT_PART_START + ROOT_PART_SIZE)) +RECOVERY_PART_SIZE=$(((RECOVERY_SIZE + ALIGN - 1) / ALIGN * ALIGN)) + +IMG_SIZE=$((RECOVERY_PART_START + RECOVERY_PART_SIZE)) truncate -s "${IMG_SIZE}" "${ISO_FILE}" parted --script "${ISO_FILE}" mklabel msdos parted --script "${ISO_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))" parted --script "${ISO_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))" +parted --script "${ISO_FILE}" unit B mkpart primary ext4 "${RECOVERY_PART_START}" "$((RECOVERY_PART_START + RECOVERY_PART_SIZE - 1))" echo "Creating loop device..." cnt=0 @@ -48,6 +49,7 @@ done ensure_loopdev_partitions "$LOOP_DEV" BOOT_DEV="${LOOP_DEV}p1" ROOT_DEV="${LOOP_DEV}p2" +RECOVERY_DEV="${LOOP_DEV}p3" ROOT_FEATURES="^huge_file" for FEATURE in 64bit; do @@ -64,6 +66,7 @@ fi mkdosfs -n bootfs -F "$FAT_SIZE" -s 4 -v "$BOOT_DEV" > /dev/null mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null +mkfs.ext4 -L recovery "$RECOVERY_DEV" > /dev/null mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4 mkdir -p "${ROOTFS_DIR}/boot/firmware" @@ -72,11 +75,17 @@ mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot/firmware" -t vfat rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot/firmware "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/" rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/firmware/" "${ROOTFS_DIR}/boot/firmware/" +# Optionally mount and populate the recovery partition +mkdir -p "${ROOTFS_DIR}/recovery" +mount -v "$RECOVERY_DEV" "${ROOTFS_DIR}/recovery" -t ext4 + +# (Optional) Example: copy recovery script +# cp recovery-tools/recovery.sh "${ROOTFS_DIR}/recovery/" + # Create bootable ISO with GRUB echo "Creating bootable ISO..." mkdir -p "${ROOTFS_DIR}/boot/grub" -# Install GRUB bootloader cat > "${ROOTFS_DIR}/boot/grub/grub.cfg" <