From 30804ea4f59d65559c8ba0095cac5292ec32b06c Mon Sep 17 00:00:00 2001 From: Miguel Fuertes Date: Fri, 3 Oct 2025 16:40:21 +0200 Subject: [PATCH] ledcontrol --- diffconfig | 1 + msm89xx/image/generate_gpt.sh | 20 +++++ msm89xx/image/gpt.table | 18 ++++ msm89xx/image/msm8916.mk | 10 +-- packages/ledcontrol/Makefile | 37 ++++++++ packages/ledcontrol/files/99-modem-led | 14 +++ .../files/99-wifi-led} | 7 +- packages/ledcontrol/files/ledcontrol | 87 ++++++++++++++++++ .../files/msm-firmware-dumper.sh | 47 +++++----- .../rootfs-resizer/files/rootfs-resizer.init | 88 +++++++------------ packages/uz801-tweaks/Makefile | 7 -- packages/uz801-tweaks/files/modem-led.hotplug | 13 --- readme.md | 4 +- 13 files changed, 240 insertions(+), 113 deletions(-) create mode 100755 msm89xx/image/generate_gpt.sh create mode 100644 msm89xx/image/gpt.table create mode 100644 packages/ledcontrol/Makefile create mode 100644 packages/ledcontrol/files/99-modem-led rename packages/{uz801-tweaks/files/wifi-led.hotplug => ledcontrol/files/99-wifi-led} (75%) create mode 100644 packages/ledcontrol/files/ledcontrol delete mode 100644 packages/uz801-tweaks/files/modem-led.hotplug diff --git a/diffconfig b/diffconfig index acb2f97..9f97d6d 100644 --- a/diffconfig +++ b/diffconfig @@ -21,6 +21,7 @@ CONFIG_PACKAGE_kmod-tun=y CONFIG_PACKAGE_kmod-udptunnel4=y CONFIG_PACKAGE_kmod-udptunnel6=y CONFIG_PACKAGE_kmod-wireguard=y +CONFIG_PACKAGE_ledcontrol=y CONFIG_PACKAGE_libattr=y CONFIG_PACKAGE_libdbus=y CONFIG_PACKAGE_libexpat=y diff --git a/msm89xx/image/generate_gpt.sh b/msm89xx/image/generate_gpt.sh new file mode 100755 index 0000000..d1c9415 --- /dev/null +++ b/msm89xx/image/generate_gpt.sh @@ -0,0 +1,20 @@ +#!/bin/sh -e +# Usage: generate-gpt.sh + +OUTFILE="$1" +TMPDIR="$(mktemp -d)" +IMG="${TMPDIR}/gpt.img" +SECTOR_SIZE=512 +SECTORS_TOTAL=7634944 +truncate -s $((SECTORS_TOTAL*SECTOR_SIZE)) "${IMG}" + +sfdisk "${IMG}" < gpt.table + +{ + dd if="${IMG}" bs=${SECTOR_SIZE} count=34 status=none + dd if="${IMG}" bs=${SECTOR_SIZE} skip=$((SECTORS_TOTAL - 33)) count=33 status=none +} > "${OUTFILE}" + +echo "Wrote: ${OUTFILE}" + +rm -rf "${TMPDIR}" \ No newline at end of file diff --git a/msm89xx/image/gpt.table b/msm89xx/image/gpt.table new file mode 100644 index 0000000..6bfd53a --- /dev/null +++ b/msm89xx/image/gpt.table @@ -0,0 +1,18 @@ +label: gpt +unit: sectors +sector-size: 512 + +p1 : start= 4096, size= 2, type=57B90A16-22C9-E33B-8F5D-0E81686A68CB, name="fsc" +p2 : start= 4098, size= 3072, type=638FF8E2-22C9-E33B-8F5D-0E81686A68CB, name="fsg" +p3 : start= 7170, size= 131072, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="modem" +p4 : start= 138242, size= 3072, type=EBBEADAF-22C9-E33B-8F5D-0E81686A68CB, name="modemst1" +p5 : start= 141314, size= 3072, type=0A288B1F-22C9-E33B-8F5D-0E81686A68CB, name="modemst2" +p6 : start= 144386, size= 65536, type=6C95E238-E343-4BA8-B489-8681ED22AD0B, name="persist" +p7 : start= 209922, size= 32, type=303E6AC3-AF15-4C54-9E9B-D9A8FBECF401, name="sec" +p8 : start= 209954, size= 1024, type=E1A6A689-0C8D-4CC6-B4E8-55A4320FBD8A, name="hyp" +p9 : start= 210978, size= 1024, type=098DF793-D712-413D-9D4E-89D711772228, name="rpm" +p10: start= 212002, size= 1024, type=DEA0BA2C-CBDD-4805-B4F9-F428251C3E98, name="sbl1" +p11: start= 213026, size= 2048, type=A053AA7F-40B8-4B1C-BA08-2F68AC71A4F4, name="tz" +p12: start= 215074, size= 2048, type=400FFDCD-22E0-47E7-9A23-F16ED9382388, name="aboot" +p13: start= 217122, size= 131072, type=20117F86-E985-4357-B9EE-374BC1D8487D, name="boot" +p14: start= 348194, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="rootfs" \ No newline at end of file diff --git a/msm89xx/image/msm8916.mk b/msm89xx/image/msm8916.mk index e6aa306..ea886fa 100644 --- a/msm89xx/image/msm8916.mk +++ b/msm89xx/image/msm8916.mk @@ -2,11 +2,9 @@ ifeq ($(SUBTARGET),msm8916) -define Build/generate-gpt-ext4 - $(TOPDIR)/target/linux/$(BOARD)/image/generate_gpt.sh \ - "$(dir $@)" \ - $(TOPDIR)/target/linux/$(BOARD)/image/gpt-ext4.table \ - "$(notdir $@)" +define Build/generate-gpt + chmod +x $(TOPDIR)/target/linux/$(BOARD)/image/generate_gpt.sh + $(TOPDIR)/target/linux/$(BOARD)/image/generate_gpt.sh $@ endef define Build/install-flasher @@ -28,7 +26,7 @@ define Device/yiming-uz801v3 DEVICE_PACKAGES := uz801-tweaks wpad-basic-wolfssl msm-firmware-dumper rmtfs rootfs-resizer msm8916-usb-gadget IMAGE/system.img := append-rootfs | append-metadata | sparse-img ARTIFACTS := gpt_both0.bin flash.sh - ARTIFACT/gpt_both0.bin := generate-gpt-ext4 + ARTIFACT/gpt_both0.bin := generate-gpt ARTIFACT/flash.sh := install-flasher endef TARGET_DEVICES += yiming-uz801v3 diff --git a/packages/ledcontrol/Makefile b/packages/ledcontrol/Makefile new file mode 100644 index 0000000..398bc77 --- /dev/null +++ b/packages/ledcontrol/Makefile @@ -0,0 +1,37 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ledcontrol +PKG_VERSION:=1.0 +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/ledcontrol + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Simple LED control utility + DEPENDS:= +endef + +define Package/ledcontrol/description + Simple utility to control device LEDs via sysfs + Usage: ledcontrol + Includes hotplug scripts for WiFi and modem LED management +endef + +define Build/Compile +endef + +define Package/ledcontrol/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) ./files/ledcontrol $(1)/usr/sbin/ + + $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 + $(INSTALL_DATA) ./files/etc/hotplug.d/ieee80211/99-wifi-led $(1)/etc/hotplug.d/ieee80211/ + + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DATA) ./files/etc/hotplug.d/iface/99-modem-led $(1)/etc/hotplug.d/iface/ +endef + +$(eval $(call BuildPackage,ledcontrol)) diff --git a/packages/ledcontrol/files/99-modem-led b/packages/ledcontrol/files/99-modem-led new file mode 100644 index 0000000..667a18e --- /dev/null +++ b/packages/ledcontrol/files/99-modem-led @@ -0,0 +1,14 @@ +#!/bin/sh +# /etc/hotplug.d/iface/99-modem-led +# Modem LED control based on interface status + +case "$ACTION:$INTERFACE" in + ifup:modem) + ledcontrol green on + logger -t modem-led "Modem UP - Green LED ON" + ;; + ifdown:modem) + ledcontrol green off + logger -t modem-led "Modem DOWN - Green LED OFF" + ;; +esac diff --git a/packages/uz801-tweaks/files/wifi-led.hotplug b/packages/ledcontrol/files/99-wifi-led similarity index 75% rename from packages/uz801-tweaks/files/wifi-led.hotplug rename to packages/ledcontrol/files/99-wifi-led index f962992..fb634b1 100644 --- a/packages/uz801-tweaks/files/wifi-led.hotplug +++ b/packages/ledcontrol/files/99-wifi-led @@ -1,22 +1,23 @@ #!/bin/sh # /etc/hotplug.d/ieee80211/99-wifi-led +# WiFi LED control based on phy0 status case "$ACTION" in add) if [ "$DEVICENAME" = "phy0" ]; then sleep 5 if ip link show phy0-ap0 2>/dev/null >/dev/null; then - echo 1 > /sys/class/leds/blue:wan/brightness + ledcontrol blue on logger -t wifi-led "phy0-ap0 exists, blue LED ON" else - echo 0 > /sys/class/leds/blue:wan/brightness + ledcontrol blue off logger -t wifi-led "phy0-ap0 missing, blue LED OFF" fi fi ;; remove) if [ "$DEVICENAME" = "phy0" ]; then - echo 0 > /sys/class/leds/blue:wan/brightness + ledcontrol blue off logger -t wifi-led "phy0 removed, blue LED OFF" fi ;; diff --git a/packages/ledcontrol/files/ledcontrol b/packages/ledcontrol/files/ledcontrol new file mode 100644 index 0000000..68e338a --- /dev/null +++ b/packages/ledcontrol/files/ledcontrol @@ -0,0 +1,87 @@ +#!/bin/sh +# LED Control Utility for OpenWrt +# Usage: ledcontrol + +set -e + +COLOR="$1" +ACTION="$2" + +# LED base path +LED_BASE="/sys/class/leds" + +# Find LED by color +find_led() { + local color="$1" + local led_path + + # Search for LED containing the color in name + led_path=$(find "$LED_BASE" -maxdepth 1 -type l -iname "*:${color}:*" 2>/dev/null | head -n 1) + + if [ -z "$led_path" ]; then + # Try without colons + led_path=$(find "$LED_BASE" -maxdepth 1 -type l -iname "*${color}*" 2>/dev/null | head -n 1) + fi + + if [ -z "$led_path" ]; then + logger -t ledcontrol "LED color '$color' not found" + echo "[!] LED color '$color' not found" >&2 + echo "[*] Available LEDs:" >&2 + ls -1 "$LED_BASE" | sed 's/^/ /' >&2 + return 1 + fi + + echo "$led_path" +} + +# Set LED state +set_led() { + local led_path="$1" + local action="$2" + + case "$action" in + on) + echo none > "$led_path/trigger" + echo 1 > "$led_path/brightness" + ;; + off) + echo none > "$led_path/trigger" + echo 0 > "$led_path/brightness" + ;; + blink) + echo timer > "$led_path/trigger" + echo 500 > "$led_path/delay_on" + echo 500 > "$led_path/delay_off" + ;; + blink_fast) + echo timer > "$led_path/trigger" + echo 100 > "$led_path/delay_on" + echo 100 > "$led_path/delay_off" + ;; + *) + logger -t ledcontrol "Invalid action: $action" + echo "[!] Invalid action: $action" >&2 + echo "[*] Valid actions: on, off, blink, blink_fast" >&2 + return 1 + ;; + esac +} + +# Main +if [ -z "$COLOR" ] || [ -z "$ACTION" ]; then + echo "Usage: ledcontrol " >&2 + echo "" >&2 + echo "Available LEDs:" >&2 + ls -1 "$LED_BASE" 2>/dev/null | sed 's/^/ /' >&2 + exit 1 +fi + +LED_PATH=$(find_led "$COLOR") || exit 1 +LED_NAME=$(basename "$LED_PATH") + +if set_led "$LED_PATH" "$ACTION"; then + logger -t ledcontrol "LED '$LED_NAME' set to '$ACTION'" + echo "[+] LED '$COLOR' set to '$ACTION'" +else + exit 1 +fi diff --git a/packages/msm-firmware-dumper/files/msm-firmware-dumper.sh b/packages/msm-firmware-dumper/files/msm-firmware-dumper.sh index bc3a93b..01b09a7 100644 --- a/packages/msm-firmware-dumper/files/msm-firmware-dumper.sh +++ b/packages/msm-firmware-dumper/files/msm-firmware-dumper.sh @@ -1,8 +1,5 @@ #!/bin/sh -# One-shot Qualcomm firmware dumper: mount partitions read-only, -# copy relevant blobs into /lib/firmware, set a marker to avoid -# re-running, and trigger a reboot. Accepts optional 'MCFG_PATH' -# env var to override the MCFG relative path within modem/persist. +# One-shot Qualcomm firmware dumper with LED feedback set -e DEFAULT_MARKER="/lib/firmware/DUMPED" @@ -12,63 +9,61 @@ MARKER="${MSM_DUMPER_FLAG_FILE:-$DEFAULT_MARKER}" [ -f "$MARKER" ] && exit 0 log() { logger -t msm-fw-dumper "$*"; } +led() { command -v ledcontrol >/dev/null 2>&1 && ledcontrol "$@" || true; } MNT="/tmp/mnt/msmfw" FW="/lib/firmware" MCFG_REL="${MCFG_PATH:-$DEFAULT_MCFG_PATH}" -log "start (marker not present)" +log "starting firmware dump" +led blue blink # Prepare mount points and target mkdir -p "$MNT/modem" "$MNT/persist" "$FW/wlan/prima" -# Mount partitions read-only (adjust device nodes if needed) +# Mount partitions read-only mount -t vfat -o ro,nosuid,nodev,noexec,iocharset=iso8859-1,codepage=437 /dev/mmcblk0p3 "$MNT/modem" 2>/dev/null || log "WARN: modem mount failed" mount -t ext4 -o ro,nosuid,nodev,noexec /dev/mmcblk0p6 "$MNT/persist" 2>/dev/null || log "WARN: persist mount failed" -# Copy if exists! +# Copy helper copy_if() { - src="$1"; dst="$2" - if [ -f "$src" ]; then - cp -af "$src" "$dst" && log "copied $(basename "$src")" || return $? - fi - return 0 + [ -f "$1" ] && cp -af "$1" "$2" && log "copied $(basename "$1")" } -# Modem/Wi-Fi core blobs (MDT + fragments + MBA if present) -for p in "$MNT/modem"/image/wcnss.mdt "$MNT/modem"/image/wcnss.b* \ - "$MNT/modem"/image/modem.mdt "$MNT/modem"/image/modem.b* \ +# Modem/Wi-Fi core blobs +for p in "$MNT/modem"/image/wcnss.{mdt,b*} \ + "$MNT/modem"/image/modem.{mdt,b*} \ "$MNT/modem"/image/mba.mbn do - [ -f "$p" ] && cp -af "$p" "$FW/" + copy_if "$p" "$FW/" done -# Wi‑Fi NV/configs required by wcn36xx (place under wlan/prima) +# Wi‑Fi NV/configs copy_if "$MNT/persist/WCNSS_qcom_wlan_nv.bin" "$FW/wlan/prima/WCNSS_qcom_wlan_nv.bin" copy_if "$MNT/modem/image/wlan/prima/WCNSS_qcom_wlan_nv.bin" "$FW/wlan/prima/WCNSS_qcom_wlan_nv.bin" copy_if "$MNT/modem/image/wlan/prima/WCNSS_cfg.dat" "$FW/wlan/prima/WCNSS_cfg.dat" copy_if "$MNT/modem/image/wlan/prima/WCNSS_qcom_cfg.ini" "$FW/wlan/prima/WCNSS_qcom_cfg.ini" -# MCFG handling: +# MCFG handling if [ -f "$MNT/modem/$MCFG_REL/mcfg_sw.mbn" ]; then cp -af "$MNT/modem/$MCFG_REL/mcfg_sw.mbn" "$FW/MCFG_SW.MBN" && log "MCFG from modem:$MCFG_REL" else - log "WARN: MCFG 'MCFG_PATH=$MCFG_REL' not found in modem" + log "WARN: MCFG '$MCFG_REL' not found" fi -# Honoring any user copied MCFG to /lib/firmware +# User override support [ -f "$FW/mcfg_sw.mbn" ] && ln -sf "$FW/mcfg_sw.mbn" "$FW/MCFG_SW.MBN" 2>/dev/null || true sync -# Unmount and cleanup -umount "$MNT/modem" 2>/dev/null || true -umount "$MNT/persist" 2>/dev/null || true +# Cleanup +umount "$MNT/modem" "$MNT/persist" 2>/dev/null || true rmdir "$MNT/persist" "$MNT/modem" 2>/dev/null || true -# Set marker and reboot once +# Mark done touch "$MARKER" -log "done, rebooting" -( sleep 2; reboot ) & +log "firmware dump complete, rebooting" +led green on +( sleep 2; led green blink; sleep 1; reboot ) & exit 0 diff --git a/packages/rootfs-resizer/files/rootfs-resizer.init b/packages/rootfs-resizer/files/rootfs-resizer.init index f3ddddb..1fae6ba 100644 --- a/packages/rootfs-resizer/files/rootfs-resizer.init +++ b/packages/rootfs-resizer/files/rootfs-resizer.init @@ -1,74 +1,50 @@ #!/bin/sh /etc/rc.common -# Early ext4 rootfs resizer with flag and logs (OpenWrt rc.common) +# Early ext4 rootfs resizer with LED feedback START=01 -STOP=00 NAME=rootfs-resizer -FLAG="/etc/rootfs-resizer.done" +FLAG="/RESIZED" log() { logger -t rootfs-resizer "$*"; } +led() { command -v ledcontrol >/dev/null 2>&1 && ledcontrol "$@" || true; } get_rootdev() { - local dev - dev="$(findmnt -n -o SOURCE / 2>/dev/null || awk '$2=="/"{print $1; exit}' /proc/mounts)" - [ -n "$dev" ] || dev="$(sed -n 's/.*\broot=\([^ ]*\).*/\1/p' /proc/cmdline)" + local dev="$(awk '$2=="/"{print $1; exit}' /proc/mounts)" [ "$dev" = "/dev/root" ] && dev="$(sed -n 's/.*\broot=\([^ ]*\).*/\1/p' /proc/cmdline)" - case "$dev" in - LABEL=*|UUID=*|PARTUUID=*|PARTLABEL=*) - dev="$(blkid -l -t "$dev" -o device 2>/dev/null || true)" - ;; - esac echo "$dev" } start() { - if [ -f "$FLAG" ]; then - log "flag present, skipping resize" - return 0 - fi - - log "starting early rootfs resize" - - local dev rc out - dev="$(get_rootdev)" - if [ -z "$dev" ] || [ ! -b "$dev" ]; then - log "could not resolve a valid root block device; aborting" - return 0 - fi - log "root device resolved: $dev" - - # Remount root read-only before metadata changes/checks - log "remounting / read-only" - mount -o ro,remount / 2>/dev/null || log "WARN: remount ro failed (continuing)" - - # Clear resize_inode like the working script (safe to ignore errors if not present) - log "clearing resize_inode feature if present" - out="$(tune2fs -O^resize_inode "$dev" 2>&1)"; rc=$? - echo "$out" | logger -t rootfs-resizer - [ $rc -ne 0 ] && log "tune2fs exited rc=$rc (continuing)" - - # Run fsck (note: generally discouraged on mounted FS; we remounted ro) - log "running e2fsck -yDf on $dev" - out="$(e2fsck -yDf "$dev" 2>&1)"; rc=$? - echo "$out" | logger -t rootfs-resizer - [ $rc -ne 0 ] && log "e2fsck exited rc=$rc (continuing)" - - # Back to read-write for online resize - log "remounting / read-write" - mount -o rw,remount / 2>/dev/null || log "WARN: remount rw failed (continuing)" - - log "invoking resize2fs (online) on $dev" - out="$(resize2fs "$dev" 2>&1)"; rc=$? - echo "$out" | logger -t rootfs-resizer - - if [ $rc -eq 0 ]; then - log "resize2fs succeeded on $dev" + [ -f "$FLAG" ] && { log "already resized, skipping"; return 0; } + + log "starting rootfs resize" + led blue blink + + local dev="$(get_rootdev)" + [ -z "$dev" ] || [ ! -b "$dev" ] && { + log "ERROR: invalid root device"; + led red blink_fast; + return 1; + } + + log "resizing $dev" + + # Prepare filesystem + mount -o ro,remount / 2>/dev/null + tune2fs -O^resize_inode "$dev" >/dev/null 2>&1 + e2fsck -yDf "$dev" >/dev/null 2>&1 + mount -o rw,remount / 2>/dev/null + + # Resize + if resize2fs "$dev" 2>&1 | logger -t rootfs-resizer; then + log "resize successful" + led green on touch "$FLAG" sync - log "flag created at $FLAG; syncing and rebooting" - - ( sleep 1; reboot -f ) & + ( sleep 2; led green blink; sleep 1; reboot -f ) & else - log "resize2fs failed rc=$rc; leaving system as-is" + log "ERROR: resize failed" + led red blink_fast + return 1 fi } diff --git a/packages/uz801-tweaks/Makefile b/packages/uz801-tweaks/Makefile index 88750b8..29a6a7e 100644 --- a/packages/uz801-tweaks/Makefile +++ b/packages/uz801-tweaks/Makefile @@ -29,13 +29,6 @@ endef define Package/$(PKG_NAME)/install $(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_BIN) ./files/uci_defaults $(1)/etc/uci-defaults/99-default-config - - $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 - $(INSTALL_BIN) ./files/wifi-led.hotplug $(1)/etc/hotplug.d/ieee80211/99-wifi-led - - $(INSTALL_DIR) $(1)/etc/hotplug.d/iface - $(INSTALL_BIN) ./files/modem-led.hotplug $(1)/etc/hotplug.d/iface/99-modem-led - endef $(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/packages/uz801-tweaks/files/modem-led.hotplug b/packages/uz801-tweaks/files/modem-led.hotplug deleted file mode 100644 index f4da69a..0000000 --- a/packages/uz801-tweaks/files/modem-led.hotplug +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# /etc/hotplug.d/iface/99-modem-led - -case "$ACTION:$INTERFACE" in - ifup:modem) - echo 1 > /sys/class/leds/green:wlan/brightness - logger -t smart-leds "Modem UP - Green LED ON" - ;; - ifdown:modem) - echo 0 > /sys/class/leds/green:wlan/brightness - logger -t smart-leds "Modem DOWN - Green LED OFF" - ;; -esac diff --git a/readme.md b/readme.md index 1e16814..54a417b 100644 --- a/readme.md +++ b/readme.md @@ -20,8 +20,8 @@ Modern version of OpenWrt working on UZ801v3: - Wireguard Installed - `hotplug.d` scripts to manage leds, only on/off if iface, no blinking: - On default Linux Kernel `dts`, leds are swapped! - - Wifi Led: [packages/uz801-tweaks/files/wifi-led.hotplug](packages/uz801-tweaks/files/wifi-led.hotplug) - - Modem Led: [packages/uz801-tweaks/files/modem-led.hotplug](packages/uz801-tweaks/files/modem-led.hotplug) + - Wifi Led: [packages/ledcontrol/files/99-modem-led](packages/ledcontrol/files/99-modem-led) + - Modem Led: [packages/ledcontrol/files/99-wifi-led](packages/ledcontrol/files/99-wifi-led) - Firmware is dumped on first boot from modem/persist partition: - Uses the binaries/firmware from the own device. - __This might imply that a port for other devices would be easier... but I have not tested it as I only have this device.___