diff --git a/README.md b/README.md index 21f6aad..d32607c 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,8 @@ compulab guide: [OS installation](https://mediawiki.compulab.com/w/index.php?tit ## Add layers -Files to update system to Buster +```bash +sudo ./install.sh +``` -Two options: - -1. copy `firmware` to device. (partial `config.txt` and overlays) -2. install repackaged .deb overlay (**untested**) +Copies `firmware/config.txt` (backing up the original as `config.bak`) and the `iotg-rpi4` device tree overlays to `/boot/firmware/`. Reboot afterwards. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..41f3843 --- /dev/null +++ b/install.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FIRMWARE_SRC="$SCRIPT_DIR/firmware" +BOOT="/boot/firmware" + +if [[ $EUID -ne 0 ]]; then + echo "ERROR: this script must be run as root (use sudo)" >&2 + exit 1 +fi + +echo "=== IOT-GATE-RPI4 layer install ===" +echo "Source : $FIRMWARE_SRC" +echo "Target : $BOOT" +echo + +# --- config.txt --- +echo "[1/2] Installing config.txt" + +if [[ -f "$BOOT/config.txt" ]]; then + echo " Backing up $BOOT/config.txt -> $BOOT/config.bak" + cp -v "$BOOT/config.txt" "$BOOT/config.bak" +else + echo " WARNING: $BOOT/config.txt not found, skipping backup" +fi + +echo " Copying $FIRMWARE_SRC/config.txt -> $BOOT/config.txt" +cp -v "$FIRMWARE_SRC/config.txt" "$BOOT/config.txt" + +# --- overlays --- +echo +echo "[2/2] Installing device tree overlays" + +OVERLAY_SRC="$FIRMWARE_SRC/overlays/iotg-rpi4" +OVERLAY_DST="$BOOT/overlays/iotg-rpi4" + +if [[ ! -d "$OVERLAY_SRC" ]]; then + echo " ERROR: overlay source directory not found: $OVERLAY_SRC" >&2 + exit 1 +fi + +echo " Creating $OVERLAY_DST" +mkdir -p "$OVERLAY_DST" + +for f in "$OVERLAY_SRC"/*; do + echo " Copying $(basename "$f")" + cp -v "$f" "$OVERLAY_DST/" +done + +echo +echo "=== Done ===" +echo "Reboot for overlay changes to take effect." diff --git a/iotg-rpi4-config_1.3-1_all.deb b/iotg-rpi4-config_1.3-1_all.deb deleted file mode 100644 index 50dab3d..0000000 Binary files a/iotg-rpi4-config_1.3-1_all.deb and /dev/null differ diff --git a/iotg-rpi4-config_1.3-1buster1_all.deb b/iotg-rpi4-config_1.3-1buster1_all.deb deleted file mode 100644 index 46c691d..0000000 Binary files a/iotg-rpi4-config_1.3-1buster1_all.deb and /dev/null differ diff --git a/led_status.sh b/led_status.sh new file mode 100755 index 0000000..951270f --- /dev/null +++ b/led_status.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# green: gpiochip3 line 13 / LED1_GREEN (0 = on, 1 = off, active-low) +# red: gpiochip3 line 14 / LED2_RED (0 = on, 1 = off, active-low) +# +# gpioset v2 holds the line until the process exits, so each LED is driven +# by a background process. We kill and replace it to change state. + +CHIP=/dev/gpiochip3 +GREEN_PIN=13 +RED_PIN=14 + +green_pid="" +red_pid="" + +set_led() { + local pin=$1 val=$2 pid_var=$3 + kill "${!pid_var}" 2>/dev/null || true + gpioset --chip "$CHIP" "${pin}=${val}" & + printf -v "$pid_var" '%s' "$!" +} + +cleanup() { + kill "$green_pid" "$red_pid" 2>/dev/null || true +} +trap 'cleanup; exit 0' INT TERM +trap cleanup EXIT + +# release any lines left held by a previous run of this script +pkill -f "gpioset.*$CHIP" 2>/dev/null || true + +green_state=0 # start ON + +while true; do + green_state=$(( 1 - green_state )) + set_led "$GREEN_PIN" "$green_state" green_pid + + if ping -q -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then + set_led "$RED_PIN" 1 red_pid + else + set_led "$RED_PIN" 0 red_pid + fi + + sleep 2 +done diff --git a/repackage_for_buster.py b/repackage_for_buster.py deleted file mode 100755 index 215def3..0000000 --- a/repackage_for_buster.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python3 -""" -Repackage iotg-rpi4-config .deb for Debian Buster+ compatibility. - -Changes: -- Updates CONFIG path from /boot/config.txt to /boot/firmware/config.txt -- Relocates overlays from /boot/overlays/ to /boot/firmware/overlays/ -""" - -import shutil -import subprocess -import tempfile -from pathlib import Path - - -def run_cmd(cmd: list[str], cwd: Path | None = None) -> None: - """Run shell command and handle errors.""" - result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True) - if result.returncode != 0: - raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{result.stderr}") - - -def modify_functions_file(functions_path: Path) -> None: - """Update CONFIG path in iotg-rpi4-functions.""" - content = functions_path.read_text() - - # Replace the CONFIG path - modified = content.replace( - "CONFIG=/boot/config.txt", - "CONFIG=/boot/firmware/config.txt" - ) - - # Also update the backup path reference (it uses ${CONFIG} so should be fine) - # But let's verify the change was made - if modified == content: - raise RuntimeError("Failed to modify CONFIG path - pattern not found") - - functions_path.write_text(modified) - print(f"✓ Modified {functions_path.name}") - - -def relocate_overlays(extract_dir: Path) -> None: - """Move overlays from /boot/overlays to /boot/firmware/overlays.""" - old_path = extract_dir / "boot" / "overlays" / "iotg-rpi4" - new_path = extract_dir / "boot" / "firmware" / "overlays" / "iotg-rpi4" - - if not old_path.exists(): - raise RuntimeError(f"Overlay directory not found: {old_path}") - - # Create new directory structure - new_path.parent.mkdir(parents=True, exist_ok=True) - - # Move the iotg-rpi4 directory - shutil.move(str(old_path), str(new_path)) - - # Remove old empty directories - (extract_dir / "boot" / "overlays").rmdir() - - print(f"✓ Relocated overlays to boot/firmware/overlays/iotg-rpi4/") - - -def repackage_deb(original_deb: Path, output_deb: Path) -> None: - """Extract, modify, and repackage the .deb file.""" - - with tempfile.TemporaryDirectory() as tmpdir: - work_dir = Path(tmpdir) - extract_dir = work_dir / "package" - control_dir = work_dir / "DEBIAN" - - extract_dir.mkdir() - control_dir.mkdir() - - print(f"Extracting {original_deb.name}...") - run_cmd(["dpkg-deb", "-x", str(original_deb), str(extract_dir)]) - run_cmd(["dpkg-deb", "-e", str(original_deb), str(control_dir)]) - - # Modify the functions file - functions_file = extract_dir / "usr" / "local" / "bin" / "iotg-rpi4-functions" - modify_functions_file(functions_file) - - # Relocate overlays - relocate_overlays(extract_dir) - - # Update control file version - control_file = control_dir / "control" - control_content = control_file.read_text() - control_content = control_content.replace( - "Version: 1.3-1", - "Version: 1.3-1buster1" - ) - control_file.write_text(control_content) - print("✓ Updated control file version") - - # Copy DEBIAN directory into extract_dir - shutil.copytree(control_dir, extract_dir / "DEBIAN") - - # Build new .deb - print(f"Building {output_deb.name}...") - run_cmd(["dpkg-deb", "-b", str(extract_dir), str(output_deb)]) - - print(f"\n✓ Successfully created {output_deb}") - - -def main() -> None: - """Main entry point.""" - script_dir = Path(__file__).parent - original_deb = script_dir / "iotg-rpi4-config_1.3-1_all.deb" - output_deb = script_dir / "iotg-rpi4-config_1.3-1buster1_all.deb" - - if not original_deb.exists(): - raise FileNotFoundError(f"Original .deb not found: {original_deb}") - - if output_deb.exists(): - print(f"Removing existing {output_deb.name}...") - output_deb.unlink() - - print("Repackaging for Debian Buster+ compatibility\n") - repackage_deb(original_deb, output_deb) - - print("\nChanges made:") - print(" • CONFIG=/boot/config.txt → CONFIG=/boot/firmware/config.txt") - print(" • Overlays moved from /boot/overlays/ → /boot/firmware/overlays/") - print(" • Version updated to 1.3-1buster1") - print(f"\nInstall with: sudo dpkg -i {output_deb.name}") - - -if __name__ == "__main__": - main()