diff --git a/.gitignore b/.gitignore index fd3237c..d72ce04 100644 --- a/.gitignore +++ b/.gitignore @@ -7,12 +7,15 @@ __pycache__/ # Generated Mujina image artifacts /mujina_loader/mujina_armhf_base/ /mujina_loader/mujina_armhf_full/ +/mujina_loader/mujina_armhf_s19jpro_amlogic/ +/mujina_loader/output/ # Local Yocto/BSP worktree /yocto/ # Generated stock-signed USB burn artifacts /tools/mujina-usburner/output/ +/tools/mujina-usburner/output-s19jpro/ # Generated custom-kernel build artifacts /tools/kernel_build/output/ diff --git a/README.md b/README.md index 3fc1316..2cf2762 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ This repo is organized around one release goal: - build the `mujina_armhf_base` rootfs image +- optionally extend it into an S19j Pro Amlogic deployment payload with + `mujina-minerd` and the board config preloaded into `/home/root` - flash it onto Amlogic S21 control boards - restore boards back to stock when needed @@ -37,6 +39,13 @@ cd mujina_loader ./build_armhf_base_payload.sh ``` +Build the S19j Pro-ready payload: + +```bash +cd mujina_loader +./build_s19jpro_amlogic_payload.sh +``` + Flash it over USB burn: ```bash diff --git a/mujina_loader/README.md b/mujina_loader/README.md index f28f8aa..32ce4af 100644 --- a/mujina_loader/README.md +++ b/mujina_loader/README.md @@ -24,6 +24,12 @@ This directory now focuses on building the release image: - `build_armhf_base_payload.sh` - builds the first release-oriented `armhf` base profile with SSH enabled and telnet/HTTP disabled by default +- `build_mujina_minerd_armhf.sh` + - cross-builds `mujina-minerd` for the Amlogic board using Docker, with a + `cargo-zigbuild` fallback if Docker is unavailable +- `build_s19jpro_amlogic_payload.sh` + - extends a base payload by baking `mujina-minerd`, `start.sh`, `stop.sh`, + `mujina-hb2.toml`, and `mujina.env` into `/home/root` - `mujina_armhf_full/` - generated development-oriented output directory - `mujina_armhf_base/` @@ -91,6 +97,23 @@ cd mujina_loader ./build_armhf_base_payload.sh ``` +Build a deployable S19j Pro Amlogic payload with the miner bundle already +staged into `/home/root`: + +```bash +cd mujina_loader +./build_s19jpro_amlogic_payload.sh +``` + +Override the worker name or reuse an existing base payload: + +```bash +cd mujina_loader +./build_s19jpro_amlogic_payload.sh \ + --base-payload-dir ./mujina_armhf_base \ + --pool-user 'your-address.worker' +``` + Run the stock-board SSH installer flow: ```bash diff --git a/mujina_loader/build_armhf_full_payload.sh b/mujina_loader/build_armhf_full_payload.sh index 3ef549c..fe1d116 100755 --- a/mujina_loader/build_armhf_full_payload.sh +++ b/mujina_loader/build_armhf_full_payload.sh @@ -107,8 +107,8 @@ mkdir -p /config /etc/dropbear /etc/init.d /etc/mujina/rc.d /etc/udhcpc /root /r chmod 1777 /tmp for tool in wpa_supplicant wpa_cli wpa_passphrase; do - tool_path="$(command -v "${tool}" || true)" - [ -n "${tool_path}" ] && ln -sf "${tool_path}" "/usr/local/bin/${tool}" + tool_path="\$(command -v "\${tool}" || true)" + [ -n "\${tool_path}" ] && ln -sf "\${tool_path}" "/usr/local/bin/\${tool}" done ln -sf /bin/busybox /sbin/udhcpc ln -sf /bin/busybox /usr/sbin/udhcpc @@ -231,130 +231,130 @@ if [ -f /config/wifi-autostart.conf ]; then . /config/wifi-autostart.conf fi -if [ -z "$WIFI_CONFIG_PATH" ]; then - WIFI_CONFIG_PATH="/config/wpa_supplicant-$WIFI_IFACE.conf" +if [ -z "\$WIFI_CONFIG_PATH" ]; then + WIFI_CONFIG_PATH="/config/wpa_supplicant-\$WIFI_IFACE.conf" fi -WPA_PID="/var/run/wpa_supplicant-$WIFI_IFACE.pid" -DHCP_PID="/var/run/udhcpc.$WIFI_IFACE.pid" -MODULE_PATH="/lib/modules/$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8821cu/8821cu.ko" -MODULE_PATH_ALT="/lib/modules/$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8812au/88XXau.ko" +WPA_PID="/var/run/wpa_supplicant-\$WIFI_IFACE.pid" +DHCP_PID="/var/run/udhcpc.\$WIFI_IFACE.pid" +MODULE_PATH="/lib/modules/\$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8821cu/8821cu.ko" +MODULE_PATH_ALT="/lib/modules/\$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8812au/88XXau.ko" log() { - echo "wifi-autostart: $*" + echo "wifi-autostart: \$*" } usb_wifi_id() { - if [ -n "$USB_WIFI_ID" ]; then - printf '%s\n' "$USB_WIFI_ID" + if [ -n "\$USB_WIFI_ID" ]; then + printf '%s\n' "\$USB_WIFI_ID" return 0 fi for dev in /sys/bus/usb/devices/*; do - [ -f "$dev/idVendor" ] || continue - vendor=$(cat "$dev/idVendor" 2>/dev/null || true) - product=$(cat "$dev/idProduct" 2>/dev/null || true) - if [ -n "$vendor" ] && [ -n "$product" ]; then - printf '%s:%s\n' "$vendor" "$product" + [ -f "\$dev/idVendor" ] || continue + vendor=\$(cat "\$dev/idVendor" 2>/dev/null || true) + product=\$(cat "\$dev/idProduct" 2>/dev/null || true) + if [ -n "\$vendor" ] && [ -n "\$product" ]; then + printf '%s:%s\n' "\$vendor" "\$product" fi done } load_wifi_module() { - for id in $(usb_wifi_id); do - case "$id" in + for id in \$(usb_wifi_id); do + case "\$id" in 2357:011e|2357:011f|2357:0120) - log "loading 88XXau for USB ID $id" - modprobe 88XXau >/dev/null 2>&1 || insmod "$MODULE_PATH_ALT" >/dev/null 2>&1 || true + log "loading 88XXau for USB ID \$id" + modprobe 88XXau >/dev/null 2>&1 || insmod "\$MODULE_PATH_ALT" >/dev/null 2>&1 || true return 0 ;; 0bda:c811|0bda:c82b|0bda:c82a|0bda:c820|0bda:c821|0bda:b820|0bda:b82b) - log "loading 8821cu for USB ID $id" - modprobe 8821cu >/dev/null 2>&1 || insmod "$MODULE_PATH" >/dev/null 2>&1 || true + log "loading 8821cu for USB ID \$id" + modprobe 8821cu >/dev/null 2>&1 || insmod "\$MODULE_PATH" >/dev/null 2>&1 || true return 0 ;; esac done log "no known USB Wi-Fi ID found, trying 8821cu then 88XXau" - modprobe 8821cu >/dev/null 2>&1 || insmod "$MODULE_PATH" >/dev/null 2>&1 || true - modprobe 88XXau >/dev/null 2>&1 || insmod "$MODULE_PATH_ALT" >/dev/null 2>&1 || true + modprobe 8821cu >/dev/null 2>&1 || insmod "\$MODULE_PATH" >/dev/null 2>&1 || true + modprobe 88XXau >/dev/null 2>&1 || insmod "\$MODULE_PATH_ALT" >/dev/null 2>&1 || true } kill_pidfile() { - pidfile=$1 - if [ -f "$pidfile" ]; then - kill "$(cat "$pidfile")" 2>/dev/null || true - rm -f "$pidfile" + pidfile=\$1 + if [ -f "\$pidfile" ]; then + kill "\$(cat "\$pidfile")" 2>/dev/null || true + rm -f "\$pidfile" fi } wait_for_iface() { count=0 - while [ "$count" -lt 20 ]; do - if ip link show "$WIFI_IFACE" >/dev/null 2>&1; then + while [ "\$count" -lt 20 ]; do + if ip link show "\$WIFI_IFACE" >/dev/null 2>&1; then return 0 fi sleep 1 - count=$((count + 1)) + count=\$((count + 1)) done return 1 } wait_for_assoc() { count=0 - while [ "$count" -lt 20 ]; do - if wpa_cli -i "$WIFI_IFACE" status 2>/dev/null | grep -q '^wpa_state=COMPLETED$'; then + while [ "\$count" -lt 20 ]; do + if wpa_cli -i "\$WIFI_IFACE" status 2>/dev/null | grep -q '^wpa_state=COMPLETED$'; then return 0 fi sleep 1 - count=$((count + 1)) + count=\$((count + 1)) done return 1 } apply_arp_policy() { - for key in all default "$ETH_IFACE" "$WIFI_IFACE"; do - [ -d "/proc/sys/net/ipv4/conf/$key" ] || continue - echo 1 > "/proc/sys/net/ipv4/conf/$key/arp_ignore" - echo 2 > "/proc/sys/net/ipv4/conf/$key/arp_announce" - echo 1 > "/proc/sys/net/ipv4/conf/$key/arp_filter" + for key in all default "\$ETH_IFACE" "\$WIFI_IFACE"; do + [ -d "/proc/sys/net/ipv4/conf/\$key" ] || continue + echo 1 > "/proc/sys/net/ipv4/conf/\$key/arp_ignore" + echo 2 > "/proc/sys/net/ipv4/conf/\$key/arp_announce" + echo 1 > "/proc/sys/net/ipv4/conf/\$key/arp_filter" done } apply_wifi_routing() { - wifi_cidr=$(ip -4 addr show dev "$WIFI_IFACE" | awk '/inet / {print $2; exit}') - [ -n "$wifi_cidr" ] || return 0 + wifi_cidr=\$(ip -4 addr show dev "\$WIFI_IFACE" | awk '/inet / {print \$2; exit}') + [ -n "\$wifi_cidr" ] || return 0 - wifi_src=${wifi_cidr%/*} - wifi_subnet=$(ip -4 route show dev "$WIFI_IFACE" scope link | awk 'NR==1 {print $1; exit}') - wifi_gw=$(ip route show default | awk 'NR==1 {print $3; exit}') + wifi_src=\${wifi_cidr%/*} + wifi_subnet=\$(ip -4 route show dev "\$WIFI_IFACE" scope link | awk 'NR==1 {print \$1; exit}') + wifi_gw=\$(ip route show default | awk 'NR==1 {print \$3; exit}') - ip rule del from "$wifi_src/32" table "$WIFI_ROUTE_TABLE" 2>/dev/null || true - ip route flush table "$WIFI_ROUTE_TABLE" 2>/dev/null || true + ip rule del from "\$wifi_src/32" table "\$WIFI_ROUTE_TABLE" 2>/dev/null || true + ip route flush table "\$WIFI_ROUTE_TABLE" 2>/dev/null || true - if [ -n "$wifi_subnet" ]; then - ip route add "$wifi_subnet" dev "$WIFI_IFACE" src "$wifi_src" table "$WIFI_ROUTE_TABLE" + if [ -n "\$wifi_subnet" ]; then + ip route add "\$wifi_subnet" dev "\$WIFI_IFACE" src "\$wifi_src" table "\$WIFI_ROUTE_TABLE" fi - if [ -n "$wifi_gw" ]; then - ip route add default via "$wifi_gw" dev "$WIFI_IFACE" table "$WIFI_ROUTE_TABLE" 2>/dev/null || true + if [ -n "\$wifi_gw" ]; then + ip route add default via "\$wifi_gw" dev "\$WIFI_IFACE" table "\$WIFI_ROUTE_TABLE" 2>/dev/null || true fi - ip rule add from "$wifi_src/32" table "$WIFI_ROUTE_TABLE" priority 10000 2>/dev/null || true + ip rule add from "\$wifi_src/32" table "\$WIFI_ROUTE_TABLE" priority 10000 2>/dev/null || true apply_arp_policy } cleanup_stale_eth_ipv4() { - carrier=$(cat "/sys/class/net/$ETH_IFACE/carrier" 2>/dev/null || echo 0) - if [ "$carrier" = "0" ]; then - ip -4 addr flush dev "$ETH_IFACE" scope global 2>/dev/null || true + carrier=\$(cat "/sys/class/net/\$ETH_IFACE/carrier" 2>/dev/null || echo 0) + if [ "\$carrier" = "0" ]; then + ip -4 addr flush dev "\$ETH_IFACE" scope global 2>/dev/null || true fi } start_wifi() { - if [ ! -s "$WIFI_CONFIG_PATH" ]; then - log "skip: missing $WIFI_CONFIG_PATH" + if [ ! -s "\$WIFI_CONFIG_PATH" ]; then + log "skip: missing \$WIFI_CONFIG_PATH" return 0 fi @@ -362,36 +362,36 @@ start_wifi() { load_wifi_module if ! wait_for_iface; then - log "skip: $WIFI_IFACE did not appear" + log "skip: \$WIFI_IFACE did not appear" return 0 fi - kill_pidfile "$WPA_PID" - kill_pidfile "$DHCP_PID" - rm -f "/var/run/wpa_supplicant/$WIFI_IFACE" + kill_pidfile "\$WPA_PID" + kill_pidfile "\$DHCP_PID" + rm -f "/var/run/wpa_supplicant/\$WIFI_IFACE" - ifconfig "$WIFI_IFACE" down >/dev/null 2>&1 || true - ifconfig "$WIFI_IFACE" up >/dev/null 2>&1 || true + ifconfig "\$WIFI_IFACE" down >/dev/null 2>&1 || true + ifconfig "\$WIFI_IFACE" up >/dev/null 2>&1 || true - wpa_supplicant -B -D nl80211,wext -i "$WIFI_IFACE" -c "$WIFI_CONFIG_PATH" -P "$WPA_PID" + wpa_supplicant -B -D nl80211,wext -i "\$WIFI_IFACE" -c "\$WIFI_CONFIG_PATH" -P "\$WPA_PID" wait_for_assoc || true - /bin/busybox udhcpc -n -q -t 10 -T 3 -p "$DHCP_PID" -i "$WIFI_IFACE" || true + /bin/busybox udhcpc -n -q -t 10 -T 3 -p "\$DHCP_PID" -i "\$WIFI_IFACE" || true apply_wifi_routing cleanup_stale_eth_ipv4 - log "$WIFI_IFACE ready" + log "\$WIFI_IFACE ready" return 0 } stop_wifi() { - kill_pidfile "$DHCP_PID" - kill_pidfile "$WPA_PID" - rm -f "/var/run/wpa_supplicant/$WIFI_IFACE" + kill_pidfile "\$DHCP_PID" + kill_pidfile "\$WPA_PID" + rm -f "/var/run/wpa_supplicant/\$WIFI_IFACE" ip rule del priority 10000 2>/dev/null || true - ip route flush table "$WIFI_ROUTE_TABLE" 2>/dev/null || true - ifconfig "$WIFI_IFACE" down >/dev/null 2>&1 || true + ip route flush table "\$WIFI_ROUTE_TABLE" 2>/dev/null || true + ifconfig "\$WIFI_IFACE" down >/dev/null 2>&1 || true } -case "${1:-start}" in +case "\${1:-start}" in start) start_wifi ;; @@ -403,11 +403,11 @@ case "${1:-start}" in start_wifi ;; status) - wpa_cli -i "$WIFI_IFACE" status 2>/dev/null || true - ip route show table "$WIFI_ROUTE_TABLE" 2>/dev/null || true + wpa_cli -i "\$WIFI_IFACE" status 2>/dev/null || true + ip route show table "\$WIFI_ROUTE_TABLE" 2>/dev/null || true ;; *) - echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 + echo "Usage: \$0 {start|stop|restart|force-reload|status}" >&2 exit 2 ;; esac diff --git a/mujina_loader/build_mujina_minerd_armhf.sh b/mujina_loader/build_mujina_minerd_armhf.sh new file mode 100755 index 0000000..2ed031e --- /dev/null +++ b/mujina_loader/build_mujina_minerd_armhf.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" +MUJINA_DIR="${MUJINA_DIR:-${WORKSPACE_ROOT}/mujina}" +OUTPUT_BIN="${OUTPUT_BIN:-${SCRIPT_DIR}/output/mujina-minerd-armhf}" +DOCKER_IMAGE="${DOCKER_IMAGE:-messense/rust-musl-cross:armv7-musleabihf}" +DOCKER_PLATFORM="${DOCKER_PLATFORM:-linux/amd64}" +GNU_TARGET="${GNU_TARGET:-armv7-unknown-linux-gnueabihf}" +MUSL_TARGET="${MUSL_TARGET:-armv7-unknown-linux-musleabihf}" + +usage() { + cat <&2 + exit 1 +} + +need_cmd() { + command -v "$1" >/dev/null 2>&1 || die "Missing required command: $1" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --mujina-dir) MUJINA_DIR="${2:-}"; shift 2 ;; + --out) OUTPUT_BIN="${2:-}"; shift 2 ;; + --help|-h) usage; exit 0 ;; + *) die "Unknown argument: $1" ;; + esac +done + +[[ -d "${MUJINA_DIR}" ]] || die "Missing Mujina repo: ${MUJINA_DIR}" +[[ -f "${MUJINA_DIR}/Cargo.toml" ]] || die "Missing Cargo.toml in ${MUJINA_DIR}" +[[ -d "${MUJINA_DIR}/../amlogic-cb-tools" ]] || die "Missing sibling amlogic-cb-tools repo at ${MUJINA_DIR}/../amlogic-cb-tools" + +mkdir -p "$(dirname "${OUTPUT_BIN}")" + +if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then + docker run --rm \ + --platform "${DOCKER_PLATFORM}" \ + -v "${WORKSPACE_ROOT}:/work" \ + -w /work/mujina \ + "${DOCKER_IMAGE}" \ + bash -lc "set -euo pipefail; cargo build --release --bin mujina-minerd --target ${MUSL_TARGET} --no-default-features" + + cp "${MUJINA_DIR}/target/${MUSL_TARGET}/release/mujina-minerd" "${OUTPUT_BIN}" + chmod 0755 "${OUTPUT_BIN}" + echo "Built ${OUTPUT_BIN} via Docker (${MUSL_TARGET})" + exit 0 +fi + +if command -v cargo-zigbuild >/dev/null 2>&1 && command -v zig >/dev/null 2>&1; then + need_cmd rustup + + ( + cd "${MUJINA_DIR}" + rustup target add "${MUSL_TARGET}" >/dev/null + cargo-zigbuild --release --bin mujina-minerd --target "${MUSL_TARGET}" --no-default-features + ) + + cp "${MUJINA_DIR}/target/${MUSL_TARGET}/release/mujina-minerd" "${OUTPUT_BIN}" + chmod 0755 "${OUTPUT_BIN}" + echo "Built ${OUTPUT_BIN} via cargo-zigbuild (${MUSL_TARGET})" + exit 0 +fi + +die "No supported cross-build path available. Start Docker Desktop for the repo's preferred build path, or install both zig and cargo-zigbuild for the musl fallback." diff --git a/mujina_loader/build_s19jpro_amlogic_payload.sh b/mujina_loader/build_s19jpro_amlogic_payload.sh new file mode 100755 index 0000000..d5f6c4e --- /dev/null +++ b/mujina_loader/build_s19jpro_amlogic_payload.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +WORKSPACE_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" +BASE_BUILDER="${SCRIPT_DIR}/build_armhf_base_payload.sh" +MINER_BUILDER="${SCRIPT_DIR}/build_mujina_minerd_armhf.sh" +MUJINA_DIR="${MUJINA_DIR:-${WORKSPACE_ROOT}/mujina}" +BASE_PAYLOAD_DIR="${BASE_PAYLOAD_DIR:-}" +OUT_PAYLOAD="${OUT_PAYLOAD:-${SCRIPT_DIR}/mujina_armhf_s19jpro_amlogic}" +HOSTNAME_VALUE="${HOSTNAME_VALUE:-mujina-s19jpro-aml}" +PROFILE_NAME="${PROFILE_NAME:-Mujina S19j Pro Amlogic payload}" +VERSION_VALUE="${VERSION_VALUE:-0.3.0 (s19jpro-amlogic)}" +VERSION_ID_VALUE="${VERSION_ID_VALUE:-0.3.0}" +RUST_LOG_VALUE="${RUST_LOG_VALUE:-debug}" +POOL_URL="${POOL_URL:-stratum+tcp://pool.256foundation.org:3333}" +POOL_USER="${POOL_USER:-npub1ql2zzp3g6yndgz05js7wdc4qkr88wkyne5nw2cc7csrtzqs0yeesgwrxya.mujina-jPro-amlogic}" +POOL_PASS="${POOL_PASS:-x}" +API_LISTEN="${API_LISTEN:-0.0.0.0:7785}" +MINER_BIN="${MINER_BIN:-}" +WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/mujina-s19jpro-payload.XXXXXX")" + +cleanup() { + rm -rf "${WORK_DIR}" +} +trap cleanup EXIT + +usage() { + cat <&2 + exit 1 +} + +need_cmd() { + command -v "$1" >/dev/null 2>&1 || die "Missing required command: $1" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --mujina-dir) MUJINA_DIR="${2:-}"; shift 2 ;; + --base-payload-dir) BASE_PAYLOAD_DIR="${2:-}"; shift 2 ;; + --miner-bin) MINER_BIN="${2:-}"; shift 2 ;; + --out-dir) OUT_PAYLOAD="${2:-}"; shift 2 ;; + --hostname) HOSTNAME_VALUE="${2:-}"; shift 2 ;; + --pool-url) POOL_URL="${2:-}"; shift 2 ;; + --pool-user) POOL_USER="${2:-}"; shift 2 ;; + --pool-pass) POOL_PASS="${2:-}"; shift 2 ;; + --api-listen) API_LISTEN="${2:-}"; shift 2 ;; + --rust-log) RUST_LOG_VALUE="${2:-}"; shift 2 ;; + --help|-h) usage; exit 0 ;; + *) die "Unknown argument: $1" ;; + esac +done + +need_cmd python3 +need_cmd shasum + +[[ -d "${MUJINA_DIR}" ]] || die "Missing Mujina repo: ${MUJINA_DIR}" +for required in start.sh stop.sh mujina-hb2.toml mujina.env.example; do + [[ -f "${MUJINA_DIR}/${required}" ]] || die "Missing ${required} in ${MUJINA_DIR}" +done + +if [[ -z "${BASE_PAYLOAD_DIR}" ]]; then + [[ -x "${BASE_BUILDER}" ]] || die "Missing base payload builder: ${BASE_BUILDER}" + BASE_PAYLOAD_DIR="${WORK_DIR}/base-payload" + OUT_PAYLOAD="${OUT_PAYLOAD}" + + OUT_PAYLOAD="${BASE_PAYLOAD_DIR}" \ + HOSTNAME_VALUE="${HOSTNAME_VALUE}" \ + PROFILE_NAME="${PROFILE_NAME}" \ + VERSION_VALUE="${VERSION_VALUE}" \ + VERSION_ID_VALUE="${VERSION_ID_VALUE}" \ + "${BASE_BUILDER}" +fi + +[[ -d "${BASE_PAYLOAD_DIR}" ]] || die "Missing base payload dir: ${BASE_PAYLOAD_DIR}" +[[ -f "${BASE_PAYLOAD_DIR}/rootfs.tar.gz" ]] || die "Missing ${BASE_PAYLOAD_DIR}/rootfs.tar.gz" +[[ -f "${BASE_PAYLOAD_DIR}/nand_env.bin" ]] || die "Missing ${BASE_PAYLOAD_DIR}/nand_env.bin" + +if [[ -z "${MINER_BIN}" ]]; then + [[ -x "${MINER_BUILDER}" ]] || die "Missing miner build helper: ${MINER_BUILDER}" + MINER_BIN="${WORK_DIR}/mujina-minerd" + MUJINA_DIR="${MUJINA_DIR}" OUTPUT_BIN="${MINER_BIN}" "${MINER_BUILDER}" +fi + +[[ -f "${MINER_BIN}" ]] || die "Missing miner binary: ${MINER_BIN}" + +rm -rf "${OUT_PAYLOAD}" +mkdir -p "${OUT_PAYLOAD}" "${WORK_DIR}/rootfs/home/root" +cp -R "${BASE_PAYLOAD_DIR}/." "${OUT_PAYLOAD}/" + +python3 - "${BASE_PAYLOAD_DIR}/rootfs.tar.gz" "${WORK_DIR}/rootfs" <<'PY' +import sys +import tarfile + +rootfs_tar = sys.argv[1] +dest = sys.argv[2] + +with tarfile.open(rootfs_tar, "r:*") as tar: + kwargs = {} + if hasattr(tarfile, "data_filter"): + kwargs["filter"] = "fully_trusted" + tar.extractall(dest, **kwargs) +PY + +cp "${MINER_BIN}" "${WORK_DIR}/rootfs/home/root/mujina-minerd" +cp "${MUJINA_DIR}/start.sh" "${WORK_DIR}/rootfs/home/root/start.sh" +cp "${MUJINA_DIR}/stop.sh" "${WORK_DIR}/rootfs/home/root/stop.sh" +cp "${MUJINA_DIR}/mujina-hb2.toml" "${WORK_DIR}/rootfs/home/root/mujina-hb2.toml" +cp "${MUJINA_DIR}/mujina.env.example" "${WORK_DIR}/rootfs/home/root/mujina.env.example" + +cat > "${WORK_DIR}/rootfs/home/root/mujina.env" < tarfile.TarInfo: + ti.uid = 0 + ti.gid = 0 + ti.uname = "root" + ti.gname = "root" + return ti + +with tarfile.open(output, "w:gz", format=tarfile.USTAR_FORMAT) as tar: + for entry in sorted(os.listdir(root)): + tar.add(os.path.join(root, entry), arcname=entry, recursive=True, filter=normalize) +PY + +miner_rev="$(git -C "${MUJINA_DIR}" rev-parse HEAD 2>/dev/null || echo unknown)" +cat >> "${OUT_PAYLOAD}/manifest.txt" < SHA256SUMS +) + +echo "Built ${OUT_PAYLOAD}" +echo "Ready-to-copy board assets baked into /home/root:" +echo " mujina-minerd" +echo " start.sh" +echo " stop.sh" +echo " mujina-hb2.toml" +echo " mujina.env" +echo " mujina.env.example" diff --git a/tools/mujina-usburner/flash_stock_signed_mujina_image.sh b/tools/mujina-usburner/flash_stock_signed_mujina_image.sh index 50bd758..2c43622 100755 --- a/tools/mujina-usburner/flash_stock_signed_mujina_image.sh +++ b/tools/mujina-usburner/flash_stock_signed_mujina_image.sh @@ -27,7 +27,7 @@ verify_inputs() { [[ -f "${ENV_BIN}" ]] || die "Missing env blob: ${ENV_BIN}" [[ -x "${FLASH_TOOL}" ]] || die "Missing flash-tool: ${FLASH_TOOL}" [[ -x "${UPDATE_BIN}" ]] || die "Missing update binary: ${UPDATE_BIN}" - [[ -e /usr/local/opt/libusb-compat/lib/libusb-0.1.4.dylib ]] || die "Missing libusb-compat. Run tools/stock_fw_restore/install_host_deps.sh first." + [[ -e /usr/local/opt/libusb-compat/lib/libusb-0.1.4.dylib || -e /opt/homebrew/opt/libusb-compat/lib/libusb-0.1.4.dylib ]] || die "Missing libusb-compat. Run tools/stock_fw_restore/install_host_deps.sh first." need_cmd awk } diff --git a/tools/stock_fw_restore/flash_stock_s21_aml_macos.sh b/tools/stock_fw_restore/flash_stock_s21_aml_macos.sh index 94220d8..c91bce1 100755 --- a/tools/stock_fw_restore/flash_stock_s21_aml_macos.sh +++ b/tools/stock_fw_restore/flash_stock_s21_aml_macos.sh @@ -26,7 +26,7 @@ if [[ ! -x "${UPDATE_BIN}" ]]; then exit 1 fi -if [[ ! -e /usr/local/opt/libusb-compat/lib/libusb-0.1.4.dylib ]]; then +if [[ ! -e /usr/local/opt/libusb-compat/lib/libusb-0.1.4.dylib && ! -e /opt/homebrew/opt/libusb-compat/lib/libusb-0.1.4.dylib ]]; then echo "Missing libusb-compat. Run ./install_host_deps.sh first." >&2 exit 1 fi