build: an apk-managed root, with SchOS as a package

make aroot builds a SchFS root from Alpine's minirootfs, the packages
ports/alpine/world lists, and SchOS itself as the signed apk package
schos-base, in its own repository inside the root. apk add installs from
Alpine; apk upgrade updates both. Booted: zsh is Alpine's, apk update
sees 28669 packages, apk add htop works, and so does xorg-server.

world.lock pins every package with its sha256; a build fetches only what
dist/alpine/ lacks and never looks for newer versions. make alpine-lock
is the one step that does.

Alpine's zsh, busybox commands and hwdata replace SchOS's copies; SchOS
keeps its own tools, toybox's other commands, and static mksh, which
schinit's recovery shell now tries first.

Also: the dependency-file include matched Alpine's usr/lib/sysctl.d, a
directory, and stopped every make. See docs/plan/alpine.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 15:28:32 +02:00
commit 406cff2ec0
9 changed files with 473 additions and 1 deletions

View file

@ -1555,6 +1555,52 @@ $(BUILD)/schfs.img: $(MKSCHFS) $(BUILD)/sysroot.stamp
@rm -f $@
./$(MKSCHFS) $@ --size $(SCHFS_BLOCKS) --label schos --sysroot $(SYSROOT)
# --- The apk-managed root ------------------------------------------------------
#
# Alpine's minirootfs, the packages ports/alpine/world names, and SchOS as the
# apk package schos-base -- a root that `apk add` and `apk upgrade` manage.
# See tools/posix/mkaroot.sh for what goes where and why.
#
# make aroot build/aroot.img, a SchFS root volume of AROOT_BLOCKS
# make qemu-aroot boot it as the root disk (the disk-root kernel)
# make alpine-lock re-resolve ports/alpine/world against Alpine's mirror;
# the one step that looks for newer packages
#
# The build itself is offline once dist/ has the files world.lock names.
AROOT_BLOCKS ?= 262144
AROOT_DIR = $(BUILD)/aroot
AROOT_KEYS = $(BUILD)/apk-keys
APK_STATIC = $(BUILD)/ports/alpine/apk.static
ALPINE_MINI = dist/alpine-minirootfs-3.24.3-x86_64.tar.gz
SCHOS_PKGVER ?= 0.1_git$(shell git log -1 --format=%cd --date=format:%Y%m%d%H%M 2>/dev/null || echo 0)-r0
alpine-port:
$(MAKE) -C ports/alpine install
alpine-lock:
$(MAKE) -C ports/alpine lock
$(AROOT_DIR)/stamp: $(BUILD)/sysroot.stamp ports/alpine/world.lock tools/posix/mkaroot.sh | alpine-port
sh tools/posix/mkaroot.sh $(SYSROOT) $(AROOT_DIR) $(APK_STATIC) $(ALPINE_MINI) \
$(AROOT_KEYS) $(SCHOS_PKGVER) ports/alpine/world.lock dist/alpine
touch $@
$(BUILD)/aroot.img: $(MKSCHFS) $(AROOT_DIR)/stamp
@rm -f $@
./$(MKSCHFS) $@ --size $(AROOT_BLOCKS) --label schos --sysroot $(AROOT_DIR)/root
aroot: $(BUILD)/aroot.img
qemu-aroot: esp $(BUILD)/aroot.img $(OVMF_CODE) $(OVMF_VARS)
$(QEMU) -machine pc-i440fx-9.2 \
-drive if=pflash,format=raw,unit=0,readonly=on,file=$(OVMF_CODE) \
-drive if=pflash,format=raw,unit=1,file=$(OVMF_VARS) \
-drive file=fat:rw:$(BUILD)/esp,index=0,media=disk,format=raw \
-drive file=$(BUILD)/aroot.img,format=raw,index=1,media=disk \
-m 2G -smp 2 $(QEMU_ACCEL) -serial mon:stdio $(QEMU_DISPLAY) $(QEMU_INPUT) $(QEMU_NET) $(QEMU_AUDIO)
.PHONY: alpine-port alpine-lock aroot qemu-aroot
# Boot with a SchFS volume attached as the second disk.
#
# Needs the ramdisk-root kernel ("make ramroot" first): with RAMROOT the root
@ -1673,4 +1719,7 @@ distclean: clean
# Everything under arch/ and schfs/ therefore had NO header dependency
# tracking at all -- editing include/fs/schfs.h or include/arch/mmu.h left stale
# objects that linked without complaint. find actually recurses.
-include $(shell find $(BUILD) -name '*.d' 2>/dev/null)
# Files only, and not under the trees that are root filesystems rather than
# build output: Alpine's usr/lib/sysctl.d is a directory, and including it
# stopped every make with "Is a directory".
-include $(shell find $(BUILD) \( -path $(BUILD)/aroot -o -path $(BUILD)/iso -o -path $(BUILD)/ports \) -prune -o -type f -name '*.d' -print 2>/dev/null)