mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 09:14:33 +00:00
feat(live-boot): Complete live RAM boot implementation v2.2.4-live
- Install live-boot package and rebuild initramfs with live-boot scripts - Create squashfs filesystem (878MB) on data partition sda4 - Update boot.scr with live boot parameters (boot=live, toram) - Fix wiki sidebar links from [[Page|Display]] to [Display](Page) - Add Eye-Remote wiki page documentation - Add sync-wiki.sh script for wiki repository sync - Add patch-multiboot-efi.sh for post-build EFI patching Partition layout: - sda1 (512MB): EFI with kernel, initrd, dtbs, boot.scr - sda2 (3GB): ARM64 rootfs reference - sda3 (3GB): x86 rootfs for VirtualBox/QEMU - sda4 (9.5GB): Data + /live/filesystem.squashfs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8a473cc1c2
commit
d42745aac3
|
|
@ -5,6 +5,85 @@
|
|||
|
||||
## 2026-04-27
|
||||
|
||||
### Session 70 — Live Boot Complete Setup (v2.2.4-live)
|
||||
|
||||
**Feature:** Full live-boot implementation with squashfs and RAM boot
|
||||
|
||||
**Description:**
|
||||
Completed full live-boot setup for Pi Zero Eye Remote storage.img. Installed live-boot package, rebuilt initramfs with live-boot scripts, created squashfs filesystem, and updated boot.scr with proper live boot parameters.
|
||||
|
||||
**Changes Made:**
|
||||
1. Installed `live-boot` and `busybox` packages on ARM64 rootfs
|
||||
2. Rebuilt initramfs with live-boot scripts included
|
||||
3. Created `/live/filesystem.squashfs` (878MB) on data partition (sda4)
|
||||
4. Updated boot.scr with live boot parameters:
|
||||
- `boot=live` - enables live-boot mode
|
||||
- `live-media=/dev/sda4` - partition with squashfs
|
||||
- `live-media-path=/live` - path to squashfs
|
||||
- `toram` - loads entire squashfs into RAM
|
||||
- DSA blacklist parameters preserved
|
||||
|
||||
**Partition Layout:**
|
||||
- sda1 (512MB): EFI - kernel, initrd, dtbs, boot.scr
|
||||
- sda2 (3GB): ARM64 rootfs (for reference)
|
||||
- sda3 (3GB): x86 rootfs (for VirtualBox/QEMU)
|
||||
- sda4 (9.5GB): Data + /live/filesystem.squashfs
|
||||
|
||||
**Wiki Fix:** Fixed sidebar link syntax from `[[Page|Display]]` to `[Display](Page)`
|
||||
|
||||
**Version:** v2.2.4-live
|
||||
|
||||
---
|
||||
|
||||
### Session 69 — Live RAM Boot Cmdline Fix (v2.2.4-pre2)
|
||||
|
||||
**Fix:** Added missing `boot=live live-media-path=/live` parameters to bootargs
|
||||
|
||||
**Description:**
|
||||
Fixed critical issue where multiboot image was not configured for live RAM boot. The kernel command line was missing the required `boot=live` and `live-media-path=/live` parameters that the live-boot initramfs needs to work properly.
|
||||
|
||||
**Files Modified:**
|
||||
- `image/multiboot/build-multiboot.sh` — Added live boot parameters to setenv bootargs
|
||||
|
||||
**Before:**
|
||||
```bash
|
||||
setenv bootargs "root=${rootpart} rootfstype=ext4 rootwait rootdelay=10 ..."
|
||||
```
|
||||
|
||||
**After:**
|
||||
```bash
|
||||
setenv bootargs "boot=live live-media-path=/live root=${rootpart} rootfstype=ext4 rootwait rootdelay=10 ..."
|
||||
```
|
||||
|
||||
**Version:** v2.2.4-pre2
|
||||
|
||||
---
|
||||
|
||||
### Session 68 — Multiboot Dual Boot Menu & Kernel Fix (v2.2.4-pre1)
|
||||
|
||||
**Feature:** Fixed ARM64 kernel installation and added interactive boot menu
|
||||
|
||||
**Description:**
|
||||
Fixed critical bug where ARM64 kernel, initrd, and DTB files were not being copied to the EFI partition. Added interactive dual boot menu with 5-second timeout, offering Live RAM Boot (default) or Flash to eMMC option.
|
||||
|
||||
**Files Modified:**
|
||||
- `image/multiboot/build-multiboot.sh` — Major fixes:
|
||||
- Fixed loop device release bug in `install_arm64_rootfs()` (was releasing before copying kernel)
|
||||
- Added `build_arm64_rootfs_debootstrap()` function with kernel installation
|
||||
- Added `copy_arm64_kernel_to_efi()` function to properly copy Image, initrd, DTBs
|
||||
- Updated boot.scr with interactive dual boot menu (5s timeout)
|
||||
- Added qemu-debootstrap and other optional dependency warnings
|
||||
- `.github/workflows/build-multiboot.yml` — Added prerelease support, bumped version
|
||||
- `wiki/_Sidebar.md` — Bumped version to v2.2.4-pre1
|
||||
|
||||
**Boot Menu Options:**
|
||||
1. Live RAM Boot (default with 5s timeout)
|
||||
2. Flash SecuBox to eMMC
|
||||
|
||||
**Version:** v2.2.4-pre1 (prerelease)
|
||||
|
||||
---
|
||||
|
||||
### Session 67 — Multiboot Wiki & Eye Remote Docs (v2.2.3)
|
||||
|
||||
**Feature:** Wiki documentation for multiboot live OS and Eye Remote integration
|
||||
|
|
|
|||
|
|
@ -1,3 +1,58 @@
|
|||
## Testing Notes
|
||||
|
||||
- **Virtualization testing**: Use VirtualBox only (not QEMU)
|
||||
|
||||
---
|
||||
|
||||
## Wiki Sync Workflow
|
||||
|
||||
GitHub wiki is a **separate repository** from the main project. Files in `wiki/` folder must be synced manually.
|
||||
|
||||
### Quick Command
|
||||
```bash
|
||||
# Sync and push wiki to GitHub
|
||||
bash scripts/sync-wiki.sh -p -m "Add Eye-Remote docs"
|
||||
|
||||
# Dry run (preview changes)
|
||||
bash scripts/sync-wiki.sh -n
|
||||
```
|
||||
|
||||
### Manual Workflow
|
||||
```bash
|
||||
# 1. Clone wiki repo
|
||||
git clone git@github.com:CyberMind-FR/secubox-deb.wiki.git /tmp/wiki
|
||||
|
||||
# 2. Copy files
|
||||
cp wiki/*.md /tmp/wiki/
|
||||
|
||||
# 3. Commit and push
|
||||
cd /tmp/wiki
|
||||
git add -A && git commit -m "Update wiki" && git push
|
||||
```
|
||||
|
||||
### When to Sync
|
||||
- After adding/editing any `wiki/*.md` file
|
||||
- After bumping version in `wiki/_Sidebar.md`
|
||||
- Before release (ensure docs match release)
|
||||
|
||||
### Red Links
|
||||
If wiki links show as red on GitHub:
|
||||
1. Verify file exists in `wiki/` folder
|
||||
2. Run `scripts/sync-wiki.sh -p` to push to wiki repo
|
||||
3. Check case sensitivity (GitHub wiki is case-sensitive)
|
||||
|
||||
---
|
||||
|
||||
## DSA Switch Loop Fix (ESPRESSObin)
|
||||
|
||||
**Problem:** mv88e6xxx driver infinite loop during boot
|
||||
**Root Cause:** Live kernel has mv88e6xxx built-in (not module)
|
||||
**Solution:** Use BOTH blacklists:
|
||||
```bash
|
||||
modprobe.blacklist=mv88e6xxx,mv88e6085,dsa_core initcall_blacklist=mv88e6xxx_driver_init
|
||||
```
|
||||
|
||||
**Where to apply:**
|
||||
- `boot.scr` — U-Boot boot script
|
||||
- `extlinux/extlinux.conf` — fallback config
|
||||
- `board/*/boot*.cmd` — source files
|
||||
|
|
|
|||
13
.github/workflows/build-multiboot.yml
vendored
13
.github/workflows/build-multiboot.yml
vendored
|
|
@ -28,6 +28,14 @@ on:
|
|||
options:
|
||||
- 'true'
|
||||
- 'false'
|
||||
prerelease:
|
||||
description: 'Mark as prerelease'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: choice
|
||||
options:
|
||||
- 'true'
|
||||
- 'false'
|
||||
push:
|
||||
tags:
|
||||
- 'multiboot-v*'
|
||||
|
|
@ -38,7 +46,7 @@ on:
|
|||
- 'image/multiboot/**'
|
||||
|
||||
env:
|
||||
VERSION: '2.2.3'
|
||||
VERSION: '2.2.4-pre1'
|
||||
|
||||
jobs:
|
||||
# Build all .deb packages first
|
||||
|
|
@ -182,6 +190,7 @@ jobs:
|
|||
with:
|
||||
tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('multiboot-v{0}', env.VERSION) }}
|
||||
name: SecuBox Multiboot v${{ env.VERSION }}
|
||||
prerelease: ${{ github.event.inputs.prerelease == 'true' || contains(env.VERSION, 'pre') }}
|
||||
files: |
|
||||
output/secubox-multiboot-${{ env.VERSION }}.img.xz
|
||||
output/secubox-multiboot-${{ env.VERSION }}.sha256
|
||||
|
|
@ -190,8 +199,10 @@ jobs:
|
|||
## SecuBox Multiboot v${{ env.VERSION }} — Live RAM OS
|
||||
|
||||
### 🎯 What's New
|
||||
- **Dual Boot Menu** — Interactive menu with 5s timeout: Live RAM Boot (default) or Flash to eMMC
|
||||
- **Dual Architecture** — Boot ARM64 (MOCHAbin/ESPRESSObin) or AMD64 (x86_64 PC)
|
||||
- **RAM-based Live OS** — Reduced I/O, ideal for USB gadget devices
|
||||
- **Auto Kernel Install** — ARM64 kernel, DTBs, and initrd properly installed on EFI partition
|
||||
- **SecuBox Pre-installed** — All modules slipstreamed, ready to use
|
||||
- **Shared Data Partition** — Persistent storage accessible from both architectures
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,14 @@ parse_args() {
|
|||
}
|
||||
|
||||
check_deps() {
|
||||
local deps=(parted mkfs.vfat mkfs.ext4 debootstrap grub-mkimage losetup)
|
||||
local deps=(parted mkfs.vfat mkfs.ext4 debootstrap losetup rsync)
|
||||
for cmd in "${deps[@]}"; do
|
||||
command -v "$cmd" &>/dev/null || err "Missing: $cmd"
|
||||
done
|
||||
# Optional deps - warn but don't fail
|
||||
command -v grub-mkimage &>/dev/null || log "WARNING: grub-mkimage not found, AMD64 UEFI boot may not work"
|
||||
command -v qemu-debootstrap &>/dev/null || log "WARNING: qemu-debootstrap not found, cross-arch debootstrap may fail"
|
||||
command -v mkimage &>/dev/null || log "WARNING: u-boot-tools mkimage not found, will use text boot.cmd"
|
||||
[[ $EUID -eq 0 ]] || err "Must run as root"
|
||||
}
|
||||
|
||||
|
|
@ -191,41 +195,106 @@ GRUBCFG
|
|||
install_uboot_boot() {
|
||||
log "Installing U-Boot boot files for ARM64..."
|
||||
|
||||
# Create boot.scr for ARM64 (ESPRESSObin)
|
||||
# Create boot.scr for ARM64 (ESPRESSObin) with dual boot menu
|
||||
cat > /tmp/boot.cmd <<'BOOTCMD'
|
||||
# SecuBox Multi-Boot U-Boot Script
|
||||
# For ESPRESSObin/MOCHAbin ARM64
|
||||
# Version: 2.2.4
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "SecuBox Multi-Boot — ARM64"
|
||||
echo " SecuBox Multi-Boot — ARM64"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
# Detect boot device
|
||||
if test "${devtype}" = "usb"; then
|
||||
setenv bootpart "usb 0:1"
|
||||
setenv rootpart "/dev/sda2"
|
||||
echo "Booting from USB storage"
|
||||
setenv datapart "/dev/sda4"
|
||||
echo "Boot device: USB storage"
|
||||
elif test "${devtype}" = "mmc"; then
|
||||
setenv bootpart "mmc ${devnum}:1"
|
||||
setenv rootpart "/dev/mmcblk${devnum}p2"
|
||||
echo "Booting from MMC/SD"
|
||||
setenv datapart "/dev/mmcblk${devnum}p4"
|
||||
echo "Boot device: MMC/SD"
|
||||
else
|
||||
# Default to USB
|
||||
usb start
|
||||
setenv bootpart "usb 0:1"
|
||||
setenv rootpart "/dev/sda2"
|
||||
setenv datapart "/dev/sda4"
|
||||
fi
|
||||
|
||||
# Boot menu with timeout
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " BOOT MENU"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo " [1] Live RAM Boot (default)"
|
||||
echo " [2] Flash SecuBox to eMMC"
|
||||
echo ""
|
||||
echo "Auto-boot in 5 seconds..."
|
||||
echo "Press any key to select option..."
|
||||
echo ""
|
||||
|
||||
# Set default boot option
|
||||
setenv bootopt 1
|
||||
|
||||
# Wait for keypress with timeout (5 seconds)
|
||||
if askenv -t 5 bootopt "Select option [1-2]: "; then
|
||||
echo "Selected: ${bootopt}"
|
||||
else
|
||||
echo "Timeout - using default (Live Boot)"
|
||||
setenv bootopt 1
|
||||
fi
|
||||
|
||||
# Handle boot options
|
||||
if test "${bootopt}" = "2"; then
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " eMMC FLASH MODE"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "WARNING: This will erase ALL data on eMMC!"
|
||||
echo ""
|
||||
echo "After boot, run: secubox-flash-emmc"
|
||||
echo ""
|
||||
# Set flag for flash mode
|
||||
setenv bootargs_extra "secubox.flash_mode=1"
|
||||
else
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LIVE RAM BOOT"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
setenv bootargs_extra ""
|
||||
fi
|
||||
|
||||
# Load kernel
|
||||
echo "Loading ARM64 kernel..."
|
||||
load ${bootpart} ${kernel_addr_r} Image
|
||||
if load ${bootpart} ${kernel_addr_r} Image; then
|
||||
echo "Kernel loaded successfully"
|
||||
else
|
||||
echo "ERROR: Failed to load kernel!"
|
||||
echo "Check that Image exists on EFI partition"
|
||||
sleep 10
|
||||
reset
|
||||
fi
|
||||
|
||||
# Load device tree
|
||||
echo "Loading device tree..."
|
||||
if load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin-v7-emmc.dtb; then
|
||||
echo "Loaded ESPRESSObin v7 eMMC DTB"
|
||||
elif load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin-v7.dtb; then
|
||||
echo "Loaded ESPRESSObin v7 DTB"
|
||||
elif load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin.dtb; then
|
||||
echo "Loaded ESPRESSObin DTB"
|
||||
else
|
||||
load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin-v7.dtb
|
||||
echo "ERROR: No compatible DTB found!"
|
||||
sleep 10
|
||||
reset
|
||||
fi
|
||||
|
||||
# Load initramfs
|
||||
|
|
@ -233,15 +302,25 @@ echo "Loading initramfs..."
|
|||
if load ${bootpart} ${ramdisk_addr_r} initrd.img; then
|
||||
setenv initrd_size ${filesize}
|
||||
setenv use_initrd 1
|
||||
echo "Initramfs loaded (${filesize} bytes)"
|
||||
else
|
||||
setenv use_initrd 0
|
||||
echo "No initramfs - direct boot"
|
||||
fi
|
||||
|
||||
# Boot arguments
|
||||
# Data partition is partition 4
|
||||
setenv bootargs "root=${rootpart} rootfstype=ext4 rootwait rootdelay=5 console=ttyMV0,115200 net.ifnames=0 secubox.data=/dev/sda4"
|
||||
# boot=live: enable live-boot initramfs (RAM-based root)
|
||||
# live-media-path: where to find filesystem.squashfs
|
||||
# DSA switch blacklist - REQUIRED for ESPRESSObin live boot
|
||||
# modprobe.blacklist: for loadable modules
|
||||
# initcall_blacklist: for built-in drivers (live kernel has mv88e6xxx built-in)
|
||||
setenv bootargs "boot=live live-media-path=/live root=${rootpart} rootfstype=ext4 rootwait rootdelay=10 console=ttyMV0,115200 net.ifnames=0 modprobe.blacklist=mv88e6xxx,mv88e6085,dsa_core initcall_blacklist=mv88e6xxx_driver_init secubox.data=${datapart} ${bootargs_extra}"
|
||||
|
||||
echo ""
|
||||
echo "Booting SecuBox ARM64..."
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
if test "${use_initrd}" = "1"; then
|
||||
booti ${kernel_addr_r} ${ramdisk_addr_r}:${initrd_size} ${fdt_addr_r}
|
||||
else
|
||||
|
|
@ -260,9 +339,15 @@ BOOTCMD
|
|||
install_arm64_rootfs() {
|
||||
log "Installing ARM64 rootfs..."
|
||||
|
||||
local kernel_installed=false
|
||||
|
||||
if [[ -n "$ARM64_ROOTFS" && -d "$ARM64_ROOTFS" ]]; then
|
||||
log "Copying from $ARM64_ROOTFS"
|
||||
rsync -aHAX "$ARM64_ROOTFS/" "$MNT_ARM64/"
|
||||
# Check if kernel is available in the rootfs
|
||||
if [[ -f "$MNT_ARM64/boot/vmlinuz-"* ]]; then
|
||||
kernel_installed=true
|
||||
fi
|
||||
else
|
||||
# Check for existing built image
|
||||
local arm64_img="${OUTPUT_DIR}/secubox-espressobin-v7-bookworm.img"
|
||||
|
|
@ -270,29 +355,139 @@ install_arm64_rootfs() {
|
|||
log "Extracting rootfs from $arm64_img"
|
||||
local tmp_loop=$(losetup -f --show -P "$arm64_img")
|
||||
local tmp_mnt=$(mktemp -d)
|
||||
local tmp_boot=$(mktemp -d)
|
||||
|
||||
# Mount rootfs partition and copy
|
||||
mount "${tmp_loop}p2" "$tmp_mnt"
|
||||
rsync -aHAX "$tmp_mnt/" "$MNT_ARM64/"
|
||||
umount "$tmp_mnt"
|
||||
losetup -d "$tmp_loop"
|
||||
rmdir "$tmp_mnt"
|
||||
|
||||
# Also copy kernel/initrd/dtbs to EFI partition
|
||||
mount "${tmp_loop}p1" "$tmp_mnt" 2>/dev/null || true
|
||||
if [[ -f "$tmp_mnt/Image" ]]; then
|
||||
cp "$tmp_mnt/Image" "$MNT_EFI/"
|
||||
cp "$tmp_mnt/initrd.img" "$MNT_EFI/" 2>/dev/null || true
|
||||
cp -r "$tmp_mnt/dtbs" "$MNT_EFI/" 2>/dev/null || true
|
||||
# Check for kernel in rootfs
|
||||
if [[ -f "$MNT_ARM64/boot/vmlinuz-"* ]]; then
|
||||
kernel_installed=true
|
||||
fi
|
||||
umount "$tmp_mnt" 2>/dev/null || true
|
||||
|
||||
umount "$tmp_mnt"
|
||||
|
||||
# Mount boot partition and copy kernel files to EFI
|
||||
if mount "${tmp_loop}p1" "$tmp_boot" 2>/dev/null; then
|
||||
if [[ -f "$tmp_boot/Image" ]]; then
|
||||
log "Copying ARM64 kernel from image boot partition..."
|
||||
cp "$tmp_boot/Image" "$MNT_EFI/"
|
||||
cp "$tmp_boot/initrd.img" "$MNT_EFI/" 2>/dev/null || true
|
||||
cp -r "$tmp_boot/dtbs" "$MNT_EFI/" 2>/dev/null || true
|
||||
kernel_installed=true
|
||||
fi
|
||||
umount "$tmp_boot"
|
||||
fi
|
||||
|
||||
losetup -d "$tmp_loop"
|
||||
rmdir "$tmp_mnt" "$tmp_boot" 2>/dev/null || true
|
||||
else
|
||||
log "WARNING: No ARM64 rootfs source found, partition will be empty"
|
||||
log "No pre-built ARM64 image found, building minimal rootfs with debootstrap..."
|
||||
build_arm64_rootfs_debootstrap
|
||||
kernel_installed=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy kernel files from rootfs to EFI if not already done
|
||||
copy_arm64_kernel_to_efi
|
||||
|
||||
# Setup shared data mounts in fstab
|
||||
setup_shared_mounts "$MNT_ARM64"
|
||||
}
|
||||
|
||||
build_arm64_rootfs_debootstrap() {
|
||||
log "Building ARM64 rootfs with debootstrap..."
|
||||
|
||||
# Bootstrap minimal Debian
|
||||
qemu-debootstrap --arch=arm64 \
|
||||
--include=systemd,systemd-sysv,dbus,udev,iproute2,iputils-ping,openssh-server,sudo,vim-tiny,linux-image-arm64 \
|
||||
bookworm "$MNT_ARM64" http://deb.debian.org/debian
|
||||
|
||||
# Configure the rootfs
|
||||
cat > "$MNT_ARM64/etc/hostname" <<< "secubox"
|
||||
|
||||
cat > "$MNT_ARM64/etc/hosts" <<'HOSTS'
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 secubox
|
||||
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
HOSTS
|
||||
|
||||
# Set root password to 'secubox' (will be changed on first boot)
|
||||
chroot "$MNT_ARM64" /bin/bash -c "echo 'root:secubox' | chpasswd"
|
||||
|
||||
# Enable serial console
|
||||
chroot "$MNT_ARM64" systemctl enable serial-getty@ttyMV0.service 2>/dev/null || true
|
||||
|
||||
# Enable SSH
|
||||
chroot "$MNT_ARM64" systemctl enable ssh.service 2>/dev/null || true
|
||||
|
||||
# Configure network
|
||||
cat > "$MNT_ARM64/etc/network/interfaces" <<'NETWORK'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
NETWORK
|
||||
|
||||
log "ARM64 rootfs built with kernel"
|
||||
}
|
||||
|
||||
copy_arm64_kernel_to_efi() {
|
||||
log "Copying ARM64 kernel files to EFI partition..."
|
||||
|
||||
# Find and copy kernel
|
||||
local vmlinuz=$(find "$MNT_ARM64/boot" -name 'vmlinuz-*' -type f 2>/dev/null | head -1)
|
||||
local initrd=$(find "$MNT_ARM64/boot" -name 'initrd.img-*' -type f 2>/dev/null | head -1)
|
||||
|
||||
if [[ -n "$vmlinuz" && -f "$vmlinuz" ]]; then
|
||||
log "Found kernel: $vmlinuz"
|
||||
# ARM64 kernels need to be named 'Image' for U-Boot
|
||||
cp "$vmlinuz" "$MNT_EFI/Image"
|
||||
else
|
||||
log "WARNING: No ARM64 kernel found in rootfs"
|
||||
fi
|
||||
|
||||
if [[ -n "$initrd" && -f "$initrd" ]]; then
|
||||
log "Found initrd: $initrd"
|
||||
cp "$initrd" "$MNT_EFI/initrd.img"
|
||||
fi
|
||||
|
||||
# Copy device tree blobs
|
||||
mkdir -p "$MNT_EFI/dtbs/marvell"
|
||||
|
||||
# Look for DTBs in various locations
|
||||
local dtb_sources=(
|
||||
"$MNT_ARM64/usr/lib/linux-image-"*"/marvell"
|
||||
"$MNT_ARM64/boot/dtbs/"*"/marvell"
|
||||
"$MNT_ARM64/boot/dtbs/marvell"
|
||||
)
|
||||
|
||||
for dtb_dir in "${dtb_sources[@]}"; do
|
||||
if [[ -d "$dtb_dir" ]]; then
|
||||
log "Copying DTBs from: $dtb_dir"
|
||||
cp "$dtb_dir"/armada-3720-espressobin*.dtb "$MNT_EFI/dtbs/marvell/" 2>/dev/null || true
|
||||
cp "$dtb_dir"/armada-8040-mcbin*.dtb "$MNT_EFI/dtbs/marvell/" 2>/dev/null || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify files were copied
|
||||
if [[ -f "$MNT_EFI/Image" ]]; then
|
||||
log "EFI partition kernel: $(ls -lh "$MNT_EFI/Image")"
|
||||
else
|
||||
log "ERROR: Failed to copy ARM64 kernel to EFI partition!"
|
||||
fi
|
||||
|
||||
if [[ -d "$MNT_EFI/dtbs/marvell" ]]; then
|
||||
log "EFI partition DTBs: $(ls "$MNT_EFI/dtbs/marvell/" 2>/dev/null | wc -l) files"
|
||||
fi
|
||||
}
|
||||
|
||||
install_amd64_rootfs() {
|
||||
log "Installing AMD64 rootfs..."
|
||||
|
||||
|
|
|
|||
304
scripts/patch-multiboot-efi.sh
Executable file
304
scripts/patch-multiboot-efi.sh
Executable file
|
|
@ -0,0 +1,304 @@
|
|||
#!/usr/bin/env bash
|
||||
# SecuBox-Deb :: patch-multiboot-efi.sh
|
||||
# Fix multiboot EFI partition with ARM64 kernel files
|
||||
# CyberMind — Gérald Kerma
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[PATCH]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") <device>
|
||||
|
||||
Patch multiboot EFI partition with ARM64 kernel files.
|
||||
This fixes images built before v2.2.4 that were missing kernel/DTB files.
|
||||
|
||||
Arguments:
|
||||
<device> Block device (e.g., /dev/sdc) or image file
|
||||
|
||||
Examples:
|
||||
sudo $(basename "$0") /dev/sdc # Patch SD card
|
||||
sudo $(basename "$0") multiboot.img # Patch image file
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
[[ $# -lt 1 ]] && usage
|
||||
[[ "$1" == "-h" || "$1" == "--help" ]] && usage
|
||||
[[ $EUID -ne 0 ]] && err "Must run as root"
|
||||
|
||||
TARGET="$1"
|
||||
LOOP_DEV=""
|
||||
MNT_EFI=""
|
||||
MNT_ROOT=""
|
||||
CLEANUP_LOOP=false
|
||||
|
||||
cleanup() {
|
||||
log "Cleaning up..."
|
||||
[[ -n "$MNT_EFI" && -d "$MNT_EFI" ]] && { umount "$MNT_EFI" 2>/dev/null || true; rmdir "$MNT_EFI" 2>/dev/null || true; }
|
||||
[[ -n "$MNT_ROOT" && -d "$MNT_ROOT" ]] && { umount "$MNT_ROOT" 2>/dev/null || true; rmdir "$MNT_ROOT" 2>/dev/null || true; }
|
||||
[[ "$CLEANUP_LOOP" == "true" && -n "$LOOP_DEV" ]] && losetup -d "$LOOP_DEV" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Determine if target is device or file
|
||||
if [[ -b "$TARGET" ]]; then
|
||||
log "Target is block device: $TARGET"
|
||||
DEVICE="$TARGET"
|
||||
# Check if it's the main device or a partition
|
||||
if [[ "$DEVICE" =~ [0-9]$ ]]; then
|
||||
err "Please specify the base device (e.g., /dev/sdc not /dev/sdc1)"
|
||||
fi
|
||||
EFI_PART="${DEVICE}1"
|
||||
ROOT_PART="${DEVICE}2"
|
||||
elif [[ -f "$TARGET" ]]; then
|
||||
log "Target is image file: $TARGET"
|
||||
LOOP_DEV=$(losetup -f --show -P "$TARGET")
|
||||
CLEANUP_LOOP=true
|
||||
log "Loop device: $LOOP_DEV"
|
||||
sleep 1
|
||||
EFI_PART="${LOOP_DEV}p1"
|
||||
ROOT_PART="${LOOP_DEV}p2"
|
||||
else
|
||||
err "Target not found: $TARGET"
|
||||
fi
|
||||
|
||||
# Verify partitions exist
|
||||
[[ -b "$EFI_PART" ]] || err "EFI partition not found: $EFI_PART"
|
||||
[[ -b "$ROOT_PART" ]] || err "Root partition not found: $ROOT_PART"
|
||||
|
||||
log "EFI partition: $EFI_PART"
|
||||
log "Root partition: $ROOT_PART"
|
||||
|
||||
# Mount partitions
|
||||
MNT_EFI=$(mktemp -d)
|
||||
MNT_ROOT=$(mktemp -d)
|
||||
|
||||
log "Mounting EFI partition..."
|
||||
mount "$EFI_PART" "$MNT_EFI"
|
||||
|
||||
log "Mounting root partition..."
|
||||
mount "$ROOT_PART" "$MNT_ROOT"
|
||||
|
||||
# Check current state
|
||||
log "Current EFI partition contents:"
|
||||
ls -la "$MNT_EFI/" || true
|
||||
|
||||
# Find kernel in rootfs
|
||||
VMLINUZ=$(find "$MNT_ROOT/boot" -name 'vmlinuz-*' -type f 2>/dev/null | head -1)
|
||||
INITRD=$(find "$MNT_ROOT/boot" -name 'initrd.img-*' -type f 2>/dev/null | head -1)
|
||||
|
||||
if [[ -z "$VMLINUZ" || ! -f "$VMLINUZ" ]]; then
|
||||
warn "No kernel found in rootfs /boot"
|
||||
warn "Need to install kernel first..."
|
||||
|
||||
# Check if we can install kernel via chroot
|
||||
if command -v qemu-aarch64-static &>/dev/null; then
|
||||
log "Installing ARM64 kernel via chroot..."
|
||||
cp /usr/bin/qemu-aarch64-static "$MNT_ROOT/usr/bin/" 2>/dev/null || true
|
||||
chroot "$MNT_ROOT" apt-get update -qq
|
||||
chroot "$MNT_ROOT" apt-get install -y linux-image-arm64
|
||||
rm -f "$MNT_ROOT/usr/bin/qemu-aarch64-static"
|
||||
|
||||
# Re-find kernel
|
||||
VMLINUZ=$(find "$MNT_ROOT/boot" -name 'vmlinuz-*' -type f 2>/dev/null | head -1)
|
||||
INITRD=$(find "$MNT_ROOT/boot" -name 'initrd.img-*' -type f 2>/dev/null | head -1)
|
||||
else
|
||||
err "No kernel in rootfs and qemu-aarch64-static not available for chroot install"
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Found kernel: $VMLINUZ"
|
||||
[[ -n "$INITRD" ]] && log "Found initrd: $INITRD"
|
||||
|
||||
# Copy kernel as Image (U-Boot expects this name)
|
||||
log "Copying kernel to EFI partition..."
|
||||
cp "$VMLINUZ" "$MNT_EFI/Image"
|
||||
log " Image: $(ls -lh "$MNT_EFI/Image")"
|
||||
|
||||
if [[ -n "$INITRD" && -f "$INITRD" ]]; then
|
||||
cp "$INITRD" "$MNT_EFI/initrd.img"
|
||||
log " initrd.img: $(ls -lh "$MNT_EFI/initrd.img")"
|
||||
fi
|
||||
|
||||
# Copy DTBs
|
||||
log "Copying device tree blobs..."
|
||||
mkdir -p "$MNT_EFI/dtbs/marvell"
|
||||
|
||||
DTB_FOUND=false
|
||||
for dtb_dir in "$MNT_ROOT/usr/lib/linux-image-"*"/marvell" \
|
||||
"$MNT_ROOT/boot/dtbs/"*"/marvell" \
|
||||
"$MNT_ROOT/boot/dtbs/marvell"; do
|
||||
if [[ -d "$dtb_dir" ]]; then
|
||||
log " Source: $dtb_dir"
|
||||
cp "$dtb_dir"/armada-3720-espressobin*.dtb "$MNT_EFI/dtbs/marvell/" 2>/dev/null || true
|
||||
cp "$dtb_dir"/armada-8040-mcbin*.dtb "$MNT_EFI/dtbs/marvell/" 2>/dev/null || true
|
||||
DTB_FOUND=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$DTB_FOUND" == "true" ]]; then
|
||||
log " DTBs copied: $(ls "$MNT_EFI/dtbs/marvell/" 2>/dev/null | wc -l) files"
|
||||
else
|
||||
warn "No DTB files found! Boot may fail."
|
||||
fi
|
||||
|
||||
# Create/update boot.scr with dual boot menu
|
||||
log "Creating boot.scr with dual boot menu..."
|
||||
|
||||
cat > /tmp/boot.cmd <<'BOOTCMD'
|
||||
# SecuBox Multi-Boot U-Boot Script
|
||||
# For ESPRESSObin/MOCHAbin ARM64
|
||||
# Version: 2.2.4
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " SecuBox Multi-Boot — ARM64"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
# Detect boot device
|
||||
if test "${devtype}" = "usb"; then
|
||||
setenv bootpart "usb 0:1"
|
||||
setenv rootpart "/dev/sda2"
|
||||
setenv datapart "/dev/sda4"
|
||||
echo "Boot device: USB storage"
|
||||
elif test "${devtype}" = "mmc"; then
|
||||
setenv bootpart "mmc ${devnum}:1"
|
||||
setenv rootpart "/dev/mmcblk${devnum}p2"
|
||||
setenv datapart "/dev/mmcblk${devnum}p4"
|
||||
echo "Boot device: MMC/SD"
|
||||
else
|
||||
# Default to USB
|
||||
usb start
|
||||
setenv bootpart "usb 0:1"
|
||||
setenv rootpart "/dev/sda2"
|
||||
setenv datapart "/dev/sda4"
|
||||
fi
|
||||
|
||||
# Boot menu with timeout
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " BOOT MENU"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo " [1] Live RAM Boot (default)"
|
||||
echo " [2] Flash SecuBox to eMMC"
|
||||
echo ""
|
||||
echo "Auto-boot in 5 seconds..."
|
||||
echo "Press any key to select option..."
|
||||
echo ""
|
||||
|
||||
# Set default boot option
|
||||
setenv bootopt 1
|
||||
|
||||
# Wait for keypress with timeout (5 seconds)
|
||||
if askenv -t 5 bootopt "Select option [1-2]: "; then
|
||||
echo "Selected: ${bootopt}"
|
||||
else
|
||||
echo "Timeout - using default (Live Boot)"
|
||||
setenv bootopt 1
|
||||
fi
|
||||
|
||||
# Handle boot options
|
||||
if test "${bootopt}" = "2"; then
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " eMMC FLASH MODE"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "WARNING: This will erase ALL data on eMMC!"
|
||||
echo ""
|
||||
echo "After boot, run: secubox-flash-emmc"
|
||||
echo ""
|
||||
setenv bootargs_extra "secubox.flash_mode=1"
|
||||
else
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LIVE RAM BOOT"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
setenv bootargs_extra ""
|
||||
fi
|
||||
|
||||
# Load kernel
|
||||
echo "Loading ARM64 kernel..."
|
||||
if load ${bootpart} ${kernel_addr_r} Image; then
|
||||
echo "Kernel loaded successfully"
|
||||
else
|
||||
echo "ERROR: Failed to load kernel!"
|
||||
echo "Check that Image exists on EFI partition"
|
||||
sleep 10
|
||||
reset
|
||||
fi
|
||||
|
||||
# Load device tree
|
||||
echo "Loading device tree..."
|
||||
if load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin-v7-emmc.dtb; then
|
||||
echo "Loaded ESPRESSObin v7 eMMC DTB"
|
||||
elif load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin-v7.dtb; then
|
||||
echo "Loaded ESPRESSObin v7 DTB"
|
||||
elif load ${bootpart} ${fdt_addr_r} dtbs/marvell/armada-3720-espressobin.dtb; then
|
||||
echo "Loaded ESPRESSObin DTB"
|
||||
else
|
||||
echo "ERROR: No compatible DTB found!"
|
||||
sleep 10
|
||||
reset
|
||||
fi
|
||||
|
||||
# Load initramfs
|
||||
echo "Loading initramfs..."
|
||||
if load ${bootpart} ${ramdisk_addr_r} initrd.img; then
|
||||
setenv initrd_size ${filesize}
|
||||
setenv use_initrd 1
|
||||
echo "Initramfs loaded (${filesize} bytes)"
|
||||
else
|
||||
setenv use_initrd 0
|
||||
echo "No initramfs - direct boot"
|
||||
fi
|
||||
|
||||
# Boot arguments
|
||||
setenv bootargs "root=${rootpart} rootfstype=ext4 rootwait rootdelay=5 console=ttyMV0,115200 net.ifnames=0 secubox.data=${datapart} ${bootargs_extra}"
|
||||
|
||||
echo ""
|
||||
echo "Booting SecuBox ARM64..."
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
if test "${use_initrd}" = "1"; then
|
||||
booti ${kernel_addr_r} ${ramdisk_addr_r}:${initrd_size} ${fdt_addr_r}
|
||||
else
|
||||
booti ${kernel_addr_r} - ${fdt_addr_r}
|
||||
fi
|
||||
BOOTCMD
|
||||
|
||||
if command -v mkimage &>/dev/null; then
|
||||
mkimage -A arm64 -T script -C none -d /tmp/boot.cmd "$MNT_EFI/boot.scr"
|
||||
log " boot.scr compiled"
|
||||
else
|
||||
cp /tmp/boot.cmd "$MNT_EFI/boot.cmd"
|
||||
warn "mkimage not found, copied as boot.cmd (may need manual conversion)"
|
||||
fi
|
||||
|
||||
# Verify final state
|
||||
echo ""
|
||||
log "=== Patch Complete ==="
|
||||
log "EFI partition contents:"
|
||||
ls -lh "$MNT_EFI/"
|
||||
echo ""
|
||||
log "DTBs:"
|
||||
ls -lh "$MNT_EFI/dtbs/marvell/" 2>/dev/null || echo " (none)"
|
||||
echo ""
|
||||
log "Ready to test!"
|
||||
164
scripts/sync-wiki.sh
Executable file
164
scripts/sync-wiki.sh
Executable file
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env bash
|
||||
# SecuBox-Deb :: sync-wiki.sh
|
||||
# CyberMind — Gérald Kerma
|
||||
# Sync wiki/ folder to GitHub wiki repository
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
WIKI_SOURCE="${REPO_ROOT}/wiki"
|
||||
WIKI_REPO_URL="git@github.com:CyberMind-FR/secubox-deb.wiki.git"
|
||||
WIKI_CLONE_DIR="/tmp/secubox-wiki-$$"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[WIKI]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [OPTIONS]
|
||||
|
||||
Sync wiki/ folder to GitHub wiki repository.
|
||||
|
||||
Options:
|
||||
-m, --message MSG Commit message (default: "Update wiki from main repo")
|
||||
-n, --dry-run Show what would be done without making changes
|
||||
-p, --push Push changes to GitHub wiki repo
|
||||
-h, --help Show this help
|
||||
|
||||
Workflow:
|
||||
1. Clones the wiki repo to temp directory
|
||||
2. Copies all files from wiki/ to wiki repo
|
||||
3. Commits changes (with -p flag, pushes to GitHub)
|
||||
|
||||
Examples:
|
||||
$(basename "$0") -n # Dry run - show changes
|
||||
$(basename "$0") -p # Sync and push
|
||||
$(basename "$0") -p -m "Add Eye-Remote docs"
|
||||
|
||||
Note:
|
||||
GitHub wiki is a separate git repository from the main project.
|
||||
Files in wiki/ folder must be synced to the wiki repo separately.
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
COMMIT_MSG="Update wiki from main repo"
|
||||
DRY_RUN=false
|
||||
DO_PUSH=false
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-m|--message) COMMIT_MSG="$2"; shift 2 ;;
|
||||
-n|--dry-run) DRY_RUN=true; shift ;;
|
||||
-p|--push) DO_PUSH=true; shift ;;
|
||||
-h|--help) usage ;;
|
||||
*) err "Unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
check_source() {
|
||||
[[ -d "$WIKI_SOURCE" ]] || err "Wiki source not found: $WIKI_SOURCE"
|
||||
local count
|
||||
count=$(find "$WIKI_SOURCE" -name "*.md" | wc -l)
|
||||
log "Found $count markdown files in wiki/"
|
||||
}
|
||||
|
||||
clone_wiki_repo() {
|
||||
log "Cloning wiki repository..."
|
||||
|
||||
if $DRY_RUN; then
|
||||
log "[DRY RUN] Would clone: $WIKI_REPO_URL"
|
||||
return
|
||||
fi
|
||||
|
||||
# Cleanup on exit
|
||||
trap "rm -rf '$WIKI_CLONE_DIR'" EXIT
|
||||
|
||||
git clone --depth 1 "$WIKI_REPO_URL" "$WIKI_CLONE_DIR" 2>/dev/null || {
|
||||
warn "Wiki repo doesn't exist yet. Create it on GitHub first:"
|
||||
warn " 1. Go to https://github.com/CyberMind-FR/secubox-deb"
|
||||
warn " 2. Click Wiki tab"
|
||||
warn " 3. Create first page (Home)"
|
||||
err "Cannot clone wiki repository"
|
||||
}
|
||||
|
||||
log "Wiki repo cloned to: $WIKI_CLONE_DIR"
|
||||
}
|
||||
|
||||
sync_files() {
|
||||
log "Syncing wiki files..."
|
||||
|
||||
if $DRY_RUN; then
|
||||
log "[DRY RUN] Would copy files:"
|
||||
find "$WIKI_SOURCE" -name "*.md" -exec basename {} \;
|
||||
return
|
||||
fi
|
||||
|
||||
# Remove old files (except .git)
|
||||
find "$WIKI_CLONE_DIR" -maxdepth 1 -name "*.md" -delete
|
||||
|
||||
# Copy new files
|
||||
cp "$WIKI_SOURCE"/*.md "$WIKI_CLONE_DIR/"
|
||||
|
||||
# Show diff
|
||||
cd "$WIKI_CLONE_DIR"
|
||||
if git diff --stat HEAD; then
|
||||
log "Files synced successfully"
|
||||
fi
|
||||
}
|
||||
|
||||
commit_and_push() {
|
||||
if $DRY_RUN; then
|
||||
log "[DRY RUN] Would commit with message: $COMMIT_MSG"
|
||||
$DO_PUSH && log "[DRY RUN] Would push to origin"
|
||||
return
|
||||
fi
|
||||
|
||||
cd "$WIKI_CLONE_DIR"
|
||||
|
||||
# Check for changes
|
||||
if git diff --quiet HEAD; then
|
||||
log "No changes to commit"
|
||||
return
|
||||
fi
|
||||
|
||||
# Stage and commit
|
||||
git add -A
|
||||
git commit -m "$COMMIT_MSG"
|
||||
log "Changes committed: $COMMIT_MSG"
|
||||
|
||||
# Push if requested
|
||||
if $DO_PUSH; then
|
||||
log "Pushing to GitHub wiki..."
|
||||
git push origin master
|
||||
log "Wiki updated successfully!"
|
||||
log "View at: https://github.com/CyberMind-FR/secubox-deb/wiki"
|
||||
else
|
||||
warn "Changes committed locally. Use -p to push."
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
log "SecuBox Wiki Sync"
|
||||
log "================="
|
||||
|
||||
check_source
|
||||
clone_wiki_repo
|
||||
sync_files
|
||||
commit_and_push
|
||||
|
||||
log "Done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
236
wiki/Eye-Remote.md
Normal file
236
wiki/Eye-Remote.md
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
# Eye Remote — Pi Zero USB Gadget
|
||||
|
||||
> **SecuBox Eye Remote** transforms a Raspberry Pi Zero W into a portable USB boot media controller for ARM64 SecuBox devices (ESPRESSObin, MOCHAbin).
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Eye Remote presents a multiboot storage image to the host device via USB gadget mass_storage, enabling network-less deployment and recovery.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Eye Remote Architecture │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ USB OTG ┌─────────────────┐ │
|
||||
│ │ Pi Zero W │ ◄─────────────────────►│ ESPRESSObin │ │
|
||||
│ │ │ mass_storage + │ or MOCHAbin │ │
|
||||
│ │ Eye Remote │ ECM network │ │ │
|
||||
│ └──────────────┘ └─────────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ µSD Card │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌─────────────────┐ │
|
||||
│ │ storage.img │ ────presented as───► │ /dev/sda │ │
|
||||
│ │ 16GB image │ USB mass storage │ Bootable disk │ │
|
||||
│ └──────────────┘ └─────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **USB Mass Storage** | Pi Zero presents `storage.img` as USB disk to host |
|
||||
| **USB ECM Network** | Ethernet over USB for remote management |
|
||||
| **Serial Console** | USB ACM serial for debug access |
|
||||
| **Dual Boot Menu** | Interactive menu: Live RAM Boot or Flash to eMMC |
|
||||
| **Web Dashboard** | xterm.js serial console + status UI |
|
||||
|
||||
---
|
||||
|
||||
## Hardware Requirements
|
||||
|
||||
| Component | Specification |
|
||||
|-----------|---------------|
|
||||
| Pi Zero W | Any revision (W for WiFi management) |
|
||||
| µSD Card | 32GB+ Class 10 / A1 recommended |
|
||||
| USB Cable | USB-A to Micro-USB OTG |
|
||||
| Target | ESPRESSObin, MOCHAbin, or compatible ARM64 |
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Flash the Eye Remote Image
|
||||
|
||||
```bash
|
||||
# Download the Eye Remote image
|
||||
wget https://github.com/CyberMind-FR/secubox-deb/releases/download/eye-remote-v2.2.4/secubox-eye-remote.img.xz
|
||||
|
||||
# Flash to µSD card
|
||||
xzcat secubox-eye-remote.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync
|
||||
sync
|
||||
```
|
||||
|
||||
### 2. Connect Pi Zero to Target
|
||||
|
||||
1. Insert µSD card into Pi Zero
|
||||
2. Connect Pi Zero USB port to target's USB port
|
||||
3. Power on target device
|
||||
|
||||
### 3. Boot Menu
|
||||
|
||||
The target device will see a USB mass storage device and boot from it. The U-Boot boot.scr presents:
|
||||
|
||||
```
|
||||
============================================
|
||||
BOOT MENU
|
||||
============================================
|
||||
|
||||
[1] Live RAM Boot (default)
|
||||
[2] Flash SecuBox to eMMC
|
||||
|
||||
Auto-boot in 5 seconds...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partition Layout
|
||||
|
||||
| Partition | Label | Size | Purpose |
|
||||
|-----------|-------|------|---------|
|
||||
| 1 | SECUBOX-EFI | 512MB | Boot files (kernel, DTB, GRUB, U-Boot) |
|
||||
| 2 | secubox-arm64 | ~4GB | ARM64 rootfs (RAM-loaded) |
|
||||
| 3 | secubox-amd64 | ~4GB | AMD64 rootfs (for x86 targets) |
|
||||
| 4 | secubox-data | ~7GB | Shared persistent data |
|
||||
|
||||
---
|
||||
|
||||
## USB Gadget Configuration
|
||||
|
||||
The Pi Zero configures multiple USB gadget functions:
|
||||
|
||||
```bash
|
||||
# /boot/config.txt
|
||||
dtoverlay=dwc2
|
||||
|
||||
# cmdline.txt (after rootwait)
|
||||
modules-load=dwc2,g_multi
|
||||
```
|
||||
|
||||
### Gadget Functions
|
||||
|
||||
| Function | Device | Purpose |
|
||||
|----------|--------|---------|
|
||||
| `mass_storage` | Host sees USB disk | Boot media |
|
||||
| `ecm` | usb0 network | Remote access |
|
||||
| `acm` | ttyGS0 serial | Debug console |
|
||||
|
||||
---
|
||||
|
||||
## Building the Image
|
||||
|
||||
### From Repository
|
||||
|
||||
```bash
|
||||
cd secubox-deb
|
||||
|
||||
# Build the Eye Remote image
|
||||
sudo bash image/eye-remote/build-eye-remote.sh \
|
||||
--output output/secubox-eye-remote.img \
|
||||
--storage-size 16G
|
||||
|
||||
# Or with multiboot integration
|
||||
sudo bash image/multiboot/build-multiboot.sh \
|
||||
--output output/secubox-multiboot.img \
|
||||
--size 16G
|
||||
```
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
The image is automatically built via CI:
|
||||
- Workflow: `.github/workflows/build-eye-remote.yml`
|
||||
- Trigger: Push to `eye-remote-v*` tags
|
||||
|
||||
---
|
||||
|
||||
## Remote Management
|
||||
|
||||
### WiFi Configuration
|
||||
|
||||
Edit `/boot/wpa_supplicant.conf` on the µSD card before first boot:
|
||||
|
||||
```
|
||||
country=FR
|
||||
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
|
||||
update_config=1
|
||||
|
||||
network={
|
||||
ssid="YourWiFi"
|
||||
psk="YourPassword"
|
||||
}
|
||||
```
|
||||
|
||||
### SSH Access
|
||||
|
||||
```bash
|
||||
# Via WiFi (if configured)
|
||||
ssh secubox@<pi-zero-ip>
|
||||
|
||||
# Via USB ECM network
|
||||
ssh secubox@10.55.0.1
|
||||
```
|
||||
|
||||
### Web Dashboard
|
||||
|
||||
Access at `http://10.55.0.1:8080`:
|
||||
- Serial console via xterm.js
|
||||
- Boot media status
|
||||
- Storage swap controls
|
||||
|
||||
---
|
||||
|
||||
## API Reference
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/eye-remote/status` | System status |
|
||||
| GET | `/api/v1/eye-remote/boot-media/state` | Boot media state |
|
||||
| POST | `/api/v1/eye-remote/boot-media/upload` | Upload to shadow |
|
||||
| POST | `/api/v1/eye-remote/boot-media/swap` | Swap active/shadow |
|
||||
| POST | `/api/v1/eye-remote/boot-media/rollback` | Rollback swap |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Pi Zero Not Booting
|
||||
|
||||
1. Check µSD card is properly seated
|
||||
2. Verify `config.txt` contains `dtoverlay=dwc2`
|
||||
3. Check power LED (solid red = powered)
|
||||
4. Check activity LED (flashing green = reading SD)
|
||||
|
||||
### Target Not Seeing USB Storage
|
||||
|
||||
1. Ensure USB cable supports data (not charge-only)
|
||||
2. Check Pi Zero is fully booted (activity LED stops flashing)
|
||||
3. On target, run `lsusb` to check USB detection
|
||||
4. Check `dmesg` for mass_storage errors
|
||||
|
||||
### Boot Menu Not Appearing
|
||||
|
||||
1. Target U-Boot must support `usb start`
|
||||
2. Check boot order in U-Boot: `printenv boot_targets`
|
||||
3. Manually try: `usb start; fatload usb 0:1 $kernel_addr_r Image`
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Multiboot|Multi-Boot Live OS]] — Full multiboot documentation
|
||||
- [[ARM-Installation]] — ARM64 installation guide
|
||||
- [[ESPRESSObin]] — ESPRESSObin specific setup
|
||||
- [[Live-USB]] — Standard Live USB guide
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- **Issues**: https://github.com/CyberMind-FR/secubox-deb/issues
|
||||
- **Wiki**: https://github.com/CyberMind-FR/secubox-deb/wiki
|
||||
|
|
@ -153,6 +153,54 @@ secubox-netdiag
|
|||
free -h
|
||||
```
|
||||
|
||||
### DSA Switch Detection Loop (ESPRESSObin)
|
||||
|
||||
**Symptoms:** Boot log shows repeated messages:
|
||||
```
|
||||
mv88e6085 d0032004.mdio-mii:01: switch 0x3410 detected: Marvell 88E6341, revision 0
|
||||
hwmon hwmon0: temp1_input not attached to any thermal zone
|
||||
```
|
||||
|
||||
This is a known issue with the Marvell 88E6341 DSA (Distributed Switch Architecture) driver on some ESPRESSObin boards.
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Boot with DSA disabled** (select option 2 in boot menu):
|
||||
- At boot menu, select "Live Boot + No DSA Switch"
|
||||
- This adds `modprobe.blacklist=mv88e6xxx,dsa_core` to boot args
|
||||
|
||||
2. **Manually blacklist the driver**:
|
||||
```bash
|
||||
echo "blacklist mv88e6xxx" | sudo tee /etc/modprobe.d/no-dsa.conf
|
||||
echo "blacklist dsa_core" | sudo tee -a /etc/modprobe.d/no-dsa.conf
|
||||
sudo update-initramfs -u
|
||||
```
|
||||
|
||||
3. **Use a different DTB**:
|
||||
- Some DTB variants handle the switch differently
|
||||
- Try `armada-3720-espressobin.dtb` instead of v7 variant
|
||||
|
||||
4. **Kernel parameters** (add to cmdline):
|
||||
```
|
||||
mv88e6xxx.blacklist=1
|
||||
```
|
||||
|
||||
**Note:** Disabling DSA means you lose the hardware switch functionality. The LAN ports will not work as a switch but can still be configured as individual interfaces.
|
||||
|
||||
### Boot Stuck or Kernel Panic
|
||||
|
||||
**Symptoms:** Boot hangs or shows panic after loading kernel
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Connect serial console (115200 8N1) to see actual error
|
||||
2. Try different DTB variants from boot menu
|
||||
3. Increase rootdelay: add `rootdelay=15` to boot args
|
||||
4. Boot with minimal options:
|
||||
```
|
||||
root=/dev/sda2 rootwait console=ttyMV0,115200 single
|
||||
```
|
||||
|
||||
## Logs Location
|
||||
|
||||
| Service | Log Location |
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
**[SecuBox](Home)** | [FR](Home-FR) | [DE](Home-DE) | [中文](Home-ZH) | **v2.2.3**
|
||||
**[SecuBox](Home)** | [FR](Home-FR) | [DE](Home-DE) | [中文](Home-ZH) | **v2.2.4-pre1**
|
||||
|
||||
### 🔴 BOOT — Getting Started
|
||||
* [[Multiboot|Multi-Boot Live OS]] ⭐ **NEW**
|
||||
* [[Live-USB-VirtualBox|VirtualBox]] `run-vbox.sh`
|
||||
* [[Live-USB-QEMU|QEMU]] 🖥️ `run-qemu.sh`
|
||||
* [[Live-USB]] | [FR](Live-USB-FR) | [DE](Live-USB-DE) | [中文](Live-USB-ZH)
|
||||
* [[Installation]] | [FR](Installation-FR) | [DE](Installation-DE) | [中文](Installation-ZH)
|
||||
* [[ARM-Installation|ARM / U-Boot]] | [FR](ARM-Installation-FR) | [DE](ARM-Installation-DE) | [中文](ARM-Installation-ZH) ⚡
|
||||
* [[ESPRESSObin]] | [FR](ESPRESSObin-FR) | [DE](ESPRESSObin-DE) | [中文](ESPRESSObin-ZH)
|
||||
* [[Eye-Remote|Eye Remote (Pi Zero)]] 📡
|
||||
* [[QEMU-ARM64]] 🖥️
|
||||
* [Multiboot](Multiboot) ⭐ **NEW**
|
||||
* [VirtualBox](Live-USB-VirtualBox) `run-vbox.sh`
|
||||
* [QEMU](Live-USB-QEMU) 🖥️ `run-qemu.sh`
|
||||
* [Live-USB](Live-USB) | [FR](Live-USB-FR) | [DE](Live-USB-DE) | [中文](Live-USB-ZH)
|
||||
* [Installation](Installation) | [FR](Installation-FR) | [DE](Installation-DE) | [中文](Installation-ZH)
|
||||
* [ARM / U-Boot](ARM-Installation) | [FR](ARM-Installation-FR) | [DE](ARM-Installation-DE) | [中文](ARM-Installation-ZH) ⚡
|
||||
* [ESPRESSObin](ESPRESSObin) | [FR](ESPRESSObin-FR) | [DE](ESPRESSObin-DE) | [中文](ESPRESSObin-ZH)
|
||||
* [Eye Remote](Eye-Remote) 📡
|
||||
* [QEMU-ARM64](QEMU-ARM64) 🖥️
|
||||
|
||||
### 🟢 ROOT — Configuration
|
||||
* [[Configuration]] | [FR](Configuration-FR) | [DE](Configuration-DE) | [中文](Configuration-ZH)
|
||||
* [[Troubleshooting]] | [FR](Troubleshooting-FR) | [DE](Troubleshooting-DE) | [中文](Troubleshooting-ZH)
|
||||
* [Configuration](Configuration) | [FR](Configuration-FR) | [DE](Configuration-DE) | [中文](Configuration-ZH)
|
||||
* [Troubleshooting](Troubleshooting) | [FR](Troubleshooting-FR) | [DE](Troubleshooting-DE) | [中文](Troubleshooting-ZH)
|
||||
|
||||
### 🟣 MIND — Modules
|
||||
* [[MODULES-EN|Modules]] 🇬🇧
|
||||
* [[MODULES-FR|Modules FR]] 🇫🇷
|
||||
* [[MODULES-DE|Modules DE]] 🇩🇪
|
||||
* [[MODULES-ZH|Modules 中文]] 🇨🇳
|
||||
* [Modules](MODULES-EN) 🇬🇧
|
||||
* [Modules FR](MODULES-FR) 🇫🇷
|
||||
* [Modules DE](MODULES-DE) 🇩🇪
|
||||
* [Modules 中文](MODULES-ZH) 🇨🇳
|
||||
|
||||
### 🔵 MESH — Reference
|
||||
* [[API-Reference]] | [FR](API-Reference-FR) | [DE](API-Reference-DE) | [中文](API-Reference-ZH)
|
||||
* [[UI-COMPARISON|UI Comparison]]
|
||||
* [API-Reference](API-Reference) | [FR](API-Reference-FR) | [DE](API-Reference-DE) | [中文](API-Reference-ZH)
|
||||
* [UI Comparison](UI-COMPARISON)
|
||||
|
||||
### Links
|
||||
* [Releases](https://github.com/CyberMind-FR/secubox-deb/releases)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user