Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions mujina_loader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/`
Expand Down Expand Up @@ -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
Expand Down
148 changes: 74 additions & 74 deletions mujina_loader/build_armhf_full_payload.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -231,167 +231,167 @@ 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

mkdir -p /var/run/wpa_supplicant
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
;;
Expand All @@ -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
Expand Down
Loading