299 lines
8.0 KiB
Markdown
299 lines
8.0 KiB
Markdown
# Alpine Zero-OS Init Script Design
|
|
|
|
Design documentation for the Alpine-based init script that maintains the exact same tmpfs approach as the current system.
|
|
|
|
## Current Init Flow Analysis
|
|
|
|
The existing init script (`config/init/init`) does:
|
|
1. Mount basic filesystems (proc, sysfs, devtmpfs)
|
|
2. Create 1536M tmpfs at `/mnt/root`
|
|
3. Copy entire filesystem to tmpfs
|
|
4. Mount filesystems in tmpfs
|
|
5. Hardware detection with udev
|
|
6. Load essential drivers
|
|
7. Debug file injection (if available)
|
|
8. `switch_root` to tmpfs and exec zinit
|
|
|
|
## Alpine Init Script - configs/init
|
|
|
|
```bash
|
|
#!/bin/sh
|
|
# Alpine-based Zero-OS Init Script
|
|
# Maintains identical flow to original busybox version
|
|
|
|
echo ""
|
|
echo "============================================"
|
|
echo "== ZERO-OS ALPINE INITRAMFS =="
|
|
echo "============================================"
|
|
|
|
echo "[+] creating ram filesystem"
|
|
mount -t proc proc /proc
|
|
mount -t sysfs sysfs /sys
|
|
mount -t tmpfs tmpfs /mnt/root -o size=1536M
|
|
mount -t devtmpfs devtmpfs /dev
|
|
|
|
echo "[+] building ram filesystem"
|
|
target="/mnt/root"
|
|
|
|
# Copy Alpine filesystem to tmpfs (same as original)
|
|
echo " copying /bin..."
|
|
cp -ar /bin $target
|
|
echo " copying /etc..."
|
|
cp -ar /etc $target
|
|
echo " copying /lib..."
|
|
cp -ar /lib* $target
|
|
echo " copying /usr..."
|
|
cp -ar /usr $target
|
|
echo " copying /root..."
|
|
cp -ar /root $target
|
|
echo " copying /sbin..."
|
|
cp -ar /sbin $target
|
|
echo " copying /tmp..."
|
|
cp -ar /tmp $target
|
|
echo " copying /var..."
|
|
cp -ar /var $target
|
|
echo " copying /run..."
|
|
cp -ar /run $target
|
|
|
|
# Create essential directories
|
|
mkdir -p $target/dev
|
|
mkdir -p $target/sys
|
|
mkdir -p $target/proc
|
|
mkdir -p $target/mnt
|
|
|
|
# Mount filesystems in tmpfs
|
|
mount -t proc proc $target/proc
|
|
mount -t sysfs sysfs $target/sys
|
|
mount -t devtmpfs devtmpfs $target/dev
|
|
|
|
# Mount devpts for terminals
|
|
mkdir -p $target/dev/pts
|
|
mount -t devpts devpts $target/dev/pts
|
|
|
|
echo "[+] setting environment"
|
|
export PATH
|
|
|
|
echo "[+] probing drivers"
|
|
# Use Alpine's udev instead of busybox udevadm
|
|
if [ -x /sbin/udevd ]; then
|
|
echo " starting udevd..."
|
|
udevd --daemon
|
|
|
|
echo " triggering device discovery..."
|
|
udevadm trigger --action=add --type=subsystems
|
|
udevadm trigger --action=add --type=devices
|
|
udevadm settle
|
|
|
|
echo " stopping udevd..."
|
|
kill $(pidof udevd) || true
|
|
else
|
|
echo " warning: udevd not found, skipping hardware detection"
|
|
fi
|
|
|
|
echo "[+] loading essential drivers"
|
|
# Load core drivers for storage and network
|
|
modprobe btrfs 2>/dev/null || true
|
|
modprobe fuse 2>/dev/null || true
|
|
modprobe overlay 2>/dev/null || true
|
|
|
|
# Load storage drivers
|
|
modprobe ahci 2>/dev/null || true
|
|
modprobe nvme 2>/dev/null || true
|
|
modprobe virtio_blk 2>/dev/null || true
|
|
modprobe virtio_scsi 2>/dev/null || true
|
|
|
|
# Load network drivers
|
|
modprobe virtio_net 2>/dev/null || true
|
|
modprobe e1000 2>/dev/null || true
|
|
modprobe e1000e 2>/dev/null || true
|
|
|
|
# Unmount init filesystems
|
|
umount /proc 2>/dev/null || true
|
|
umount /sys 2>/dev/null || true
|
|
|
|
echo "[+] checking for debug files"
|
|
if [ -e /init-debug ]; then
|
|
echo " executing debug script..."
|
|
sh /init-debug
|
|
fi
|
|
|
|
echo "[+] switching root"
|
|
echo " exec switch_root /mnt/root /sbin/zinit init"
|
|
exec switch_root /mnt/root /sbin/zinit init
|
|
```
|
|
|
|
## Debug Script - configs/init-debug
|
|
|
|
For debug mode compatibility:
|
|
|
|
```bash
|
|
#!/bin/sh
|
|
# Debug file injection script (Alpine version)
|
|
# Maintains compatibility with existing debug workflow
|
|
|
|
echo "[+] debug mode enabled"
|
|
|
|
# Check for debug device (same as original)
|
|
if [ -b /dev/sda1 ]; then
|
|
echo " debug device found: /dev/sda1"
|
|
|
|
# Create temporary mount point
|
|
mkdir -p /mnt/debug
|
|
|
|
# Try to mount as vfat (same as original)
|
|
if mount -t vfat -o ro /dev/sda1 /mnt/debug 2>/dev/null; then
|
|
echo " mounted debug device"
|
|
|
|
# Check for debug marker file
|
|
if [ -f /mnt/debug/.zero-os-debug ]; then
|
|
echo " debug marker found, copying files..."
|
|
|
|
# Copy all files from debug device to tmpfs root
|
|
target="/mnt/root"
|
|
if [ -d "$target" ]; then
|
|
cp -rv /mnt/debug/* "$target/" 2>/dev/null || true
|
|
echo " debug files copied to tmpfs"
|
|
else
|
|
echo " warning: tmpfs root not ready yet"
|
|
fi
|
|
else
|
|
echo " no debug marker (.zero-os-debug) found"
|
|
fi
|
|
|
|
# Unmount debug device
|
|
umount /mnt/debug 2>/dev/null || true
|
|
else
|
|
echo " failed to mount debug device"
|
|
fi
|
|
|
|
# Cleanup
|
|
rmdir /mnt/debug 2>/dev/null || true
|
|
else
|
|
echo " no debug device found"
|
|
fi
|
|
|
|
echo "[+] debug initialization complete"
|
|
```
|
|
|
|
## Key Differences from Original
|
|
|
|
### Advantages of Alpine Version:
|
|
1. **Better error handling**: Uses `|| true` to prevent failures
|
|
2. **More verbose output**: Better logging for debugging
|
|
3. **Alpine tools**: Uses Alpine's optimized udev/modprobe
|
|
4. **Modular approach**: Separates debug script for clarity
|
|
5. **Robust driver loading**: Loads more essential drivers upfront
|
|
|
|
### Maintained Compatibility:
|
|
1. **Identical filesystem structure**: Same tmpfs copy approach
|
|
2. **Same mount points**: Preserves all original mount points
|
|
3. **Same debug workflow**: Compatible with existing debug injection
|
|
4. **Same zinit execution**: Identical handoff to zinit
|
|
5. **Same memory usage**: 1536M tmpfs size preserved
|
|
|
|
## Hardware Detection Improvements
|
|
|
|
### Enhanced Driver Loading:
|
|
```bash
|
|
# Storage drivers (embedded in initramfs)
|
|
modprobe ahci # SATA controllers
|
|
modprobe nvme # NVMe SSDs
|
|
modprobe virtio_blk # Virtual block devices
|
|
modprobe virtio_scsi # Virtual SCSI
|
|
modprobe usb_storage # USB storage
|
|
|
|
# Network drivers (embedded in initramfs)
|
|
modprobe virtio_net # Virtual network
|
|
modprobe e1000 # Intel Gigabit
|
|
modprobe e1000e # Intel Gigabit Enhanced
|
|
modprobe r8169 # Realtek
|
|
modprobe tg3 # Broadcom
|
|
|
|
# Filesystem drivers
|
|
modprobe btrfs # Primary filesystem
|
|
modprobe overlay # Container filesystems
|
|
modprobe fuse # FUSE filesystems
|
|
```
|
|
|
|
### Advanced Hardware Detection:
|
|
```bash
|
|
# Optional: More sophisticated hardware detection
|
|
if [ -x /usr/bin/lspci ]; then
|
|
echo "[+] detecting hardware..."
|
|
|
|
# Load drivers based on detected hardware
|
|
for device in $(lspci -n | awk '{print $3}'); do
|
|
case "$device" in
|
|
"8086:*") # Intel devices
|
|
modprobe e1000e 2>/dev/null || true
|
|
;;
|
|
"10ec:*") # Realtek devices
|
|
modprobe r8169 2>/dev/null || true
|
|
;;
|
|
"14e4:*") # Broadcom devices
|
|
modprobe tg3 2>/dev/null || true
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
```
|
|
|
|
## Error Handling and Logging
|
|
|
|
### Robust Error Handling:
|
|
```bash
|
|
# Function for safe command execution
|
|
safe_exec() {
|
|
local cmd="$1"
|
|
local desc="$2"
|
|
|
|
echo " $desc..."
|
|
if $cmd; then
|
|
echo " success"
|
|
else
|
|
echo " warning: $desc failed (continuing)"
|
|
fi
|
|
}
|
|
|
|
# Usage examples:
|
|
safe_exec "modprobe btrfs" "loading btrfs driver"
|
|
safe_exec "udevadm settle" "waiting for device settlement"
|
|
```
|
|
|
|
### Enhanced Logging:
|
|
```bash
|
|
# Optional: Detailed logging for debug builds
|
|
if [ "$BUILDMODE" = "debug" ]; then
|
|
# Log to both console and file
|
|
exec 1> >(tee -a /mnt/root/var/log/init.log)
|
|
exec 2> >(tee -a /mnt/root/var/log/init.log >&2)
|
|
|
|
echo "[DEBUG] Init script started at $(date)"
|
|
echo "[DEBUG] Available memory: $(free -m)"
|
|
echo "[DEBUG] Detected hardware: $(lspci -nn)"
|
|
fi
|
|
```
|
|
|
|
## Integration with Zinit
|
|
|
|
### Zinit Configuration Preservation:
|
|
- All existing zinit YAML configs copied unchanged
|
|
- Service dependencies maintained
|
|
- Init scripts preserved in `/etc/zinit/init/`
|
|
- Same service execution flow
|
|
|
|
### Zinit Execution Environment:
|
|
```bash
|
|
# Ensure clean environment for zinit
|
|
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
|
|
export HOME="/root"
|
|
export TERM="linux"
|
|
|
|
# Clear any init-specific variables
|
|
unset target
|
|
|
|
# Execute zinit with same arguments
|
|
exec switch_root /mnt/root /sbin/zinit init
|
|
```
|
|
|
|
This design maintains 100% compatibility with the existing system while leveraging Alpine's more robust and modern tooling. |