# Linux kernel UAPI headers 6.16.12 — tercera pieza del toolchain takana-from-source (SDD 11 §7.2b). # # Tras make (pieza 1) y busybox (pieza 2), reemplazamos los headers del kernel que hoy el builder # toma del paquete `linux-headers` de Alpine (`/toolchain/usr/include/{linux,asm,asm-generic,…}`). # musl y busybox los `#include` al compilar (syscalls, ioctls, structs UAPI), así que son parte real # del toolchain, no mero relleno. # # Versión clavada a la del toolchain Alpine actual: `usr/include/linux/version.h` declara 6.16.12 # (LINUX_VERSION_CODE 397324). Construir la MISMA versión es lo que mantiene musl/busybox bit-a-bit: # un header distinto (un struct/constante que cambió entre versiones) cambiaría el binario resultante. # # A diferencia de make/busybox esto NO es un binario: `make headers_install` no compila nada del # kernel, sólo pasa los headers UAPI por `unifdef` (un toolito host que el propio target construye con # HOSTCC) y los copia saneados a INSTALL_HDR_PATH. El árbol resultante (`usr/include/*/`) se sella y # el swap-directorio del builder (variante b) lo monta sobre los de Alpine. # # Tarball .tar.gz (no .xz): `tar` lo autodetecta por cabecera y el busybox-tar de adentro descomprime # gzip nativo, sin depender de un `xz` en el rootfs del Stage 1. El sha256 clava el contenido (ADR 0006). name = "linux-headers" version = "6.16.12" license = "GPL-2.0-only WITH Linux-syscall-note" [source] tarball = "https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.16.12.tar.gz" sha256 = "ffc6af80b014ddebd55e116aa29a9f7a5256c87a29a8a9dd97270b6d49625109" # Overlay de compatibilidad con el paquete linux-headers de Alpine (ADR 0006: contenido clavado en el # patch, hasheado al artefacto). El paquete de Alpine NO es el `make headers` crudo: trae 5 archivos # que difieren de la salida vainilla y que cualquier consumidor userspace (aquí, busybox) necesita # byte-a-byte para reproducir. El patch los CREA bajo `alpine-overlay/` (no toca el árbol del kernel); # el `install` los pisa sobre /out tras `make headers`. Por qué overlay y no patch-al-source: `make # headers` corre unifdef (renombra los guards `_UAPI…`, borra `__force`/`#ifndef __KERNEL__`), así que # parchear el source daría una salida distinta a la de Alpine; pisar la salida final garantiza igualdad. # • linux/kernel.h — Alpine envuelve `#include ` en `#ifdef __GLIBC__` (musl ya # define `struct sysinfo`). Cosmético aquí (nadie del 4/4 lo incluye), pero lo # igualamos para que `diff -r` contra Alpine quede limpio. # • linux/if_tunnel.h — Alpine quita 3 `#include ` (chocan con musl). Cosmético. # • scsi/{scsi,scsi_ioctl,sg}.h — REQUERIDOS: el applet `eject` de busybox hace `#include ` # y ``. NO son UAPI (no salen de `make headers`); los del kernel en # `include/scsi/` son `__KERNEL__`-only (no compilan en userspace). Alpine trae # versiones legacy userspace-limpias; sin ellas busybox no compila ⇒ divergiría. patches = ["linux-headers-alpine-compat.patch"] [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" [deps] build = ["make"] [build.phases] # El árbol del kernel detecta como BuildSys::Make ⇒ el default de compile sería `make -j$(nproc)`, # que construiría el kernel ENTERO. No queremos eso: los headers no necesitan compilarse ni config. # Override a no-op; todo el trabajo va en `install`. compile = "true" # El target `headers` (NO `headers_install`) construye `scripts/unifdef` con HOSTCC (zig cc) y satura # los headers UAPI por unifdef hacia `./usr/include` (las líneas `HDRINST …`). Evitamos # `headers_install` a propósito: su paso final hace un `rsync` de `usr/include` → INSTALL_HDR_PATH, y # rsync NO está en el toolchain hermético (ADR 0003) — `headers_install` aborta con "rsync: not found". # En su lugar copiamos el árbol ya saturado con `cp -a` (determinista: of_tree ignora timestamps y # write-bit, los headers son 0644 sin exec). ARCH=x86 produce los `asm/` de x86_64. Sella # `usr/include/{linux,asm,asm-generic,cxl,fwctl,misc,mtd,rdma,regulator,scsi,sound,video,xen}`, # exactamente los subdirs que el paquete linux-headers de Alpine posee. # 1) `make headers` satura los UAPI en ./usr/include. 2) copiamos a /out. 3) limpiamos lo que el # rsync de `headers_install` filtra y que `cp -a` arrastró: los `.*.cmd` de kbuild, el Makefile y # headers_check.pl del propio árbol, y drm/ (Alpine no lo empaqueta). 4) pisamos el overlay de Alpine # (los 5 archivos del patch) para casar byte-a-byte. Resultado: `diff -r` contra Alpine = vacío. install = ''' make ARCH=x86 HOSTCC='zig cc -mcpu=baseline' headers && \ mkdir -p /out/usr && cp -a usr/include /out/usr/ && \ find /out/usr/include -name '.*.cmd' -delete && \ rm -f /out/usr/include/Makefile /out/usr/include/headers_check.pl && \ rm -rf /out/usr/include/drm && \ cp -a alpine-overlay/. /out/usr/include/ '''