276 lines
9.0 KiB
Bash
Executable File
276 lines
9.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# Bananarchy Linux (MSM8909 / Sxmo) Image Builder
|
|
# Supports: nokia-argon (8110 4G), nokia-beatles (2720 Flip),
|
|
# nokia-tough (800 Tough), nokia-sparkler (8000 4G), nokia-leo (6300 4G)
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
if [ -n "${ROOTFS_DIR:-}" ]; then
|
|
ROOTFS_HOST="$(realpath "$ROOTFS_DIR")"
|
|
elif [ -d "$SCRIPT_DIR/rootfs-sxmo" ]; then
|
|
ROOTFS_HOST="$(realpath "$SCRIPT_DIR/rootfs-sxmo")"
|
|
else
|
|
ROOTFS_HOST="$(realpath "$SCRIPT_DIR/rootfs")"
|
|
fi
|
|
|
|
mkdir -p "${IMAGES_DIR:-$SCRIPT_DIR/images}"
|
|
IMAGES_HOST="$(realpath "${IMAGES_DIR:-$SCRIPT_DIR/images}")"
|
|
BANANARCHY_DIR="$SCRIPT_DIR"
|
|
|
|
TARGET_DEVICE="nokia-argon"
|
|
RUN_MKINITFS=""
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--mkinitfs)
|
|
RUN_MKINITFS="--mkinitfs"
|
|
;;
|
|
sxmo|all|nokia-argon|argon)
|
|
TARGET_DEVICE="nokia-argon"
|
|
;;
|
|
nokia-beatles|beatles)
|
|
TARGET_DEVICE="nokia-beatles"
|
|
;;
|
|
nokia-tough|nokia-coconut|tough|coconut)
|
|
TARGET_DEVICE="nokia-tough"
|
|
;;
|
|
nokia-sparkler|sparkler)
|
|
TARGET_DEVICE="nokia-sparkler"
|
|
;;
|
|
nokia-leo|leo)
|
|
TARGET_DEVICE="nokia-leo"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [nokia-argon|nokia-beatles|nokia-tough|nokia-sparkler|nokia-leo] [--mkinitfs]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
mkdir -p "$IMAGES_HOST"
|
|
|
|
docker run --rm -v "$ROOTFS_HOST:/rootfs" alpine:3.24 chown -R "$(id -u):$(id -g)" /rootfs
|
|
|
|
if [ -x "$BANANARCHY_DIR/scripts/apply-bananarchy-overlay.sh" ]; then
|
|
"$BANANARCHY_DIR/scripts/apply-bananarchy-overlay.sh" "$ROOTFS_HOST" "$TARGET_DEVICE"
|
|
fi
|
|
|
|
exec docker run --rm --network=host \
|
|
-e HOST_UID="$(id -u)" \
|
|
-e HOST_GID="$(id -g)" \
|
|
-e TARGET_DEVICE="$TARGET_DEVICE" \
|
|
-e RUN_MKINITFS="$RUN_MKINITFS" \
|
|
-v "$ROOTFS_HOST:/rootfs" \
|
|
-v "$IMAGES_HOST:/images" \
|
|
-v "$BANANARCHY_DIR:/bananarchy:ro" \
|
|
alpine:3.24 sh -eu -c '
|
|
cat > /etc/apk/repositories <<EOF
|
|
https://mirror.nura.eco/postmarketos/v26.06
|
|
https://dl-cdn.alpinelinux.org/alpine/edge/main
|
|
https://dl-cdn.alpinelinux.org/alpine/edge/community
|
|
https://dl-cdn.alpinelinux.org/alpine/edge/testing
|
|
EOF
|
|
cp /bananarchy/keys/* /etc/apk/keys/
|
|
|
|
apk add --no-cache \
|
|
busybox-static \
|
|
kmod \
|
|
postmarketos-mkinitfs \
|
|
boot-deploy \
|
|
mkbootimg \
|
|
devicepkg-utils \
|
|
e2fsprogs \
|
|
e2fsprogs-extra \
|
|
util-linux \
|
|
sfdisk \
|
|
coreutils \
|
|
android-tools \
|
|
zstd >/dev/null
|
|
|
|
ROOTFS="/rootfs"
|
|
BOOT_UUID="a1b2c3d4-8110-4000-8000-000000000001"
|
|
ROOT_UUID="a1b2c3d4-8110-4000-8000-000000000002"
|
|
|
|
echo "============================================================"
|
|
echo "Building Bananarchy Linux (Sxmo 240x320) for: $TARGET_DEVICE"
|
|
echo "Source rootfs: $ROOTFS"
|
|
echo "============================================================"
|
|
|
|
echo "[1/5] Normalizing rootfs permissions and UIDs/GIDs..."
|
|
chown -R 0:0 "$ROOTFS"
|
|
chmod 700 "$ROOTFS/root" 2>/dev/null || true
|
|
chmod 1777 "$ROOTFS/tmp" "$ROOTFS/var/tmp" 2>/dev/null || true
|
|
chmod 555 "$ROOTFS/var/empty" 2>/dev/null || true
|
|
chmod 750 "$ROOTFS/etc/doas.d" "$ROOTFS/etc/polkit-1/rules.d" 2>/dev/null || true
|
|
if [ -e "$ROOTFS/etc/shadow" ]; then
|
|
chown 0:42 "$ROOTFS/etc/shadow"
|
|
chmod 640 "$ROOTFS/etc/shadow"
|
|
fi
|
|
if [ -e "$ROOTFS/etc/shadow-" ]; then
|
|
chown 0:42 "$ROOTFS/etc/shadow-"
|
|
chmod 640 "$ROOTFS/etc/shadow-"
|
|
fi
|
|
rm -f "$ROOTFS/etc/doas.d/wheel.conf"
|
|
if [ -e "$ROOTFS/etc/doas.d/50-sxmo.conf" ]; then
|
|
chmod 600 "$ROOTFS/etc/doas.d/50-sxmo.conf"
|
|
fi
|
|
if [ -e "$ROOTFS/etc/sudoers.d/wheel" ]; then
|
|
chmod 440 "$ROOTFS/etc/sudoers.d/wheel"
|
|
fi
|
|
MB_GID="$(awk -F: "/^messagebus:/ {print \$3}" "$ROOTFS/etc/group" 2>/dev/null || true)"
|
|
MB_GID="${MB_GID:-103}"
|
|
if [ -e "$ROOTFS/usr/libexec/dbus-daemon-launch-helper" ]; then
|
|
chown "0:$MB_GID" "$ROOTFS/usr/libexec/dbus-daemon-launch-helper"
|
|
chmod 4750 "$ROOTFS/usr/libexec/dbus-daemon-launch-helper"
|
|
fi
|
|
PK_UID="$(awk -F: "/^polkitd:/ {print \$3}" "$ROOTFS/etc/passwd" 2>/dev/null || true)"
|
|
PK_GID="$(awk -F: "/^polkitd:/ {print \$3}" "$ROOTFS/etc/group" 2>/dev/null || true)"
|
|
if [ -n "$PK_UID" ] && [ -n "$PK_GID" ] && [ -d "$ROOTFS/etc/polkit-1/rules.d" ]; then
|
|
chown "$PK_UID:$PK_GID" "$ROOTFS/etc/polkit-1/rules.d"
|
|
chmod 750 "$ROOTFS/etc/polkit-1/rules.d"
|
|
fi
|
|
if [ -e "$ROOTFS/usr/sbin/unix_chkpwd" ]; then
|
|
chown 0:42 "$ROOTFS/usr/sbin/unix_chkpwd"
|
|
chmod 2755 "$ROOTFS/usr/sbin/unix_chkpwd"
|
|
fi
|
|
if [ -e "$ROOTFS/usr/bin/wall" ]; then
|
|
chown 0:5 "$ROOTFS/usr/bin/wall"
|
|
chmod 2755 "$ROOTFS/usr/bin/wall"
|
|
fi
|
|
for suid_bin in \
|
|
"$ROOTFS/bin/su" \
|
|
"$ROOTFS/bin/mount" \
|
|
"$ROOTFS/bin/umount" \
|
|
"$ROOTFS/usr/bin/Xorg" \
|
|
"$ROOTFS/usr/bin/doas" \
|
|
"$ROOTFS/usr/bin/sudo" \
|
|
"$ROOTFS/usr/bin/pkexec" \
|
|
"$ROOTFS/usr/lib/polkit-1/polkit-agent-helper-1" \
|
|
"$ROOTFS/usr/bin/fusermount3" \
|
|
"$ROOTFS/usr/bin/passwd" \
|
|
"$ROOTFS/usr/bin/gpasswd" \
|
|
"$ROOTFS/usr/bin/chsh" \
|
|
"$ROOTFS/usr/bin/chfn" \
|
|
"$ROOTFS/usr/bin/chage" \
|
|
"$ROOTFS/usr/bin/expiry"; do
|
|
if [ -e "$suid_bin" ] && [ ! -L "$suid_bin" ]; then
|
|
chmod 4755 "$suid_bin"
|
|
fi
|
|
done
|
|
if [ -d "$ROOTFS/home/user" ]; then
|
|
chown -R 10000:10000 "$ROOTFS/home/user"
|
|
fi
|
|
|
|
depmod -b "$ROOTFS" 6.12.1-msm8916
|
|
|
|
if [ "$RUN_MKINITFS" = "--mkinitfs" ] || [ ! -f "$ROOTFS/boot/boot.img" ]; then
|
|
echo "[2/5] Running depmod and mkinitfs inside $ROOTFS..."
|
|
rm -rf "$ROOTFS/tmp/hostbin"
|
|
mkdir -p "$ROOTFS/tmp/hostbin"
|
|
cp /bin/busybox.static "$ROOTFS/tmp/hostbin/busybox.static"
|
|
for app in $(/bin/busybox.static --list); do
|
|
ln -sf /tmp/hostbin/busybox.static "$ROOTFS/tmp/hostbin/$app"
|
|
done
|
|
for bin in \
|
|
/sbin/depmod \
|
|
/usr/sbin/mkinitfs \
|
|
/usr/bin/boot-deploy \
|
|
/usr/bin/generate-kernel-cmdline \
|
|
/usr/bin/mkbootimg \
|
|
/usr/bin/mkbootimg-osm0sis \
|
|
/usr/bin/zstd; do
|
|
if [ -e "$bin" ]; then
|
|
cp -L "$bin" "$ROOTFS/tmp/hostbin/"
|
|
fi
|
|
done
|
|
rm -f "$ROOTFS/tmp/hostbin/df"
|
|
cat > "$ROOTFS/tmp/hostbin/df" <<EOF
|
|
#!/tmp/hostbin/sh
|
|
printf "Filesystem 1024-blocks Used Available Capacity Mounted on\n/dev/root 52428800 5242880 47185920 10%% /\n"
|
|
EOF
|
|
chmod +x "$ROOTFS/tmp/hostbin/df"
|
|
mkdir -p "$ROOTFS/proc/1/root"
|
|
cp /lib/ld-musl-x86_64.so.1 "$ROOTFS/lib/"
|
|
cp -a /usr/lib/libgcc_s.so* "$ROOTFS/tmp/hostbin/" 2>/dev/null || true
|
|
cp -a /lib/libz.so* /usr/lib/libzstd.so* /usr/lib/liblzma.so* /lib/libcrypto.so* "$ROOTFS/tmp/hostbin/" 2>/dev/null || true
|
|
ln -sf /tmp/hostbin/busybox.static "$ROOTFS/bin/sh"
|
|
|
|
chroot "$ROOTFS" /tmp/hostbin/busybox.static sh -e -c "
|
|
export PATH=/tmp/hostbin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
export LD_LIBRARY_PATH=/tmp/hostbin:/lib:/usr/lib
|
|
/tmp/hostbin/mkinitfs
|
|
"
|
|
|
|
ln -sf /bin/busybox "$ROOTFS/bin/sh"
|
|
rm -rf "$ROOTFS/tmp/hostbin" "$ROOTFS/lib/ld-musl-x86_64.so.1" "$ROOTFS/proc/1"
|
|
else
|
|
echo "[2/5] Using existing $ROOTFS/boot/boot.img (pass --mkinitfs to regenerate)..."
|
|
fi
|
|
|
|
cp "$ROOTFS/boot/boot.img" "/images/boot-bananarchy-$TARGET_DEVICE.img"
|
|
if [ "$TARGET_DEVICE" = "nokia-argon" ]; then
|
|
cp "$ROOTFS/boot/boot.img" "/images/boot-nokia-argon-sxmo.img"
|
|
fi
|
|
|
|
echo "[3/5] Creating ext2 boot (256 MiB) and ext4 root filesystems..."
|
|
BOOT_IMG="/tmp/boot.ext2"
|
|
ROOT_IMG="/tmp/root.ext4"
|
|
rm -f "$BOOT_IMG" "$ROOT_IMG"
|
|
|
|
BOOT_MB=256
|
|
truncate -s "${BOOT_MB}M" "$BOOT_IMG"
|
|
mke2fs -t ext2 -F -q -L "pmOS_boot" -U "$BOOT_UUID" -d "$ROOTFS/boot" "$BOOT_IMG"
|
|
|
|
USED_KB="$(du -sk "$ROOTFS" | awk "{print \$1}")"
|
|
ROOT_MB=$(( (USED_KB / 1024) * 125 / 100 + 160 ))
|
|
|
|
SAVED_BOOT="/tmp/saved-boot"
|
|
rm -rf "$SAVED_BOOT"
|
|
mv "$ROOTFS/boot" "$SAVED_BOOT"
|
|
mkdir -p "$ROOTFS/boot"
|
|
chown 0:0 "$ROOTFS/boot"
|
|
chmod 755 "$ROOTFS/boot"
|
|
|
|
truncate -s "${ROOT_MB}M" "$ROOT_IMG"
|
|
mke2fs -t ext4 -O ^metadata_csum -F -q -L "pmOS_root" -i 8192 -U "$ROOT_UUID" -d "$ROOTFS" "$ROOT_IMG"
|
|
|
|
rm -rf "$ROOTFS/boot"
|
|
mv "$SAVED_BOOT" "$ROOTFS/boot"
|
|
|
|
echo "[4/5] Assembling partitioned MBR raw image and Android sparse image..."
|
|
RAW_IMG="/images/bananarchy-$TARGET_DEVICE.img"
|
|
SPARSE_IMG="/images/bananarchy-$TARGET_DEVICE.sparse.img"
|
|
TOTAL_MB=$(( 1 + BOOT_MB + ROOT_MB ))
|
|
rm -f "$RAW_IMG" "$SPARSE_IMG"
|
|
truncate -s "${TOTAL_MB}M" "$RAW_IMG"
|
|
|
|
BOOT_SECTORS=$(( BOOT_MB * 2048 ))
|
|
ROOT_START_SECTOR=$(( 2048 + BOOT_SECTORS ))
|
|
|
|
sfdisk --quiet "$RAW_IMG" <<SFEOF
|
|
label: dos
|
|
unit: sectors
|
|
|
|
start=2048, size=$BOOT_SECTORS, type=83, bootable
|
|
start=$ROOT_START_SECTOR, type=83
|
|
SFEOF
|
|
|
|
dd if="$BOOT_IMG" of="$RAW_IMG" bs=1M seek=1 conv=notrunc,sparse status=none
|
|
dd if="$ROOT_IMG" of="$RAW_IMG" bs=1M seek=$(( 1 + BOOT_MB )) conv=notrunc,sparse status=none
|
|
rm -f "$BOOT_IMG" "$ROOT_IMG"
|
|
|
|
img2simg "$RAW_IMG" "$SPARSE_IMG"
|
|
|
|
if [ "$TARGET_DEVICE" = "nokia-argon" ]; then
|
|
ln -f "$RAW_IMG" "/images/nokia-argon-sxmo.img"
|
|
ln -f "$SPARSE_IMG" "/images/nokia-argon-sxmo.sparse.img"
|
|
fi
|
|
|
|
echo "[5/5] Restoring host user ownership on $ROOTFS for easy host editing..."
|
|
chown -R "$HOST_UID:$HOST_GID" "$ROOTFS" "/images"
|
|
chmod -R u+rwX "$ROOTFS"
|
|
|
|
echo "Built Bananarchy images for $TARGET_DEVICE:"
|
|
ls -lh "/images/boot-bananarchy-$TARGET_DEVICE.img" "$RAW_IMG" "$SPARSE_IMG"
|
|
'
|