# Catálogo del armador de kernel (SDD 22) — bundles de nivel 1 y perillas de nivel 2. # # UN BUNDLE NO ES UNA LISTA DE SÍMBOLOS. Es una raíz y su clausura sobre el grafo de Kconfig: # `disable = ["WIRELESS"]` son ~400 CONFIG_* que hammer calcula, no que alguien mantiene a mano. # Por eso se auto-cura: el driver wifi que entre en 6.17 cae dentro sin que nadie lo toque. # # LO QUE LA CLAUSURA NO CIERRA SOLA. `select` fuerza su destino IGNORANDO los `depends on` de éste, # así que un símbolo de fuera del bundle puede reencender lo que el bundle apagó. Cada fuga se # declara, una vez, de una de dos formas: # · `close_leaks` — se apaga también al que la provoca. # · `accept_leaks` — se deja abierta A SABIENDAS, con el motivo escrito. # `hammer kernel bundles --check` falla si aparece una fuga que no esté en ninguna de las dos: eso # es el catálogo envejeciendo, y es la mitad barata de la curación del delta entre versiones. # # CONTRADICTED_BY VA EN UN SOLO SENTIDO. Sirve para decirle al usuario «marcaste "no necesito wifi" # y tenés un AX211 activo ahora mismo». NUNCA para podar el config solo: no se puede detectar el # dock que se enchufa el mes que viene ni el fs del USB de rescate, y un kernel podado por # autodetección es cómo se fabrica un ladrillo. # # Regenerar los números / revisar las fugas: # hammer kernel bundles --kconfig <árbol> --check # hammer kernel closure --kconfig <árbol> WIRELESS --fixpoint version = 1 reviewed_against = "linux-6.16.12" # ================================================================================================= # NIVEL 1 — aserciones del dueño de la máquina. No son categorías de Kconfig: son decisiones de # vida. «No necesito wifi», «esta máquina nunca tuvo batería». # ================================================================================================= [[bundle]] id = "sin-wifi" title = "No necesito wifi" help = """ Apaga el stack 802.11 entero: cfg80211, mac80211 y todos los drivers de tarjeta. La máquina sigue teniendo ethernet. NO apaga el interruptor de radio (RFKILL): eso es «sin-radios», porque lo comparten bluetooth y NFC.""" disable = ["WIRELESS"] # WLAN no DEPENDE de WIRELESS: lo SELECCIONA. Sin cerrarlo, apagar WIRELESS es un no-op — el # olddefconfig lo reenciende y no lo dice. Fue el hallazgo que validó el diseño (SDD 22 §9). close_leaks = ["WLAN", "IWLEGACY", "GELIC_WIRELESS"] notes = "406 símbolos en 6.16.12; el bundle a mano de recipes/linux.toml da 421, y los 15 de diferencia son todos de sin-radios." [bundle.contradicted_by] pci_class = ["0280"] [[bundle]] id = "sin-bluetooth" title = "No necesito bluetooth" disable = ["BT"] # Tarjeta combo wifi+BT: entra por select desde el lado wifi. close_leaks = ["RSI_91X"] [bundle.contradicted_by] driver = ["btusb", "btintel", "btrtl"] [[bundle]] id = "sin-nfc" title = "No necesito NFC" disable = ["NFC"] [[bundle]] id = "sin-radios" title = "No necesito el interruptor de radio (rfkill)" help = """ RFKILL es el conmutador compartido de todas las radios: wifi, bluetooth y NFC lo declaran igual. Apagarlo sólo tiene sentido si ninguna de las tres se usa — y se lleva por delante los botones de radio de portátil (Dell, Lenovo, MSI…), que dependen de él.""" disable = ["RFKILL"] notes = "Es un bundle propio, no parte de sin-wifi: el config a mano de linux.toml los escribía en la misma línea y por eso parecían uno solo." [[bundle]] id = "sin-audio" title = "No necesito audio" help = "Apaga ALSA y todo el stack de sonido, incluido el códec HDMI." disable = ["SOUND"] notes = """ No cierra: los drivers de GPU hacen `select` de los helpers de audio HDMI. Cerrarlo obligaría a apagar la GPU, que es un precio que un escritorio no puede pagar — así que las fugas se aceptan y quedan escritas. En recipes/linux.toml sale gratis sólo porque ahí los gráficos TAMBIÉN están apagados.""" [bundle.accept_leaks] SND_HDA_COMPONENT = "lo selecciona DRM_AMD_DC / DRM_NOUVEAU / DRM_RADEON: cerrarlo = quedarse sin GPU" SND_HDA_I915 = "lo seleccionan DRM_I915 y DRM_XE: ídem para gráficos Intel" SND_SOC_HDMI_CODEC = "lo seleccionan diez drivers DRM (casi todos SoC ARM, inertes en x86_64)" SND_AUDIO_GRAPH_CARD = "DRM_TEGRA, inerte en x86_64" SND_SIMPLE_CARD = "DRM_TEGRA, inerte en x86_64" SND_UMP = "USB_F_MIDI2, gadget USB: sólo entra si la máquina hace de dispositivo USB" SND_UMP_LEGACY_RAWMIDI = "USB_F_MIDI2, ídem" [bundle.contradicted_by] pci_class = ["0403"] driver = ["snd_hda_intel"] [[bundle]] id = "sin-graficos" title = "No necesito salida gráfica" help = """ Kernel de servidor o de consola serie: sin DRM, sin framebuffer, sin retroiluminación. Si esta máquina tiene pantalla, este bundle la deja negra — es la aserción más peligrosa del catálogo.""" disable = ["DRM", "FB", "AGP", "BACKLIGHT_CLASS_DEVICE"] # Framebuffers de PowerMac y de SoC ARM: no existen en x86_64, cerrarlos no cuesta nada. close_leaks = [ "FB_CONTROL", "FB_IMSTT", "FB_MAC", "FB_PLATINUM", "FB_VALKYRIE", "FB_VT8500", "FB_WM8505", "PMAC_BACKLIGHT", ] [bundle.accept_leaks] DRM_AUX_BRIDGE = "lo seleccionan los muxes USB-C (TYPEC_MUX_*): apagarlos rompería el USB-C de un portátil real" DRM_AUX_HPD_BRIDGE = "ídem, TYPEC_QCOM_PMIC / UCSI_HUAWEI_GAOKUN" BACKLIGHT_CLASS_DEVICE = "lo seleccionan drivers de plataforma (ACPI_CMPC, SAMSUNG_Q10, USB_APPLEDISPLAY)" DRM_DW_HDMI_I2S_AUDIO = "SND_SOC_RK3288_HDMI_ANALOG, SoC Rockchip: inerte en x86_64" FB_SYSMEM_HELPERS_DEFERRED = "lo selecciona HID_PICOLCD_FB, una pantallita USB que es un dispositivo HID: decir «no quiero salida gráfica» no debe apagar un HID" [bundle.contradicted_by] pci_class = ["0300", "0380"] [[bundle]] id = "solo-ext4" title = "Sólo uso ext4" help = "Apaga los demás sistemas de ficheros locales. Ojo con el USB de rescate: lo que no está no se monta." disable = ["XFS_FS", "BTRFS_FS", "F2FS_FS", "JFS_FS", "GFS2_FS", "NTFS3_FS"] close_leaks = ["NTFS_FS"] notes = "REISERFS_FS NO va acá: upstream lo retiró y 6.16.12 ya no lo tiene. Las cuatro recetas lo apagaban en vano hasta `2602218`, que quitó el flag." [[bundle]] id = "sin-usb" title = "No necesito USB" help = "Kernel de VM con consola serie o de servidor sin puertos accesibles. En metal deja la máquina sin teclado." disable = ["USB_SUPPORT"] [bundle.contradicted_by] driver = ["usbhid", "usb_storage", "xhci_hcd"] [[bundle]] id = "sin-entrada-humana" title = "No necesito teclado ni ratón" help = """ La aserción de un kernel de QEMU con consola serie: nadie va a tocar esta máquina. Es exactamente lo que hace recipes/linux.toml, y por eso el gate de no-regresión tiene que ser POR OBJETIVO — un gate global rechazaría esa receta, que está sana.""" disable = ["HID_SUPPORT", "INPUT_MOUSE", "INPUT_JOYSTICK", "INPUT_TABLET", "INPUT_TOUCHSCREEN"] [bundle.contradicted_by] driver = ["usbhid", "hid_generic", "i8042"] [[bundle]] id = "sin-camaras-tv" title = "No necesito cámara ni sintonizador" disable = ["MEDIA_SUPPORT"] close_leaks = ["USB_F_UVC"] [bundle.accept_leaks] VIDEOBUF2_VMALLOC = "lo seleccionan pantallas táctiles (RMI4_F54, TOUCHSCREEN_ATMEL_MXT_T37) para sus modos de diagnóstico: decir «no quiero cámara» no debe matar el táctil" [bundle.contradicted_by] driver = ["uvcvideo"] [[bundle]] id = "sin-infiniband" title = "No necesito InfiniBand / RDMA" disable = ["INFINIBAND"] [[bundle]] id = "sin-bus-industrial" title = "No necesito buses industriales (CAN)" disable = ["CAN"] [[bundle]] id = "sin-thunderbolt-firewire" title = "No necesito Thunderbolt ni FireWire" help = "El símbolo se llama USB4 desde que upstream fundió Thunderbolt y USB4 en un solo driver." disable = ["USB4", "FIREWIRE"] notes = """ Hasta el 2026-08-10 las cuatro recetas de kernel apagaban `THUNDERBOLT`, que 6.16.12 ya no tiene, y ese `-d` era un no-op silencioso. Corregido a `USB4` en `2602218`, que lo convierte en un guardián de verdad: si mañana la base o un `select` lo encienden, ahora sí lo apaga.""" [bundle.accept_leaks] DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG = "lo selecciona DRM_I915_DEBUG: es una perilla de depuración del driver gráfico, no hardware Thunderbolt" [bundle.contradicted_by] driver = ["thunderbolt"] [[bundle]] id = "sin-lector-de-tarjetas" title = "No necesito lector de tarjetas SD/MMC" disable = ["MMC", "MEMSTICK"] [bundle.contradicted_by] driver = ["sdhci_pci", "rtsx_pci_sdmmc"] [[bundle]] id = "sin-gpu-intel" title = "No tengo gráficos Intel" help = """ `DRM_I915` es de los drivers más grandes del kernel y sólo sirve en hardware Intel. Una VM con virtio-gpu, una máquina AMD o un servidor sin pantalla no lo usan nunca. NO apaga DRM: la salida de vídeo sigue por simpledrm/EFI o por virtio-gpu.""" disable = ["DRM_I915"] [bundle.contradicted_by] driver = ["i915"] [[bundle]] id = "sin-virtualizacion" title = "No voy a virtualizar en esta máquina" help = "Apaga KVM. No afecta a correr DENTRO de una VM — sólo a hospedar una." disable = ["VIRTUALIZATION"] [bundle.contradicted_by] cpu_flag = ["vmx", "svm"] # ================================================================================================= # NIVEL 2 — política y rendimiento. El campo `side` NO es decorativo: la mitad de N2 no es Kconfig # sino variables de receta. Las dos mitades mueven el ArtifactHash igual, pero se aplican en fases # distintas y fallan distinto; una UI que no lo sepa prometerá diffs que no puede explicar. # ================================================================================================= [[knob]] id = "jaula-y-eio-moderna" title = "Jaula (Landlock + audit) y E/S moderna (io_uring, BPF)" help = """ El contrato de PLAN-KIKIN §4.bis. Sin SECURITY_LANDLOCK+AUDIT, harkaq (SDD 16) certifica TODO como hermético en silencio: sin auditoría no se emite un solo registro de denegación, y la evidencia negativa se vuelve vacía.""" side = "kconfig" enable = ["SECURITY_LANDLOCK", "AUDIT", "IO_URING", "BPF_SYSCALL"] notes = "linux-metal y linux-generic ya los declaran; linux (el de QEMU) deja IO_URING y BPF_SYSCALL al defconfig." [[knob]] id = "sin-info-de-depuracion" title = "Kernel sin información de depuración" help = "Baja mucho el tamaño de la imagen. DEBUG_INFO_BTF además exige pahole, que el toolchain de hammer no trae." side = "kconfig" disable = ["DEBUG_INFO", "DEBUG_INFO_BTF"] [[knob]] id = "unwinder-frame-pointer" title = "Desenrollado por frame pointer en vez de ORC" help = """ Reduce el trabajo de objtool, pero NO lo elimina: en x86_64 las mitigaciones (retpoline, RETHUNK) seleccionan CONFIG_OBJTOOL igual, y objtool necesita libelf.""" side = "kconfig" enable = ["UNWINDER_FRAME_POINTER"] disable = ["UNWINDER_ORC"] [[knob]] id = "preempcion-escritorio" title = "Preempción de escritorio (menos latencia, algo menos de rendimiento bruto)" side = "kconfig" enable = ["PREEMPT"] [[knob]] id = "tick-1000" title = "Reloj del sistema a 1000 Hz" side = "kconfig" enable = ["HZ_1000"] disable = ["HZ_250"] [[knob]] id = "compilador-lto" title = "LTO (optimización al enlazar)" help = """ EL EJEMPLO DE PERILLA MIXTA. Su mitad Kconfig (LTO_CLANG_FULL) sólo se vuelve seleccionable si el kernel se compila con clang, que es una decisión de RECETA. Hoy recipes/linux.toml compila con gcc por decisión formal (la capa de traducción de flags de `zig cc` choca con el kbuild de x86_64), así que esta perilla está declarada y NO es aplicable todavía.""" side = "recipe" recipe_field = "build.compiler + build.phases.compile (make LLVM=1)" notes = "Ver la cabecera de recipes/linux.toml: el kernel se queda en el gueto gcc hasta que se exponga el clang que zig empaqueta." [[knob]] id = "invitado-virtio" title = "Invitado de VM: los virtio que el defconfig deja fuera" help = """ `VIRTIO_BALLOON` (que el anfitrión pueda recuperar RAM) y `HW_RANDOM_VIRTIO` (entropía del anfitrión) no vienen en el defconfig y ninguna receta de kernel del repo los enciende. En gioser los dos están BINDEADOS ahora mismo: un kernel sin ellos arranca, pero la VM pierde el globo de memoria y la fuente de entropía. Es justo la clase de pérdida silenciosa que el gate existe para ver.""" side = "kconfig" enable = ["VIRTIO_BALLOON", "HW_RANDOM_VIRTIO", "VIRTIO_CONSOLE", "SCSI_VIRTIO"] [[knob]] id = "plataforma-pc" title = "Chipset de PC: errores PCIe, puente LPC, watchdog y bocina" help = """ Cosas que cualquier distro trae encendidas y que el defconfig y `linux-metal` dejan fuera: `PCIEAER` (reporte avanzado de errores PCIe), `LPC_ICH` (puente LPC de Intel), `INPUT_PCSPKR` y el watchdog `ITCO_WDT`. En gioser los cuatro están BINDEADOS ahora mismo. El watchdog necesita además `WATCHDOG`, que `linux-metal` apaga a propósito — por eso va acá y no en la receta base: en una máquina sin acceso físico, un watchdog es lo que la reinicia cuando se cuelga.""" side = "kconfig" enable = ["PCIEAER", "LPC_ICH", "INPUT_PCSPKR", "WATCHDOG", "ITCO_WDT"] [[knob]] id = "march-nativo" title = "Compilar para esta CPU exacta" help = "Mata la reproducibilidad ENTRE máquinas distintas, no la de una misma máquina: el artefacto sigue siendo bit a bit el mismo para la misma huella." side = "recipe" recipe_field = "build.flags" [[knob]] id = "debug-aparte" title = "Separar los símbolos de depuración del artefacto" side = "recipe" recipe_field = "build.strip_debug" notes = "SDD 23. Entra en hash_inputs sólo si está fijado, así que se puede activar receta a receta." # ================================================================================================= # OBJETIVOS — para qué es este kernel. EL GATE DE NO-REGRESIÓN NO CORRE SIN UNO. # # La regla del gate es «todo dispositivo en uso debe seguir teniendo driver». Aplicada global, # rechazaría recipes/linux.toml, que apaga USB, HID e INPUT A PROPÓSITO por ser el kernel de QEMU # con consola serie. El objetivo declara qué pérdidas son legítimas para este uso; todo lo demás # bloquea. El portón se queda — sólo que en el sitio correcto. # ================================================================================================= [[objective]] id = "qemu-serial" title = "VM con consola serie" help = """ Nadie va a tocar esta máquina: entra por ttyS0 y sale por ttyS0. Es exactamente lo que hace recipes/linux.toml, y es una receta sana.""" allow_bundles = [ "sin-wifi", "sin-bluetooth", "sin-nfc", "sin-radios", "sin-audio", "sin-graficos", "sin-usb", "sin-entrada-humana", "sin-camaras-tv", "sin-infiniband", "sin-bus-industrial", "sin-thunderbolt-firewire", "sin-lector-de-tarjetas", "solo-ext4", ] [[objective]] id = "servidor" title = "Servidor sin pantalla" help = """ Sin monitor ni sonido, pero CON teclado y USB: alguien va a enchufar un rescate el día que la red falle. Ésa es justo la clase de pérdida que el gate existe para no dejar pasar en silencio.""" allow_bundles = [ "sin-audio", "sin-graficos", "sin-camaras-tv", "sin-bluetooth", "sin-nfc", "sin-lector-de-tarjetas", "sin-thunderbolt-firewire", "sin-bus-industrial", ] [[objective]] id = "metal-escritorio" title = "Escritorio en metal" help = """ El objetivo más estricto del catálogo, y a propósito: en un escritorio casi nada de lo que hoy funciona puede desaparecer sin que el dueño se entere. Sólo se autoriza lo que un escritorio demostrablemente no usa.""" allow_bundles = ["sin-infiniband", "sin-bus-industrial"] [[objective]] id = "portatil" title = "Portátil" help = "Como el escritorio pero además con radios y lector de tarjetas: en un portátil eso se usa." allow_bundles = ["sin-infiniband", "sin-bus-industrial", "sin-nfc"]