Initial commit: Alpine Zero-OS initramfs build system with cleaned Docker configuration
This commit is contained in:
299
docs/INIT.md
Normal file
299
docs/INIT.md
Normal file
@@ -0,0 +1,299 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user