diff --git a/alpine/build-rootfs.sh b/alpine/build-rootfs.sh index 8031868..9d4990f 100755 --- a/alpine/build-rootfs.sh +++ b/alpine/build-rootfs.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -euo pipefail + /preload-k8s-images.sh || exit 1 REGISTRY_DATA_DIR="${KUBE_IMG_CACHE}/registry-data/${ARCH}/${KUBE_VERSION}" @@ -11,6 +13,7 @@ cp -a "${REGISTRY_DATA_DIR}/." "${ROOTFS}/var/lib/registry/" mkdir -p "$ROOTFS/var/cache/apk" mkdir -p "$ROOTFS/var/cache/k8s-images" +mkdir -p "$ROOTFS/opt/monok8s/config" mkdir -p "$ROOTFS/build" mount --bind /var/cache/apk "$ROOTFS/var/cache/apk" @@ -51,12 +54,15 @@ rm -r "$ROOTFS/build" echo "##################################################### Packaging RootFS "$( du -sh "$ROOTFS/" ) IMG=output.img -SIZE=3072MB +SIZE=8GB dd if=/dev/zero of="$IMG" bs=1 count=0 seek=$SIZE sgdisk -o "$IMG" \ - -n 1:65536:-1M -t 1:8300 + -n 1:2048:+64M -t 1:0700 -c 1:config \ + -n 2:0:+3G -t 2:8300 -c 2:rootfsA \ + -n 3:0:+3G -t 3:8300 -c 3:rootfsB \ + -n 4:0:0 -t 4:8300 -c 4:data losetup -D LOOP=$(losetup --find --show -P "$IMG") @@ -64,11 +70,14 @@ LOOP=$(losetup --find --show -P "$IMG") /sync-loop.sh "$LOOP" TMP_LOOP="/tmp$LOOP" -mkfs.ext4 -F "${TMP_LOOP}p1" +mkfs.vfat -F 32 -n MONOK8S_CFG "${TMP_LOOP}p1" +mkfs.ext4 -F "${TMP_LOOP}p2" +mkfs.ext4 -F "${TMP_LOOP}p3" +mkfs.ext4 -F "${TMP_LOOP}p4" mkdir -p /mnt/img-root -mount "${TMP_LOOP}p1" /mnt/img-root +mount "${TMP_LOOP}p2" /mnt/img-root cp -a "$ROOTFS"/. /mnt/img-root/ diff --git a/alpine/rootfs-extra/etc/fstab b/alpine/rootfs-extra/etc/fstab new file mode 100644 index 0000000..0a60008 --- /dev/null +++ b/alpine/rootfs-extra/etc/fstab @@ -0,0 +1,2 @@ +PARTLABEL=config /opt/monok8s/config vfat defaults,noatime 0 0 +PARTLABEL=data /data ext4 defaults,noatime 0 21 diff --git a/docs/uboot.md b/docs/uboot.md new file mode 100644 index 0000000..8ec25f5 --- /dev/null +++ b/docs/uboot.md @@ -0,0 +1,70 @@ +Booting release image with bootusb + - Use this if you are flashing image from macos/flashusb.sh +``` +setenv bootusb ' +usb start; +setenv bootargs "console=ttyS0,115200 root=/dev/sda2 rw rootwait"; +ext4load usb 0:2 ${kernel_addr_r} /boot/Image.gz; +ext4load usb 0:2 ${fdt_addr_r} /boot/mono-gateway-dk-sdk.dtb; +booti ${kernel_addr_r} - ${fdt_addr_r} +' + +run bootusb +``` + +Booting into initramfs (board.itb in usb drive root) +``` +setenv bootusb 'usb start; ext4load usb 0:2 ${mks_loadaddr} /boot/kernel.itb; bootm ${mks_loadaddr}' +run bootusb +``` + + +Original uboot env from mono +``` +arch=arm +baudrate=115200 +board=gateway_dk +board_name=gateway_dk +bootargs_console=console=ttyS0,115200 earlycon=uart8250,mmio,0x21c0500 mtdparts=${mtdparts} +bootcmd=run emmc || run recovery +bootdelay=5 +cpu=armv8 +emmc=setenv bootargs "${bootargs_console} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 ${bootargs_hwtest}"; \ + ext4load mmc 0:1 ${kernel_addr_r} /boot/Image.gz && \ + ext4load mmc 0:1 ${fdt_addr_r} /boot/mono-gateway-dk-sdk.dtb && \ + booti ${kernel_addr_r} - ${fdt_addr_r} || \ + ext4load mmc 0:1 ${kernel_addr_r} /boot/kernel.itb && \ + bootm ${kernel_addr_r} +eth1addr=E8:F6:D7:00:1E:93 +eth2addr=E8:F6:D7:00:1E:94 +eth3addr=E8:F6:D7:00:1E:95 +eth4addr=E8:F6:D7:00:1E:96 +ethact=fm1-mac5 +ethaddr=E8:F6:D7:00:1E:92 +ethprime=fm1-mac5 +fdt_addr=0x500000 +fdt_addr_r=0x88000000 +fdt_size=0x100000 +fdtcontroladdr=fbc01220 +fman_ucode=fbc12d40 +fsl_bootcmd_mcinitcmd_set=y +kernel_addr=0xA00000 +kernel_addr_r=0x82000000 +kernel_comp_addr_r=0x90000000 +kernel_comp_size=0x1600000 +kernel_size=0x1600000 +load_addr=0xa0000000 +loadaddr=0xa0000000 +mks_loadaddr=0x80000000 +model=Mono Gateway Development Kit +mtdparts=1550000.spi:1M(rcw-bl2),2M(uboot),1M(uboot-env),1M(fman-ucode),1M(recovery-dtb),4M(unallocated),-(kernel-initramfs) +netmask=255.255.255.0 +ramdisk_addr_r=0x88080000 +recovery=setenv bootargs "${bootargs_console} rw rootwait quiet ${bootargs_hwtest}"; sf probe 0:0; sf read ${kernel_addr_r} ${kernel_addr} ${kernel_size}; sf read ${fdt_addr_r} ${fdt_addr} ${fdt_size}; booti ${kernel_addr_r} - ${fdt_addr_r} +serial_number=MT-R01A-0326-00747 +soc=fsl-layerscape +stderr=serial@21c0500 +stdin=serial@21c0500 +stdout=serial@21c0500 +vendor=freescale +``` diff --git a/initramfs/rootfs-extra/bin/flash-emmc.sh.tmpl b/initramfs/rootfs-extra/bin/flash-emmc.sh.tmpl index b3ed5e1..6ac1b08 100755 --- a/initramfs/rootfs-extra/bin/flash-emmc.sh.tmpl +++ b/initramfs/rootfs-extra/bin/flash-emmc.sh.tmpl @@ -2,16 +2,19 @@ set -eu MNT=/mnt -ROOT_MNT=/mnt-root +CONFIG_MNT=/mnt-config USB_DEV=/dev/sda EMMC_DEV=/dev/mmcblk0 -EMMC_ROOT_PART=/dev/mmcblk0p1 -CONFIG_DIR=/opt/monok8s/config + +EMMC_CONFIG_PART=/dev/mmcblk0p1 +EMMC_ROOTFS_A_PART=/dev/mmcblk0p2 +EMMC_ROOTFS_B_PART=/dev/mmcblk0p3 +EMMC_DATA_PART=/dev/mmcblk0p4 DEFAULT_GLOB="${MNT}/${BUILD_TAG}_RELEASE_IMAGE" cleanup() { - umount "$ROOT_MNT" 2>/dev/null || true + umount "$CONFIG_MNT" 2>/dev/null || true umount "$MNT" 2>/dev/null || true } @@ -61,7 +64,7 @@ wait_for_partition_ready() { return 1 } -mkdir -p "$MNT" "$ROOT_MNT" +mkdir -p "$MNT" "$CONFIG_MNT" trap cleanup EXIT log "Mounting USB..." @@ -108,7 +111,6 @@ echo printf "Type 'YES' to continue: " read -r CONFIRM - [ "$CONFIRM" = "YES" ] || die "Aborted." log "Flashing image to eMMC..." @@ -120,40 +122,45 @@ sync reread_partitions log "Waiting for partition nodes..." -if ! wait_for_partition_ready "$EMMC_ROOT_PART" 15; then +if ! wait_for_partition_ready "$EMMC_CONFIG_PART" 15; then warn "Initial partition scan did not settle; retrying after another reread..." reread_partitions sleep 2 - wait_for_partition_ready "$EMMC_ROOT_PART" 15 || die "root partition not ready: $EMMC_ROOT_PART" + wait_for_partition_ready "$EMMC_CONFIG_PART" 15 || die "config partition not ready: $EMMC_CONFIG_PART" fi +# These are useful sanity checks, but not strictly required for copying config. +wait_for_partition_ready "$EMMC_ROOTFS_A_PART" 5 || warn "rootfsA partition not ready yet: $EMMC_ROOTFS_A_PART" +wait_for_partition_ready "$EMMC_ROOTFS_B_PART" 5 || warn "rootfsB partition not ready yet: $EMMC_ROOTFS_B_PART" +wait_for_partition_ready "$EMMC_DATA_PART" 5 || warn "data partition not ready yet: $EMMC_DATA_PART" + log "Partition sizes:" -echo " $(basename "$EMMC_DEV"): $(get_sectors "$EMMC_DEV") sectors" -echo " $(basename "$EMMC_ROOT_PART"): $(get_sectors "$EMMC_ROOT_PART") sectors" +echo " $(basename "$EMMC_DEV"): $(get_sectors "$EMMC_DEV") sectors" +echo " $(basename "$EMMC_CONFIG_PART"): $(get_sectors "$EMMC_CONFIG_PART") sectors" +echo " $(basename "$EMMC_ROOTFS_A_PART"): $(get_sectors "$EMMC_ROOTFS_A_PART") sectors" +echo " $(basename "$EMMC_ROOTFS_B_PART"): $(get_sectors "$EMMC_ROOTFS_B_PART") sectors" +echo " $(basename "$EMMC_DATA_PART"): $(get_sectors "$EMMC_DATA_PART") sectors" if [ -n "$ENV_FILES" ]; then - log "Mounting flashed root partition..." - mount "$EMMC_ROOT_PART" "$ROOT_MNT" || { + log "Mounting flashed config partition..." + mount -t vfat "$EMMC_CONFIG_PART" "$CONFIG_MNT" || { warn "Mount failed; retrying once after partition reread..." reread_partitions sleep 2 - mount "$EMMC_ROOT_PART" "$ROOT_MNT" + mount -t vfat "$EMMC_CONFIG_PART" "$CONFIG_MNT" } - log "Creating config dir: $CONFIG_DIR" - mkdir -p "$ROOT_MNT$CONFIG_DIR" - - log "Copying env files..." + log "Copying env files to config partition..." for f in $ENV_FILES; do base="$(basename "$f")" - cp "$f" "$ROOT_MNT$CONFIG_DIR/$base" + cp "$f" "$CONFIG_MNT/$base" echo " copied: $base" done log "Syncing copied config..." sync - umount "$ROOT_MNT" + umount "$CONFIG_MNT" fi log "Done." diff --git a/macos/flashusb.sh b/macos/flashusb.sh new file mode 100755 index 0000000..53804fa --- /dev/null +++ b/macos/flashusb.sh @@ -0,0 +1,174 @@ +#!/bin/sh +set -eu + +### User-configurable vars +IMG="./out/monok8s-dev.img.gz" +DEFAULT_DISK="/dev/disk7" # whole disk, not a partition +CONFIG_PART_SUFFIX="s1" # config partition after flashing +ENV_SEARCH_DIR="./out" # optional; leave empty to use image dir + +MNT="/tmp/monok8s-usb-config.$$" + +cleanup() { + if mount | grep -q "on ${MNT} "; then + diskutil unmount "$MNT" >/dev/null 2>&1 || true + fi + rmdir "$MNT" >/dev/null 2>&1 || true +} + +log() { + echo "[*] $*" +} + +warn() { + echo "[!] $*" >&2 +} + +die() { + echo "[!] ERROR: $*" >&2 + exit 1 +} + +require_cmd() { + command -v "$1" >/dev/null 2>&1 || die "Missing required command: $1" +} + +wait_for_disk() { + dev="$1" + timeout="${2:-15}" + i=0 + while [ "$i" -lt "$timeout" ]; do + [ -e "$dev" ] && return 0 + i=$((i + 1)) + sleep 1 + done + return 1 +} + +wait_for_mountable_partition() { + dev="$1" + timeout="${2:-20}" + i=0 + while [ "$i" -lt "$timeout" ]; do + if [ -e "$dev" ] && diskutil info "$dev" >/dev/null 2>&1; then + return 0 + fi + i=$((i + 1)) + sleep 1 + done + return 1 +} + +### Sanity checks +require_cmd diskutil +require_cmd gunzip +require_cmd dd +require_cmd sync +require_cmd mount +require_cmd find +require_cmd cp +require_cmd sed +require_cmd stat +require_cmd pv + +printf "disk ($DEFAULT_DISK): " +read -r TARGET_DISK + +if [ -z "$TARGET_DISK" ]; then + TARGET_DISK="$DEFAULT_DISK" +fi + +TARGET_RAW_DISK="/dev/r$(basename "$TARGET_DISK")" +TARGET_BASENAME="$(basename "$TARGET_DISK")" + +### Derived vars +TARGET_CONFIG_PART="/dev/${TARGET_BASENAME}${CONFIG_PART_SUFFIX}" +IMG_DIR="$(cd "$(dirname "$IMG")" && pwd)" +SEARCH_DIR="${ENV_SEARCH_DIR:-$IMG_DIR}" +IMG_SIZE_BYTES="$(stat -f%z "$IMG")" + +[ -f "$IMG" ] || die "Image not found: $IMG" +[ -b "$TARGET_DISK" ] || die "Target disk not found: $TARGET_DISK" +[ "$(id -u)" -eq 0 ] || die "Run this script with sudo" + +case "$TARGET_DISK" in + /dev/disk[0-9]*) + ;; + *) + die "TARGET_DISK must look like /dev/diskN" + ;; +esac + +mkdir -p "$MNT" +trap cleanup EXIT + +log "Image: $IMG" +log "Compressed image size: $IMG_SIZE_BYTES bytes" +log "Target disk: $TARGET_DISK" +log "Raw target disk: $TARGET_RAW_DISK" +log "Expected config partition after flash: $TARGET_CONFIG_PART" + +log "Target disk info:" +diskutil info "$TARGET_DISK" || die "Unable to inspect target disk" + +echo +printf "Type 'YES' to continue: " +read -r CONFIRM +[ "$CONFIRM" = "YES" ] || die "Aborted." + +log "Unmounting target disk..." +diskutil unmountDisk force "$TARGET_DISK" || die "Failed to unmount $TARGET_DISK" + +log "Flashing image with progress..." +pv -s "$IMG_SIZE_BYTES" "$IMG" \ + | gunzip \ + | dd of="$TARGET_RAW_DISK" bs=1m + +log "Syncing writes..." +sync + +log "Ejecting and re-reading disk..." +diskutil eject "$TARGET_DISK" >/dev/null 2>&1 || true +sleep 2 + +log "Waiting for disk to come back..." +if ! wait_for_disk "$TARGET_DISK" 15; then + warn "Disk node did not reappear quickly. You may need to replug the drive." +fi + +log "Disk layout after flashing:" +diskutil list "$TARGET_DISK" || warn "Could not list flashed disk yet" + +ENV_FILES="$(find "$SEARCH_DIR" -maxdepth 1 -type f -name '*.env' | sort || true)" + +if [ -n "$ENV_FILES" ]; then + log "Found env files:" + echo "$ENV_FILES" | sed 's/^/ /' + + log "Waiting for config partition..." + wait_for_mountable_partition "$TARGET_CONFIG_PART" 20 || die "Config partition not ready: $TARGET_CONFIG_PART" + + log "Mounting flashed config partition..." + diskutil mount -mountPoint "$MNT" "$TARGET_CONFIG_PART" >/dev/null || die "Failed to mount $TARGET_CONFIG_PART" + + log "Copying env files to config partition..." + echo "$ENV_FILES" | while IFS= read -r f; do + [ -n "$f" ] || continue + base="$(basename "$f")" + cp "$f" "$MNT/$base" + echo " copied: $base" + done + + log "Syncing copied config..." + sync + + log "Config partition contents:" + ls -la "$MNT" || true + + log "Unmounting config partition..." + diskutil unmount "$MNT" >/dev/null || warn "Unmount failed for $MNT" +else + log "No .env files found in $SEARCH_DIR" +fi + +log "Done."