Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions v0.2.2/PI4_PHASE2.5_EINK_QOL_HANDOFF.md

Large diffs are not rendered by default.

207 changes: 207 additions & 0 deletions v0.2.2/PI4_PHASE2_EINK_HDMI_HANDOFF.md

Large diffs are not rendered by default.

29 changes: 11 additions & 18 deletions v0.2.2/buildroot/board/slowcomputer/genimage.cfg
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
# SlowOS SD card image layout
#
# Partition 1: boot (FAT32) - kernel, device tree, firmware
# Partition 2: rootfs (ext4) - the OS
# Partition 3: data (ext4) - user documents, config, music
# Pi 4 baseline: FAT32 LBA boot partition, 1 MiB aligned

image boot.vfat {
vfat {
extraargs = "-F 32"
files = {
"bcm2710-rpi-zero-2-w.dtb",
"zImage",
"rpi-firmware/bootcode.bin",
"rpi-firmware/start.elf",
"rpi-firmware/fixup.dat",
"bcm2711-rpi-4-b.dtb",
"Image",
"rpi-firmware/start4.elf",
"rpi-firmware/fixup4.dat",
"rpi-firmware/cmdline.txt",
"rpi-firmware/config.txt"
"rpi-firmware/config.txt",
"rpi-firmware/overlays"
}
}
size = 64M
}

image rootfs.ext4 {
ext4 {
label = "rootfs"
}
size = 256M
}

image data.ext4 {
ext4 {
label = "data"
Expand All @@ -35,17 +26,19 @@ image data.ext4 {

image sdcard.img {
hdimage {
partition-table-type = "mbr"
}

partition boot {
partition-type = 0xC
bootable = "true"
image = "boot.vfat"
offset = 1M
}

partition rootfs {
partition-type = 0x83
image = "rootfs.ext4"
image = "rootfs.ext2"
}

partition data {
Expand Down
18 changes: 17 additions & 1 deletion v0.2.2/buildroot/board/slowcomputer/post-image.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
#!/bin/sh
# SlowOS post-image script
# SlowOS post-image script — Pi 4 baseline
# Creates the final SD card image with boot + rootfs + data partitions.

BOARD_DIR="$(dirname $0)"

# cmdline.txt for SD card images (standalone boot).
#
# IMPORTANT FOR FUTURE DEVELOPERS:
# - SD card / standalone boot (what you are building here):
# Must use local root on the SD card: root=/dev/mmcblk0p2
# - Network boot development (from gx2):
# The cmdline is supplied via TFTP instead
# (see config/pi4-phase2-serial-tftp-config.txt + the
# sync-pi4-tftp-videocore-from-buildroot.sh and
# deploy-pi4-phase2-deterministic.sh scripts).
# The old NFS root line is ONLY valid during network-boot testing.

cat > "${RPI_FW_DIR}/cmdline.txt" << BOOTCMD
console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootwait
BOOTCMD

# Generate SD card image
support/scripts/genimage.sh -c "${BOARD_DIR}/genimage.cfg"

Expand Down
144 changes: 144 additions & 0 deletions v0.2.2/buildroot/configs/slowos_pi4_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# SlowOS Pi 4 HDMI Configuration
# Target: Raspberry Pi 4 Model B (HDMI with Mesa swrast)
#
# Usage:
# make BR2_EXTERNAL=../buildroot slowos_pi4_defconfig
# make
#

# Architecture: ARM 64-bit
BR2_aarch64=y
BR2_cortex_a72=y

# Toolchain
BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
BR2_TOOLCHAIN_BUILDROOT_CXX=y
BR2_PACKAGE_HOST_RUSTC=y
BR2_PACKAGE_HOST_RUST_BIN=y

# System
BR2_TARGET_GENERIC_HOSTNAME="slowbook"
BR2_TARGET_GENERIC_ISSUE="Welcome to SlowOS"
BR2_TARGET_GENERIC_GETTY_PORT="tty1"
BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200=y
BR2_SYSTEM_DHCP="wlan0,eth0"

# Root filesystem
BR2_TARGET_GENERIC_ROOT_PASSWD="0917"
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_4=y
BR2_TARGET_ROOTFS_EXT2_SIZE="512M"

# Kernel
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2711-rpi-4-b"

# Bootloader
BR2_PACKAGE_RPI_FIRMWARE=y
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y

# Firmware for WiFi
BR2_PACKAGE_LINUX_FIRMWARE=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM43XX=y

# HDMI Display Stack (Xorg modesetting + KMS: Pi4 VC4/V3D Gallium + swrast fallback)
BR2_PACKAGE_MESA3D=y
BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_SWRAST=y
BR2_PACKAGE_MESA3D_DRI_DRIVER_V3D=y
BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VC4=y
BR2_PACKAGE_MESA3D_OPENGL_EGL=y
BR2_PACKAGE_MESA3D_OPENGL_ES=y
BR2_PACKAGE_MESA3D_OPENGL_GLX=y
BR2_PACKAGE_MESA3D_GBM=y
BR2_PACKAGE_MESA3D_NEEDS_X11=y
BR2_PACKAGE_MESA3D_DEMOS=y
BR2_PACKAGE_LIBDRM=y

# Xorg for HDMI
BR2_PACKAGE_XORG7=y
BR2_PACKAGE_XSERVER_XORG_SERVER=y
BR2_PACKAGE_XDRIVER_XF86_VIDEO_FBDEV=y
BR2_PACKAGE_XDRIVER_XF86_VIDEO_MODESETTING=y
BR2_PACKAGE_XDRIVER_XF86_INPUT_EVDEV=y
BR2_PACKAGE_XDRIVER_XF86_INPUT_MOUSE=y
BR2_PACKAGE_XAPP_XINIT=y
BR2_PACKAGE_XAPP_XINPUT=y
BR2_PACKAGE_XAPP_XEV=y
BR2_PACKAGE_LIBINPUT=y
BR2_PACKAGE_XAPP_XSET=y
BR2_PACKAGE_XAPP_XDPYINFO=y
BR2_PACKAGE_XAPP_XPROP=y
BR2_PACKAGE_XAPP_XWININFO=y
BR2_PACKAGE_XAPP_XRANDR=y
BR2_PACKAGE_XLIB_LIBXRANDR=y
BR2_PACKAGE_XLIB_LIBXCURSOR=y
BR2_PACKAGE_WMCTRL=y
BR2_PACKAGE_XDOTOOL=y
BR2_PACKAGE_EVTEST=y

# X11 support libraries
BR2_PACKAGE_LIBXKBCOMMON=y
BR2_PACKAGE_LIBXKBCOMMON_X11=y

# Audio (for slowMusic)
BR2_PACKAGE_ALSA_UTILS=y
BR2_PACKAGE_ALSA_LIB=y

# Networking
BR2_PACKAGE_WPA_SUPPLICANT=y
BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
BR2_PACKAGE_DHCPCD=y

# SSH Access (unset SMALL: Buildroot default is y; full Dropbear improves pubkey interoperability)
BR2_PACKAGE_DROPBEAR=y
BR2_PACKAGE_DROPBEAR_SERVER=y
BR2_PACKAGE_DROPBEAR_KEYGEN=y
# BR2_PACKAGE_DROPBEAR_SMALL is not set

# Core utilities
BR2_PACKAGE_BUSYBOX=y
BR2_PACKAGE_BASH=y

# Filesystem tools
BR2_PACKAGE_E2FSPROGS=y

# SlowOS package
BR2_PACKAGE_SLOWOS=y

# E-ink bridge dependencies (keep minimal for compatibility)
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_PILLOW=y
BR2_PACKAGE_PYTHON_SPIDEV=y
BR2_PACKAGE_PYTHON_GPIOZERO=y
BR2_PACKAGE_XAPP_XWD=y
BR2_PACKAGE_IMAGEMAGICK=y

# Root filesystem overlay for Pi 4
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_SLOWOS_PATH)/rootfs_overlay"

# Post-build scripts
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_SLOWOS_PATH)/board/slowcomputer/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_SLOWOS_PATH)/board/slowcomputer/post-image.sh"

# SD card image generation
BR2_PACKAGE_HOST_DOSFSTOOLS=y
BR2_PACKAGE_HOST_GENIMAGE=y
BR2_PACKAGE_HOST_MTOOLS=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y

# Kernel config fragments
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_SLOWOS_PATH)/board/slowcomputer/kernel-configs/fragments.config"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_SLOWOS_PATH)/board/slowcomputer/kernel-configs/linux.config"

# Locale support
BR2_ENABLE_LOCALE=y
BR2_LOCALES="en_US.UTF-8 C"
BR2_ENABLE_LOCALE_PURGE=n
BR2_GENERATE_LOCALE="en_US.UTF-8 C"

# Common GPIO/Raspberry Pi utilities
BR2_PACKAGE_PYTHON_RPI_GPIO=y
BR2_PACKAGE_PYTHON_COLORZERO=y
BR2_PACKAGE_PYTHON_SETUPTOOLS=y
18 changes: 18 additions & 0 deletions v0.2.2/buildroot/rootfs_overlay/etc/default/slowos-eink
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Optional e-ink overrides — sourced by /etc/init.d/S99zeink before the bridge starts.
# Use `export` on every active line so variables reach the start-stop-daemon child.
#
# export SLOWOS_EINK_BUSY_INVERT=1
# export SLOWOS_EINK_PHASE25=1
# export SLOWOS_EINK_POINTER_HZ=6
# export SLOWOS_EINK_RECONCILE_SEC=3
# export SLOWOS_EINK_ESCAL_SOFT_SEC=3
# export SLOWOS_EINK_ESCAL_HARD_SEC=6
# export SLOWOS_EINK_REGION_CAP=3
# export SLOWOS_EINK_POINTER_ARENA=96
# export SLOWOS_EINK_RESTART_GRACE_SEC=2
#
# Typing / caret / watchdog (defaults match eink-bridge; override before boot if needed)
export SLOWOS_EINK_WATCHDOG_FRAMES="${SLOWOS_EINK_WATCHDOG_FRAMES:-24}"
export SLOWOS_EINK_FOCUS_HINTS="${SLOWOS_EINK_FOCUS_HINTS:-1}"
export SLOWOS_EINK_FOCUS_POLL_HZ="${SLOWOS_EINK_FOCUS_POLL_HZ:-4}"
export SLOWOS_EINK_POINTER_TRAIL="${SLOWOS_EINK_POINTER_TRAIL:-1}"
5 changes: 5 additions & 0 deletions v0.2.2/buildroot/rootfs_overlay/etc/default/slowos-panel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Panel-first display geometry (Waveshare 13.3" e-Paper K). Xorg + slowdesktop match this;
# HDMI mirrors the same logical canvas (debug), not 16:9 as the source of truth.
# Override before boot if your panel differs.
SLOWOS_PANEL_WIDTH=960
SLOWOS_PANEL_HEIGHT=680
104 changes: 104 additions & 0 deletions v0.2.2/buildroot/rootfs_overlay/etc/init.d/S99zeink
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/sh
#
# S99zeink — E-ink bridge (runs after S99slowos: same S99* prefix, sorts after "slowos").
# Captures Xorg :0 root (panel-first 960×680 canvas); HDMI mirrors the same framebuffer for debug.
# Default on: Phase 2 Pi4 expects HDMI+e-ink together when SPI is present. Disable with SLOWOS_ENABLE_EINK=0.
# Phase 2.5: persistent SPI failures may exec-restart eink-bridge in-process; use `restart` here for a clean
# relaunch without reboot. See SLOWOS_EINK_* in /usr/bin/eink-bridge header and PI4_PHASE2.5_EINK_QOL_HANDOFF.md.
#

PIDFILE="/var/run/eink-bridge.pid"
LOGFILE="/var/log/eink-bridge.log"
INIT_LOG="/var/log/eink-init.log"
DISPLAY_VALUE=":0"
LAUNCHER="/usr/local/sbin/slowos-eink-launch.sh"
SLOWOS_ENABLE_EINK="${SLOWOS_ENABLE_EINK:-1}"
# Waits for SPI + X0 happen in slowos-eink-launch.sh (background) so rcS is not blocked.

zeink_log() {
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "?")"
echo "$ts $*" >>"$INIT_LOG"
}

is_eink_enabled() {
case "$SLOWOS_ENABLE_EINK" in 1|true|TRUE|yes|YES|on|ON) return 0;; esac
return 1
}

eink_already_running() {
[ -s "$PIDFILE" ] || return 1
old="$(tr -d ' \t\r\n' <"$PIDFILE")"
[ -n "$old" ] || return 1
kill -0 "$old" 2>/dev/null || return 1
return 0
}

start() {
rm -f /etc/profile.d/eink.sh
zeink_log "S99zeink start"

if ! is_eink_enabled; then
echo "SKIP (e-ink disabled)"
zeink_log "SKIP SLOWOS_ENABLE_EINK=$SLOWOS_ENABLE_EINK"
return 0
fi

if eink_already_running; then
echo "e-ink bridge already running ($(tr -d ' \t\r\n' <"$PIDFILE"))"
zeink_log "already_running pid=$(tr -d ' \t\r\n' <"$PIDFILE")"
return 0
fi

if [ ! -f "$LAUNCHER" ]; then
echo "SKIP ($LAUNCHER missing)"
zeink_log "SKIP launcher missing"
return 0
fi

# Optional overrides e.g. SLOWOS_EINK_BUSY_INVERT=1, SLOWOS_EINK_PHASE25=0 — see PI4_PHASE2*.md
if [ -r /etc/default/slowos-eink ]; then
# shellcheck disable=SC1091
. /etc/default/slowos-eink
fi

zeink_log "scheduling background launcher (SPI+X waits non-blocking for rcS)"
export SLOWOS_EINK_DISPLAY="$DISPLAY_VALUE"
/bin/sh "$LAUNCHER" &
echo "e-ink bring-up started in background (see $INIT_LOG and $LOGFILE)"
return 0
}

stop() {
printf "stopping e-ink bridge: "
# BusyBox start-stop-daemon: omit -x here; -x /usr/bin/python3 falsely reports "not found"
# because the running argv is eink-bridge, not the interpreter path.
start-stop-daemon -K -p "$PIDFILE" -s TERM 2>/dev/null || true
rm -f "$PIDFILE" /etc/profile.d/eink.sh
zeink_log "stop"
echo "OK"
}

restart() {
stop
# SPI/GPIO release after stop; extend manually (e.g. sleep 12) after hardware faults.
sleep 3
start
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac

exit $?
8 changes: 8 additions & 0 deletions v0.2.2/buildroot/rootfs_overlay/etc/network/interfaces
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
pre-up /etc/network/nfs_check
wait-delay 15
hostname $(hostname)
20 changes: 20 additions & 0 deletions v0.2.2/buildroot/rootfs_overlay/etc/network/nfs_check
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh

# This allows NFS booting to work while also being able to configure
# the network interface via DHCP when not NFS booting. Otherwise, a
# NFS booted system will likely hang during DHCP configuration.

# Attempting to configure the network interface used for NFS will
# initially bring that network down. Since the root filesystem is
# accessed over this network, the system hangs.

# This script is run by ifup and will attempt to detect if a NFS root
# mount uses the interface to be configured (IFACE), and if so does
# not configure it. This should allow the same build to be disk/flash
# booted or NFS booted.

nfsip=`sed -n '/^[^ ]*:.* \/ nfs.*[ ,]addr=\([0-9.]\+\).*/s//\1/p' /proc/mounts`
if [ -n "$nfsip" ] && ip route get to "$nfsip" | grep -q "dev $IFACE"; then
echo Skipping $IFACE, used for NFS from $nfsip
exit 1
fi
Loading