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
40 changes: 40 additions & 0 deletions overlays/firmware-debian/00-debian-rootfs/pre-scripts/01_rootfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

if [[ $# -ne 1 ]]; then
echo "Usage: $0 <rootfs-dir>"
exit 1
fi

ROOTFS_DIR="$(realpath "$1")"

VERSION=20260111-cb35d27
FILENAME="debian-rootfs-trixie-$VERSION.tgz"
URL="https://github.com/Snapmaker-U1-Extended-Firmware/base-debian-os/releases/download/$VERSION/$FILENAME"
SHA256="1a2d1dec1039ddf55575b0c7c8d818278fa786c1723aa0437ff6547431007063"

set -e

if [[ ! -d "${ROOTFS_DIR}.org" ]]; then
echo ">> Backuping rootfs..."
mv "$ROOTFS_DIR"{,.org}
else
echo ">> Cleaning rootfs..."
rm -rf "$ROOTFS_DIR"
fi

echo ">> Downloading and extracting debian rootfs tarball..."
cache_file.sh "$CACHE_DIR/$FILENAME" "$URL" "$SHA256" "$ROOTFS_DIR"

# EXTRA_DEPS="iw net-tools wireless-tools"

# if [[ $(cat "$ROOTFS_DIR/.deps" || true) != "$EXTRA_DEPS" ]]; then
# "$ROOT_DIR/scripts/helpers/chroot_firmware.sh" "$ROOTFS_DIR" bash -c "apt update -y && apt install -y $EXTRA_DEPS"
# echo "$EXTRA_DEPS" > "$ROOTFS_DIR/.deps"
# fi

echo ">> Debian Bootstrap installed to $ROOTFS_DIR"
2 changes: 2 additions & 0 deletions overlays/firmware-debian/00-debian-rootfs/root/etc/fstab
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PARTLABEL=oem /oem ext4 rw,relatime 0 2
PARTLABEL=userdata /userdata ext4 rw,relatime 0 2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
u1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
allow-hotplug en*
iface en* inet dhcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
allow-hotplug eth*
iface eth* inet dhcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
allow-hotplug eth0
iface eth0 inet dhcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Use WiFi credentials configured by Lava GUI app

allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /oem/printer_data/gui/wpa_supplicant.conf
post-up iw dev wlan0 set power_save off
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PermitRootLogin yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# List of files and directories to persist across sysupgrades
# Each line should contain a path relative to the root filesystem
# Lines starting with '#' are comments and will be ignored
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# persistent internal storage links(Android style): /dev/block/by-name
#
# based on udev's 60-persistent-storage.rules

ACTION=="remove", GOTO="persistent_storage_end"

SUBSYSTEM!="block", GOTO="persistent_storage_end"

# ignore removable devices
ATTRS{removable}=="1", GOTO="persistent_storage_end"

# ignore SD Cards
ATTRS{TYPE}=="SD", GOTO="persistent_storage_end"

# honor various types of names
ENV{ID_PART_ENTRY_NAME}=="?*", \
SYMLINK+="block/by-name/$env{ID_PART_ENTRY_NAME}", GOTO="persistent_storage_end"
ENV{PARTNAME}=="?*", SYMLINK+="block/by-name/$env{PARTNAME}", \
GOTO="persistent_storage_end"
ENV{ID_FS_LABEL}=="?*", SYMLINK+="block/by-name/$env{ID_FS_LABEL}", \
GOTO="persistent_storage_end"
KERNEL=="mtdblock*", TEST=="device/name", SYMLINK+="block/by-name/$attr{device/name}"

LABEL="persistent_storage_end"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SUBSYSTEM=="spidev", GROUP="dialout", MODE="0660"
81 changes: 81 additions & 0 deletions overlays/firmware-debian/00-debian-rootfs/root/usr/sbin/init
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/sh
# early-init-overlay.sh

echo "Starting early init overlay..."

# mount kernel filesystems
mount -t proc proc /proc
mount -t sysfs sysfs /sys

# loading kernel modules
/usr/sbin/insmod /opt/lava/modules/io_manager.ko # IO manager (powers USB, etc.)
/usr/sbin/insmod /opt/lava/modules/bcmdhd.ko # WiFi/BT driver
/usr/sbin/insmod /opt/lava/modules/chsc6540.ko # Touchpanel driver

# mounting persistent storage overlay
if OEM_DISK=$(blkid -o device -t PARTLABEL=oem | head -n 1); then
# check and mount oem partition (in case of improper shutdown)
if ! fsck -y "$OEM_DISK"; then
echo "Filesystem check failed on $OEM_DISK"
fi

if mount -t ext4 "$OEM_DISK" /oem; then
echo "Mounted /oem partition from $OEM_DISK"
mkdir -p /oem/overlay-debian
mount --bind /oem/overlay-debian /overlay
umount /oem
fi
fi

# fallback to tmpfs overlay
if ! mountpoint /overlay; then
echo "Failed to mount /oem partition!"
mount -t tmpfs tmpfs /overlay
fi

# remove extra files from previous overlay
overlay_persist_files() {
# user specified persistent files
[ -e /overlay/upper/etc/sysupgrade.conf ] && echo --exclude-from=/overlay/upper/etc/sysupgrade.conf

# always persist custom sysupgrade version file
echo "--exclude=/etc/sysupgrade.conf"

# system files
echo "--exclude=/etc/machine-id"
echo "--exclude=/etc/ssh/ssh_host_*"
echo "--exclude=/var/lib/systemd/random-seed"
echo "--exclude=/var/lib/systemd/timesync"
echo "--exclude=/var/lib/dhcpcd"
}

# if overlay version mismatches, clean up previous overlay
if [ -d /overlay/upper ] && ! diff -u /overlay/current_version /etc/CUSTOM_VERSION; then
echo "Cleaning up previous overlay..."
# misuse /rom as this is empty directory at this point
rsync -a --delete $(overlay_persist_files) /rom /overlay/upper
# write current version
cp -n /etc/CUSTOM_VERSION /overlay/first_version
cp /etc/CUSTOM_VERSION /overlay/current_version
sync
fi

# mount overlay rootfs
mkdir -p /overlay/upper /overlay/work
mount -t overlay overlay /overlay \
-o lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/work

# move kernel mounts into new root
mount --move /proc /overlay/proc
mount --move /sys /overlay/sys
mount --move /dev /overlay/dev

# pivot root: old root becomes /rom
pivot_root /overlay /overlay/rom

# move essential mounts to new root
mount --move /rom/overlay /overlay

# hand off to real init
echo "Starting real init..."
exec /lib/systemd/systemd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[Unit]
Description=Generate SSH keys if not there
Before=ssh.service
ConditionPathExists=|!/etc/ssh/ssh_host_key
ConditionPathExists=|!/etc/ssh/ssh_host_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key.pub

[Service]
ExecStart=/usr/bin/ssh-keygen -A
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=ssh.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

set -e

echo ">> Creating required directories..."
mkdir -p /{overlay,rom,oem,userdata}

echo ">> Enabling multi-user.target as default..."
systemctl set-default multi-user.target

echo ">> Disabling systemd-networkd-wait-online.service..."
systemctl mask systemd-networkd-wait-online.service

echo ">> Installing systemd-resolved..."
systemctl enable systemd-resolved
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

set -e

if [[ ! -u "/usr/bin/sudo" ]]; then
echo ">> Setting setuid bit on /usr/bin/sudo..."
chmod u+s /usr/bin/sudo
fi

echo ">> Add user lava..."
useradd -m -G sudo,video,input,dialout -s /bin/bash lava
echo lava:snapmaker | chpasswd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

set -e

echo ">> Set root password..."
echo root:snapmaker | chpasswd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

set -e

echo ">> Enabling nginx service..."
systemctl enable nginx

echo ">> Create /var/log/nginx directory"
mkdir -p /var/log/nginx
chown www-data:www-data /var/log/nginx
chmod 755 /var/log/nginx

echo ">> Remove sites-enabled/default"
rm -f "/etc/nginx/sites-enabled/default"

echo ">> Nginx installation complete"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

set -e

echo ">> Creating virtual environment in /opt..."
python3 -m venv /opt/venv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[Unit]
Description=Klipper 3D Printer Firmware
After=network.target init-printer-data.service mosquitto.service klippy-mcu.service

[Service]
Type=simple
User=lava
Group=lava
WorkingDirectory=/opt/klipper
Environment="PYTHONPATH=/opt/klipper"
ExecStartPre=-/opt/lava/bin/lava_io set MAIN_MCU_POWER=0 HEAD_MCU_POWER=0
ExecStartPre=-/bin/sleep 1
ExecStartPre=-/opt/lava/bin/lava_io set MAIN_MCU_POWER=1 HEAD_MCU_POWER=1
ExecStart=/opt/venv/bin/python /opt/klipper/klippy/klippy.py /home/lava/printer_data/config/printer.cfg -I /home/lava/printer_data/comms/klippy.serial -l /home/lava/printer_data/logs/klippy.log -a /home/lava/printer_data/comms/klippy.sock
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Description=Klipper MCU Firmware
After=network.target
Before=klipper.service
ConditionPathExists=/dev/lava-io

[Service]
Type=simple
User=root
Group=root
ExecStart=/opt/lava/firmware_mcu/klippy_mcu -r
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

if [[ -z "$CREATE_FIRMWARE" ]]; then
echo "Error: This script should be run within the create_firmware.sh environment."
exit 1
fi

if [[ $# -ne 1 ]]; then
echo "Usage: $0 <rootfs-dir>"
exit 1
fi

ROOT_DIR="$(realpath "$(dirname "$0")/../../../..")"
ROOTFS_DIR="$(realpath "$1")"
ORG_ROOTFS_DIR="${ROOTFS_DIR}.org"

set -e

mkdir_chroot() {
for dir; do
echo ">> Creating directory $dir in chroot..."
mkdir -p "$ROOTFS_DIR/$dir"
done
}

copy_chroot() {
local target="$1"
shift

echo ">> Copying to $target the $@..."
for src; do
cp -rv -L --remove-destination "$ORG_ROOTFS_DIR/$src" "$ROOTFS_DIR/$target"
done
}

in_chroot() {
"$ROOT_DIR/scripts/helpers/chroot_firmware.sh" "$ROOTFS_DIR" bash -c "$@"
}

echo ">> Copying Klipper from /home/lava/klipper to /opt/klipper..."
mkdir_chroot /opt/klipper
copy_chroot /opt/klipper/ /home/lava/klipper/.

echo ">> Installing klipper requirements..."
in_chroot '/opt/venv/bin/pip3 install --upgrade pip'
in_chroot '/opt/venv/bin/pip3 install -r /opt/klipper/scripts/klippy-requirements.txt'

# Additional modules not included in klippy-requirements.txt
echo ">> Installing additional klipper requirements..."
in_chroot '/opt/venv/bin/pip3 install paho-mqtt spidev cryptography "numpy<2.0"'

echo ">> Setting ownership to lava:lava..."
in_chroot 'chown -R lava:lava /opt/klipper'

echo ">> Klipper installation complete"
Loading
Loading