init commit

This commit is contained in:
Luxferre
2026-10-19 09:23:54 +03:00
commit 6942acf5cf
307 changed files with 35003 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
#!/bin/sh
# Apply Bananarchy prebuilt binaries, DTBs, panel firmwares, artwork, and Sxmo 240x320 overlay to a target rootfs
set -eu
BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
TARGET_ROOTFS="${1:-${ROOTFS_DIR:-$BASE_DIR/rootfs}}"
DEVICE="${2:-nokia-argon}"
if [ ! -d "$TARGET_ROOTFS" ]; then
echo "Error: Target rootfs directory does not exist: $TARGET_ROOTFS" >&2
exit 1
fi
case "$DEVICE" in
nokia-argon|argon)
DEVICE="nokia-argon"
DTB_FILE="qcom-msm8905-nokia-argon.dtb"
;;
nokia-beatles|beatles)
DEVICE="nokia-beatles"
DTB_FILE="qcom-msm8905-nokia-beatles.dtb"
;;
nokia-tough|nokia-coconut|tough|coconut)
DEVICE="nokia-tough"
DTB_FILE="qcom-msm8905-nokia-coconut.dtb"
;;
nokia-sparkler|sparkler)
DEVICE="nokia-sparkler"
DTB_FILE="qcom-msm8909-nokia-sparkler.dtb"
;;
nokia-leo|leo)
DEVICE="nokia-sparkler"
DTB_FILE="qcom-msm8909-nokia-leo.dtb"
;;
*)
echo "Error: Unsupported device '$DEVICE'." >&2
echo "Supported devices: nokia-argon, nokia-beatles, nokia-tough, nokia-sparkler, nokia-leo" >&2
exit 1
;;
esac
echo "[1/4] Installing Bananarchy rootfs overlay (artwork, branding, Sxmo 240x320, UCM, udev)..."
rm -f "$TARGET_ROOTFS/usr/bin/bantam" "$TARGET_ROOTFS/usr/local/bin/bantam" "$TARGET_ROOTFS/etc/doas.d/wheel.conf"
cp -af "$BASE_DIR/overlay/rootfs/." "$TARGET_ROOTFS/"
chown 0:0 "$TARGET_ROOTFS/etc/doas.d/50-sxmo.conf" 2>/dev/null || true
chmod 600 "$TARGET_ROOTFS/etc/doas.d/50-sxmo.conf" 2>/dev/null || true
echo "[2/4] Installing prebuilt QDSP6/Q6Voice kernel modules, torch LED module, and DTBs..."
if [ -d "$TARGET_ROOTFS/lib/modules/6.12.1-msm8916/kernel/sound/soc/qcom/qdsp6" ]; then
cp -af "$BASE_DIR/prebuilt/kernel-6.12.1-msm8916/qdsp6/"*.ko* \
"$TARGET_ROOTFS/lib/modules/6.12.1-msm8916/kernel/sound/soc/qcom/qdsp6/"
fi
if [ -d "$BASE_DIR/prebuilt/kernel-6.12.1-msm8916/leds" ] && \
[ -d "$TARGET_ROOTFS/lib/modules/6.12.1-msm8916/kernel/drivers/leds" ]; then
cp -af "$BASE_DIR/prebuilt/kernel-6.12.1-msm8916/leds/"*.ko* \
"$TARGET_ROOTFS/lib/modules/6.12.1-msm8916/kernel/drivers/leds/"
fi
mkdir -p "$TARGET_ROOTFS/boot/dtbs"
cp -af "$BASE_DIR/prebuilt/kernel-6.12.1-msm8916/dtbs/"*.dtb "$TARGET_ROOTFS/boot/dtbs/"
cp -af "$BASE_DIR/prebuilt/kernel-6.12.1-msm8916/dtbs/$DTB_FILE" "$TARGET_ROOTFS/boot/$DTB_FILE"
echo "[3/4] Installing prebuilt multi-mode fcitx5-t9 and Bantam AI agent..."
cp -af "$BASE_DIR/prebuilt/fcitx5-t9/usr/." "$TARGET_ROOTFS/usr/"
cp -af "$BASE_DIR/prebuilt/bantam/bantam" "$TARGET_ROOTFS/usr/bin/bantam"
cp -af "$BASE_DIR/prebuilt/bantam/bantam" "$TARGET_ROOTFS/usr/local/bin/bantam"
rm -f \
"$TARGET_ROOTFS/home/user/.bantam.cfg" \
"$TARGET_ROOTFS/etc/skel/.bantam.cfg" \
"$TARGET_ROOTFS/root/.bantam.cfg"
echo "[4/4] Installing deviceinfo for $DEVICE ($DTB_FILE)..."
if [ -f "$BASE_DIR/devices/$DEVICE/deviceinfo" ]; then
cp -a "$BASE_DIR/devices/$DEVICE/deviceinfo" "$TARGET_ROOTFS/etc/deviceinfo"
fi
echo "Bananarchy overlay applied to $TARGET_ROOTFS for device $DEVICE."
+103
View File
@@ -0,0 +1,103 @@
#!/bin/sh
# Fetch the latest master branch of Bantam AI agent from
# https://code.luxferre.top/luxferre/bantam-cpp and cross-compile for armv7
set -eu
BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
BANTAM_REPO_URL="${BANTAM_REPO_URL:-https://code.luxferre.top/luxferre/bantam-cpp}"
BANTAM_BRANCH="${BANTAM_BRANCH:-master}"
ROOTFS_DIR="${ROOTFS_DIR:-$BASE_DIR/rootfs}"
if [ -e "$ROOTFS_DIR" ]; then
ROOTFS_DIR="$(realpath "$ROOTFS_DIR")"
fi
exec docker run --rm --network=host \
-e HOST_UID="$(id -u)" \
-e HOST_GID="$(id -g)" \
-e BANTAM_REPO_URL="$BANTAM_REPO_URL" \
-e BANTAM_BRANCH="$BANTAM_BRANCH" \
-v "$BASE_DIR:/bananarchy" \
-v "$ROOTFS_DIR:/target-rootfs" \
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 \
build-base \
git \
ca-certificates \
gcc-armv7 \
g++-armv7 \
binutils-armv7 >/dev/null
# Keep target-rootfs clean of -dev headers; use an ephemeral armv7 build sysroot
if [ -d /target-rootfs/etc/apk ]; then
apk --root /target-rootfs --arch armv7 del --no-scripts \
curl-dev readline-dev ncurses-dev >/dev/null 2>&1 || true
fi
echo "[1/4] Preparing ephemeral armv7 sysroot (musl-dev, curl-dev, readline-dev)..."
mkdir -p /tmp/armv7-sysroot/etc/apk/keys
cp /etc/apk/repositories /tmp/armv7-sysroot/etc/apk/repositories
cp /etc/apk/keys/* /tmp/armv7-sysroot/etc/apk/keys/
apk --root /tmp/armv7-sysroot --initdb --arch armv7 add --no-scripts \
alpine-baselayout \
musl-dev \
linux-headers \
curl-dev \
readline-dev \
ncurses-dev >/dev/null
echo "[2/4] Cloning latest $BANTAM_BRANCH from $BANTAM_REPO_URL..."
rm -rf /tmp/bantam-cpp
git clone --depth 1 --branch "$BANTAM_BRANCH" "$BANTAM_REPO_URL" /tmp/bantam-cpp
cd /tmp/bantam-cpp
echo " Commit: $(git rev-parse --short HEAD) ($(git log -1 --format=%s))"
echo "[3/4] Cross-compiling Bantam AI agent for armv7..."
mkdir -p \
/bananarchy/prebuilt/bantam \
/bananarchy/overlay/rootfs/usr/bin \
/bananarchy/overlay/rootfs/usr/local/bin
armv7-alpine-linux-musleabihf-g++ \
-std=c++20 -Wall -Wextra -Wpedantic -O2 \
-D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_XOPEN_SOURCE=700 \
--sysroot=/tmp/armv7-sysroot \
-I. \
-I/tmp/armv7-sysroot/usr/include \
main.cpp config.cpp util.cpp json.cpp llm.cpp tools.cpp session.cpp render.cpp editor.cpp \
-L/tmp/armv7-sysroot/usr/lib \
-lcurl -lreadline -lncursesw \
-o /bananarchy/prebuilt/bantam/bantam
armv7-alpine-linux-musleabihf-strip --strip-unneeded /bananarchy/prebuilt/bantam/bantam
chmod 755 /bananarchy/prebuilt/bantam/bantam
echo "[4/4] Installing Bantam into prebuilt/, overlay/rootfs/, and target rootfs..."
cp -a /bananarchy/prebuilt/bantam/bantam /bananarchy/overlay/rootfs/usr/bin/bantam
cp -a /bananarchy/prebuilt/bantam/bantam /bananarchy/overlay/rootfs/usr/local/bin/bantam
if [ -d /target-rootfs/usr/bin ]; then
cp -a /bananarchy/prebuilt/bantam/bantam /target-rootfs/usr/bin/bantam
cp -a /bananarchy/prebuilt/bantam/bantam /target-rootfs/usr/local/bin/bantam
fi
# Ensure no default .bantam.cfg is included anywhere
rm -f \
/bananarchy/overlay/rootfs/home/user/.bantam.cfg \
/bananarchy/overlay/rootfs/etc/skel/.bantam.cfg \
/bananarchy/overlay/rootfs/root/.bantam.cfg \
/target-rootfs/home/user/.bantam.cfg \
/target-rootfs/etc/skel/.bantam.cfg \
/target-rootfs/root/.bantam.cfg
chown "$HOST_UID:$HOST_GID" /target-rootfs/usr/bin/bantam /target-rootfs/usr/local/bin/bantam 2>/dev/null || true
chown -R "$HOST_UID:$HOST_GID" /bananarchy/prebuilt/bantam /bananarchy/overlay/rootfs/usr
ls -lh /bananarchy/prebuilt/bantam/bantam
'
+76
View File
@@ -0,0 +1,76 @@
#!/bin/sh
# Cross-compile Bananarchy multi-mode fcitx5-t9 engine (abc/Abc/ABC/Sym/Ctl/123) for armv7
set -eu
BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ROOTFS_DIR="${ROOTFS_DIR:-$BASE_DIR/rootfs}"
if [ -e "$ROOTFS_DIR" ]; then
ROOTFS_DIR="$(realpath "$ROOTFS_DIR")"
fi
exec docker run --rm --network=host \
-e HOST_UID="$(id -u)" \
-e HOST_GID="$(id -g)" \
-v "$BASE_DIR:/bananarchy" \
-v "$ROOTFS_DIR:/target-rootfs" \
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 \
build-base \
gcc-armv7 \
g++-armv7 \
binutils-armv7 >/dev/null
echo "[1/3] Preparing ephemeral armv7 sysroot (musl-dev, fcitx5-dev)..."
mkdir -p /tmp/armv7-sysroot/etc/apk/keys
cp /etc/apk/repositories /tmp/armv7-sysroot/etc/apk/repositories
cp /etc/apk/keys/* /tmp/armv7-sysroot/etc/apk/keys/
apk --root /tmp/armv7-sysroot --initdb --arch armv7 add --no-scripts \
alpine-baselayout \
musl-dev \
linux-headers \
fcitx5-dev >/dev/null
echo "[2/3] Compiling Bananarchy multi-mode fcitx5-t9 engine for armv7..."
mkdir -p \
/bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5 \
/bananarchy/prebuilt/fcitx5-t9/usr/share/fcitx5/addon \
/bananarchy/prebuilt/fcitx5-t9/usr/share/fcitx5/inputmethod
armv7-alpine-linux-musleabihf-g++ \
-shared -fPIC -O2 -std=c++20 \
--sysroot=/tmp/armv7-sysroot \
-I/tmp/armv7-sysroot/usr/include/Fcitx5/Core \
-I/tmp/armv7-sysroot/usr/include/Fcitx5/Config \
-I/tmp/armv7-sysroot/usr/include/Fcitx5/Utils \
-I/bananarchy/src/fcitx5-t9/src \
/bananarchy/src/fcitx5-t9/src/t9.cpp \
-L/tmp/armv7-sysroot/usr/lib \
-lFcitx5Core -lFcitx5Config -lFcitx5Utils \
-o /bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5/libt9.so
armv7-alpine-linux-musleabihf-strip --strip-unneeded \
/bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5/libt9.so
cp -f /bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5/libt9.so \
/bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5/t9.so
cp /bananarchy/src/fcitx5-t9/src/t9-addon.conf \
/bananarchy/prebuilt/fcitx5-t9/usr/share/fcitx5/addon/t9.conf
cp /bananarchy/src/fcitx5-t9/src/t9-inputmethod.conf \
/bananarchy/prebuilt/fcitx5-t9/usr/share/fcitx5/inputmethod/t9.conf
echo "[3/3] Updating overlay/rootfs and target rootfs with compiled fcitx5-t9..."
cp -a /bananarchy/prebuilt/fcitx5-t9/usr/. /bananarchy/overlay/rootfs/usr/
if [ -d /target-rootfs/usr/lib/fcitx5 ]; then
cp -a /bananarchy/prebuilt/fcitx5-t9/usr/. /target-rootfs/usr/
fi
chown -R "$HOST_UID:$HOST_GID" /bananarchy/prebuilt/fcitx5-t9 /bananarchy/overlay/rootfs/usr
ls -lh /bananarchy/prebuilt/fcitx5-t9/usr/lib/fcitx5/libt9.so
'
+97
View File
@@ -0,0 +1,97 @@
#!/bin/sh
# Cross-compile Linux 6.12.1-msm8916 QDSP6/Q6Voice audio modules and MSM8905/MSM8909 DTBs
set -eu
BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ROOTFS_DIR="${ROOTFS_DIR:-$BASE_DIR/rootfs}"
if [ -e "$ROOTFS_DIR" ]; then
ROOTFS_DIR="$(realpath "$ROOTFS_DIR")"
fi
KERNEL_TAG="v6.12.1-msm8916"
KERNEL_URL="https://github.com/msm8916-mainline/linux/archive/refs/tags/${KERNEL_TAG}.tar.gz"
exec docker run --rm --network=host \
-e HOST_UID="$(id -u)" \
-e HOST_GID="$(id -g)" \
-e KERNEL_TAG="$KERNEL_TAG" \
-e KERNEL_URL="$KERNEL_URL" \
-v "$BASE_DIR:/bananarchy" \
-v "$ROOTFS_DIR:/target-rootfs: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 \
build-base \
bc \
bison \
flex \
openssl-dev \
elfutils-dev \
perl \
python3 \
dtc \
findutils \
patch \
curl \
tar \
xz \
gcc-armv7 \
g++-armv7 \
binutils-armv7
mkdir -p /tmp/kbuild
cd /tmp/kbuild
echo "[1/5] Downloading Linux ${KERNEL_TAG}..."
curl -sSL "$KERNEL_URL" -o linux.tar.gz
tar -xzf linux.tar.gz
cd "linux-${KERNEL_TAG#v}"
echo "[2/5] Applying Bananarchy QDSP6/Q6Voice and MSM8905/MSM8909 DTS patches..."
patch -p1 < /bananarchy/patches/kernel/0001-msm8909-qdsp6-voice-sound-nokia-argon-6.12.patch
echo "[3/5] Preparing kernel configuration and Module.symvers..."
cp /bananarchy/patches/kernel/config-bananarchy-msm8909.armv7 .config
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- olddefconfig
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- modules_prepare
echo "[4/5] Building QDSP6/Q6Voice sound modules, torch LED module, and Nokia MSM8905/MSM8909 DTBs..."
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- -j"$(nproc)" \
KBUILD_MODPOST_WARN=1 M=sound/soc/qcom/qdsp6 modules
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- -j"$(nproc)" \
KBUILD_MODPOST_WARN=1 M=/bananarchy/src/leds-msm8905-torch modules
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- -j"$(nproc)" \
qcom/qcom-msm8905-nokia-argon.dtb \
qcom/qcom-msm8909-nokia-sparkler.dtb \
qcom/qcom-msm8909-nokia-leo.dtb
echo "[5/5] Exporting built modules and DTBs to prebuilt/kernel-6.12.1-msm8916..."
mkdir -p /bananarchy/prebuilt/kernel-6.12.1-msm8916/qdsp6 \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/leds \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/dtbs
cp -a sound/soc/qcom/qdsp6/*.ko /bananarchy/prebuilt/kernel-6.12.1-msm8916/qdsp6/
cp -a /bananarchy/src/leds-msm8905-torch/leds-msm8905-torch.ko \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/leds/
armv7-alpine-linux-musleabihf-strip --strip-unneeded \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/qdsp6/*.ko \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/leds/*.ko
make ARCH=arm CROSS_COMPILE=armv7-alpine-linux-musleabihf- \
M=/bananarchy/src/leds-msm8905-torch clean
cp -a arch/arm/boot/dts/qcom/qcom-msm8905-nokia-argon.dtb \
arch/arm/boot/dts/qcom/qcom-msm8909-nokia-sparkler.dtb \
arch/arm/boot/dts/qcom/qcom-msm8909-nokia-leo.dtb \
/bananarchy/prebuilt/kernel-6.12.1-msm8916/dtbs/
dtc -I dts -O dtb -o /bananarchy/prebuilt/kernel-6.12.1-msm8916/dtbs/qcom-msm8905-nokia-beatles.dtb \
/bananarchy/devices/nokia-beatles/qcom-msm8905-nokia-beatles.dts 2>/dev/null
dtc -I dts -O dtb -o /bananarchy/prebuilt/kernel-6.12.1-msm8916/dtbs/qcom-msm8905-nokia-coconut.dtb \
/bananarchy/devices/nokia-tough/qcom-msm8905-nokia-coconut.dts 2>/dev/null
chown -R "$HOST_UID:$HOST_GID" /bananarchy/prebuilt/kernel-6.12.1-msm8916 /bananarchy/src/leds-msm8905-torch
echo "Kernel audio modules, torch LED module, and DTBs built successfully."
'
+704
View File
@@ -0,0 +1,704 @@
#!/bin/sh
set -eu
BANANARCHY_DIR="${BANANARCHY_DIR:-/bananarchy}"
WORK="${WORK:-/work}"
echo "[1/4] Installing lightweight host helper tools in container..."
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
if [ -d "$BANANARCHY_DIR/keys" ]; then
cp "$BANANARCHY_DIR/keys/"* /etc/apk/keys/
elif [ -d "$WORK/pmbootstrap/pmb/data/keys" ]; then
cp "$WORK/pmbootstrap/pmb/data/keys/"* /etc/apk/keys/
fi
apk add --no-cache \
busybox-static \
busybox-extras \
dbus \
ca-certificates \
fontconfig \
glib \
gtk+3.0 \
gdk-pixbuf \
librsvg \
shared-mime-info \
desktop-file-utils \
gtk-update-icon-cache \
kmod \
eudev \
postmarketos-mkinitfs \
boot-deploy \
mkbootimg \
devicepkg-utils \
e2fsprogs \
e2fsprogs-extra \
util-linux \
sfdisk \
android-tools \
python3 \
zstd \
file
configure_common_rootfs() {
ROOTFS="$1"
UI_TYPE="$2"
BOOT_UUID="$3"
ROOT_UUID="$4"
echo "=== Configuring $ROOTFS ($UI_TYPE) ==="
cp /etc/apk/repositories "$ROOTFS/etc/apk/repositories"
echo " -> Ensuring fcitx5-gtk3 and Bananarchy development/scripting packages are installed in $ROOTFS..."
apk --root "$ROOTFS" --arch armv7 add --no-scripts \
fcitx5-gtk3 \
git \
gcc \
g++ \
musl-dev \
make \
nano \
janet \
janet-dev \
jpm \
perl \
perl-io-socket-ssl \
tcl \
tcl-lib \
tcl-tls \
sqlite \
sqlite-tcl
echo " -> Installing busybox and busybox-extras symlinks..."
for applet in $(/bin/busybox --list-full); do
target="$ROOTFS/$applet"
mkdir -p "$(dirname "$target")"
if [ ! -e "$target" ] && [ ! -L "$target" ]; then
ln -s /bin/busybox "$target"
fi
done
if [ -x /bin/busybox-extras ]; then
for applet in $(/bin/busybox-extras --list-full); do
target="$ROOTFS/$applet"
mkdir -p "$(dirname "$target")"
if [ ! -e "$target" ] && [ ! -L "$target" ]; then
ln -s /bin/busybox-extras "$target"
fi
done
fi
if [ -e "$ROOTFS/sbin/losetup" ] && [ ! -e "$ROOTFS/usr/sbin/losetup" ]; then
ln -sf /sbin/losetup "$ROOTFS/usr/sbin/losetup"
fi
echo " -> Setting up temporary x86_64 hostbin for chroot execution..."
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"
echo " -> Creating system groups, users, and default user (UID 10000)..."
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"
addgroup -S -g 42 shadow 2>/dev/null || true
chown root:shadow /etc/shadow
[ -e /etc/shadow- ] && chown root:shadow /etc/shadow-
addgroup -S -g 86 avahi 2>/dev/null || true
adduser -S -u 86 -D -H -h /dev/null -s /sbin/nologin -G avahi -g "Avahi System User" avahi 2>/dev/null || true
addgroup -S klogd 2>/dev/null || true
adduser -S -D -H -h /dev/null -s /sbin/nologin -G klogd -g klogd klogd 2>/dev/null || true
addgroup -S chrony 2>/dev/null || true
adduser -S -D -H -h /dev/null -s /sbin/nologin -G chrony -g chrony chrony 2>/dev/null || true
addgroup -S messagebus 2>/dev/null || true
adduser -S -D -H -h /dev/null -s /sbin/nologin -G messagebus -g messagebus messagebus 2>/dev/null || true
addgroup -S dnsmasq 2>/dev/null || true
adduser -S -D -H -h /dev/null -s /sbin/nologin -G dnsmasq -g dnsmasq dnsmasq 2>/dev/null || true
addgroup -S geoclue 2>/dev/null || true
adduser -S -D -h /var/lib/geoclue -s /sbin/nologin -G geoclue geoclue 2>/dev/null || true
addgroup -S plugdev 2>/dev/null || true
addgroup -S pipewire 2>/dev/null || true
addgroup -S seat 2>/dev/null || true
addgroup -S feedbackd 2>/dev/null || true
addgroup -S polkitd 2>/dev/null || true
adduser -S -D -H -h /var/empty -s /sbin/nologin -G polkitd -g polkitd polkitd 2>/dev/null || true
addgroup -S colord 2>/dev/null || true
adduser -S -D -H -h /var/lib/colord -s /sbin/nologin -G colord -g colord colord 2>/dev/null || true
addgroup -S greetd 2>/dev/null || true
adduser -S -D -H -h /var/lib/greetd -s /sbin/nologin -G greetd -g greetd greetd 2>/dev/null || true
addgroup greetd video 2>/dev/null || true
if ! grep -q "^user:" /etc/passwd 2>/dev/null; then
adduser -D -u 10000 -s /bin/ash user 2>/dev/null || true
fi
for grp in audio input netdev plugdev video wheel seat feedbackd dialout tty pipewire; do
addgroup -S "$grp" 2>/dev/null || true
addgroup user "$grp" 2>/dev/null || true
done
echo "user:147147" | chpasswd
passwd -l root >/dev/null 2>&1 || true
'
echo " -> Configuring sudo/doas, hostname, locale, timezone, inittab, and sysctl..."
mkdir -p "$ROOTFS/etc/doas.d" "$ROOTFS/etc/sudoers.d"
rm -f "$ROOTFS/etc/doas.d/wheel.conf"
cat > "$ROOTFS/etc/sudoers.d/wheel" <<EOF
%wheel ALL=(ALL:ALL) ALL
EOF
chmod 440 "$ROOTFS/etc/sudoers.d/wheel"
echo "nokia-argon" > "$ROOTFS/etc/hostname"
cat > "$ROOTFS/etc/hosts" <<EOF
127.0.0.1 nokia-argon localhost.localdomain localhost
::1 localhost ipv6-localhost ipv6-loopback
fe00::0 ipv6-localnet
ff00::0 ipv6-mcastprefix
ff02::1 ipv6-allnodes
ff02::2 ipv6-allrouters
ff02::3 ipv6-allhosts
EOF
echo "LANG=en_US.UTF-8" > "$ROOTFS/etc/locale.conf"
if [ -f "$ROOTFS/usr/share/zoneinfo/UTC" ]; then
cp "$ROOTFS/usr/share/zoneinfo/UTC" "$ROOTFS/etc/localtime"
echo "UTC" > "$ROOTFS/etc/timezone"
fi
touch "$ROOTFS/etc/apk/interactive"
mkdir -p "$ROOTFS/run/openrc"
touch "$ROOTFS/run/openrc/shutdowntime"
dbus-uuidgen --ensure="$ROOTFS/etc/machine-id"
if grep -q "^#ttyS0::respawn:/sbin/getty" "$ROOTFS/etc/inittab"; then
sed -i 's|^#ttyS0::respawn:/sbin/getty.*|ttyMSM0::respawn:/sbin/getty -L 115200 ttyMSM0 vt100|' "$ROOTFS/etc/inittab"
fi
if ! grep -qx "panel_mipi_dbi" "$ROOTFS/etc/modules" 2>/dev/null; then
echo "panel_mipi_dbi" >> "$ROOTFS/etc/modules"
fi
mkdir -p "$ROOTFS/etc/udev/rules.d"
cat > "$ROOTFS/etc/udev/rules.d/90-nokia-argon-leds.rules" <<EOF
SUBSYSTEM=="leds", ACTION=="add", RUN+="/bin/chgrp video /sys/class/leds/%k/brightness", RUN+="/bin/chmod 0664 /sys/class/leds/%k/brightness"
SUBSYSTEM=="backlight", ACTION=="add", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness", RUN+="/bin/chmod 0664 /sys/class/backlight/%k/brightness"
EOF
mkdir -p "$ROOTFS/etc/sysctl.d"
cat > "$ROOTFS/etc/sysctl.d/90-nokia-argon-lowram.conf" <<EOF
vm.swappiness = 180
vm.page-cluster = 0
vm.vfs_cache_pressure = 150
vm.min_free_kbytes = 16384
EOF
echo " -> Installing patched audio DTB, 20 QDSP6 kernel modules, UCM, and WirePlumber S16LE rules..."
cp "$BANANARCHY_DIR/prebuilt/kernel-6.12.1-msm8916/dtbs/qcom-msm8905-nokia-argon.dtb" \
"$ROOTFS/boot/dtbs/qcom-msm8905-nokia-argon.dtb"
cp "$BANANARCHY_DIR/prebuilt/kernel-6.12.1-msm8916/qdsp6/"*.ko* \
"$ROOTFS/lib/modules/6.12.1-msm8916/kernel/sound/soc/qcom/qdsp6/"
depmod -b "$ROOTFS" 6.12.1-msm8916
sed -i 's/"CS-Voice"/"VoiceMMode1"/g' \
"$ROOTFS/usr/share/alsa/ucm2/platforms/msm8916/qdsp6.conf"
mkdir -p \
"$ROOTFS/usr/share/wireplumber/wireplumber.conf.d" \
"$ROOTFS/etc/wireplumber/wireplumber.conf.d" \
"$ROOTFS/etc/skel/.config/wireplumber/wireplumber.conf.d" \
"$ROOTFS/home/user/.config/wireplumber/wireplumber.conf.d"
cat > "$ROOTFS/usr/share/wireplumber/wireplumber.conf.d/msm8916-s16le.conf" <<EOF
monitor.alsa.rules = [
{
matches = [
{
node.name = "~alsa_output.platform-7702000.*"
},
{
node.name = "~alsa_output.platform-sound.*"
}
]
actions = {
update-props = {
audio.format = "S16LE"
}
}
}
]
EOF
cp "$ROOTFS/usr/share/wireplumber/wireplumber.conf.d/msm8916-s16le.conf" \
"$ROOTFS/etc/wireplumber/wireplumber.conf.d/msm8916-s16le.conf"
cp "$ROOTFS/usr/share/wireplumber/wireplumber.conf.d/msm8916-s16le.conf" \
"$ROOTFS/etc/skel/.config/wireplumber/wireplumber.conf.d/msm8916-s16le.conf"
cp "$ROOTFS/usr/share/wireplumber/wireplumber.conf.d/msm8916-s16le.conf" \
"$ROOTFS/home/user/.config/wireplumber/wireplumber.conf.d/msm8916-s16le.conf"
echo " -> Installing fcitx5-t9 addon and T9 profile..."
cp -a "$BANANARCHY_DIR/prebuilt/fcitx5-t9/usr/"* "$ROOTFS/usr/"
mkdir -p \
"$ROOTFS/usr/share/superd/services" \
"$ROOTFS/etc/skel/.config/superd/services/enabled" \
"$ROOTFS/home/user/.config/superd/services/enabled" \
"$ROOTFS/etc/skel/.config/fcitx5" \
"$ROOTFS/home/user/.config/fcitx5"
cat > "$ROOTFS/usr/share/superd/services/fcitx5.service" <<EOF
[Unit]
Description=fcitx5 input support
[Service]
Type=simple
ExecStart=/usr/bin/fcitx5
Restart=always
EOF
ln -sf /usr/share/superd/services/fcitx5.service \
"$ROOTFS/etc/skel/.config/superd/services/enabled/fcitx5.service"
ln -sf /usr/share/superd/services/fcitx5.service \
"$ROOTFS/home/user/.config/superd/services/enabled/fcitx5.service"
cat > "$ROOTFS/etc/skel/.config/fcitx5/profile" <<EOF
[Groups/0]
# Group Name
Name=Default
# Layout
Default Layout=us
# Default Input Method
DefaultIM=t9
[Groups/0/Items/0]
# Name
Name=keyboard-us
# Layout
Layout=
[Groups/0/Items/1]
# Name
Name=t9
# Layout
Layout=
[GroupOrder]
0=Default
EOF
cp "$ROOTFS/etc/skel/.config/fcitx5/profile" "$ROOTFS/home/user/.config/fcitx5/profile"
cat > "$ROOTFS/etc/profile.d/fcitx5-t9.sh" <<EOF
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export SXMO_MENU=wofi
EOF
chmod 755 "$ROOTFS/etc/profile.d/fcitx5-t9.sh"
if ! grep -q "GTK_IM_MODULE=fcitx" "$ROOTFS/etc/skel/.profile" 2>/dev/null; then
cat >> "$ROOTFS/etc/skel/.profile" <<EOF
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export SXMO_MENU=wofi
EOF
fi
cp "$ROOTFS/etc/skel/.profile" "$ROOTFS/home/user/.profile"
echo " -> Enabling OpenRC runlevel services..."
mkdir -p \
"$ROOTFS/etc/runlevels/sysinit" \
"$ROOTFS/etc/runlevels/boot" \
"$ROOTFS/etc/runlevels/default" \
"$ROOTFS/etc/runlevels/shutdown"
rm -f "$ROOTFS/etc/runlevels/boot/hwclock"
for svc in devfs dmesg msm-firmware-loader udev udev-trigger udev-settle; do
if [ -e "$ROOTFS/etc/init.d/$svc" ]; then
ln -sf "/etc/init.d/$svc" "$ROOTFS/etc/runlevels/sysinit/$svc"
fi
done
for svc in osclock swclock-offset-boot modules sysctl hostname bootmisc logbookd tmpfs msm-firmware-loader-unpack; do
if [ -e "$ROOTFS/etc/init.d/$svc" ]; then
ln -sf "/etc/init.d/$svc" "$ROOTFS/etc/runlevels/boot/$svc"
fi
done
for svc in \
udev-postmount \
rmtfs \
msm-modem-uim-selection \
msm8909-modem-wwan-port \
q6voiced \
modemmanager \
networkmanager \
wpa_supplicant \
bluetooth \
dbus \
cgroups \
haveged \
chronyd \
rfkill \
sleep-inhibitor \
sshd \
swapfile \
local \
postmarketos-zram-swap \
nftables \
iio-sensor-proxy \
hkdm \
kill-plymouth; do
if [ -e "$ROOTFS/etc/init.d/$svc" ]; then
ln -sf "/etc/init.d/$svc" "$ROOTFS/etc/runlevels/default/$svc"
fi
done
for svc in mount-ro killprocs savecache swclock-offset-shutdown; do
if [ -e "$ROOTFS/etc/init.d/$svc" ]; then
ln -sf "/etc/init.d/$svc" "$ROOTFS/etc/runlevels/shutdown/$svc"
fi
done
if [ "$UI_TYPE" = "sxmo" ]; then
echo " -> Applying Sxmo UI & User:Ybon keypad/RAM/display tweaks..."
for svc in seatd tinydm; do
if [ -e "$ROOTFS/etc/init.d/$svc" ]; then
ln -sf "/etc/init.d/$svc" "$ROOTFS/etc/runlevels/default/$svc"
fi
done
mkdir -p "$ROOTFS/var/lib/tinydm"
ln -sf /usr/share/wayland-sessions/swmo.desktop "$ROOTFS/var/lib/tinydm/default-session.desktop"
cat > "$ROOTFS/usr/bin/sxmo_deviceprofile_nokia,argon.sh" <<EOF
#!/bin/sh
export SXMO_WM=sway
export SXMO_ROTATION=normal
# Scaling factor for 240x320 QVGA screen
export SXMO_SWAY_SCALE=0.7
# Physical button mappings as determined via evtest
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
export SXMO_VOLUME_UP_BUTTON="0:103:KEY_UP"
export SXMO_VOLUME_DOWN_BUTTON="0:108:KEY_DOWN"
export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
# Nokia 8110 4G has a physical keypad and no touchscreen
export SXMO_NO_VIRTUAL_KEYBOARD=1
export KEYBOARD_ARGS="-H 1 -L 1"
export SXMO_MENU=wofi
EOF
chmod 755 "$ROOTFS/usr/bin/sxmo_deviceprofile_nokia,argon.sh"
cat > "$ROOTFS/usr/bin/sxmo_inputhandler.sh" <<'EOF'
#!/bin/sh
exec sxmo_hook_inputhandler.sh "$@"
EOF
chmod 755 "$ROOTFS/usr/bin/sxmo_inputhandler.sh"
sed -i 's|--input-device="$pwr" ||g' "$ROOTFS/usr/bin/sxmo_swayinitconf.sh"
if ! grep -q "superctl start fcitx5" "$ROOTFS/usr/share/sxmo/default_hooks/sxmo_hook_start.sh"; then
sed -i 's|superctl start bonsaid|[ "$(command -v bonsaid)" ] \&\& superctl start bonsaid\n\t\t[ "$(command -v fcitx5)" ] \&\& superctl start fcitx5|' \
"$ROOTFS/usr/share/sxmo/default_hooks/sxmo_hook_start.sh"
fi
mkdir -p "$ROOTFS/etc/skel/.cache/sxmo" "$ROOTFS/home/user/.cache/sxmo"
touch "$ROOTFS/etc/skel/.cache/sxmo/sxmo.nogesture" "$ROOTFS/home/user/.cache/sxmo/sxmo.nogesture"
cat > "$ROOTFS/usr/share/sxmo/appcfg/wofi.config" <<EOF
# Space to setup configversion
# configversion: eb37989d3b93bf46e0df32db4ffd833e
matching=multi-contains
width=240
height=320
halign=fill
orientation=vertical
content_halign=fill
insensitive=true
prompt=
show=dmenu
no_actions=true
EOF
cat > "$ROOTFS/usr/share/sxmo/appcfg/wofi.css" <<EOF
/* Space to setup configversion */
/* configversion: 2ecca20b604bc0b37d13aba5a0fabc07 */
* {
font-family: monospace;
font-size: 12px;
}
window {
margin: 0px;
border: 1px solid #005577;
background-color: #222222;
}
#input {
margin: 0px;
border-radius: 0px;
border: 1px solid #005577;
background-color: #444444;
color: white;
}
#inner-box {
margin: 0px;
}
#outer-box {
margin: 1px;
}
#scroll {
margin: 0px;
color: yellow;
}
#text {
margin: 1px;
color: white;
}
#entry {
padding: 0;
margin: 0;
}
#entry:selected {
background-color: #005577;
}
EOF
cat > "$ROOTFS/usr/share/sxmo/appcfg/conky.conf" <<EOF
-- Space to setup configversion
-- configversion: 19ec5c7f9e83bc6534d657f6180feba2
conky.config = {
out_to_x = false,
out_to_wayland = true,
alignment = 'middle_middle',
own_window_argb_value = 0,
own_window_type = 'desktop',
default_shade_color = 'grey',
draw_shades = true,
font = 'Sxmo:size=11',
use_xft = true,
update_interval = 15,
}
conky.text = [[
\${alignc}\${font Sxmo:size=36:style=Bold}\${time %H}\${font Sxmo:size=36}:\${time %M}\${font}
\${alignc}\${font Sxmo:size=14}\${time %a %d %b %Y}\${font}
]]
EOF
python3 - "$ROOTFS/usr/share/sxmo/appcfg/sway_template" <<'PYEOF'
import sys
path = sys.argv[1]
txt = open(path).read()
if "xwayland disable" not in txt:
txt = txt.replace('font "Sxmo 11"\n', 'font "Sxmo 11"\nxwayland disable\n', 1)
old_menu = """mode "menu" {
# This is slower than remapping the keys using a keymap, but we don't need
# to know the device names, so use it as a fallback so this functionality
# keeps working if a deviceprofile doesn't exist.
# TODO: the correct way to do this is to implement custom keybindings in
# bemenu & wofi
bindsym XF86PowerOff exec wtype -k Return
bindsym XF86AudioRaiseVolume exec wtype -k Up
bindsym XF86AudioLowerVolume exec wtype -k Down
}"""
new_menu = """mode "menu" {
bindsym XF86PowerOff exec sxmo_dmenu.sh close
bindsym XF86PickupPhone exec wtype -k Return
bindsym XF86KbdLcdMenu1 exec sxmo_dmenu.sh close
bindsym XF86KbdLcdMenu2 exec sxmo_dmenu.sh close
bindsym XF86NumericStar exec wtype "*"
bindsym XF86NumericPound exec fcitx5-remote -t
bindsym XF86AudioRaiseVolume exec wtype -k Up
bindsym XF86AudioLowerVolume exec wtype -k Down
}"""
if old_menu in txt:
txt = txt.replace(old_menu, new_menu, 1)
old_lid = """bindswitch lid:on exec sxmo_wm.sh display off
bindswitch lid:off exec sxmo_wm.sh display on"""
new_lid = """bindswitch lid:on exec sh -c "brightnessctl -d white:kbd_backlight set 0; sxmo_wm.sh display off"
bindswitch lid:off exec sh -c "brightnessctl -d white:kbd_backlight set 255; sxmo_wm.sh display on"
# Nokia 8110 4G hardware keypad bindings (User:Ybon)
bindsym --no-repeat XF86KbdLcdMenu1 exec sxmo_hook_inputhandler.sh menuleft_one
bindsym --no-repeat XF86KbdLcdMenu2 exec sxmo_hook_inputhandler.sh menuright_one
bindsym --no-repeat XF86PickupPhone exec sxmo_hook_inputhandler.sh enter_one
bindsym --no-repeat XF86NumericStar exec wtype "*"
bindsym --no-repeat XF86NumericPound exec sh -c 'fcitx5-remote -t && sxmo_notify_user.sh -t 1500 "Input: $(fcitx5-remote -n)"'"""
if old_lid in txt:
txt = txt.replace(old_lid, new_lid, 1)
open(path, "w").write(txt)
PYEOF
python3 - "$ROOTFS/usr/share/sxmo/default_hooks/sxmo_hook_inputhandler.sh" <<'PYEOF'
import sys
path = sys.argv[1]
txt = open(path).read()
old_power = """ "powerbutton_one")
if echo "$WMCLASS" | grep -i "megapixels"; then
sxmo_type.sh -k space
else
sxmo_state.sh click
fi
exit 0
;;"""
new_power = """ "menuright"*|"menuright_one")
if sxmo_dmenu.sh isopen; then
sxmo_dmenu.sh close
else
sxmo_appmenu.sh "$WMCLASS" "$WMNAME"
fi
exit 0
;;
"menuleft"*|"menuleft_one")
if sxmo_dmenu.sh isopen; then
sxmo_dmenu.sh close
else
sxmo_appmenu.sh sys
fi
exit 0
;;
"enter_one")
if pidof -q sxmo_RepeatRing.sh; then
sxmo_hook_pickup.sh
else
sxmo_appmenu.sh "$WMCLASS" "$WMNAME"
fi
exit 0
;;
"powerbutton_one")
if echo "$WMCLASS" | grep -i "megapixels"; then
sxmo_type.sh -k space
else
sxmo_appmenu.sh power
fi
exit 0
;;"""
if "menuright_one" not in txt:
assert old_power in txt, "old_power block not found in sxmo_hook_inputhandler.sh"
txt = txt.replace(old_power, new_power, 1)
open(path, "w").write(txt)
PYEOF
for target_home in "$ROOTFS/etc/skel" "$ROOTFS/home/user"; do
mkdir -p \
"$target_home/.config/sxmo/hooks" \
"$target_home/.config/wofi" \
"$target_home/.config/foot" \
"$target_home/.config/wob" \
"$target_home/.config/fontconfig/conf.d"
cp "$ROOTFS/usr/share/sxmo/appcfg/profile_template" "$target_home/.config/sxmo/profile"
if ! grep -q "SXMO_MENU=wofi" "$target_home/.config/sxmo/profile"; then
cat >> "$target_home/.config/sxmo/profile" <<EOF
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export SXMO_MENU=wofi
EOF
fi
cp "$ROOTFS/usr/share/sxmo/appcfg/sway_template" "$target_home/.config/sxmo/sway"
cp "$ROOTFS/usr/share/sxmo/appcfg/conky.conf" "$target_home/.config/sxmo/conky.conf"
cp "$ROOTFS/usr/share/sxmo/appcfg/wofi.config" "$target_home/.config/wofi/config"
cp "$ROOTFS/usr/share/sxmo/appcfg/wofi.css" "$target_home/.config/wofi/style.css"
cp "$ROOTFS/usr/share/sxmo/appcfg/foot.ini" "$target_home/.config/foot/foot.ini"
cp "$ROOTFS/usr/share/sxmo/appcfg/wob.ini" "$target_home/.config/wob/wob.ini"
cp "$ROOTFS/usr/share/sxmo/appcfg/bonsai_tree.json" "$target_home/.config/sxmo/bonsai_tree.json"
cp "$ROOTFS/usr/share/sxmo/appcfg/fontconfig.conf" "$target_home/.config/fontconfig/conf.d/50-sxmo.conf"
cp "$ROOTFS/usr/share/sxmo/default_hooks/sxmo_hook_inputhandler.sh" "$target_home/.config/sxmo/hooks/sxmo_hook_inputhandler.sh"
chmod 755 "$target_home/.config/sxmo/hooks/sxmo_hook_inputhandler.sh"
done
fi
if [ -x /bananarchy/scripts/apply-bananarchy-overlay.sh ]; then
/bananarchy/scripts/apply-bananarchy-overlay.sh "$ROOTFS" nokia-argon
fi
chown -R 10000:10000 "$ROOTFS/home/user"
echo " -> Generating initramfs, boot.img, and extlinux.conf via mkinitfs..."
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
'
echo " -> Restoring armv7 /bin/sh symlink and cleaning up temporary hostbin..."
ln -sf /bin/busybox "$ROOTFS/bin/sh"
rm -rf "$ROOTFS/tmp/hostbin" "$ROOTFS/lib/ld-musl-x86_64.so.1" "$ROOTFS/proc/1"
echo " -> Verifying $ROOTFS boot artifacts:"
ls -lh "$ROOTFS/boot/initramfs" "$ROOTFS/boot/boot.img" "$ROOTFS/boot/extlinux/extlinux.conf"
cat "$ROOTFS/boot/extlinux/extlinux.conf"
}
BOOT_UUID_SXMO="a1b2c3d4-8110-4000-8000-000000000001"
ROOT_UUID_SXMO="a1b2c3d4-8110-4000-8000-000000000002"
configure_common_rootfs "$WORK/rootfs-sxmo" "sxmo" "$BOOT_UUID_SXMO" "$ROOT_UUID_SXMO"
echo "BANANARCHY ROOTFS CONFIGURATION COMPLETED SUCCESSFULLY!"
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""Generate Bananarchy OS artwork assets from artwork/icon-large.png."""
import math
import os
import sys
from PIL import Image, ImageDraw, ImageFont
BASE_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
ARTWORK_DIR = os.path.join(BASE_DIR, "artwork")
SOURCE_ICON = os.path.join(ARTWORK_DIR, "icon-large.png")
def load_font(size, bold=True):
candidates = [
"/usr/share/fonts/TTF/DejaVuSansMono-Bold.ttf" if bold else "/usr/share/fonts/TTF/DejaVuSansMono.ttf",
"/usr/share/fonts/TTF/DejaVuSans-Bold.ttf" if bold else "/usr/share/fonts/TTF/DejaVuSans.ttf",
"/usr/share/fonts/liberation/LiberationMono-Bold.ttf",
"/usr/share/fonts/gnu-free/FreeMonoBold.ttf",
]
for path in candidates:
if os.path.isfile(path):
try:
return ImageFont.truetype(path, size)
except Exception:
pass
return ImageFont.load_default()
def make_transparent_icon(src_rgb):
"""Create an RGBA version with the outer black background keyed to alpha."""
w, h = src_rgb.size
cx, cy = w / 2.0, h / 2.0
# The circular emblem spans radius ~495px on a 1024x1024 canvas
outer_r = min(w, h) * 0.486
feather = min(w, h) * 0.012
rgba = src_rgb.convert("RGBA")
px = rgba.load()
for y in range(h):
dy = y - cy
for x in range(w):
dx = x - cx
dist = math.hypot(dx, dy)
r, g, b, _ = px[x, y]
lum = max(r, g, b)
if dist > outer_r + feather and lum < 18:
px[x, y] = (0, 0, 0, 0)
elif dist > outer_r - feather and lum < 28:
# Smooth alpha ramp near outer ring
t = (outer_r + feather - dist) / (2.0 * feather)
t = max(0.0, min(1.0, t))
alpha = int(round(255.0 * max(t, min(1.0, (lum - 2) / 26.0))))
px[x, y] = (r, g, b, alpha)
return rgba
def make_canvas(width, height, bg=(1, 1, 1)):
return Image.new("RGB", (width, height), bg)
def paste_centered(canvas, icon_rgb, box_size, center_x, center_y):
resized = icon_rgb.resize((box_size, box_size), Image.Resampling.LANCZOS)
x0 = int(round(center_x - box_size / 2.0))
y0 = int(round(center_y - box_size / 2.0))
canvas.paste(resized, (x0, y0))
return canvas
def main():
if not os.path.isfile(SOURCE_ICON):
print(f"Error: Source icon not found at {SOURCE_ICON}", file=sys.stderr)
sys.exit(1)
os.makedirs(ARTWORK_DIR, exist_ok=True)
src = Image.open(SOURCE_ICON).convert("RGB")
src_rgba = make_transparent_icon(src)
# 1. Standard square RGB icons
square_sizes = [512, 256, 192, 128, 64, 48, 32, 24, 16]
for sz in square_sizes:
out_path = os.path.join(ARTWORK_DIR, f"icon-{sz}.png")
src.resize((sz, sz), Image.Resampling.LANCZOS).save(out_path, "PNG", optimize=True)
# 2. Transparent RGBA icons for freedesktop / UI themes
for sz in [512, 256, 128, 64, 48, 32]:
out_path = os.path.join(ARTWORK_DIR, f"icon-transparent-{sz}.png")
src_rgba.resize((sz, sz), Image.Resampling.LANCZOS).save(out_path, "PNG", optimize=True)
# 3. Multi-size favicon.ico
ico_path = os.path.join(ARTWORK_DIR, "favicon.ico")
src_rgba.save(
ico_path,
format="ICO",
sizes=[(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
)
# 4. Sxmo 240x320 portrait wallpaper (emblem placed below Conky clock area)
# Top bar is 24px (0..24), Conky clock occupies y=28..118, emblem sits in y=126..314
wp_portrait = make_canvas(240, 320, (1, 1, 1))
paste_centered(wp_portrait, src, 188, 120, 220)
wp_portrait.save(os.path.join(ARTWORK_DIR, "wallpaper-240x320.png"), "PNG", optimize=True)
wp_portrait.save(os.path.join(ARTWORK_DIR, "wallpaper-240x320.jpg"), "JPEG", quality=95, subsampling=0)
# 5. Centered 240x320 portrait wallpaper
wp_centered = make_canvas(240, 320, (1, 1, 1))
paste_centered(wp_centered, src, 216, 120, 160)
wp_centered.save(os.path.join(ARTWORK_DIR, "wallpaper-240x320-centered.png"), "PNG", optimize=True)
wp_centered.save(os.path.join(ARTWORK_DIR, "wallpaper-240x320-centered.jpg"), "JPEG", quality=95, subsampling=0)
# 6. Landscape 320x240 QVGA wallpaper
wp_landscape = make_canvas(320, 240, (1, 1, 1))
paste_centered(wp_landscape, src, 208, 160, 120)
wp_landscape.save(os.path.join(ARTWORK_DIR, "wallpaper-320x240.png"), "PNG", optimize=True)
wp_landscape.save(os.path.join(ARTWORK_DIR, "wallpaper-320x240.jpg"), "JPEG", quality=95, subsampling=0)
# 7. Square 240x240 wallpaper (Nokia 2720 Flip external screen)
wp_square = make_canvas(240, 240, (1, 1, 1))
paste_centered(wp_square, src, 216, 120, 120)
wp_square.save(os.path.join(ARTWORK_DIR, "wallpaper-240x240.png"), "PNG", optimize=True)
# 8. Boot splash 240x320 (PNG + raw PPM for framebuffer/initramfs)
splash = make_canvas(240, 320, (1, 1, 1))
paste_centered(splash, src, 196, 120, 134)
draw = ImageDraw.Draw(splash)
font_title = load_font(20, bold=True)
font_sub = load_font(11, bold=False)
title_text = "BANANARCHY"
tb = draw.textbbox((0, 0), title_text, font=font_title)
tw = tb[2] - tb[0]
draw.text(((240 - tw) // 2, 248), title_text, fill=(255, 214, 10), font=font_title)
sub_text = "MSM8909 LINUX // SXMO"
sb = draw.textbbox((0, 0), sub_text, font=font_sub)
sw = sb[2] - sb[0]
draw.text(((240 - sw) // 2, 276), sub_text, fill=(180, 180, 180), font=font_sub)
splash.save(os.path.join(ARTWORK_DIR, "splash-240x320.png"), "PNG", optimize=True)
splash.save(os.path.join(ARTWORK_DIR, "splash-240x320.ppm"), "PPM")
# 9. Project documentation banner (800x240)
banner = make_canvas(800, 240, (1, 1, 1))
paste_centered(banner, src, 204, 118, 120)
bdraw = ImageDraw.Draw(banner)
font_btitle = load_font(44, bold=True)
font_bsub = load_font(16, bold=True)
font_bdesc = load_font(12, bold=False)
bdraw.text((238, 46), "BANANARCHY", fill=(255, 214, 10), font=font_btitle)
bdraw.text(
(240, 108),
"Keypad-First Linux Hardfork for Qualcomm MSM8909",
fill=(240, 240, 240),
font=font_bsub,
)
bdraw.text(
(240, 142),
"Nokia 8110 4G | Nokia 2720 Flip | Nokia 800 Tough | Nokia 8000 4G",
fill=(255, 140, 26),
font=font_bdesc,
)
bdraw.text(
(240, 170),
"240x320 Native Sxmo * Multi-Mode T9 Input * QDSP6 Voice & Modem",
fill=(170, 170, 170),
font=font_bdesc,
)
banner.save(os.path.join(ARTWORK_DIR, "banner-800x240.png"), "PNG", optimize=True)
print(f"Generated Bananarchy artwork suite in {ARTWORK_DIR}:")
for name in sorted(os.listdir(ARTWORK_DIR)):
p = os.path.join(ARTWORK_DIR, name)
if os.path.isfile(p):
print(f" {name:32s} {os.stat(p).st_size:8d} bytes")
if __name__ == "__main__":
main()
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Compile MIPI-DBI panel init command text files into binary firmware blobs."""
import sys
MAGIC_HEADER = b"MIPI DBI\x00\x00\x00\x00\x00\x00\x00\x01"
def compile_mipi_dbi(txt_path, bin_path):
out = bytearray(MAGIC_HEADER)
with open(txt_path, "r", encoding="utf-8") as f:
for lineno, raw_line in enumerate(f, 1):
line = raw_line.split("#", 1)[0].strip()
if not line:
continue
parts = line.split()
op = parts[0].lower()
if op == "command":
if len(parts) < 2:
raise ValueError(f"{txt_path}:{lineno}: 'command' requires at least 1 byte")
cmd = int(parts[1], 0)
args = [int(x, 0) for x in parts[2:]]
out.append(cmd & 0xFF)
out.append(len(args) & 0xFF)
for a in args:
out.append(a & 0xFF)
elif op == "delay":
if len(parts) != 2:
raise ValueError(f"{txt_path}:{lineno}: 'delay' requires 1 integer argument (ms)")
ms = int(parts[1], 0)
out.append(0x00)
out.append(0x01)
out.append(ms & 0xFF)
else:
raise ValueError(f"{txt_path}:{lineno}: unknown directive '{op}'")
with open(bin_path, "wb") as wf:
wf.write(out)
def main():
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <output.bin> <input.txt>", file=sys.stderr)
sys.exit(1)
compile_mipi_dbi(sys.argv[2], sys.argv[1])
if __name__ == "__main__":
main()