Migrate boot to runit

This commit is contained in:
Adeeb Shihadeh
2026-05-02 19:08:26 -07:00
parent ccac0cba21
commit 9d4350c6f8
107 changed files with 1181 additions and 699 deletions
+332
View File
@@ -0,0 +1,332 @@
#!/bin/bash
PATH=/usr/comma/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
BOOTSH_RUN=/run/bootsh
log() {
local ts="?"
if [ -r /proc/uptime ]; then
ts="$(cut -d' ' -f1 /proc/uptime)"
fi
printf 'boot.sh[%d]: %s %s\n' "$$" "$ts" "$*" >/dev/console 2>/dev/null || true
printf '<6>boot.sh[%d]: %s %s\n' "$$" "$ts" "$*" >/dev/kmsg 2>/dev/null || true
}
mount_one() {
local type="$1"
local what="$2"
local where="$3"
shift 3
mkdir -p "$where"
mountpoint -q "$where" && return 0
mount -t "$type" "$@" "$what" "$where" 2>/dev/kmsg
}
wait_block() {
local dev="$1"
local i
for i in $(seq 1 150); do
[ -b "$dev" ] && return 0
sleep 0.01
done
log "timeout waiting for $dev"
return 1
}
mount_block() {
local what="$1"
local where="$2"
local type="$3"
local opts="$4"
wait_block "$what" || return 1
mkdir -p "$where"
mountpoint -q "$where" && return 0
log "mount $where"
mount -t "$type" -o "$opts" "$what" "$where" 2>/dev/kmsg
}
boost_early() {
echo performance >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null || true
echo performance >/sys/devices/system/cpu/cpufreq/policy4/scaling_governor 2>/dev/null || true
echo 2649600 >/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq 2>/dev/null || true
echo 2649600 >/sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq 2>/dev/null || true
echo 2649600 >/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq 2>/dev/null || true
echo 2649600 >/sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq 2>/dev/null || true
}
set_graphics_perms() {
chgrp gpu /dev/adsprpc-smd /dev/ion /dev/kgsl-3d0 /dev/dri/* 2>/dev/null || true
chmod 660 /dev/adsprpc-smd /dev/kgsl-3d0 /dev/dri/* 2>/dev/null || true
chmod 664 /dev/ion 2>/dev/null || true
}
set_device_perms() {
set_graphics_perms
chgrp gpio /dev/i2c-* 2>/dev/null || true
chmod 660 /dev/i2c-* 2>/dev/null || true
chmod 666 /dev/spidev* 2>/dev/null || true
chmod 666 /dev/input/* 2>/dev/null || true
chgrp disk /dev/sd* 2>/dev/null || true
chmod 660 /dev/sd* 2>/dev/null || true
chgrp gpio /sys/class/gpio/gpio*/direction /sys/class/gpio/gpio*/value 2>/dev/null || true
chmod 660 /sys/class/gpio/gpio*/direction /sys/class/gpio/gpio*/value 2>/dev/null || true
chgrp video /sys/class/backlight/panel0-backlight/brightness \
/sys/class/backlight/panel0-backlight/bl_power \
/sys/devices/platform/soc/soc:qcom,dsi-display@0/max_brightness_percent 2>/dev/null || true
chmod g+w /sys/class/backlight/panel0-backlight/brightness \
/sys/class/backlight/panel0-backlight/bl_power \
/sys/devices/platform/soc/soc:qcom,dsi-display@0/max_brightness_percent 2>/dev/null || true
}
create_tmpfiles() {
mkdir -p /var/crash /var/tmp /var/lib/dpkg /var/lib/logrotate \
/var/spool/cron/atjobs /var/cache/pollinate
chmod 1777 /var/tmp 2>/dev/null || true
touch /var/lib/dpkg/lock-frontend /var/lib/dpkg/status 2>/dev/null || true
}
permission_loop() {
local i
for i in $(seq 1 200); do
set_device_perms
sleep 0.025
done
}
mount_data() {
log "mount /data"
mkdir -p /data
mountpoint -q /data && return 0
wait_block /dev/sda12 || return 1
mount -t ext4 -o discard,noatime,nodiratime,nosuid,nodev /dev/sda12 /data 2>/dev/kmsg
}
data_late_setup() {
mkdir -p /data/etc/netplan /data/etc/NetworkManager/system-connections /data/ssh /data/tmp /data/media
chown comma:comma /data /data/media /data/ssh /data/tmp 2>/dev/null || true
touch /data/etc/timezone /data/etc/localtime 2>/dev/null || true
if [ ! -d /data/persist ] && [ -d /system/persist ]; then
cp -a /system/persist /data/ 2>/dev/null || true
fi
}
mount_early_state() {
mount_one tmpfs tmpfs /var -o rw,nosuid,nodev,size=128M,mode=755 || true
mount_one tmpfs tmpfs /tmp -o rw,nosuid,nodev,size=150M,mode=1777 || true
mount_one tmpfs tmpfs /run -o nosuid,nodev,mode=755,size=714M,nr_inodes=819200 || true
mount_one tmpfs tmpfs /rwtmp -o rw,nosuid,nodev,size=100M,mode=1777 || true
mkdir -p "$BOOTSH_RUN" /var/tmp/xdg /var/log /run/sudo /run/user/1000 /rwtmp/home_work /rwtmp/home_upper
chmod 1777 /var/tmp
chown comma:comma /var/tmp/xdg /run/user/1000 2>/dev/null || true
chmod 700 /run/user/1000 2>/dev/null || true
mount_one tmpfs tmpfs /var/log -o rw,nosuid,nodev,size=128M,mode=755 || true
chown root:syslog /var/log 2>/dev/null || true
chmod 775 /var/log 2>/dev/null || true
create_tmpfiles
mountpoint -q /home || mount -t overlay overlay \
-o lowerdir=/usr/default/home,upperdir=/rwtmp/home_upper,workdir=/rwtmp/home_work \
/home 2>/dev/kmsg || true
}
mount_core() {
mount_one proc proc /proc || true
mount_one sysfs sysfs /sys || true
mount_one devtmpfs devtmpfs /dev -o mode=755 || true
mkdir -p /dev/pts /dev/shm /sys/fs/cgroup /sys/fs/pstore /sys/fs/bpf /sys/kernel/debug /sys/kernel/tracing /sys/kernel/config
mount_one devpts devpts /dev/pts -o gid=5,mode=620,ptmxmode=000 || true
mount_one tmpfs tmpfs /dev/shm -o nosuid,nodev,size=1800M || true
}
mount_firmware() {
mount_block /dev/sde4 /firmware vfat ro || true
mount_block /dev/sde9 /dsp ext4 ro || true
log "firmware mounts done"
}
mount_deferred() {
mount_one tmpfs tmpfs /run/lock -o nosuid,nodev,noexec,size=5M || true
mount_one cgroup2 cgroup2 /sys/fs/cgroup -o nosuid,nodev,noexec || true
mount_one pstore pstore /sys/fs/pstore -o nosuid,nodev,noexec || true
mount_one bpf bpf /sys/fs/bpf -o nosuid,nodev,noexec || true
mount_one debugfs debugfs /sys/kernel/debug -o nosuid,nodev,noexec || true
mount_one tracefs tracefs /sys/kernel/tracing -o nosuid,nodev,noexec || true
mount_one configfs configfs /sys/kernel/config || true
ln -sf /sys/kernel/tracing /sys/kernel/debug/tracing 2>/dev/null || true
mount_firmware
mount_block /dev/sda2 /persist squashfs ro,nosuid,nodev,noexec || true
mount_block /dev/sda10 /systemrw ext4 relatime,data=ordered,noauto_da_alloc,discard,noexec,nodev || true
mount_block /dev/sda11 /cache ext4 relatime,data=ordered,noauto_da_alloc,discard,noexec,nodev,nosuid || true
chown -R comma:comma /cache 2>/dev/null || true
log "deferred mounts done"
}
setup_input_links() {
local event i name
for i in $(seq 1 250); do
for event in /sys/class/input/event*; do
[ -r "$event/device/name" ] || continue
name="$(cat "$event/device/name" 2>/dev/null || true)"
if [ "$name" = "fts_ts" ]; then
mkdir -p /dev/input/by-path
ln -sf "../$(basename "$event")" /dev/input/by-path/platform-894000.i2c-event
log "input link ready"
return 0
fi
done
sleep 0.02
done
log "timeout waiting for touch input"
}
setup_gpios() {
local p i pins
pins="30 49 134 41 50 116 124 34 33 32 52 1264"
for p in $pins; do
if [ "$p" = "41" ] && grep -q "comma tici" /sys/firmware/devicetree/base/model 2>/dev/null; then
continue
fi
[ -d "/sys/class/gpio/gpio$p" ] || echo "$p" >/sys/class/gpio/export 2>/dev/null || true
done
for p in $pins; do
if [ "$p" = "41" ] && grep -q "comma tici" /sys/firmware/devicetree/base/model 2>/dev/null; then
continue
fi
for i in $(seq 1 20); do
[ -d "/sys/class/gpio/gpio$p" ] && break
sleep 0.005
done
done
echo out >/sys/class/gpio/gpio30/direction 2>/dev/null || true
echo 1 >/sys/class/gpio/gpio30/value 2>/dev/null || true
set_device_perms
touch "$BOOTSH_RUN/gpio-ready"
log "gpio ready"
}
make_bootdevice_links() {
local dev i key part uevent value
mkdir -p /dev/block/bootdevice/by-name /dev/disk/by-partlabel
for i in $(seq 1 150); do
for uevent in /sys/class/block/sd*[0-9]*/uevent; do
[ -e "$uevent" ] || continue
dev="${uevent#/sys/class/block/}"
dev="${dev%/uevent}"
part=""
while IFS='=' read -r key value; do
if [ "$key" = "PARTNAME" ]; then
part="$value"
break
fi
done <"$uevent"
if [ -n "$part" ]; then
ln -sf "/dev/$dev" "/dev/block/bootdevice/by-name/$part"
ln -sf "/dev/$dev" "/dev/disk/by-partlabel/$part"
fi
done
[ -e /dev/block/bootdevice/by-name/modemst1 ] && break
sleep 0.02
done
log "bootdevice links ready"
}
qcom_early() {
local f
for f in /sys/bus/msm_subsys/devices/subsys*/restart_level; do
[ -e "$f" ] && echo related >"$f" 2>/dev/null || true
done
boost_early
[ -e /sys/kernel/boot_wlan/boot_wlan ] && echo 1 >/sys/kernel/boot_wlan/boot_wlan 2>/dev/null || true
[ -x /usr/bin/irsc_util ] && /usr/bin/irsc_util /etc/sec_config >/tmp/irsc_util.log 2>&1 || true
[ -e /sys/kernel/boot_cdsp/boot ] && echo 1 >/sys/kernel/boot_cdsp/boot 2>/dev/null || true
[ -e /dev/ipa ] && echo 1 >/dev/ipa 2>/dev/null || true
log "qcom early done"
}
start_magic() {
log "start magic"
/usr/comma/start-magic.sh >/tmp/magic.log 2>&1 &
touch "$BOOTSH_RUN/magic-started"
}
start_comma() {
log "start comma"
/usr/comma/start-comma.sh >/tmp/comma-start.log 2>&1
log "comma launched"
}
start_sound() {
log "start sound"
/usr/comma/sound/start-sound.sh --boot >/tmp/sound.log 2>&1 &
}
start_serial_shell() {
[ -c /dev/ttyMSM0 ] || return 0
setsid /bin/bash -l </dev/ttyMSM0 >/dev/ttyMSM0 2>&1 &
}
log "pid1 start"
mount_core
start_serial_shell
boost_early
mount_data &
data_mount_pid=$!
mount_early_state
/usr/comma/set-hostname.sh >/tmp/set-hostname.log 2>&1 || true
permission_loop &
setup_gpios &
gpio_pid=$!
setup_input_links &
start_magic
wait "$data_mount_pid" || true
data_late_setup
touch "$BOOTSH_RUN/data-ready"
start_comma
mount_deferred &
mount_deferred_pid=$!
qcom_early &
qcom_early_pid=$!
make_bootdevice_links &
bootdevice_pid=$!
wait "$mount_deferred_pid" || true
touch "$BOOTSH_RUN/fs-setup-done"
/usr/comma/debug.py >/tmp/agnos-debug.log 2>&1 || true
/usr/comma/screen_calibration.py >/tmp/screen-calibration.log 2>&1 || true
start_sound
wait "$qcom_early_pid" || true
wait "$bootdevice_pid" || true
wait "$gpio_pid" || true
set_device_perms
log "boot path done"
exit 0
+15 -2
View File
@@ -27,6 +27,11 @@ mount_fs() {
local type="$3"
local options="$4"
if mountpoint -q "$where"; then
log "$where already mounted"
return 0
fi
if [[ "$what" == /dev/* ]] && ! wait_for_block "$what"; then
failed=1
return 1
@@ -45,6 +50,11 @@ mount_fs() {
log "start"
if [[ -e /run/bootsh/fs-setup-done ]]; then
log "already done by boot.sh"
exit 0
fi
failed=0
mount_fs /dev/sde9 /dsp ext4 ro
mount_fs /dev/sde4 /firmware vfat ro
@@ -59,8 +69,11 @@ mount_fs tmpfs /rwtmp tmpfs rw,nosuid,nodev,size=100M,mode=1777
# Ensure the symlinks in the read only rootfs are
# backed by real files and directories on userdata.
# tmpfiles
systemd-tmpfiles --create /usr/comma/tmpfiles.conf
# Runtime files normally created by tmpfiles.d.
mkdir -p /var/crash /var/tmp /var/lib/dpkg /var/lib/logrotate \
/var/spool/cron/atjobs /var/cache/pollinate
chmod 1777 /var/tmp
touch /var/lib/dpkg/lock-frontend /var/lib/dpkg/status
# /var/log/ tmpfs
mkdir -p /var/log/
+27 -11
View File
@@ -2,7 +2,7 @@
import os, socket, struct, subprocess, threading, time
from array import array
import pyray as rl
rl = None
UPDATER_PATH = "/usr/comma/updater"
WESTON_RUNTIME_DIR = "/var/tmp/weston"
@@ -13,6 +13,14 @@ DRM_DEVICE = "/dev/dri/card0"
BACKLIGHT_POWER = "/sys/class/backlight/panel0-backlight/bl_power"
BACKGROUND = "/usr/comma/bg.jpg"
def log(msg):
print(f"MAGIC {time.monotonic():.2f} {msg}", flush=True)
try:
with open("/dev/kmsg", "w") as f:
f.write(f"magic: {time.monotonic():.2f} {msg}\n")
except Exception:
pass
# This is needed to keep the old updater working. Updater used to be stored in
# openpilot directly instead of in AGNOS. This will intercept the old updater
# trying to use a Weston socket and start our own.
@@ -83,6 +91,8 @@ def handle_client(client, drm_master):
pass
def main():
global rl
threading.Thread(target=updater_weston, daemon=True).start()
while True:
@@ -94,6 +104,21 @@ def main():
time.sleep(0.1)
os.environ['DRM_FD'] = str(drm_master)
try:
os.unlink(SOCK_PATH)
except FileNotFoundError:
pass
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(SOCK_PATH)
server.settimeout(0.1)
server.listen(1)
log("drmfd socket ready")
import pyray as rl
log("raylib imported")
while not os.access(BACKLIGHT_POWER, os.W_OK):
time.sleep(0.1)
@@ -105,16 +130,7 @@ def main():
pos = rl.Vector2((rl.get_screen_width() - tex.width)/2.0, (rl.get_screen_height() - tex.height)/2.0)
rl.unload_image(img)
show_background(tex, pos)
try:
os.unlink(SOCK_PATH)
except FileNotFoundError:
pass
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(SOCK_PATH)
server.settimeout(0.1)
server.listen(1)
log("splash drawn")
clients = set()
need_background = False
@@ -95,7 +95,7 @@ def perform_controlled_shutdown():
# Kill services that draw a lot of power
printk("Killing services")
subprocess.call(["/usr/bin/systemctl", "kill", "--signal=9", "comma"])
subprocess.call(["/usr/comma/shims/systemctl", "kill", "--signal=9", "comma"])
set_screen_power(False)
printk("Halt")
@@ -122,4 +122,3 @@ if __name__ == '__main__':
perform_controlled_shutdown()
except Exception:
pass
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
PATH=/usr/comma/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
log() {
local name ts
name="${SVDIR##*/}"
[ -n "$name" ] || name="${0##*/}"
ts="?"
[ -r /proc/uptime ] && ts="$(cut -d' ' -f1 /proc/uptime)"
printf '<6>runit-%s[%d]: %s %s\n' "$name" "$$" "$ts" "$*" >/dev/kmsg 2>/dev/null || true
printf 'runit-%s[%d]: %s %s\n' "$name" "$$" "$ts" "$*"
}
wait_path() {
local path="$1"
local i
for i in $(seq 1 300); do
[ -e "$path" ] && return 0
sleep 0.1
done
log "timeout waiting for $path"
return 1
}
wait_dbus() {
wait_path /run/dbus/system_bus_socket
}
param_enabled() {
local path="$1"
[ -f "$path" ] && [ "$(cat "$path" 2>/dev/null)" = "1" ]
}
run_as_comma() {
exec env \
HOME=/home/comma \
LOGNAME=comma \
SHELL=/bin/bash \
TERM=xterm-256color \
USER=comma \
XDG_RUNTIME_DIR=/var/tmp/xdg \
PATH="$PATH" \
setpriv --reuid=1000 --regid=1000 --init-groups "$@"
}
@@ -0,0 +1,13 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
last=""
while true; do
cur="$(cat /data/params/d/AdbEnabled 2>/dev/null || true)"
if [ "$cur" != "$last" ]; then
last="$cur"
log "AdbEnabled changed to ${cur:-unset}"
sv restart /run/runit/services/adbd 2>/dev/null || true
fi
sleep 2
done
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
if ! param_enabled /data/params/d/AdbEnabled; then
log "disabled"
[ -d /config/usb_gadget/g1 ] && echo "" >/config/usb_gadget/g1/UDC 2>/dev/null || true
while sleep 3600; do :; done
fi
mkdir -p /config /dev/usb-ffs/adb
mountpoint -q /config || mount -t configfs none /config
mkdir -p /config/usb_gadget/g1
cd /config/usb_gadget/g1
echo "" > UDC 2>/dev/null || true
mkdir -p strings/0x409 configs/c.1/strings/0x409 functions/ncm.0 functions/ffs.adb
echo 0x04D8 > idVendor
echo 0x1234 > idProduct
sed -n 's/^.*androidboot.serialno=\([^ ]*\).*$/\1/p' /proc/cmdline > strings/0x409/serialnumber
echo comma.ai > strings/0x409/manufacturer
echo "Linux USB Gadget" > strings/0x409/product
echo 250 > configs/c.1/MaxPower
echo "NCM+ADB" > configs/c.1/strings/0x409/configuration
mountpoint -q /dev/usb-ffs/adb || mount -t functionfs adb /dev/usb-ffs/adb
rm -f configs/c.1/ncm.0 configs/c.1/ffs.adb
ln -sf functions/ncm.0 configs/c.1/ncm.0
ln -sf functions/ffs.adb configs/c.1/ffs.adb
command -v setprop >/dev/null && setprop service.adb.tcp.port -1 2>/dev/null || true
/usr/comma/adbd &
pid=$!
sleep 2
for _ in $(seq 1 40); do
echo a600000.dwc3 > UDC 2>/tmp/adbd-udc.err || true
[ "$(cat UDC 2>/dev/null)" = "a600000.dwc3" ] && break
sleep 0.25
done
wait "$pid"
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_dbus || true
exec /usr/sbin/avahi-daemon -s
@@ -0,0 +1,6 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_dbus || true
sleep 1
run_as_comma /usr/comma/avahi-publish-service.sh
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
exec /usr/local/venv/bin/python -u /usr/comma/brightnessd.py
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
if ! pgrep -x cnss_daemon >/dev/null 2>&1; then
if [ -e /tmp/cnss_daemon.log ]; then
/usr/sbin/cnss_daemon -d -f /tmp/cnss_daemon.log
else
/usr/sbin/cnss_daemon
fi
fi
while sleep 5; do
pgrep -x cnss_daemon >/dev/null 2>&1 || exit 1
done
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /run/bootsh/data-ready || true
exec /usr/comma/start-comma.sh --monitor
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
mkdir -p /run/dbus /var/lib/dbus
rm -f /run/dbus/pid
exec dbus-daemon --system --nofork --nopidfile
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /firmware/verinfo/ver_info.txt || true
exec /sbin/init_mss
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /systemrw || true
exec /sbin/leprop-service
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
mkdir -p /dev/socket
chmod 777 /dev/socket
echo 600 >/proc/sys/net/unix/max_dgram_qlen 2>/dev/null || true
/sbin/logd &
pid=$!
for _ in $(seq 1 50); do
[ -S /dev/socket/logd ] && break
sleep 0.02
done
chmod 0666 /dev/socket/logd /dev/socket/logdr 2>/dev/null || true
chmod 0222 /dev/socket/logdw 2>/dev/null || true
wait "$pid"
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
mkdir -p /var/lib/logrotate
while true; do
/usr/sbin/logrotate /etc/logrotate.conf || true
sleep 3600
done
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /run/bootsh/gpio-ready || true
/usr/comma/lte/lte.sh start
log "started"
trap '/usr/comma/lte/lte.sh stop' TERM INT
while sleep 3600; do :; done
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
exec /usr/comma/start-magic.sh --monitor
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_dbus || true
wait_path /run/bootsh/fs-setup-done || true
exec /usr/sbin/ModemManager --filter-policy=strict --debug
@@ -0,0 +1,6 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_dbus || true
mkdir -p /run/NetworkManager /var/lib/NetworkManager
exec /usr/sbin/NetworkManager --no-daemon
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
for _ in $(seq 1 100); do
pgrep -x init_mss >/dev/null 2>&1 && break
sleep 0.1
done
exec /usr/bin/pdmappersvc
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
for _ in $(seq 1 100); do
pgrep -x leprop-service >/dev/null 2>&1 && break
sleep 0.1
done
/sbin/persist-prop.sh
log "done"
while sleep 3600; do :; done
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_dbus || true
if ! pgrep -u polkitd -x polkitd >/dev/null 2>&1; then
setpriv --reuid=polkitd --regid=polkitd --init-groups /usr/lib/polkit-1/polkitd --no-debug
fi
while sleep 5; do
pgrep -u polkitd -x polkitd >/dev/null 2>&1 || exit 1
done
@@ -0,0 +1,8 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
if ! grep -q -E "tici|tizi" /sys/firmware/devicetree/base/model 2>/dev/null; then
log "not supported on this hardware"
while sleep 3600; do :; done
fi
exec /usr/local/venv/bin/python -u /usr/comma/power_drop_monitor.py
@@ -0,0 +1,4 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
exec /usr/local/venv/bin/python -u /usr/comma/power_monitor.py
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /dev/qseecom || true
chmod 0666 /dev/qseecom 2>/dev/null || true
chmod 0664 /dev/ion /dev/sde20 2>/dev/null || true
exec /usr/bin/qseecomd
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
wait_path /dev/block/bootdevice/by-name/modemst1 || true
wait_path /dev/block/bootdevice/by-name/modemst2 || true
wait_path /dev/block/bootdevice/by-name/fsc || true
wait_path /dev/block/bootdevice/by-name/fsg || true
exec /sbin/rmt_storage
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
mkdir -p /var/log /var/spool/rsyslog
chown root:syslog /var/log 2>/dev/null || true
chmod 775 /var/log 2>/dev/null || true
chown syslog:adm /var/spool/rsyslog 2>/dev/null || true
exec /usr/sbin/rsyslogd -n -iNONE
@@ -0,0 +1,13 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
last=""
while true; do
cur="$(cat /data/params/d/SshEnabled 2>/dev/null || true)"
if [ "$cur" != "$last" ]; then
last="$cur"
log "SshEnabled changed to ${cur:-unset}"
sv restart /run/runit/services/ssh 2>/dev/null || true
fi
sleep 2
done
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
if ! param_enabled /data/params/d/SshEnabled; then
log "disabled"
while sleep 3600; do :; done
fi
mkdir -p /data/etc/ssh /run/sshd
ssh-keygen -A -f /data
/usr/sbin/sshd -t
exec /usr/sbin/sshd -D
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
exec 2>&1
. /usr/comma/runit/common.sh
exec /usr/local/venv/bin/python -u /usr/comma/varwatch.py
+2 -2
View File
@@ -61,12 +61,12 @@ if [ -f "$ADB_PARAM" ] && [ "$(< $ADB_PARAM)" == "1" ]; then
echo "Enabling ADB"
setup
systemctl start adbd
/usr/comma/shims/systemctl start adbd
sleep 1 # adbd does some setup before we can enable the gadget
start
else
echo "Disabling ADB"
systemctl stop adbd
/usr/comma/shims/systemctl stop adbd
stop
fi
+2 -2
View File
@@ -3,8 +3,8 @@
SSH_PARAM="/data/params/d/SshEnabled"
if [ -f "$SSH_PARAM" ] && [ "$(< $SSH_PARAM)" == "1" ]; then
echo "Enabling SSH"
systemctl start ssh
/usr/comma/shims/systemctl start ssh
else
echo "Disabling SSH"
systemctl stop ssh
/usr/comma/shims/systemctl stop ssh
fi
+95
View File
@@ -0,0 +1,95 @@
#!/bin/bash
set -u
while [[ "${1:-}" == --* ]]; do
case "$1" in
--root=*|--system|--user|--global|--preset-mode=*|--no-reload|--no-ask-password|--quiet)
shift
;;
--)
shift
break
;;
*)
break
;;
esac
done
service_dir() {
local name="${1%.service}"
case "$name" in
magic) name=magic ;;
comma) name=comma ;;
ssh|sshd) name=ssh ;;
adbd) name=adbd ;;
esac
if [ -d "/run/runit/services/$name" ]; then
printf '/run/runit/services/%s\n' "$name"
else
printf '/usr/comma/runit/services/%s\n' "$name"
fi
}
case "${1:-}" in
"")
exit 0
;;
daemon-reload|daemon-reexec|preset|preset-all|enable|disable|reenable|mask|unmask|try-reload-or-restart|reload)
exit 0
;;
esac
if [ "${1:-}" = "is-enabled" ]; then
exit 1
fi
if [ "${1:-}" = "daemon-reload" ]; then
exit 0
fi
if [ "${1:-}" = "is-active" ] && [ "${2:-}" = "--quiet" ]; then
case "${3:-}" in
magic|magic.service)
pgrep -u comma -f "/usr/comma/magic.py" >/dev/null 2>&1 && [ -S /tmp/drmfd.sock ] && exit 0
exit 3
;;
comma|comma.service)
/usr/bin/tmux has-session -t comma >/dev/null 2>&1 && exit 0
exit 3
;;
esac
sv status "$(service_dir "${3:-}")" >/dev/null 2>&1 && exit 0
exit 3
fi
case "${1:-}" in
start)
exec sv up "$(service_dir "${2:-}")"
;;
stop)
exec sv down "$(service_dir "${2:-}")"
;;
restart)
exec sv restart "$(service_dir "${2:-}")"
;;
kill)
signal=TERM
shift
if [[ "${1:-}" == --signal=* ]]; then
signal="${1#--signal=}"
shift
fi
name="${1:-}"
if [ "${name%.service}" = "comma" ]; then
pkill "-$signal" -f "/usr/comma/comma.sh" 2>/dev/null || true
pkill "-$signal" -f "tmux new-session -s comma" 2>/dev/null || true
exit 0
fi
exec sv force-stop "$(service_dir "$name")"
;;
esac
echo "systemctl shim: unsupported command: $*" >&2
exit 1
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
set -u
BOOTSH_RUN=/run/bootsh
if [ "${1:-}" = "--boot" ]; then
mkdir -p "$BOOTSH_RUN"
rm -f "$BOOTSH_RUN/sound-ready" "$BOOTSH_RUN/sound-failed"
touch "$BOOTSH_RUN/sound-started"
if /usr/comma/sound/sound_init.sh; then
touch "$BOOTSH_RUN/sound-ready"
exit 0
fi
touch "$BOOTSH_RUN/sound-failed"
exit 1
fi
if [ -e "$BOOTSH_RUN/sound-started" ]; then
while pgrep -f "/usr/comma/sound/sound_init.sh" >/dev/null 2>&1; do
sleep 0.1
done
[ -e "$BOOTSH_RUN/sound-ready" ] && exit 0
exit 1
fi
exec /usr/comma/sound/sound_init.sh
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
set -u
PATH=/usr/comma/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
log() {
local ts="?"
if [ -r /proc/uptime ]; then
ts="$(cut -d' ' -f1 /proc/uptime)"
fi
if [ -w /dev/kmsg ]; then
printf '<6>start-comma[%d]: %s %s\n' "$$" "$ts" "$*" >/dev/kmsg 2>/dev/null || true
fi
}
set_limits() {
ulimit -Hr 100 2>/dev/null || true
ulimit -Sr 100 2>/dev/null || true
ulimit -He 30 2>/dev/null || true
ulimit -Se 30 2>/dev/null || true
}
start_session() {
local agnos_version
agnos_version="$(cat /VERSION 2>/dev/null || true)"
export AGNOS_VERSION="$agnos_version"
export HOME=/home/comma
export LOGNAME=comma
export SHELL=/bin/bash
export TERM=xterm-256color
export USER=comma
export XDG_RUNTIME_DIR=/var/tmp/xdg
if /usr/bin/tmux has-session -t comma >/dev/null 2>&1; then
log "tmux session already running"
return 0
fi
/usr/bin/tmux new-session -s comma -d "/bin/bash -lc 'exec /bin/bash /usr/comma/comma.sh >>/tmp/comma.log 2>&1'"
log "tmux session started"
}
monitor_session() {
while /usr/bin/tmux has-session -t comma >/dev/null 2>&1; do
sleep 5
done
}
set_limits
if [ "$(id -u)" = "0" ]; then
exec env \
HOME=/home/comma \
LOGNAME=comma \
SHELL=/bin/bash \
TERM=xterm-256color \
USER=comma \
XDG_RUNTIME_DIR=/var/tmp/xdg \
PATH="$PATH" \
setpriv --reuid=1000 --regid=1000 --init-groups "$0" "$@"
fi
start_session
if [ "${1:-}" = "--monitor" ]; then
monitor_session
fi
+81
View File
@@ -0,0 +1,81 @@
#!/bin/bash
set -u
PATH=/usr/comma/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
export HOME=/home/comma
export LOGNAME=comma
export SHELL=/bin/bash
export USER=comma
export XDG_RUNTIME_DIR=/var/tmp/xdg
export PYTHONPATH=/data/pythonpath
export UV_PYTHON_INSTALL_DIR=/usr/local/uv/python
export UV_PYTHON_PREFERENCE=only-system
export UV_LINK_MODE=copy
log() {
local ts="?"
if [ -r /proc/uptime ]; then
ts="$(cut -d' ' -f1 /proc/uptime)"
fi
if [ -w /dev/kmsg ]; then
printf '<6>start-magic[%d]: %s %s\n' "$$" "$ts" "$*" >/dev/kmsg 2>/dev/null || true
fi
}
magic_running() {
pgrep -u comma -f "/usr/comma/magic.py" >/dev/null 2>&1
}
prep_root() {
chgrp gpu /dev/adsprpc-smd /dev/ion /dev/kgsl-3d0 /dev/dri/* 2>/dev/null || true
chmod 660 /dev/adsprpc-smd /dev/kgsl-3d0 /dev/dri/* 2>/dev/null || true
chmod 664 /dev/ion 2>/dev/null || true
mkdir -p /data/misc/display /var/tmp/xdg
(echo 0 >/data/misc/display/sdm_dbg_cfg.txt) 2>/dev/null || true
(echo 0 >/data/misc/display/gbm_dbg_cfg.txt) 2>/dev/null || true
chown comma:comma /var/tmp/xdg 2>/dev/null || true
}
prep_user() {
mkdir -p /var/tmp/xdg 2>/dev/null || true
}
monitor_magic() {
while magic_running; do
sleep 5
done
log "magic exited"
return 1
}
if [ "$(id -u)" = "0" ]; then
prep_root
exec env \
HOME="$HOME" \
LOGNAME="$LOGNAME" \
SHELL="$SHELL" \
USER="$USER" \
XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
PYTHONPATH="$PYTHONPATH" \
UV_PYTHON_INSTALL_DIR="$UV_PYTHON_INSTALL_DIR" \
UV_PYTHON_PREFERENCE="$UV_PYTHON_PREFERENCE" \
UV_LINK_MODE="$UV_LINK_MODE" \
PATH="$PATH" \
setpriv --reuid=1000 --regid=1000 --init-groups "$0" "$@"
fi
prep_user
if magic_running; then
log "magic already running"
if [ "${1:-}" = "--monitor" ]; then
monitor_magic
fi
exit 0
fi
log "exec magic"
exec /usr/local/venv/bin/python -u /usr/comma/magic.py
@@ -1,22 +1,18 @@
#!/usr/bin/env python3
import subprocess
import re
from tabulate import tabulate
# serial with timestamps:
# grabserial -d /dev/serial/by-id/usb-FTDI_FT230X* -t
# systemd-analyze critical-chain comma.service
# boot chart:
# systemd-analyze plot > /tmp/bootup.svg
def get_journal_time(x):
out = subprocess.check_output("journalctl -x -o short-monotonic", shell=True, encoding='utf8')
jlines = out.strip().splitlines()
for l in jlines:
if x in l:
t = l.split('[')[1].split(']')[0]
return float(t)
def get_bootsh_time(x):
out = subprocess.check_output("dmesg | grep 'boot.sh'", shell=True, encoding='utf8')
for line in out.strip().splitlines():
if x in line:
m = re.search(r"boot\.sh\[\d+\]: ([0-9.]+)", line)
if m:
return float(m.group(1))
return None
if __name__ == "__main__":
@@ -30,12 +26,8 @@ if __name__ == "__main__":
def tot_since_kern():
return sum(ts.values()) - (ts['PON'] + ts['XBL'] + ts['ABL'])
out = subprocess.check_output("systemd-analyze", shell=True, encoding='utf8')
l = out.splitlines()[0].split(' ')
ts['kernel'] = float(l[3][:-1])
#ts['systemd'] = float(l[6][:-1])
ts['comma'] = get_journal_time("Starting comma.service") - tot_since_kern()
ts['kernel-to-pid1'] = get_bootsh_time("pid1 start") or 0.0
ts['comma'] = (get_bootsh_time("comma launched") or 0.0) - ts['kernel-to-pid1']
# print
tot = 0
+16 -7
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
import json
import re
import time
import subprocess
@@ -51,13 +52,21 @@ def test_dmesg():
# TODO: ensure no new errors in dmesg. would catch things like the brightness setting bug
pass
def test_systemd_services():
pass
def test_runit_services():
assert run("cat /proc/1/comm").strip() == "runit"
assert run("pgrep -a 'systemd|journald|udevd' || true").strip() == ""
out = run("sv status /run/runit/services/*")
failed = [line for line in out.splitlines() if not line.startswith("run:")]
assert failed == []
def test_boot_time():
out = subprocess.check_output("systemd-analyze", shell=True, encoding='utf8')
out = run("dmesg | grep 'boot.sh'")
marks = {}
for line in out.splitlines():
m = re.search(r"boot\.sh\[\d+\]: ([0-9.]+) (.*)", line)
if m:
marks[m.group(2)] = float(m.group(1))
a = out.splitlines()[0]
print(out, a)
# check comma service
assert "comma launched" in marks
print(marks)
+8 -12
View File
@@ -3,24 +3,20 @@ import os
import time
import subprocess
good = """
Starting Sound...
[INFO] Bringing adsp out of reset
subsys4
waiting for sound card to come online
sound card online
sound.service: Succeeded.
Finished Sound.
""".strip()
required = [
"[INFO] Bringing adsp out of reset",
"waiting for sound card to come online",
"sound card online",
]
if __name__ == "__main__":
time.sleep(3)
log = subprocess.check_output("journalctl -o cat -u sound", shell=True, encoding='utf8').strip()
passed = log == good
log = subprocess.check_output("cat /tmp/sound.log 2>/dev/null || true", shell=True, encoding='utf8').strip()
passed = all(line in log for line in required)
with open('/data/tmp/sound_log', 'a') as f:
f.write(f"{passed}\n")
os.system("journalctl -u sound.service -o short-monotonic >> /data/tmp/sound_service_log")
os.system("cat /tmp/sound.log >> /data/tmp/sound_service_log")
os.system("sudo su -c 'tail /data/tmp/sound_log > /dev/console'")
os.system("sudo su -c 'wc -l /data/tmp/sound_log > /dev/console'")
os.sync()
+3 -5
View File
@@ -5,7 +5,7 @@ RATE=${1:-1}
log_message() {
# /var/log/syslog
cat /usr/include/sqlite3.h | systemd-cat -t SPAM_TEST
cat /usr/include/sqlite3.h | logger -t SPAM_TEST
# /var/log/kern.log
#cat /usr/include/sqlite3.h | sudo tee /dev/kmsg > /dev/null
@@ -15,10 +15,8 @@ log_message() {
sudo logrotate -d /etc/logrotate.conf
sudo rm -rf /var/log/*
sudo systemctl daemon-reload
sudo systemctl restart rsyslog
sudo systemctl restart systemd-journald
sudo systemctl restart logrotate-hourly.timer
sudo sv restart /run/runit/services/rsyslog
sudo sv restart /run/runit/services/logrotate
while true; do
for i in $(seq 1 $RATE); do
-23
View File
@@ -1,23 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# See tmpfiles.d(5) for details
# /var: rebuild enough for services to be happy
d /var/crash 0755 - - -
q /var/tmp 1777 root root 30d
d /var/lib/dpkg 0755 - - -
f /var/lib/dpkg/lock-frontend 0755 - - -
f /var/lib/dpkg/status 0755 - - -
d /var/lib/logrotate 0755 - - -
d /var/spool 0755 - - -
d /var/spool/cron/atjobs 0755 - - -
d /var/cache/pollinate 0755 pollinate daemon -