Update files

This commit is contained in:
Pat Nakajima 2026-05-18 06:46:40 +00:00
parent 9aa96cb51d
commit 13dce65128
10 changed files with 290 additions and 46 deletions

View File

@ -3,11 +3,17 @@ set -ex
# builds the audio overlay _inside_ the image. # builds the audio overlay _inside_ the image.
modprobe i2c-dev || true if [ ! -s /tmp/toesaudio.dts ]; then
modprobe snd-soc-simple-card || true echo "missing /tmp/toesaudio.dts" >&2
modprobe snd-soc-tlv320aic31xx || true exit 1
modprobe snd-soc-ics43432 || true fi
mkdir -p /boot/firmware/overlays
dtc -@ -I dts -O dtb -o \ dtc -@ -I dts -O dtb -o \
"/boot/firmware/overlays/toesaudio.dtbo" \ "/boot/firmware/overlays/toesaudio.dtbo" \
"/tmp/audio/toesaudio.dts" "/tmp/toesaudio.dts"
if [ ! -s /boot/firmware/overlays/toesaudio.dtbo ]; then
echo "failed to build /boot/firmware/overlays/toesaudio.dtbo" >&2
exit 1
fi

0
audio/init-audio Normal file → Executable file
View File

43
build.sh Normal file → Executable file
View File

@ -2,9 +2,40 @@
set -ex set -ex
scripts/check-qemu.sh BUILD_START=$SECONDS
scripts/download-base.sh
scripts/setup-mount.sh format_duration() {
scripts/copy-files.sh local total="$1"
scripts/update-configtxt.sh printf '%02d:%02d:%02d' "$((total / 3600))" "$(((total % 3600) / 60))" "$((total % 60))"
scripts/build-in-chroot.sh }
run_phase() {
local name="$1"
shift
local start=$SECONDS
local status=0
printf '====> starting %s\n' "$name"
if "$@"; then
status=0
else
status=$?
fi
printf '====> finished %s in %s\n' "$name" "$(format_duration "$((SECONDS - start))")"
return "$status"
}
finish() {
local status=$?
run_phase cleanup scripts/cleanup.sh || true
printf '====> total build.sh time: %s\n' "$(format_duration "$((SECONDS - BUILD_START))")"
exit "$status"
}
trap finish EXIT
run_phase check-qemu scripts/check-qemu.sh
run_phase download-base scripts/download-base.sh
run_phase setup-mount scripts/setup-mount.sh
run_phase copy-files scripts/copy-files.sh
run_phase update-configtxt scripts/update-configtxt.sh
run_phase build-in-chroot scripts/build-in-chroot.sh

View File

@ -0,0 +1,16 @@
[Unit]
Description=Toes Matter service
Wants=bluetooth.service avahi-daemon.service wpa_supplicant.service
After=dbus.service bluetooth.service avahi-daemon.service wpa_supplicant.service
Before=toes.service
[Service]
Type=simple
Environment=MATTER_CREDS_DIR=/var/lib/toes-matter
StateDirectory=toes-matter
ExecStart=/usr/local/bin/toes-matter
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target

View File

@ -1,13 +1,37 @@
#! /bin/bash #! /bin/bash
set -ex set -ex
# runs _inside_ the image, under qemu arm64. # runs setup commands inside the image, under qemu arm64.
echo "====> mounting" sudo tee mnt/root/tmp/image-build.sh >/dev/null <<'EOF'
sudo chroot mnt/root /bin/bash #! /bin/bash
set -ex
export DEBIAN_FRONTEND=noninteractive
mkdir -p /etc/apt/apt.conf.d/disabled
for f in \
/etc/apt/apt.conf.d/*command-not-found* \
/etc/apt/apt.conf.d/*appstream* \
/etc/apt/apt.conf.d/*packagekit*
do
[ -e "$f" ] && mv "$f" /etc/apt/apt.conf.d/disabled/
done
rm -rf /var/lib/apt/lists/*
mkdir -p /var/lib/apt/lists/partial
# The preinstalled image may contain packages from noble-updates while only
# noble and noble-security are enabled. Enable noble-updates before installing
# -dev packages so apt can resolve exact-version dependencies.
if grep -q '^Suites: noble$' /etc/apt/sources.list.d/ubuntu.sources; then
sed -i 's/^Suites: noble$/Suites: noble noble-updates/' /etc/apt/sources.list.d/ubuntu.sources
fi
echo "====> updating apt" echo "====> updating apt"
apt-get update apt-get update
echo "====> installing apt packages" echo "====> installing apt packages"
apt-get install -y \ apt-get install -y \
ca-certificates \ ca-certificates \
@ -16,14 +40,16 @@ apt-get install -y \
git \ git \
locales \ locales \
network-manager \ network-manager \
wpasupplicant \
iproute2 \
isc-dhcp-client \
libcap2-bin \
pkg-config \ pkg-config \
libdbus-1-dev \ libdbus-1-dev \
avahi-daemon \ avahi-daemon \
avahi-utils \ avahi-utils \
libavahi-client-dev \ libavahi-client-dev \
bluez \ bluez \
build-essential \
python3-dev \
python3-pip \ python3-pip \
sox \ sox \
alsa-utils \ alsa-utils \
@ -32,18 +58,127 @@ apt-get install -y \
i2c-tools \ i2c-tools \
device-tree-compiler \ device-tree-compiler \
unzip \ unzip \
"linux-modules-$(uname -r)" sudo
# setup locale # setup locale
locale-gen en_US.UTF-8 locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
echo "====> configuring Wi-Fi for direct wpa_supplicant control"
mkdir -p /etc/NetworkManager/conf.d
cat >/etc/NetworkManager/conf.d/10-unmanaged-wifi.conf <<'EONM'
[keyfile]
unmanaged-devices=type:wifi
EONM
echo "====> creating toes user"
if id -u toes >/dev/null 2>&1; then
usermod -aG sudo toes
else
useradd -m -s /bin/bash -G sudo toes
fi
echo 'toes:nicetrywiseguy' | chpasswd
printf 'toes ALL=(ALL) NOPASSWD:ALL\n' >/etc/sudoers.d/90-toes
chmod 0440 /etc/sudoers.d/90-toes
visudo -cf /etc/sudoers.d/90-toes
# enable serial over usb
echo 'g_serial' >/etc/modules-load.d/usb-serial-gadget.conf
systemctl enable serial-getty@ttyGS0.service
echo "====> building audio overlay"
/tmp/build-audio.sh
systemctl enable init-audio.service
echo "====> installing rgbled" echo "====> installing rgbled"
curl -fsSL https://git.nose.space/nakajima/rgbled/releases/download/v0.1.1/install.sh | bash curl -fsSL https://git.nose.space/nakajima/rgbled/releases/download/v0.1.1/install.sh | bash
echo "====> installing matter stack"
curl -fsSL https://git.fishmt.net/nakajima/toes-matter/releases/download/v0.1.1/install.sh | sh
if [ ! -x /usr/local/bin/toes-matter ]; then
echo "missing /usr/local/bin/toes-matter after install" >&2
exit 1
fi
systemctl enable toes-matter.service
TOES_HOME="$(getent passwd toes | cut -d: -f6)"
mkdir -p "$TOES_HOME"
chown toes:toes "$TOES_HOME"
echo "====> installing bun" echo "====> installing bun"
curl -fsSL https://bun.com/install | bash runuser -u toes -- env HOME="$TOES_HOME" USER=toes LOGNAME=toes bash -c \
'curl -fsSL https://bun.sh/install | bash >/dev/null 2>&1'
BUN="$TOES_HOME/.bun/bin/bun"
if [ ! -x "$BUN" ]; then
echo "missing bun after install: $BUN" >&2
exit 1
fi
ln -sf "$BUN" /usr/local/bin/bun
setcap 'cap_net_bind_service=+ep' "$BUN"
echo "====> installing toes app as toes"
runuser -u toes -- env HOME="$TOES_HOME" USER=toes LOGNAME=toes bash <<'EOSU'
set -ex
export PATH="$HOME/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
quiet() {
"$@"
}
REPO="https://git.nose.space/defunkt/toes"
DEST="$HOME/toes"
APPS_DIR="$HOME/apps"
DATA_DIR="$HOME/data"
echo "====> installing baudy" echo "====> installing baudy"
cd /tmp if [ ! -d "$HOME/baudy" ]; then
git clone https://git.nose.space/nakajima/baudy git clone https://git.nose.space/nakajima/baudy "$HOME/baudy"
fi
if [ -d "$DEST/.git" ]; then
echo "====> Pulling latest toes"
git -C "$DEST" fetch origin main
git -C "$DEST" reset --hard origin/main
else
echo "====> Cloning toes"
git clone "$REPO" "$DEST"
fi
mkdir -p "$APPS_DIR" "$DATA_DIR" "$DATA_DIR/toes"
cd "$DEST"
echo "====> Installing dependencies"
bun install
echo "====> Building"
bun run build
for app in $BUNDLED_APPS; do
[ -d "$DEST/apps/$app" ] || continue
echo " $app"
cp -r "$DEST/apps/$app" "$APPS_DIR/"
if [ -f "$APPS_DIR/$app/package.json" ]; then
quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app"
fi
done
EOSU
echo "====> Installing toes service"
install -m 644 "$TOES_HOME/toes/scripts/toes.service" /etc/systemd/system/toes.service
systemctl enable toes.service
EOF
sudo chmod +x mnt/root/tmp/image-build.sh
sudo chroot mnt/root /bin/bash /tmp/image-build.sh
sudo rm -f mnt/root/tmp/image-build.sh
if [ ! -s mnt/boot/overlays/toesaudio.dtbo ]; then
echo "missing mnt/boot/overlays/toesaudio.dtbo after chroot build" >&2
exit 1
fi

View File

@ -3,6 +3,13 @@ set -ex
# make sure the repo is properly setup by bootstrap-repo.sh # make sure the repo is properly setup by bootstrap-repo.sh
case "$(uname -m)" in
aarch64|arm64)
echo "native arm64 host detected; qemu-aarch64 binfmt is not required"
exit 0
;;
esac
required_binfmt="/proc/sys/fs/binfmt_misc/qemu-aarch64" required_binfmt="/proc/sys/fs/binfmt_misc/qemu-aarch64"
if [ ! -e "$required_binfmt" ]; then if [ ! -e "$required_binfmt" ]; then

20
scripts/cleanup.sh Executable file
View File

@ -0,0 +1,20 @@
#! /bin/bash
set -ex
sudo umount mnt/root/run/systemd/resolve || true
sudo umount mnt/root/run || true
sudo umount mnt/root/sys || true
sudo umount mnt/root/proc || true
sudo umount mnt/root/dev || true
sudo umount mnt/boot || true
sudo umount mnt/root/boot/firmware || true
sudo umount mnt/root || true
if [ -f build/loop-device ]; then
loop_device="$(cat build/loop-device)"
sudo losetup -d "$loop_device" || true
rm -f build/loop-device
fi
echo "--------------------------------------------"
echo "cleanup complete. image path is build/toes-ubuntu-base.img"

View File

@ -2,12 +2,9 @@
set -ex set -ex
# copy files from this repo to _inside_ the image # copy files from this repo to _inside_ the image
cp audio/toesaudio.dts mnt/root/tmp/toesaudio.dts sudo install -m 644 audio/toesaudio.dts mnt/root/tmp/toesaudio.dts
cp audio/asound.conf mnt/root/etc/asound.conf sudo install -m 644 audio/asound.conf mnt/root/etc/asound.conf
cp audio/init-audio mnt/root/usr/local/sbin/init-audio sudo install -m 755 audio/init-audio mnt/root/usr/local/sbin/init-audio
cp audio/init-audio.service mnt/root/etc/systemd/system/init-audio.service sudo install -m 644 audio/init-audio.service mnt/root/etc/systemd/system/init-audio.service
cp audio/build-audio.sh mnt/root/tmp/build-audio.sh sudo install -m 644 matter/toes-matter.service mnt/root/etc/systemd/system/toes-matter.service
sudo install -m 755 audio/build-audio.sh mnt/root/tmp/build-audio.sh
# make sure these are executable
chmod +x mnt/root/usr/local/sbin/init-audio
chmod +x mnt/root/tmp/build-audio.sh

View File

@ -7,12 +7,22 @@ mkdir -p build
xz -dkc cache/ubuntu-24.04.4-preinstalled-server-arm64+raspi.img.xz >build/toes-ubuntu-base.img xz -dkc cache/ubuntu-24.04.4-preinstalled-server-arm64+raspi.img.xz >build/toes-ubuntu-base.img
loop_device="$(sudo losetup --find --show --partscan build/toes-ubuntu-base.img)" loop_device="$(sudo losetup --find --show --partscan build/toes-ubuntu-base.img)"
printf '%s\n' "$loop_device" >build/loop-device
echo "$loop_device" echo "$loop_device"
lsblk "$loop_device" lsblk "$loop_device"
mkdir -p mnt/root mnt/boot mkdir -p mnt/root mnt/boot
sudo mount "${loop_device}p2" mnt/root sudo mount "${loop_device}p2" mnt/root
sudo mount "${loop_device}p1" mnt/boot sudo mkdir -p mnt/root/boot/firmware
sudo mount "${loop_device}p1" mnt/root/boot/firmware
sudo mount --bind mnt/root/boot/firmware mnt/boot
sudo mount --bind /dev mnt/root/dev
sudo mount -t proc proc mnt/root/proc
sudo mount -t sysfs sysfs mnt/root/sys
sudo mount -t tmpfs tmpfs mnt/root/run
if [ -d /run/systemd/resolve ]; then
sudo mkdir -p mnt/root/run/systemd/resolve
sudo mount --bind /run/systemd/resolve mnt/root/run/systemd/resolve
fi

50
scripts/update-configtxt.sh Normal file → Executable file
View File

@ -2,21 +2,43 @@
set -ex set -ex
# add stuff we want to config.txt # add stuff we want to config.txt
add = <<-END config="mnt/boot/config.txt"
dtparam=spi=on add_file="$(mktemp)"
# we can adjust these values as needed trap 'rm -f "$add_file"' EXIT
dtparam=cooling_fan=on,fan_temp0=62000,fan_temp0_hyst=8000,fan_temp0_speed=80,fan_temp1=70000,fan_temp1_hyst=5000,fan_temp1_speed=100,fan_temp2=76000,fan_temp2_hyst=4000,fan_temp2_speed=170,fan_temp3=80000,fan_temp3_hyst=3000,fan_temp3_speed=250
# enable i2s for audio cat >"$add_file" <<'END'
dtparam=i2s=on dtparam=spi=on
# use an external antenna instead of the pcb antenna on the CM # we can adjust these values as needed
dtparam=ant2 dtparam=cooling_fan=on,fan_temp0=62000,fan_temp0_hyst=8000,fan_temp0_speed=80,fan_temp1=70000,fan_temp1_hyst=5000,fan_temp1_speed=100,fan_temp2=76000,fan_temp2_hyst=4000,fan_temp2_speed=170,fan_temp3=80000,fan_temp3_hyst=3000,fan_temp3_speed=250
# load our audio driver # enable i2s for audio
dtoverlay=toesaudio dtparam=i2s=on
# enable gpio12 which we use to reset the audio codec # use an external antenna instead of the pcb antenna on the CM
gpio=12=op,dh dtparam=ant2
# load our audio driver
dtoverlay=toesaudio
# enable gpio12 which we use to reset the audio codec
gpio=12=op,dh
# enable serial over usb in gadget/peripheral mode
dtoverlay=dwc2,dr_mode=peripheral
END END
sed -i "s/dtparam=spi=on/$add" mnt/boot/config.txt if ! sudo grep -qx 'dtparam=spi=on' "$config"; then
echo "missing dtparam=spi=on in $config" >&2
exit 1
fi
sudo awk -v add_file="$add_file" '
$0 == "dtparam=spi=on" && !done {
while ((getline line < add_file) > 0) {
print line
}
close(add_file)
done = 1
next
}
{ print }
' "$config" | sudo tee "$config.tmp" >/dev/null
sudo mv "$config.tmp" "$config"
# we don't need fancy graphics. we don't have a screen. # we don't need fancy graphics. we don't have a screen.
echo "\ngpu_mem=16" >>mnt/boot/config.txt printf '\ngpu_mem=16\n' | sudo tee -a "$config" >/dev/null