ASELSANMicrokernel
S143 · SOURCE-BOUND GATE EVIDENCE

K1/MEM0–MEM2/K2: reply-derived broker ACK ve otomatik session close

Operations --test hedefi → focused test içindeki include_str!/#[path] bağı → kaynak kesiti Bu sayfa yalnız S143 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.

S143Focused kod testiOperations id exactsource SHA exacttest target exact

operation: k1-mem0-mem1-mem2-k2-reply-derived-broker-commit-partial

uygulama/model · focused test · Operations · 3 exact excerpt

sequence-bound=true · implementation-bound=true
01 · Testin bağlı olduğu uygulama/model kodu

Kapının yürüttüğü gerçek kaynak

tam dosyaL1–L6159
Makefile::Makefile
# ASELSAN OS - Makefile
# M8.1 — Board destekli build (QEMU + Raspberry Pi 4 + Raspberry Pi 5)

export PATH := $(HOME)/.cargo/bin:$(PATH)

BOARD ?= qemu
KERNEL_DIR := kernel
CARGO := cargo
QEMU ?= qemu-system-aarch64
TARGET := aarch64-unknown-none
BOARD_TARGET_DIR := target/$(BOARD)
KERNEL_TARGET_DIR := ../$(BOARD_TARGET_DIR)
ELF := $(BOARD_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI4_ELF := target/rpi4/$(TARGET)/debug/aselsan_kernel
RPI5_ELF := target/rpi5/$(TARGET)/debug/aselsan_kernel
RPI5_IMG := build/rpi5/aselsanos-rpi5.img
RPI5_SUMS := build/rpi5/SHA256SUMS
RPI5_SCREEN_TARGET_DIR := target/rpi5-screen
RPI5_SCREEN_ELF := $(RPI5_SCREEN_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_SCREEN_DIR := build/rpi5-screen
RPI5_SCREEN_IMG := $(RPI5_SCREEN_DIR)/aselsanos-rpi5-screen.img
RPI5_SCREEN_SUMS := $(RPI5_SCREEN_DIR)/SHA256SUMS
RPI5_TOUCH_TARGET_DIR := target/rpi5-touch
RPI5_TOUCH_ELF := $(RPI5_TOUCH_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_TOUCH_DIR := build/rpi5-touch
RPI5_TOUCH_IMG := $(RPI5_TOUCH_DIR)/aselsanos-rpi5-touch.img
RPI5_TOUCH_SUMS := $(RPI5_TOUCH_DIR)/SHA256SUMS
RPI5_TOUCH_PROFILE := firmware/rpi5-touch-profile.txt
RPI5_UI_SERVER_TARGET_DIR := target/rpi5-ui-server
RPI5_UI_SERVER_ELF := $(RPI5_UI_SERVER_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_UI_SERVER_DIR := build/rpi5-ui-server
RPI5_UI_SERVER_IMG := $(RPI5_UI_SERVER_DIR)/aselsanos-rpi5-ui-server.img
RPI5_UI_SERVER_SUMS := $(RPI5_UI_SERVER_DIR)/SHA256SUMS
RPI5_IOS_HOME_TARGET_DIR := target/rpi5-ios-home
RPI5_IOS_HOME_ELF := $(RPI5_IOS_HOME_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_IOS_HOME_DIR := build/rpi5-ios-home
RPI5_IOS_HOME_IMG := $(RPI5_IOS_HOME_DIR)/aselsanos-rpi5-ios-home.img
RPI5_IOS_HOME_SUMS := $(RPI5_IOS_HOME_DIR)/SHA256SUMS
RPI5_IOS_HOME_PROFILE := firmware/rpi5-ios-home-profile.txt
A21_SCREEN_PACKAGE := evidence/rpi5/screen/attempt-21-compose-home-candidate-freeze
A22_UI_SERVER_PACKAGE := evidence/rpi5/screen/attempt-22-ui-server-live-frame-candidate-freeze
A23_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-23-ios-home-pager-candidate-freeze
A24_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-24-ios-home-pager-candidate-freeze
A26_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-26-ios-home-settings-candidate-freeze
A27_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-27-ios-home-settings-candidate-freeze
A28_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-28-ios-home-settings-candidate-freeze
A29_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-29-ios-home-control-center-candidate-freeze
A30_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-30-control-center-rebuild-candidate-freeze
A31_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-31-clock-before-mmu-candidate-freeze
A32_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-32-present-60hz-candidate-freeze
A33_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-33-scanout-dirty-present-candidate-freeze
A34_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-34-page-swipe-exits-edit-candidate-freeze
A35_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-35-tap-slop-release-watchdog-candidate-freeze
A36_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-36-icon-drop-not-page-swipe-candidate-freeze
A37_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-37-drag-sprite-not-full-paint-candidate-freeze
A38_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-38-tap-after-drop-opens-candidate-freeze
A39_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-39-carry-never-recomposes-candidate-freeze
A40_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-40-cell-preview-follows-the-finger-candidate-freeze
A41_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-41-outline-stamped-once-candidate-freeze
A42_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-42-double-buffered-scanout-candidate-freeze
A43_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-43-flip-retired-at-the-latching-boundary-candidate-freeze
A44_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-44-an-unexpected-contact-is-data-candidate-freeze
A45_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-45-aselbrowser-is-in-the-image-candidate-freeze
A46_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-46-browser-reference-layout-candidate-freeze
A47_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-47-device-found-defects-closed-candidate-freeze
A48_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-48-page-shell-and-proportional-body-candidate-freeze
A49_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-49-honest-refusal-and-locked-cadence-candidate-freeze
A50_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-50-one-model-for-every-transition-candidate-freeze
A51_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-51-measure-the-phases-not-guess-them-candidate-freeze
A52_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-52-drawing-is-the-cost-and-a-swipe-must-not-exit-candidate-freeze
A53_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-53-do-not-compose-what-did-not-change-candidate-freeze
A54_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-54-a-frozen-screen-and-a-stack-gauge-candidate-freeze
A55_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-55-read-the-stack-do-not-write-it-candidate-freeze
A56_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-56-the-caret-goes-where-you-tap-candidate-freeze
A57_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-57-a-text-field-behaviour-contract-candidate-freeze
A58_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-58-the-shortcut-strip-slides-candidate-freeze
A59_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-59-an-app-switcher-that-costs-no-ram-candidate-freeze
A60_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-60-turkish-letters-and-a-back-button-that-does-nothing-candidate-freeze
A61_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-61-a-key-balloon-and-a-gesture-you-can-measure-candidate-freeze
A62_IOS_HOME_PACKAGE := evidence/rpi5/screen/attempt-62-a-settings-list-that-matches-the-reference-candidate-freeze
# Sensor zinciri: kendi build dizini.  Uc sayfa haritalar; yalnizca RNG yazar.
RPI5_SENSOR_TARGET_DIR := target/rpi5-sensors
RPI5_SENSOR_ELF := $(RPI5_SENSOR_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_SENSOR_DIR := build/rpi5-sensors
RPI5_SENSOR_IMG := $(RPI5_SENSOR_DIR)/aselsanos-rpi5-sensors.img
RPI5_SENSOR_PROFILE := firmware/rpi5-sensor-profile.txt

# Radyo zinciri: kendi build dizini.  Ekran ve SD zincirlerinden ayridir,
# cunku bu imaj UC sayfa haritalar ve ikisine YAZAR.
RPI5_RADIO_TARGET_DIR := target/rpi5-radio
RPI5_RADIO_ELF := $(RPI5_RADIO_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_RADIO_DIR := build/rpi5-radio
RPI5_RADIO_IMG := $(RPI5_RADIO_DIR)/aselsanos-rpi5-radio.img
RPI5_RADIO_PROFILE := firmware/rpi5-radio-profile.txt
RPI5_RADIO_FEATURES ?= board-rpi5,rpi5-radio-inventory
RPI5_RADIO_SCAN ?= 0

# SD kart zinciri: ekran zincirinden ayri kanit koku ve ayri build dizini.
RPI5_SD_TARGET_DIR := target/rpi5-sd
RPI5_SD_ELF := $(RPI5_SD_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_SD_DIR := build/rpi5-sd
RPI5_SD_IMG := $(RPI5_SD_DIR)/aselsanos-rpi5-sd.img
SDA0_PACKAGE := evidence/rpi5/sdcard/attempt-sda0-inventory-candidate-freeze
SDA1_PACKAGE := evidence/rpi5/sdcard/attempt-sda1-first-read-candidate-freeze
SDB_PACKAGE := evidence/rpi5/sdcard/attempt-sdb-fat32-lookup-candidate-freeze
SDB2_PACKAGE := evidence/rpi5/sdcard/attempt-sdb2-fat32-run-map-candidate-freeze
SDCW0_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w0-aselrec1-candidate-freeze
SDCW1_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w1-ownership-candidate-freeze
SDCW2_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w2-response-candidate-freeze
SDCW3_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w3-first-write-candidate-freeze
SDCW3B_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w3b-first-write-candidate-freeze
SDCW4_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w4-superblock-candidate-freeze
SDCW5_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w5-bulk-timing-candidate-freeze
SDCW6_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w6-cmd25-candidate-freeze
SDCW7_PACKAGE := evidence/rpi5/sdcard/attempt-sdc-w7-one-frame-candidate-freeze
RPI5_DTB := firmware/bcm2712-rpi-5-b.dtb
RPI5_CONFIG := firmware/config.txt
RPI5_PACKAGE_DTB := build/rpi5/bcm2712-rpi-5-b.dtb
RPI5_PACKAGE_CONFIG := build/rpi5/config.txt
RPI5_ENTRY := 0x80000
RPI_FIRMWARE_REV := 3d301dd924bcd758a4c8cb19fe8531031f033f43
RPI5_DTB_SHA256 := 40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00
RPI5_G8G_FIXTURE := simulation/tests/fixtures/rpi5_g8g_uart_suffix.log
RPI5_G8G_FIXTURE_SHA256 := 9996bfc9e620e50be5ac288b103a488a60a1c2df940f2b80c0cdb69f2813ab7d
RPI5_G8G_FIXTURE_BYTES := 1734
RPI5_G8G_STAGED_PACKAGE := evidence/rpi5/g8g/sequence-89-package-staged/package
RPI5_G8H_STAGED_ROOT := evidence/rpi5/g8h/sequence-100-package-staged
RPI5_G8H_STAGED_PACKAGE := $(RPI5_G8H_STAGED_ROOT)/package
SD_MOUNT ?= /Volumes/ASELSANBOOT
# Bilinçli olarak boş: yanlış /dev/diskN varsayılanı veri kaybına yol açabilir.
SD_DISK ?=

ifeq ($(BOARD),rpi5)
    FEATURES := --no-default-features --features board-rpi5
    BUILD_MSG := ">>> ASELSAN Kernel derleniyor (Raspberry Pi 5 - BCM2712)..."
else ifeq ($(BOARD),rpi4)
    FEATURES := --no-default-features --features board-rpi4
    BUILD_MSG := ">>> ASELSAN Kernel derleniyor (Raspberry Pi 4 - BCM2711)..."
else
    FEATURES :=
    BUILD_MSG := ">>> ASELSAN Kernel derleniyor (QEMU virt)..."
endif

.PHONY: all kernel kernel-rpi4 kernel-rpi5 userspace-binaries \
        userspace-hello userspace-ipc-demo userspace-ipc-responder \
        userspace-ipc-caller userspace-oom-supervisor \
        userspace-oom-timer-supervisor userspace-oom-batch-supervisor \
        userspace-oom-crash-supervisor userspace-oom-recovery-supervisor \
        userspace-oom-lifecycle-crash-supervisor userspace-oom-lifecycle-recovery-supervisor \
        userspace-oom-fault-supervisor userspace-oom-fault-recovery-supervisor \
        userspace-oom-reply-bridge-supervisor \
        userspace-ipc-timeout-caller userspace-ipc-timeout-responder \
        userspace-ipc-recv-timeout-receiver userspace-ipc-recv-late-caller \
        userspace-notification-waiter userspace-notification-signaler \
        userspace-notification-revoked-waiter userspace-notification-race-waiter \
        image-rpi4 image-rpi5 image-rpi5-screen image-rpi5-touch image-rpi5-ui-server image-rpi5-ios-home flash-rpi5-screen flash-rpi5-ui-server flash-rpi5-path-b flash-rpi5-ios-home \
        verify-rpi5-screen-attempt-07-candidate-freeze \
        freeze-rpi5-screen-attempt-07 \
        verify-rpi5-screen-attempt-08-candidate-freeze \
        freeze-rpi5-screen-attempt-08 \
        verify-rpi5-screen-attempt-09-candidate-freeze \
        freeze-rpi5-screen-attempt-09 \
        verify-rpi5-screen-attempt-10-candidate-freeze \
        freeze-rpi5-screen-attempt-10 \
        verify-rpi5-screen-attempt-11-candidate-freeze \
        freeze-rpi5-screen-attempt-11 \
        verify-rpi5-screen-attempt-12-candidate-freeze \
        freeze-rpi5-screen-attempt-12 \
        verify-rpi5-screen-attempt-13-candidate-freeze \
        freeze-rpi5-screen-attempt-13 \
        verify-rpi5-screen-attempt-14-candidate-freeze \
        freeze-rpi5-screen-attempt-14 \
        verify-rpi5-screen-attempt-15-candidate-freeze \
        freeze-rpi5-screen-attempt-15 \
        verify-rpi5-screen-attempt-16-candidate-freeze \
        freeze-rpi5-screen-attempt-16 \
        verify-rpi5-screen-attempt-17-candidate-freeze \
        freeze-rpi5-screen-attempt-17 \
        verify-rpi5-screen-attempt-18-candidate-freeze \
        freeze-rpi5-screen-attempt-18 \
        verify-rpi5-screen-attempt-19-candidate-freeze \
        freeze-rpi5-screen-attempt-19 \
        verify-rpi5-screen-attempt-20-candidate-freeze \
        freeze-rpi5-screen-attempt-20 \
        verify-rpi5-screen-attempt-21-candidate-freeze \
        freeze-rpi5-screen-attempt-21 \
        verify-rpi5-screen-attempt-22-candidate-freeze \
        freeze-rpi5-screen-attempt-22 \
        verify-rpi5-touch-path-b-candidate-freeze \
        freeze-rpi5-touch-path-b \
        verify-rpi5-screen-attempt-23-candidate-freeze \
        freeze-rpi5-screen-attempt-23 \
        verify-rpi5-screen-attempt-24-candidate-freeze \
        freeze-rpi5-screen-attempt-24 \
        verify-rpi5-screen-attempt-26-candidate-freeze \
        freeze-rpi5-screen-attempt-26 \
        verify-rpi5-screen-attempt-27-candidate-freeze \
        freeze-rpi5-screen-attempt-27 \
        verify-rpi5-screen-attempt-28-candidate-freeze \
        freeze-rpi5-screen-attempt-28 \
        verify-rpi5-screen-attempt-29-candidate-freeze \
        freeze-rpi5-screen-attempt-29 \
        verify-rpi5-screen-attempt-30-candidate-freeze \
        freeze-rpi5-screen-attempt-30 \
        flash-rpi5-ios-home-a30 \
        verify-rpi5-screen-attempt-31-candidate-freeze \
        freeze-rpi5-screen-attempt-31 \
        flash-rpi5-ios-home-a31 \
        verify-rpi5-screen-attempt-32-candidate-freeze \
        freeze-rpi5-screen-attempt-32 \
        flash-rpi5-ios-home-a32 \
        verify-rpi5-screen-attempt-33-candidate-freeze \
        freeze-rpi5-screen-attempt-33 \
        flash-rpi5-ios-home-a33 \
        verify-rpi5-screen-attempt-34-candidate-freeze \
        freeze-rpi5-screen-attempt-34 \
        flash-rpi5-ios-home-a34 \
        verify-rpi5-screen-attempt-35-candidate-freeze \
        freeze-rpi5-screen-attempt-35 \
        flash-rpi5-ios-home-a35 \
        verify-rpi5-screen-attempt-36-candidate-freeze \
        freeze-rpi5-screen-attempt-36 \
        flash-rpi5-ios-home-a36 \
        verify-rpi5-screen-attempt-37-candidate-freeze \
        freeze-rpi5-screen-attempt-37 \
        flash-rpi5-ios-home-a37 \
        verify-rpi5-screen-attempt-38-candidate-freeze \
        freeze-rpi5-screen-attempt-38 \
        flash-rpi5-ios-home-a38 \
        verify-rpi5-screen-attempt-39-candidate-freeze \
        freeze-rpi5-screen-attempt-39 \
        flash-rpi5-ios-home-a39 \
        verify-rpi5-screen-attempt-40-candidate-freeze \
        freeze-rpi5-screen-attempt-40 \
        flash-rpi5-ios-home-a40 \
        verify-rpi5-screen-attempt-41-candidate-freeze \
        freeze-rpi5-screen-attempt-41 \
        flash-rpi5-ios-home-a41 \
        verify-rpi5-screen-attempt-42-candidate-freeze \
        freeze-rpi5-screen-attempt-42 \
        flash-rpi5-ios-home-a42 \
        verify-rpi5-screen-attempt-43-candidate-freeze \
        freeze-rpi5-screen-attempt-43 \
        flash-rpi5-ios-home-a43 \
        verify-rpi5-screen-attempt-44-candidate-freeze \
        freeze-rpi5-screen-attempt-44 \
        flash-rpi5-ios-home-a44 \
        verify-rpi5-screen-attempt-45-candidate-freeze \
        freeze-rpi5-screen-attempt-45 \
        flash-rpi5-ios-home-a45 \
        verify-rpi5-screen-attempt-46-candidate-freeze \
        freeze-rpi5-screen-attempt-46 \
        flash-rpi5-ios-home-a46 \
        verify-rpi5-screen-attempt-47-candidate-freeze \
        freeze-rpi5-screen-attempt-47 \
        flash-rpi5-ios-home-a47 \
        verify-rpi5-screen-attempt-48-candidate-freeze \
        freeze-rpi5-screen-attempt-48 \
        flash-rpi5-ios-home-a48 \
        verify-rpi5-screen-attempt-49-candidate-freeze \
        freeze-rpi5-screen-attempt-49 \
        flash-rpi5-ios-home-a49 \
        verify-rpi5-screen-attempt-50-candidate-freeze \
        freeze-rpi5-screen-attempt-50 \
        flash-rpi5-ios-home-a50 \
        verify-rpi5-screen-attempt-51-candidate-freeze \
        freeze-rpi5-screen-attempt-51 \
        flash-rpi5-ios-home-a51 \
        verify-rpi5-screen-attempt-52-candidate-freeze \
        freeze-rpi5-screen-attempt-52 \
        flash-rpi5-ios-home-a52 \
        verify-rpi5-screen-attempt-53-candidate-freeze \
        freeze-rpi5-screen-attempt-53 \
        flash-rpi5-ios-home-a53 \
        verify-rpi5-screen-attempt-54-candidate-freeze \
        freeze-rpi5-screen-attempt-54 \
        flash-rpi5-ios-home-a54 \
        verify-rpi5-screen-attempt-55-candidate-freeze \
        freeze-rpi5-screen-attempt-55 \
        flash-rpi5-ios-home-a55 \
        verify-rpi5-screen-attempt-56-candidate-freeze \
        freeze-rpi5-screen-attempt-56 \
        flash-rpi5-ios-home-a56 \
        verify-rpi5-screen-attempt-57-candidate-freeze \
        freeze-rpi5-screen-attempt-57 \
        flash-rpi5-ios-home-a57 \
        verify-rpi5-screen-attempt-58-candidate-freeze \
        freeze-rpi5-screen-attempt-58 \
        flash-rpi5-ios-home-a58 \
        verify-rpi5-screen-attempt-59-candidate-freeze \
        freeze-rpi5-screen-attempt-59 \
        flash-rpi5-ios-home-a59 \
        verify-rpi5-screen-attempt-60-candidate-freeze \
        freeze-rpi5-screen-attempt-60 \
        flash-rpi5-ios-home-a60 \
        verify-rpi5-screen-attempt-61-candidate-freeze \
        freeze-rpi5-screen-attempt-61 \
        flash-rpi5-ios-home-a61 \
        verify-rpi5-screen-attempt-62-candidate-freeze \
        freeze-rpi5-screen-attempt-62 \
        flash-rpi5-ios-home-a62 \
        image-rpi5-sd-inventory \
        check-rpi5-radio-inventory \
        image-rpi5-wifi-scan \
        flash-rpi5-wifi-scan \
        image-rpi5-wifi-scan-r108 \
        flash-rpi5-wifi-scan-r108 \
        image-rpi5-wifi-scan-r109 \
        flash-rpi5-wifi-scan-r109 \
        image-rpi5-wifi-scan-r110 \
        flash-rpi5-wifi-scan-r110 \
        image-rpi5-wifi-scan-r111 \
        flash-rpi5-wifi-scan-r111 \
        image-rpi5-wifi-scan-r112 \
        flash-rpi5-wifi-scan-r112 \
        image-rpi5-wifi-scan-r113 \
        flash-rpi5-wifi-scan-r113 \
        image-rpi5-wifi-scan-r114 \
        flash-rpi5-wifi-scan-r114 \
        image-rpi5-wifi-scan-r115 \
        flash-rpi5-wifi-scan-r115 \
        image-rpi5-wifi-scan-r116 \
        flash-rpi5-wifi-scan-r116 \
        check-rpi5-sensors \
        verify-rpi5-wifi-firmware \
        copy-rpi5-wifi-firmware \
        image-rpi5-sensors \
        flash-rpi5-sensors \
        flash-rpi5-radio \
        flash-rpi5-radio-nowifi \
        flash-rpi5-radio-d0probe \
        image-rpi5-sd-write \
        image-rpi5-sd-superblock \
        image-rpi5-sd-bulk \
        image-rpi5-sd-multi \
        image-rpi5-sd-frame \
        verify-rpi5-sd-attempt-a0-candidate-freeze \
        freeze-rpi5-sd-attempt-a0 \
        flash-rpi5-sd-a0 \
        verify-rpi5-sd-attempt-a1-candidate-freeze \
        freeze-rpi5-sd-attempt-a1 \
        flash-rpi5-sd-a1 \
        verify-rpi5-sd-attempt-b-candidate-freeze \
        freeze-rpi5-sd-attempt-b \
        flash-rpi5-sd-b \
        refresh-rpi5-epoch \
        verify-rpi5-sd-attempt-w0-candidate-freeze \
        freeze-rpi5-sd-attempt-w0 \
        flash-rpi5-sd-w0 \
        verify-rpi5-sd-attempt-w1-candidate-freeze \
        freeze-rpi5-sd-attempt-w1 \
        flash-rpi5-sd-w1 \
        verify-rpi5-sd-attempt-w2-candidate-freeze \
        verify-rpi5-sd-attempt-w2-package \
        freeze-rpi5-sd-attempt-w2 \
        flash-rpi5-sd-w2 \
        verify-rpi5-sd-attempt-w3-candidate-freeze \
        verify-rpi5-sd-attempt-w3-package \
        freeze-rpi5-sd-attempt-w3 \
        flash-rpi5-sd-w3 \
        verify-rpi5-sd-attempt-w3b-candidate-freeze \
        verify-rpi5-sd-attempt-w3b-package \
        freeze-rpi5-sd-attempt-w3b \
        flash-rpi5-sd-w3b \
        verify-rpi5-sd-attempt-w4-candidate-freeze \
        verify-rpi5-sd-attempt-w4-package \
        freeze-rpi5-sd-attempt-w4 \
        flash-rpi5-sd-w4 \
        verify-rpi5-sd-attempt-w5-candidate-freeze \
        verify-rpi5-sd-attempt-w5-package \
        freeze-rpi5-sd-attempt-w5 \
        flash-rpi5-sd-w5 \
        verify-rpi5-sd-attempt-w6-candidate-freeze \
        verify-rpi5-sd-attempt-w6-package \
        freeze-rpi5-sd-attempt-w6 \
        flash-rpi5-sd-w6 \
        verify-rpi5-sd-attempt-w7-candidate-freeze \
        verify-rpi5-sd-attempt-w7-package \
        freeze-rpi5-sd-attempt-w7 \
        flash-rpi5-sd-w7 \
        verify-rpi5-sd-attempt-b2-candidate-freeze \
        freeze-rpi5-sd-attempt-b2 \
        flash-rpi5-sd-b2 \
        flash-rpi5 flash-rpi5-g8g-staged flash-rpi5-g8h-staged \
        format-sd-rpi5 check-sd-rpi5 \
        verify-sd-volume-rpi5 verify-rpi5-g8g-staged-flash-source \
        verify-rpi5-g8h-staged-flash-source \
        verify-rpi5-g8g-capture-source verify-rpi5-g8g-physical-raw-source \
        verify verify-core verify-qemu verify-web verify-rpi5-g7c-host \
	        verify-rpi5-g7d-host verify-rpi5-g8-host verify-rpi5-g8b-host \
	        verify-rpi5-g8c-host verify-rpi5-g8d-host verify-rpi5-g8e-host \
	        verify-rpi5-g8f-host verify-rpi5-g8g-contract \
	        verify-rpi5-g8h-contract verify-rpi5-g8h-runtime \
	        verify-rpi5-g8h-integration \
	        verify-rpi5-g8g-runtime verify-rpi5-g8g-integration \
	        verify-rpi5-g8g-layout verify-rpi5-g8h-layout \
	        verify-rpi5-g8g-matrix verify-rpi5-g8h-matrix \
	        verify-rpi5-g8h-reproducible verify-rpi5-g8h-image-input \
	        verify-rpi5-g8h-package-source stage-rpi5-g8h-package \
	        verify-rpi5-g8h-package \
        run run-rpi4 clean help FORCE

all: kernel

help:
	@echo "ASELSAN Kernel Build System (M8.1 / RPi5)"
	@echo ""
	@echo "  make kernel          - Build for current BOARD (default: qemu)"
	@echo "  make kernel-rpi4     - Build for Raspberry Pi 4"
	@echo "  make kernel-rpi5     - Build for Raspberry Pi 5"
	@echo "  make image-rpi4      - RPi4 kernel + SD copy hints"
	@echo "  make image-rpi5      - RPi5 ELF → aselsanos-rpi5.img + SHA256"
	@echo "  make image-rpi5-screen - Opt-in Touch Display 2 DSI demo image (separate from frozen RPi5 payload)"
	@echo "  make image-rpi5-touch  - Path B GT911 17 ms poll candidate (separate from A21/A22; freeze-rpi5-touch-path-b)"
	@echo "  make image-rpi5-ui-server - Attempt-22 UI-Server live-frame candidate (separate from A21 screen freeze)"
	@echo "  make flash-rpi5-screen SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT - Screen image to an explicitly identified FAT32 card"
	@echo "  make flash-rpi5-ui-server SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT - Attempt-22 UI-Server image (does not use flash-rpi5-screen / A21 freeze)"
	@echo "  make flash-rpi5-path-b SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT - Path B touch image (does not use A21/A22 flash targets)"
	@echo "  make image-rpi5-ios-home - Attempt-29 iPhone-like pager + Kontrol Merkezi"
	@echo "  make check-rpi5-radio-inventory - radyo kaynak sözleşmesi + AArch64 check (radyo PASS değil)"
	@echo "  make image-rpi5-radio          - WIFI-A1 + BT-A1 adayı (yazan imaj, fiziksel PASS değil)"
	@echo "  make check-rpi5-sensors        - RNG/sıcaklık/güç düğmesi/PMU kaynak sözleşmesi"
	@echo "  make image-rpi5-sensors        - sensör adayı (fiziksel PASS değil)"
	@echo "  make flash-rpi5-ios-home SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT - Attempt-29 freeze (not A21/A22/Path B/A24/A26/A27/A28)"
	@echo "  scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT - TOUCHREADY terminal, 30s grace"
	@echo "  make verify          - Core + 3 board + paket + web kalite kapıları"
	@echo "  make verify-qemu     - Kontrollü QEMU EL0/scheduler runtime smoke"
	@echo "  make verify-rpi5-g8g-runtime - Frozen G8g source + AArch64 compile regresyonu"
	@echo "  make verify-rpi5-g8g-integration - G8g production seam + RPi5 kernel build kapısı"
	@echo "  make verify-rpi5-g8g-layout - G8–G8g production AArch64 layout kapıları"
	@echo "  make verify-rpi5-g8g-matrix - Tam regresyon + QEMU + beş izole board/feature profili"
	@echo "  make verify-rpi5-g8g-capture-source - G8g UART10 helper + PTY + strict validator"
	@echo "  make verify-rpi5-g8g-physical-raw-source - Read-only G7a–G8g raw validator chain"
	@echo "  make verify-rpi5-g8h-contract - G8h CPU1 local static-preemption contract/parser"
	@echo "  make verify-rpi5-g8h-runtime - Dormant G8h source + AArch64 object/FP gate"
	@echo "  make verify-rpi5-g8h-integration - G8h production seam + RPi5 kernel build kapısı"
	@echo "  make verify-rpi5-g8h-layout - G8–G8h production AArch64 layout + mutation kapıları"
	@echo "  make verify-rpi5-g8h-matrix - Image-free tam regresyon + QEMU + beş temiz profil"
	@echo "  make verify-rpi5-g8h-reproducible - Dört temiz RPi5 deploy-payload reproducibility kapısı"
	@echo "  make verify-rpi5-g8h-package-source - BOOT8H immutable package source + negatif kapıları"
	@echo "  make stage-rpi5-g8h-package - Tek clean offline image-rpi5 ile immutable evidence stage"
	@echo "  make verify-rpi5-g8h-package - Var olan Sequence 100 package exact4 salt-okunur kapısı"
	@echo "  make verify-rpi5-g8h-staged-flash-source - S101 source/fake-tool microSD hazırlık kapısı"
	@echo "  make format-sd-rpi5 SD_DISK=/dev/diskN - FAT32 MBR boot partition"
	@echo "  make flash-rpi5      - Build image and copy to SD_MOUNT ($(SD_MOUNT))"
	@echo "  make flash-rpi5-g8g-staged SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT"
	@echo "  make flash-rpi5-g8h-staged SD_DISK=/dev/diskN SD_MOUNT=/Volumes/ASELSANBOOT S101_FLASH_AUTH=..."
	@echo "  make run             - Build + run on QEMU"
	@echo "  make clean           - Clean build artifacts"

userspace-binaries: userspace-hello userspace-ipc-demo userspace-ipc-responder userspace-ipc-caller userspace-oom-supervisor userspace-oom-timer-supervisor userspace-oom-batch-supervisor userspace-oom-crash-supervisor userspace-oom-recovery-supervisor userspace-oom-lifecycle-crash-supervisor userspace-oom-lifecycle-recovery-supervisor userspace-oom-fault-supervisor userspace-oom-fault-recovery-supervisor userspace-oom-reply-bridge-supervisor userspace-ipc-timeout-caller userspace-ipc-timeout-responder userspace-ipc-recv-timeout-receiver userspace-ipc-recv-late-caller userspace-notification-waiter userspace-notification-signaler userspace-notification-revoked-waiter userspace-notification-race-waiter

userspace-hello:
	cd userspace/hello && $(CARGO) build --target $(TARGET) --release

userspace-ipc-demo:
	cd userspace/ipc_demo && $(CARGO) build --target $(TARGET) --release

userspace-ipc-responder:
	cd userspace/ipc_responder && $(CARGO) build --target $(TARGET) --release

userspace-ipc-caller:
	cd userspace/ipc_caller && $(CARGO) build --target $(TARGET) --release

userspace-oom-supervisor:
	cd userspace/oom_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-timer-supervisor:
	cd userspace/oom_timer_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-batch-supervisor:
	cd userspace/oom_batch_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-crash-supervisor:
	cd userspace/oom_crash_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-recovery-supervisor:
	cd userspace/oom_recovery_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-lifecycle-crash-supervisor:
	cd userspace/oom_lifecycle_crash_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-lifecycle-recovery-supervisor:
	cd userspace/oom_lifecycle_recovery_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-fault-supervisor:
	cd userspace/oom_fault_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-fault-recovery-supervisor:
	cd userspace/oom_fault_recovery_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-oom-reply-bridge-supervisor:
	cd userspace/oom_reply_bridge_supervisor && $(CARGO) build --target $(TARGET) --release

userspace-ipc-timeout-caller:
	cd userspace/ipc_timeout_caller && $(CARGO) build --target $(TARGET) --release

userspace-ipc-timeout-responder:
	cd userspace/ipc_timeout_responder && $(CARGO) build --target $(TARGET) --release

userspace-ipc-recv-timeout-receiver:
	cd userspace/ipc_recv_timeout_receiver && $(CARGO) build --target $(TARGET) --release

userspace-ipc-recv-late-caller:
	cd userspace/ipc_recv_late_caller && $(CARGO) build --target $(TARGET) --release

userspace-notification-waiter:
	cd userspace/notification_waiter && $(CARGO) build --target $(TARGET) --release

userspace-notification-signaler:
	cd userspace/notification_signaler && $(CARGO) build --target $(TARGET) --release

userspace-notification-revoked-waiter:
	cd userspace/notification_revoked_waiter && $(CARGO) build --target $(TARGET) --release

userspace-notification-race-waiter:
	cd userspace/notification_race_waiter && $(CARGO) build --target $(TARGET) --release

kernel: userspace-binaries
	@echo $(BUILD_MSG)
	cd $(KERNEL_DIR) && CARGO_TARGET_DIR=$(KERNEL_TARGET_DIR) \
		$(CARGO) build --target $(TARGET) $(FEATURES)

kernel-rpi4:
	@$(MAKE) BOARD=rpi4 kernel

kernel-rpi5:
	@$(MAKE) BOARD=rpi5 kernel

image-rpi4:
	@$(MAKE) BOARD=rpi4 kernel
	@echo ""
	@echo "✅ Raspberry Pi 4 ELF hazır: $(RPI4_ELF)"
	@echo "  rust-objcopy -O binary ile kernel8.img üretin ve FAT32 karta kopyalayın."
	@echo "  docs/M8.1-Raspberry-Pi-4-Testing-Guide.md"

# llvm-objcopy: rustup component llvm-tools-preview
OBJCOPY ?= $(shell \
	. "$$HOME/.cargo/env" 2>/dev/null; \
	find "$$(rustc --print sysroot 2>/dev/null)" -name llvm-objcopy -print -quit 2>/dev/null)
READOBJ ?= $(shell \
	. "$$HOME/.cargo/env" 2>/dev/null; \
	find "$$(rustc --print sysroot 2>/dev/null)" -name llvm-readobj -print -quit 2>/dev/null)
OBJDUMP ?= $(shell \
	. "$$HOME/.cargo/env" 2>/dev/null; \
	find "$$(rustc --print sysroot 2>/dev/null)" -name llvm-objdump -print -quit 2>/dev/null)

verify-rpi5-g7c-host: userspace-hello
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g7c_elf --test rpi5_g7c_page_flags --test rpi5_g7c_uart

verify-rpi5-g7d-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g7d_source --test rpi5_g7d_uart

verify-rpi5-g8-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8_contract --test rpi5_g8_source --test rpi5_g8_uart

verify-rpi5-g8b-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8b_source --test rpi5_g8b_uart

verify-rpi5-g8c-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8c_source --test rpi5_g8c_uart

verify-rpi5-g8d-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8d_source --test rpi5_g8d_uart

verify-rpi5-g8e-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8e_source --test rpi5_g8e_uart

verify-rpi5-g8f-host:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8e_source --test rpi5_g8e_uart \
		--test rpi5_g8f_source --test rpi5_g8f_uart

verify-rpi5-g8g-contract:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8f_uart \
		--test rpi5_g8g_source --test rpi5_g8g_uart
	$(CARGO) check -p aselsan_microkernel_simulation \
		--example verify_rpi5_g8g_log

verify-rpi5-g8h-contract:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_uart \
		--test rpi5_g8h_source --test rpi5_g8h_uart
	$(CARGO) check -p aselsan_microkernel_simulation \
		--example verify_rpi5_g8h_log
	$(CARGO) run -p aselsan_microkernel_simulation \
		--example verify_rpi5_g8h_log -- --canonical

verify-rpi5-g8h-runtime: verify-rpi5-g8h-contract
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_runtime_source --test rpi5_g8h_runtime_compile

verify-rpi5-g8h-integration: verify-rpi5-g8h-runtime
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_integration_source
	$(MAKE) BOARD=rpi5 kernel

verify-rpi5-g8g-runtime: userspace-binaries verify-rpi5-g8g-contract
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_runtime_source --test rpi5_g8g_runtime_compile
	$(CARGO) check -p aselsan_kernel --target $(TARGET) \
		--no-default-features --features board-rpi5

verify-rpi5-g8g-integration: verify-rpi5-g8g-runtime
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_integration_source
	$(MAKE) BOARD=rpi5 kernel
	@if [ -z "$(OBJDUMP)" ] || [ ! -x "$(OBJDUMP)" ]; then \
		echo "llvm-objdump bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@sh scripts/verify-rpi5-g8f-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"

verify-rpi5-g8g-layout: verify-rpi5-g8g-integration
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(OBJDUMP)" ] || [ ! -x "$(OBJDUMP)" ]; then \
		echo "llvm-objdump bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@sh scripts/verify-rpi5-g8-layout.sh "$(READOBJ)" "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8b-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8c-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8d-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8e-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8f-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8g-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"

verify-rpi5-g8h-layout: verify-rpi5-g8h-integration
	@ASELSAN_REQUIRE_G8H_ELF=1 $(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_layout_source
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(OBJDUMP)" ] || [ ! -x "$(OBJDUMP)" ]; then \
		echo "llvm-objdump bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@sh scripts/verify-rpi5-g8-layout.sh "$(READOBJ)" "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8b-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8c-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8d-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8e-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8f-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8g-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8h-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"

# Sıra 87: verify-core'un tam regresyon/QEMU/üç production board zincirine ek
# olarak iki compile-only SMP profili ve fresh, izole RPi5 layout doğrulaması.
# Profil scripti özellikle kernel/ içinde çalışır; workspace kökünden doğrudan
# cargo çağrısı kernel/.cargo/config.toml bağlamını taşımadığı için production
# ELF kanıtı sayılamaz.
verify-rpi5-g8g-matrix: verify-core
	@$(MAKE) verify-rpi5-g8g-layout
	@sh scripts/verify-rpi5-g8g-matrix.sh "$(CARGO)" "$(READOBJ)" "$(OBJDUMP)"

# Sıra 98: image/package/device yan etkisi olmadan tam workspace regresyonu,
# current G8h layout zinciri ve kernel/.cargo/config.toml içinden beş fresh,
# izole board/feature profili. SMP profilleri yalnız compile-only kalır.
verify-rpi5-g8h-matrix: userspace-binaries
	$(CARGO) test --workspace -- --test-threads=1
	@$(MAKE) verify-rpi5-g8h-layout
	@sh scripts/verify-rpi5-g8h-matrix.sh \
		"$(CARGO)" "$(READOBJ)" "$(OBJDUMP)" "$(QEMU)"

# Sıra 99: workspace ELF'ini yeniden üretmeden onun deploy semantiğini, aynı
# exact input snapshotından dört temiz production-context build ile karşılaştır.
# Audit kökü bağımsız inceleme için saklanır; image/package/device çalıştırılmaz.
verify-rpi5-g8h-reproducible:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_reproducible_source
	@sh scripts/verify-rpi5-g8h-reproducible.sh \
		"$(MAKE)" "$(CARGO)" "$(READOBJ)" "$(OBJDUMP)" "$(OBJCOPY)" \
		"$(RPI5_ELF)" "$(RPI5_DTB)" "$(RPI5_CONFIG)"

# Sıra 100 image-input bridge: GNU Make 3.81'de sibling prerequisite'ler
# paralel koşabileceği için production kernel, G8h layout ve S99 kapıları
# ayrı recursive Make adımlarıyla happens-before sırasında tamamlanır.
verify-rpi5-g8h-image-input:
	@$(MAKE) kernel-rpi5
	@$(MAKE) verify-rpi5-g8h-layout
	@$(MAKE) verify-rpi5-g8h-reproducible

verify-rpi5-g8h-package-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_package_source
	@sh -n scripts/stage-rpi5-g8h-package.sh
	@sh scripts/stage-rpi5-g8h-package.sh --self-test

stage-rpi5-g8h-package: verify-rpi5-g8h-package-source
	@sh scripts/stage-rpi5-g8h-package.sh --require-destination-absent \
		"$(RPI5_G8H_STAGED_PACKAGE)"
	@$(MAKE) image-rpi5
	@sh scripts/stage-rpi5-g8h-package.sh --stage \
		"$(MAKE)" "$(CARGO)" "$(READOBJ)" "$(OBJDUMP)" "$(OBJCOPY)" \
		"build/rpi5" "$(RPI5_G8H_STAGED_PACKAGE)"

verify-rpi5-g8h-package:
	@ASELSAN_REQUIRE_G8H_PACKAGE=1 $(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_package_source
	@sh scripts/stage-rpi5-g8h-package.sh --verify-package "$(RPI5_G8H_STAGED_PACKAGE)"

# Sıra 101 source-only hazırlık: frozen S100 package ve fake-tool state-machine
# testleri. Bu target gerçek diskutil, /Volumes, sync, eject veya device açmaz.
verify-rpi5-g8h-staged-flash-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_staged_flash_source
	@sh -n scripts/flash-rpi5-g8h-staged.sh
	@sh scripts/flash-rpi5-g8h-staged.sh --self-test
	@sh scripts/flash-rpi5-g8h-staged.sh \
		--verify-source-only "$(RPI5_G8H_STAGED_PACKAGE)"

image-rpi5: verify-rpi5-g8h-image-input verify-rpi5-g7c-host verify-rpi5-g7d-host verify-rpi5-g8-host verify-rpi5-g8b-host verify-rpi5-g8c-host verify-rpi5-g8d-host verify-rpi5-g8e-host verify-rpi5-g8f-host $(RPI5_DTB) $(RPI5_CONFIG)
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(OBJDUMP)" ] || [ ! -x "$(OBJDUMP)" ]; then \
		echo "llvm-objdump bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: RPi5 ELF entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@grep -qx 'arm_64bit=1' $(RPI5_CONFIG) || \
		(echo "HATA: RPi5 config arm_64bit=1 sözleşmesini taşımıyor"; exit 1)
	@grep -qx 'kernel_address=$(RPI5_ENTRY)' $(RPI5_CONFIG) || \
		(echo "HATA: RPi5 config kernel_address=$(RPI5_ENTRY) sözleşmesini taşımıyor"; exit 1)
	@sh scripts/verify-rpi5-pre-mmu-atomics.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g7c-layout.sh "$(READOBJ)" "$(OBJDUMP)" \
		userspace/hello/target/$(TARGET)/release/hello "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g7d-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8-layout.sh "$(READOBJ)" "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8b-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8c-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8d-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8e-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8f-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8g-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@sh scripts/verify-rpi5-g8h-layout.sh "$(OBJDUMP)" "$(RPI5_ELF)"
	@strings $(RPI5_ELF) | grep -q "ASELSAN/BOOT0 BCM2712" || \
		(echo "HATA: RPi5 board marker ELF içinde yok"; exit 1)
	@for MARKER in \
		"ASELSAN/RAM0" \
		"ASELSAN/RAM1" \
		"ASELSAN/GIC0" \
		"ASELSAN/TIMER0" \
		"ASELSAN/IRQ0 INTID=27" \
		"ASELSAN/BOOT5 GIC+TIMER=OK" \
		"ASELSAN/BOOT6 DT+RAM+HEAP=OK" \
		"ASELSAN/G7S0" \
		"ASELSAN/BOOT7 SCHED=OK" \
		"ASELSAN/G7B0 RANGES=" \
		"ASELSAN/BOOT7B PMM=OK TIMER=OK ALLOC=1 BASE_TICKS=" \
		"ASELSAN/G7C0 CPU=0 MODE=EL0 ROOT=SHARED ASID=0 ELF=TRUSTED PMM_ALLOC=3" \
		"ASELSAN/G7C1 SVC=WRITE ELR=0x" \
		"ASELSAN/G7C2 SVC=EXIT ELR=0x" \
		"ASELSAN/BOOT7C EL0=OK SVC_WRITE=OK SVC_EXIT=OK SWITCH=EL1H TIMER=OK MAPS=OK" \
		"ASELSAN/G7D0 CPU=0 MODE=PREEMPT IRQ=PPI27 TASKS=2" \
		"ASELSAN/G7D1" \
		"ASELSAN/G7D2" \
		"ASELSAN/G7D3" \
		"ASELSAN/G7D4" \
		"ASELSAN/BOOT7D PREEMPT=OK IRQ=PPI27 ORDER=ABABA SWITCHES=4" \
		"ASELSAN/G8S0 CPU=0 DT=PSCI-1.0 CONDUIT=SMC CPUS=4 TARGET=0x" \
		"ASELSAN/G8S1 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8 PSCI=OK CPU_ON=OK SECONDARY=CPU1" \
		"ASELSAN/G8B0 CPU=0 TARGET=CPU1 MPIDR=0x" \
		"ASELSAN/G8B1 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8B GIC=OK TIMER=OK CPU1_IRQ=1" \
		"ASELSAN/G8C0 CPU=0 TARGET=CPU1 MPIDR=0x" \
		"ASELSAN/G8C1 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8C SCHED=LOCAL CPU1_TASK=1" \
		"ASELSAN/G8D0 CPU=0 SOURCE=CPU0 TARGET=CPU1" \
		"ASELSAN/G8D1 CPU=1 MPIDR=0x" \
		"ASELSAN/G8D2 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8D IPI=SGI1 CPU0_TO_CPU1=1" \
		"ASELSAN/G8E0 CPU=0 ROUND1=G8D ROUND2=G8E" \
		"ASELSAN/G8E1 ROUND=2 CPU=1 MPIDR=0x" \
		"ASELSAN/G8E2 ROUND=2 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8E IPI=SGI1 CPU0_TO_CPU1=2" \
		"ASELSAN/G8F0 CPU=0 PREREQ=BOOT8E SOURCE=CPU0 TARGET=CPU1" \
		"ASELSAN/G8F1 REPORTER=CPU0 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8F HANDOFF=POST_BOOT8E SOURCE=CPU0 TARGET=CPU1"; do \
		strings $(RPI5_ELF) | grep -Fq "$$MARKER" || \
			{ echo "HATA: RPi5 proof marker ELF içinde yok: $$MARKER"; exit 1; }; \
	done
	@for MARKER in \
		"ASELSAN/G8G0 " \
		"ASELSAN/G8G1 " \
		"ASELSAN/G8G2 " \
		"ASELSAN/BOOT8G "; do \
		COUNT=$$(LC_ALL=C strings "$(RPI5_ELF)" | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: G8g proof marker ELF exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@G8G_ERROR_MARKER="ASELSAN/G8GERR CODE="; \
		COUNT=$$(LC_ALL=C strings "$(RPI5_ELF)" | grep -Fo -- "$$G8G_ERROR_MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: G8g hata markerı ELF exact-once değil: $$COUNT"; exit 1; }
	@G8F_FIXTURE=simulation/tests/fixtures/rpi5_g8f_uart_suffix.log; \
		for MARKER in "ASELSAN/G8F0 " "ASELSAN/G8F1 " "ASELSAN/BOOT8F "; do \
			COUNT=$$(grep -Fc "$$MARKER" "$$G8F_FIXTURE" || true); \
			[ "$$COUNT" -eq 1 ] || \
				{ echo "HATA: canonical G8f UART marker exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
		done; \
		if grep -Fq "ASELSAN/G8FERR" "$$G8F_FIXTURE"; then \
			echo "HATA: canonical G8f UART success fixture hata markerı içeriyor"; \
			exit 1; \
		fi
	@printf '%s  %s\n' "$(RPI5_G8G_FIXTURE_SHA256)" "$(RPI5_G8G_FIXTURE)" | \
		shasum -a 256 -c - >/dev/null || \
		{ echo "HATA: canonical G8g UART success fixture SHA256 uyuşmuyor"; exit 1; }
	@G8G_FIXTURE="$(RPI5_G8G_FIXTURE)"; \
		BYTES=$$(wc -c < "$$G8G_FIXTURE" | tr -d '[:space:]'); \
		[ "$$BYTES" -eq "$(RPI5_G8G_FIXTURE_BYTES)" ] || \
			{ echo "HATA: G8g UART success fixture byte sayısı exact değil: $$BYTES"; exit 1; }; \
		LINES=$$(wc -l < "$$G8G_FIXTURE" | tr -d '[:space:]'); \
		[ "$$LINES" -eq 4 ] || \
			{ echo "HATA: G8g UART success fixture satır sayısı exact değil: $$LINES"; exit 1; }; \
		for MARKER in "ASELSAN/G8G0 " "ASELSAN/G8G1 " "ASELSAN/G8G2 " "ASELSAN/BOOT8G "; do \
			COUNT=$$(grep -Fo -- "$$MARKER" "$$G8G_FIXTURE" | wc -l | tr -d '[:space:]'); \
			[ "$$COUNT" -eq 1 ] || \
				{ echo "HATA: canonical G8g UART marker exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
		done; \
		if grep -Fq "ASELSAN/G8GERR" "$$G8G_FIXTURE"; then \
			echo "HATA: canonical G8g UART success fixture hata markerı içeriyor"; \
			exit 1; \
		fi
	@mkdir -p build/rpi5
	$(OBJCOPY) -O binary $(RPI5_ELF) $(RPI5_IMG)
	@for MARKER in \
		"ASELSAN/G8F0 CPU=0 PREREQ=BOOT8E SOURCE=CPU0 TARGET=CPU1" \
		"ASELSAN/G8F1 REPORTER=CPU0 CPU=1 MPIDR=0x" \
		"ASELSAN/BOOT8F HANDOFF=POST_BOOT8E SOURCE=CPU0 TARGET=CPU1"; do \
		COUNT=$$(strings $(RPI5_IMG) | grep -Fc "$$MARKER" || true); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: RPi5 paket marker exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@for MARKER in \
		"ASELSAN/G8G0 " \
		"ASELSAN/G8G1 " \
		"ASELSAN/G8G2 " \
		"ASELSAN/BOOT8G "; do \
		COUNT=$$(LC_ALL=C strings "$(RPI5_IMG)" | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: G8g proof marker raw image exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@G8G_ERROR_MARKER="ASELSAN/G8GERR CODE="; \
		COUNT=$$(LC_ALL=C strings "$(RPI5_IMG)" | grep -Fo -- "$$G8G_ERROR_MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: G8g hata markerı raw image exact-once değil: $$COUNT"; exit 1; }
	cp $(RPI5_DTB) $(RPI5_PACKAGE_DTB)
	cp $(RPI5_CONFIG) $(RPI5_PACKAGE_CONFIG)
	@cd build/rpi5 && shasum -a 256 \
		aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt > SHA256SUMS
	@cd build/rpi5 && \
		LINES=$$(wc -l < SHA256SUMS | tr -d '[:space:]'); \
		[ "$$LINES" -eq 3 ] || \
			{ echo "HATA: RPi5 SHA256SUMS exact üç kayıt taşımıyor: $$LINES"; exit 1; }; \
		for FILE in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do \
			COUNT=$$(awk -v file="$$FILE" '$$2 == file { count++ } END { print count + 0 }' SHA256SUMS); \
			[ "$$COUNT" -eq 1 ] || \
				{ echo "HATA: RPi5 SHA256SUMS kaydı exact-once değil: $$FILE ($$COUNT)"; exit 1; }; \
		done; \
		awk 'NF != 2 || length($$1) != 64 || $$1 !~ /^[0-9a-f]+$$/ || \
			$$2 !~ /^(aselsanos-rpi5[.]img|bcm2712-rpi-5-b[.]dtb|config[.]txt)$$/ { bad = 1 } \
			END { exit bad }' SHA256SUMS || \
			{ echo "HATA: RPi5 SHA256SUMS beklenmeyen veya bozuk kayıt içeriyor"; exit 1; }
	@cd build/rpi5 && shasum -a 256 -c SHA256SUMS
	@echo ""
	@echo "✅ RPi5 imajı: $(RPI5_IMG)"
	@echo "   SHA256: $$(cat $(RPI5_SUMS))"
	@ls -lh $(RPI5_IMG) $(RPI5_PACKAGE_DTB) $(RPI5_PACKAGE_CONFIG) $(RPI5_SUMS)
	@echo ""
	@echo "Kart için: make flash-rpi5"

# Screen bring-up is intentionally a separate target.  It never runs the
# historical G8h layout gate and never overwrites build/rpi5 (S575/S570).
image-rpi5-screen: $(RPI5_DTB) $(RPI5_CONFIG)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_pcie_driver --test rpi5_pcie_command \
		--test rpi5_clock_driver \
		--test rpi5_clock_provider \
		--test rpi5_dsi_driver --test rpi5_dphy_driver \
		--test rpi5_ili9881_driver --test rpi5_scanout_driver \
		--test rpi5_iommu_driver --test rpi5_panel_mcu_driver \
		--test rpi5_gt911_driver --test rpi5_screen_source \
		--test rpi5_screen_config --test rpi5_screen_capture_source \
		--test rpi5_screen_physical_attempt_02 \
		--test rpi5_screen_physical_attempt_03 \
		--test rpi5_screen_physical_attempt_04 \
		--test rpi5_screen_physical_attempt_05 \
		--test rpi5_screen_physical_attempt_06 \
		--test rpi5_screen_physical_attempt_07 \
		--test rpi5_screen_physical_attempt_08 \
		--test rpi5_screen_physical_attempt_09 \
		--test rpi5_screen_physical_attempt_10 \
		--test rpi5_screen_physical_attempt_11 \
		--test rpi5_screen_physical_attempt_12 \
		--test rpi5_screen_physical_attempt_13 \
		--test rpi5_screen_physical_attempt_14 \
		--test rpi5_screen_physical_attempt_14_repeat \
		--test rpi5_screen_physical_attempt_15 \
		--test rpi5_screen_physical_attempt_16 \
		--test rpi5_screen_physical_attempt_17 \
		--test rpi5_screen_physical_attempt_18 \
		--test rpi5_screen_physical_attempt_19 \
		--test rpi5_screen_physical_attempt_20 \
		--test rpi5_screen_physical_attempt_21 \
		--test rpi5_screen_physical_attempt_22 \
		--test rpi5_screen_attempt_11_candidate_freeze \
		--test rpi5_screen_attempt_12_candidate_freeze \
		--test rpi5_screen_attempt_13_candidate_freeze \
		--test rpi5_screen_attempt_14_candidate_freeze \
		--test rpi5_screen_attempt_15_candidate_freeze \
		--test rpi5_screen_attempt_16_candidate_freeze \
		--test rpi5_screen_attempt_17_candidate_freeze \
		--test rpi5_screen_attempt_18_candidate_freeze \
		--test rpi5_layer2_inventory \
		--test rpi5_splash \
		--test rpi5_home \
		--test rpi5_ui_server \
		--test rpi5_screen_attempt_19_candidate_freeze \
		--test rpi5_screen_attempt_20_candidate_freeze \
		--test rpi5_screen_attempt_21_candidate_freeze -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SCREEN_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-screen-demo
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_SCREEN_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: screen image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@strings $(RPI5_SCREEN_ELF) | grep -Fq "ASELSAN/SCREEN0 RP1=" || \
		(echo "HATA: SCREEN0 marker ELF içinde yok"; exit 1)
	@mkdir -p $(RPI5_SCREEN_DIR)
	$(OBJCOPY) -O binary $(RPI5_SCREEN_ELF) $(RPI5_SCREEN_IMG)
	@strings $(RPI5_SCREEN_IMG) | grep -Fq "ASELSAN/SCREEN0 RP1=" || \
		(echo "HATA: SCREEN0 marker raw image içinde yok"; exit 1)
	cp $(RPI5_DTB) $(RPI5_SCREEN_DIR)/bcm2712-rpi-5-b.dtb
	@set -eu; TMP_CONFIG=$(RPI5_SCREEN_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-screen.img > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SCREEN_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@SCREEN_RESET_COUNT=$$(grep -c '^pciex4_reset=0$$' $(RPI5_SCREEN_DIR)/config.txt); \
		[ "$$SCREEN_RESET_COUNT" -eq 1 ] || \
		{ echo "HATA: screen config pciex4_reset=0 exact-once değil"; exit 1; }
	@cd $(RPI5_SCREEN_DIR) && shasum -a 256 \
		aselsanos-rpi5-screen.img bcm2712-rpi-5-b.dtb config.txt > SHA256SUMS
	@cd $(RPI5_SCREEN_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ RPi5 Touch Display 2 demo imajı: $(RPI5_SCREEN_IMG)"
	@echo "   Profil: RP1 MIPI0 / DSI=0 / pciex4_reset=0 handoff; connector exact eşleşmelidir."
	@echo "   Fiziksel PASS değildir; UART SCREEN0 + PHY readback + görünür piksel gerekir."

# Attempt-22 UI-Server live-frame image. Separate target-dir and filename so
# it cannot overwrite the Attempt-21 screen freeze or the Path B touch image.
image-rpi5-ui-server: $(RPI5_DTB) $(RPI5_CONFIG)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_home --test rpi5_ui_server \
		--test rpi5_screen_attempt_22_candidate_freeze \
		--test rpi5_screen_physical_attempt_22 -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_UI_SERVER_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-ui-server-demo
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_UI_SERVER_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: ui-server image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/SCREEN0 RP1=" "ASELSAN/UISERVER0 CAP="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_UI_SERVER_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: ui-server marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@mkdir -p $(RPI5_UI_SERVER_DIR)
	$(OBJCOPY) -O binary $(RPI5_UI_SERVER_ELF) $(RPI5_UI_SERVER_IMG)
	cp $(RPI5_DTB) $(RPI5_UI_SERVER_DIR)/bcm2712-rpi-5-b.dtb
	@set -eu; TMP_CONFIG=$(RPI5_UI_SERVER_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-ui-server.img > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_UI_SERVER_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@cd $(RPI5_UI_SERVER_DIR) && shasum -a 256 \
		aselsanos-rpi5-ui-server.img bcm2712-rpi-5-b.dtb config.txt > SHA256SUMS
	@cd $(RPI5_UI_SERVER_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ RPi5 UI-Server live-frame candidate: $(RPI5_UI_SERVER_IMG)"
	@echo "   Freeze hâlâ flash kapısıdır. Fiziksel PASS arşivi: SCREEN0 + UISERVER0 + frame-7 pill JPEG."

# Attempt-23 iPhone-like home + GT911 consumer. Separate target-dir/filename
# so it cannot overwrite A21, A22 or Path B. Identity axis transform.
image-rpi5-ios-home: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_IOS_HOME_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_ios_home --test rpi5_home \
		--test rpi5_screen_source \
		--test rpi5_touch_runtime_source \
		--test rpi5_present_60hz_source \
		--test rpi5_ios_home_capture_source \
		--test rpi5_screen_attempt_21_candidate_freeze \
		--test rpi5_screen_attempt_22_candidate_freeze \
		--test rpi5_screen_attempt_24_candidate_freeze \
		--test rpi5_screen_attempt_26_candidate_freeze \
		--test rpi5_screen_attempt_27_candidate_freeze \
		--test rpi5_screen_attempt_28_candidate_freeze \
		--test rpi5_screen_attempt_29_candidate_freeze -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_IOS_HOME_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-ios-home-demo
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_IOS_HOME_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: ios-home image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/SCREEN0 RP1=" "ASELSAN/TOUCHREADY MODE=FOREGROUND" \
		"ASELSAN/TOUCHFRAME POLLS=" "ASELSAN/PAGE PAGE=" \
		"ASELSAN/PRESENT TARGET_HZ=" "ASELSAN/PRESENT FRAMES=" \
		"ASELSAN/TOUCHWATCHDOG MS="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_IOS_HOME_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: ios-home marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@ACCEPTED=$$(LC_ALL=C strings $(RPI5_IOS_HOME_ELF) | grep -Fo -- "ACCEPTED=1" | wc -l | tr -d '[:space:]'); \
		[ "$$ACCEPTED" -ge 3 ] || \
			{ echo "HATA: ACCEPTED=1 ELF içinde en az üç kez değil: $$ACCEPTED"; exit 1; }
	@CANDIDATE=$$(LC_ALL=C strings $(RPI5_IOS_HOME_ELF) | grep -Fo -- "CANDIDATE=1 ACCEPTED=0" | wc -l | tr -d '[:space:]'); \
		[ "$$CANDIDATE" -eq 0 ] || \
			{ echo "HATA: Path B CANDIDATE=1 ACCEPTED=0 ios-home ELF içinde olmamalı: $$CANDIDATE"; exit 1; }
	@mkdir -p $(RPI5_IOS_HOME_DIR)
	$(OBJCOPY) -O binary $(RPI5_IOS_HOME_ELF) $(RPI5_IOS_HOME_IMG)
	@for MARKER in "ASELSAN/SCREEN0 RP1=" "ASELSAN/TOUCHREADY MODE=FOREGROUND" \
		"ASELSAN/TOUCHFRAME POLLS=" "ASELSAN/PAGE PAGE=" \
		"ASELSAN/PRESENT TARGET_HZ=" "ASELSAN/PRESENT FRAMES=" \
		"ASELSAN/TOUCHWATCHDOG MS="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_IOS_HOME_IMG) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: ios-home marker raw image içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	cp $(RPI5_DTB) $(RPI5_IOS_HOME_DIR)/bcm2712-rpi-5-b.dtb
	cp $(RPI5_IOS_HOME_PROFILE) $(RPI5_IOS_HOME_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_IOS_HOME_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-ios-home.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_IOS_HOME_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@IOS_RESET_COUNT=$$(grep -c '^pciex4_reset=0$$' $(RPI5_IOS_HOME_DIR)/config.txt); \
		[ "$$IOS_RESET_COUNT" -eq 1 ] || \
		{ echo "HATA: ios-home config pciex4_reset=0 exact-once değil"; exit 1; }
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' $(RPI5_IOS_HOME_DIR)/config.txt || \
		{ echo "HATA: ios-home config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@IOS_EPOCH_COUNT=$$(grep -c '^initramfs aselsanos-epoch.bin 0x10000000$$' $(RPI5_IOS_HOME_DIR)/config.txt); \
		[ "$$IOS_EPOCH_COUNT" -eq 1 ] || \
		{ echo "HATA: ios-home config epoch blob directive exact-once değil"; exit 1; }
	@cd $(RPI5_IOS_HOME_DIR) && shasum -a 256 \
		aselsanos-rpi5-ios-home.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_IOS_HOME_DIR) && \
		LINES=$$(wc -l < SHA256SUMS | tr -d '[:space:]'); \
		[ "$$LINES" -eq 4 ] || \
			{ echo "HATA: ios-home SHA256SUMS exact dört kayıt taşımıyor: $$LINES"; exit 1; }; \
		for FILE in aselsanos-rpi5-ios-home.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt; do \
			COUNT=$$(awk -v file="$$FILE" '$$2 == file { count++ } END { print count + 0 }' SHA256SUMS); \
			[ "$$COUNT" -eq 1 ] || \
				{ echo "HATA: ios-home SHA256SUMS kaydı exact-once değil: $$FILE ($$COUNT)"; exit 1; }; \
		done
	@cd $(RPI5_IOS_HOME_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ RPi5 Attempt-44 adayı (A43 + avuç teması çekirdeği durdurmaz, ikinci parmak taşımayı bozmaz): $(RPI5_IOS_HOME_IMG)"
	@echo "   Profil: RP1 MIPI0 / DSI=0 / iki tampon / large_object=drop / tek birincil parmak."
	@echo "   Fiziksel PASS değildir; SCREEN0 + TOUCHREADY ACCEPTED=1 + drag without tear + JPEG gerekir."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh /dev/cu.usbmodem* /tmp/aselsanos-a44/uart10.raw"

# Attempt-07 freezes only an already-built, exact-identity screen package.
# Neither target builds an image or performs any SD/UART/device operation.
verify-rpi5-screen-attempt-07-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-07.sh
	@sh scripts/freeze-rpi5-screen-attempt-07.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_07_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-07:
	@sh -n scripts/freeze-rpi5-screen-attempt-07.sh
	@sh scripts/freeze-rpi5-screen-attempt-07.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-07.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-07-candidate-freeze

# Attempt-08 is the immutable relational BAR/root/outbound remediation package.
# These targets are host-only and never touch SD, UART or power state.
verify-rpi5-screen-attempt-08-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-08.sh
	@sh scripts/freeze-rpi5-screen-attempt-08.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_08_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-08:
	@sh -n scripts/freeze-rpi5-screen-attempt-08.sh
	@sh scripts/freeze-rpi5-screen-attempt-08.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-08.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-08-candidate-freeze

# Attempt-09 freezes the topology-derived dual CPU BAR candidate: the
# no-reset high profile maps through CPU 0x1c, while canonical low maps 0x1f.
# These targets are host-only and never touch SD, UART or power state.
verify-rpi5-screen-attempt-09-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-09.sh
	@sh scripts/freeze-rpi5-screen-attempt-09.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_09_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-09:
	@sh -n scripts/freeze-rpi5-screen-attempt-09.sh
	@sh scripts/freeze-rpi5-screen-attempt-09.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-09.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-09-candidate-freeze

# Attempt-10 freezes the diagnostic-only panel-MCU I2C6 candidate derived
# from Attempt-09 RED. It preserves the in-flight prepare phase, GPIO38/39
# raw status and DesignWare identity/configuration snapshot on failure.
# These targets are host-only and never touch SD, UART or power state.
verify-rpi5-screen-attempt-10-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-10.sh
	@sh scripts/freeze-rpi5-screen-attempt-10.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_10_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-10:
	@sh -n scripts/freeze-rpi5-screen-attempt-10.sh
	@sh scripts/freeze-rpi5-screen-attempt-10.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-10.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-10-candidate-freeze

# Attempt-11 is a single-variable CAM0 hypothesis: after the committed RP1
# topology, GPIO34 is driven high and allowed the existing bounded 20 ms
# settle before the unchanged GPIO38/39 I2C6 lane addresses MCU 0x45.
# These targets are host-only and never touch SD, UART or power state.
verify-rpi5-screen-attempt-11-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-11.sh
	@sh scripts/freeze-rpi5-screen-attempt-11.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_11_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-11:
	@sh -n scripts/freeze-rpi5-screen-attempt-11.sh
	@sh scripts/freeze-rpi5-screen-attempt-11.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-11.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-11-candidate-freeze

# Attempt-12 changes only the touch-reset release cadence derived from the
# Attempt-11 RED: write POWERON CTP release, wait the existing bounded 50 ms,
# then perform the fail-closed readback. No retry, new delay or bus fallback is
# introduced. These targets are host-only and never touch SD, UART or power.
verify-rpi5-screen-attempt-12-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-12.sh
	@sh scripts/freeze-rpi5-screen-attempt-12.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_12_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-12:
	@sh -n scripts/freeze-rpi5-screen-attempt-12.sh
	@sh scripts/freeze-rpi5-screen-attempt-12.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-12.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-12-candidate-freeze

# Attempt-13 changes only the panel-MCU transaction cadence of the prepare
# sequence, derived from the Attempt-12 RED: no I2C transaction to 0x45 inside
# the settle interval after any prepare POWERON write; each fail-closed
# readback runs after the existing 20/50/20 ms wait. Cleanup pairs, retry,
# delays and bus selection are unchanged. Host-only; never touches SD, UART
# or power.
verify-rpi5-screen-attempt-13-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-13.sh
	@sh scripts/freeze-rpi5-screen-attempt-13.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_13_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-13:
	@sh -n scripts/freeze-rpi5-screen-attempt-13.sh
	@sh scripts/freeze-rpi5-screen-attempt-13.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-13.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-13-candidate-freeze

# Attempt-14 changes only the backlight PWM cadence derived from the
# Attempt-13 RED: PWM write, then the 20 ms gap after which Attempt-13's
# deferred POWERON readbacks were acknowledged (untested for PWM), then the
# fail-closed readback, with phase + DesignWare snapshot on the UART record.
# Cleanup pairs, prepare cadence, retry policy and bus selection are
# unchanged. Host-only; never touches SD, UART or power.
verify-rpi5-screen-attempt-14-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-14.sh
	@sh scripts/freeze-rpi5-screen-attempt-14.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_14_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-14:
	@sh -n scripts/freeze-rpi5-screen-attempt-14.sh
	@sh scripts/freeze-rpi5-screen-attempt-14.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-14.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-14-candidate-freeze

# Attempt-15 follows the upstream raspberrypi,dsi-5inch order with two coupled
# device-visible changes: (a) the init program ends at DCS sleep-out, the DSI
# host streams video and RP1 DMA starts, then the existing 120 ms interval
# elapses and display-on is sent in LP during blanking; (b) the DWC host
# DPI_LP_CMD_TIM OUTVACT budget is programmed (0 -> 9 bytes, upstream cmdtim)
# so that LP command can be scheduled in video mode. Timing, lanes, PLL, init
# table, I2C cadence and retry policy are unchanged. Host-only targets.
verify-rpi5-screen-attempt-15-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-15.sh
	@sh scripts/freeze-rpi5-screen-attempt-15.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_15_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-15:
	@sh -n scripts/freeze-rpi5-screen-attempt-15.sh
	@sh scripts/freeze-rpi5-screen-attempt-15.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-15.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-15-candidate-freeze

# Attempt-16 changes one device-facing value: the D-PHY PLL input divider
# follows upstream dphy_get_div (fREFCLK/N within 5-40 MHz), N=2/M=40 instead
# of N=1/M=20 for the same 1 GHz lane rate. UART-only additions sample the RP1
# DPI-DMA status/IRQ flags and the DSI host INT_ST/PKT/PHY registers after
# display-on so SCREEN0 shows whether frames are generated. Host-only targets.
# Attempt-16 ran (SCREEN0, DMA FRAME_START, host HS, panel white): the frozen
# package is now a historical pin, verified in place rather than against build/.
verify-rpi5-screen-attempt-16-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-16.sh
	@sh scripts/freeze-rpi5-screen-attempt-16.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_16_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-16:
	@sh -n scripts/freeze-rpi5-screen-attempt-16.sh
	@sh scripts/freeze-rpi5-screen-attempt-16.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-16.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-16-candidate-freeze

# Attempt-17 changes one device-facing thing: the BCM2712 PCIe controller's
# inbound RAM window. RC BAR2 LO/HI (0x4034/0x4038) + UBUS BAR2 REMAP/HI
# (0x40b4/0x40b8) and MISC_CTRL.SCB_ACCESS_EN (0x4008 bit 12) are read back
# first; the Pi 5 pcie2 RAM dma-range (PCIe 0x10_0000_0000 -> CPU 0, 64 GiB,
# size code 21) is written exactly as upstream set_inbound_win_registers does,
# only when RC BAR2 is fully disabled and no other window decodes the range.
# Every word before/after lands in SCREEN0 (MISC_CTRL/INBOUND1-3/INBOUND_WRITES).
# Attempt-17 ran (SCREENERR fail-closed: firmware left RC BAR2 = 64 GiB at PCIe 0,
# no write performed): the frozen package is now a historical pin.
verify-rpi5-screen-attempt-17-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-17.sh
	@sh scripts/freeze-rpi5-screen-attempt-17.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_17_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-17:
	@sh -n scripts/freeze-rpi5-screen-attempt-17.sh
	@sh scripts/freeze-rpi5-screen-attempt-17.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-17.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-17-candidate-freeze

# Attempt-18 changes one word on the device: the firmware leaves RC BAR2 as the
# upstream 64 GiB RAM window but based at PCIe 0x0 (LO 0x15 / HI 0x0 / UBUS 0x1,
# Attempt-17 observation); RP1 addresses RAM at PCIe 0x10_0000_0000 + PA. When
# exactly that shape is read back, RC_BAR2_CONFIG_HI (0x4038) is rewritten
# 0x0 -> 0x10 with exact readback + rollback; every other state keeps the
# Attempt-17 fail-closed rules. SCREEN0 adds INBOUND_RELOC. Host-only targets.
# Attempt-18 ran (SCREEN PASS: SCREEN0 + photographed gradient, one word
# RC_BAR2_CONFIG_HI 0x0->0x10): the frozen package is now a historical pin.
verify-rpi5-screen-attempt-18-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-18.sh
	@sh scripts/freeze-rpi5-screen-attempt-18.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_18_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-18:
	@sh -n scripts/freeze-rpi5-screen-attempt-18.sh
	@sh scripts/freeze-rpi5-screen-attempt-18.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-18.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-18-candidate-freeze

# Attempt-19 (L2-A) ran (SCREEN PASS: SCREEN0 + photographed gradient, Layer-2
# inventory WRITES=0). The frozen package is now a historical pin; live tree
# and build/rpi5-screen may move to Attempt-20. Host-only verify-package.
verify-rpi5-screen-attempt-19-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-19.sh
	@sh scripts/freeze-rpi5-screen-attempt-19.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_19_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-19:
	@sh -n scripts/freeze-rpi5-screen-attempt-19.sh
	@sh scripts/freeze-rpi5-screen-attempt-19.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-19.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-19-candidate-freeze

# Attempt-20 splash PASS is historical. Live tree moved to Attempt-21 home.
# Host-only verify-package of the sealed splash image.
verify-rpi5-screen-attempt-20-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-20.sh
	@sh scripts/freeze-rpi5-screen-attempt-20.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_20_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-20:
	@sh -n scripts/freeze-rpi5-screen-attempt-20.sh
	@sh scripts/freeze-rpi5-screen-attempt-20.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-20.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-20-candidate-freeze

# Attempt-21 replaces only framebuffer CONTENT: compose_home (status bar,
# 3x4 app grid, dock) instead of compose_splash. Registers, clocks, inbound
# window and Layer-2 inventory stay Attempt-19/20. Host-only freeze.
verify-rpi5-screen-attempt-21-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-21.sh
	@sh scripts/freeze-rpi5-screen-attempt-21.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_21_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-21:
	@sh -n scripts/freeze-rpi5-screen-attempt-21.sh
	@sh scripts/freeze-rpi5-screen-attempt-21.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-21.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-21-candidate-freeze

# Attempt-22 is a separate image (rpi5-ui-server-demo). It is not the
# flash-rpi5-screen gate. Host-only freeze of build/rpi5-ui-server.
verify-rpi5-screen-attempt-22-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-22.sh
	@sh scripts/freeze-rpi5-screen-attempt-22.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_22_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-22:
	@sh -n scripts/freeze-rpi5-screen-attempt-22.sh
	@sh scripts/freeze-rpi5-screen-attempt-22.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-22.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-22-candidate-freeze

# Path B is a separate touch-demo image. flash-rpi5-path-b is not the
# A21 screen or A22 ui-server gate. The A21-pinned source contract
# forbids a Make target named flash-rpi5-touch.
verify-rpi5-touch-path-b-candidate-freeze:
	@sh -n scripts/freeze-rpi5-touch-path-b.sh
	@sh scripts/freeze-rpi5-touch-path-b.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_touch_path_b_candidate_freeze -- --test-threads=1

freeze-rpi5-touch-path-b:
	@sh -n scripts/freeze-rpi5-touch-path-b.sh
	@sh scripts/freeze-rpi5-touch-path-b.sh --source-check
	@sh scripts/freeze-rpi5-touch-path-b.sh --freeze
	@$(MAKE) verify-rpi5-touch-path-b-candidate-freeze

# Attempt-23 is a separate image (rpi5-ios-home-demo). Host-only freeze of
# build/rpi5-ios-home. Not the A21/A22/Path B flash gate.
verify-rpi5-screen-attempt-23-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-23.sh
	@sh scripts/freeze-rpi5-screen-attempt-23.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_23_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-23:
	@sh -n scripts/freeze-rpi5-screen-attempt-23.sh
	@sh scripts/freeze-rpi5-screen-attempt-23.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-23.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-23-candidate-freeze

verify-rpi5-screen-attempt-24-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-24.sh
	@sh scripts/freeze-rpi5-screen-attempt-24.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_24_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-24:
	@sh -n scripts/freeze-rpi5-screen-attempt-24.sh
	@sh scripts/freeze-rpi5-screen-attempt-24.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-24.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-24-candidate-freeze

verify-rpi5-screen-attempt-26-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-26.sh
	@sh scripts/freeze-rpi5-screen-attempt-26.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_26_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-26:
	@sh -n scripts/freeze-rpi5-screen-attempt-26.sh
	@sh scripts/freeze-rpi5-screen-attempt-26.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-26.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-26-candidate-freeze

verify-rpi5-screen-attempt-27-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-27.sh
	@sh scripts/freeze-rpi5-screen-attempt-27.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_27_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-27:
	@sh -n scripts/freeze-rpi5-screen-attempt-27.sh
	@sh scripts/freeze-rpi5-screen-attempt-27.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-27.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-27-candidate-freeze

verify-rpi5-screen-attempt-28-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-28.sh
	@sh scripts/freeze-rpi5-screen-attempt-28.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_28_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-28:
	@sh -n scripts/freeze-rpi5-screen-attempt-28.sh
	@sh scripts/freeze-rpi5-screen-attempt-28.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-28.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-28-candidate-freeze

verify-rpi5-screen-attempt-29-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-29.sh
	@sh scripts/freeze-rpi5-screen-attempt-29.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_29_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-29:
	@sh -n scripts/freeze-rpi5-screen-attempt-29.sh
	@sh scripts/freeze-rpi5-screen-attempt-29.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-29.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-29-candidate-freeze

# Attempt-30 rebuilds the Control Center glyphs and geometry, makes the home
# grid rearrangeable and carries the wall clock in from the host.  The epoch
# blob is written straight onto the card and is deliberately outside the five
# pinned files, so this freeze stays a byte comparison like every other one.
# Attempt-31 = Attempt-30 with the clock adopted before the MMU comes up and
# the blob loaded clear of the kernel BSS.  A30 ran RED (kernel data abort).
verify-rpi5-screen-attempt-31-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-31.sh
	@sh scripts/freeze-rpi5-screen-attempt-31.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_31_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-31:
	@sh -n scripts/freeze-rpi5-screen-attempt-31.sh
	@sh scripts/freeze-rpi5-screen-attempt-31.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-31.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-31-candidate-freeze

verify-rpi5-screen-attempt-32-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-32.sh
	@sh scripts/freeze-rpi5-screen-attempt-32.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_32_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-32:
	@sh -n scripts/freeze-rpi5-screen-attempt-32.sh
	@sh scripts/freeze-rpi5-screen-attempt-32.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-32.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-32-candidate-freeze

verify-rpi5-screen-attempt-33-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-33.sh
	@sh scripts/freeze-rpi5-screen-attempt-33.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_33_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-33:
	@sh -n scripts/freeze-rpi5-screen-attempt-33.sh
	@sh scripts/freeze-rpi5-screen-attempt-33.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-33.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-33-candidate-freeze

verify-rpi5-screen-attempt-34-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-34.sh
	@sh scripts/freeze-rpi5-screen-attempt-34.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_34_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-34:
	@sh -n scripts/freeze-rpi5-screen-attempt-34.sh
	@sh scripts/freeze-rpi5-screen-attempt-34.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-34.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-34-candidate-freeze

verify-rpi5-screen-attempt-35-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-35.sh
	@sh scripts/freeze-rpi5-screen-attempt-35.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_35_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-35:
	@sh -n scripts/freeze-rpi5-screen-attempt-35.sh
	@sh scripts/freeze-rpi5-screen-attempt-35.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-35.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-35-candidate-freeze

verify-rpi5-screen-attempt-30-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-30.sh
	@sh scripts/freeze-rpi5-screen-attempt-30.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_30_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-30:
	@sh -n scripts/freeze-rpi5-screen-attempt-30.sh
	@sh scripts/freeze-rpi5-screen-attempt-30.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-30.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-30-candidate-freeze

# Touch polling is a second, separately named candidate. It cannot overwrite
# either the frozen board image or the screen-only candidate, and this target
# deliberately has no flash side effect.
image-rpi5-touch: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_TOUCH_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_pcie_driver --test rpi5_pcie_command \
		--test rpi5_clock_driver \
		--test rpi5_clock_provider \
		--test rpi5_dsi_driver --test rpi5_dphy_driver \
		--test rpi5_ili9881_driver --test rpi5_scanout_driver \
		--test rpi5_iommu_driver --test rpi5_panel_mcu_driver \
		--test rpi5_gt911_driver --test rpi5_screen_source \
		--test rpi5_touch_runtime --test rpi5_touch_runtime_source \
		--test rpi5_screen_config --test rpi5_screen_capture_source \
		--test rpi5_screen_physical_attempt_02 \
		--test rpi5_screen_physical_attempt_03 \
		--test rpi5_screen_physical_attempt_04 \
		--test rpi5_screen_physical_attempt_05 \
		--test rpi5_screen_physical_attempt_06 \
		--test rpi5_screen_physical_attempt_07 \
		--test rpi5_screen_physical_attempt_08 \
		--test rpi5_screen_physical_attempt_09 \
		--test rpi5_screen_physical_attempt_10 \
		--test rpi5_screen_physical_attempt_11 \
		--test rpi5_screen_physical_attempt_12 \
		--test rpi5_screen_physical_attempt_13 \
		--test rpi5_screen_physical_attempt_14 \
		--test rpi5_screen_physical_attempt_14_repeat \
		--test rpi5_screen_physical_attempt_15 \
		--test rpi5_screen_physical_attempt_16 \
		--test rpi5_screen_physical_attempt_17 \
		--test rpi5_screen_physical_attempt_18 \
		--test rpi5_screen_physical_attempt_19 \
		--test rpi5_screen_physical_attempt_20 \
		--test rpi5_screen_physical_attempt_21 \
		--test rpi5_screen_physical_attempt_22 \
		--test rpi5_screen_attempt_11_candidate_freeze \
		--test rpi5_screen_attempt_12_candidate_freeze \
		--test rpi5_screen_attempt_13_candidate_freeze \
		--test rpi5_screen_attempt_14_candidate_freeze \
		--test rpi5_screen_attempt_15_candidate_freeze \
		--test rpi5_screen_attempt_16_candidate_freeze \
		--test rpi5_screen_attempt_17_candidate_freeze \
		--test rpi5_screen_attempt_18_candidate_freeze \
		--test rpi5_layer2_inventory \
		--test rpi5_splash \
		--test rpi5_home \
		--test rpi5_ui_server \
		--test rpi5_screen_attempt_19_candidate_freeze \
		--test rpi5_screen_attempt_20_candidate_freeze \
		--test rpi5_screen_attempt_21_candidate_freeze -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_TOUCH_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-touch-demo
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_TOUCH_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: touch image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/SCREEN0 RP1=" "ASELSAN/TOUCHREADY MODE=FOREGROUND" \
		"ASELSAN/TOUCHFRAME POLLS="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_TOUCH_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: touch marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@SHARED=$$(LC_ALL=C strings $(RPI5_TOUCH_ELF) | grep -Fo -- "CANDIDATE=1 ACCEPTED=0" | wc -l | tr -d '[:space:]'); \
		[ "$$SHARED" -eq 2 ] || \
			{ echo "HATA: CANDIDATE=1 ACCEPTED=0 ELF içinde exact-twice değil (TOUCHREADY+TOUCHFRAME): $$SHARED"; exit 1; }
	@mkdir -p $(RPI5_TOUCH_DIR)
	$(OBJCOPY) -O binary $(RPI5_TOUCH_ELF) $(RPI5_TOUCH_IMG)
	@for MARKER in "ASELSAN/SCREEN0 RP1=" "ASELSAN/TOUCHREADY MODE=FOREGROUND" \
		"ASELSAN/TOUCHFRAME POLLS="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_TOUCH_IMG) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: touch marker raw image içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@SHARED=$$(LC_ALL=C strings $(RPI5_TOUCH_IMG) | grep -Fo -- "CANDIDATE=1 ACCEPTED=0" | wc -l | tr -d '[:space:]'); \
		[ "$$SHARED" -eq 2 ] || \
			{ echo "HATA: CANDIDATE=1 ACCEPTED=0 raw image içinde exact-twice değil (TOUCHREADY+TOUCHFRAME): $$SHARED"; exit 1; }
	cp $(RPI5_DTB) $(RPI5_TOUCH_DIR)/bcm2712-rpi-5-b.dtb
	cp $(RPI5_TOUCH_PROFILE) $(RPI5_TOUCH_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_TOUCH_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-touch.img > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_TOUCH_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@TOUCH_RESET_COUNT=$$(grep -c '^pciex4_reset=0$$' $(RPI5_TOUCH_DIR)/config.txt); \
		[ "$$TOUCH_RESET_COUNT" -eq 1 ] || \
		{ echo "HATA: touch config pciex4_reset=0 exact-once değil"; exit 1; }
	@cd $(RPI5_TOUCH_DIR) && shasum -a 256 \
		aselsanos-rpi5-touch.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_TOUCH_DIR) && \
		LINES=$$(wc -l < SHA256SUMS | tr -d '[:space:]'); \
		[ "$$LINES" -eq 4 ] || \
			{ echo "HATA: touch SHA256SUMS exact dört kayıt taşımıyor: $$LINES"; exit 1; }; \
		for FILE in aselsanos-rpi5-touch.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt; do \
			COUNT=$$(awk -v file="$$FILE" '$$2 == file { count++ } END { print count + 0 }' SHA256SUMS); \
			[ "$$COUNT" -eq 1 ] || \
				{ echo "HATA: touch SHA256SUMS kaydı exact-once değil: $$FILE ($$COUNT)"; exit 1; }; \
		done
	@cd $(RPI5_TOUCH_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ RPi5 Touch Display 2 foreground-poll candidate: $(RPI5_TOUCH_IMG)"
	@echo "   Profil: RP1 MIPI0 / DSI=0 / GT911 17 ms foreground polling."
	@echo "   Mutable/non-frozen: aynı hedefin yeniden çalışması bu candidate'i değiştirir."
	@echo "   Fiziksel PASS değildir; SCREEN0 + TOUCHREADY + TOUCHFRAME ve Down/Move/Up gözlemi gerekir."
	@echo "   Panel VERSION_A21 ile A21 CRC'sine alias olur; ayırt edici UART TOUCHREADY/TOUCHFRAME'dir."

# Destructive only in the sense of replacing files on the explicitly named
# mounted boot volume; it never formats a card and refuses implicit disks.
flash-rpi5-screen:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-21-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	cp "$(A21_SCREEN_PACKAGE)/aselsanos-rpi5-screen.img" "$(SD_MOUNT)/aselsanos-rpi5-screen.img"
	cp "$(A21_SCREEN_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A21_SCREEN_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A21_SCREEN_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "✅ Screen imajı doğrulanmış FAT32 karta kopyalandı: $(SD_DISK)"
	@echo "   Şimdi kartı eject et, Pi 5'e tak ve UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen kaynak marker: ASELSAN/SCREEN0; PHYSICAL=0 PIXEL=0 TOUCH=0 yalnız başlangıç kodu iddiasıdır."

# Attempt-22 writes a different kernel filename and config. It must not go
# through flash-rpi5-screen (that gate is Attempt-21). Leftover
# aselsanos-rpi5-screen.img on the card is unused if config points here.
flash-rpi5-ui-server:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-22-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	cp "$(A22_UI_SERVER_PACKAGE)/aselsanos-rpi5-ui-server.img" "$(SD_MOUNT)/aselsanos-rpi5-ui-server.img"
	cp "$(A22_UI_SERVER_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A22_UI_SERVER_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A22_UI_SERVER_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ui-server.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ui-server.img değil"; exit 1; }
	sync
	@echo "✅ UI-Server imajı doğrulanmış FAT32 karta kopyalandı: $(SD_DISK)"
	@echo "   Şimdi kartı eject et, Pi 5'e tak ve UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ui-server.img bytes 1052448, SCREEN0, UISERVER0 FRAME_CRC=0x5350bcf591ef10cd."

# Path B writes aselsanos-rpi5-touch.img. It must not go through
# flash-rpi5-screen (A21) or flash-rpi5-ui-server (A22). Leftover
# A21/A22 kernels on the card are unused if config points here.
flash-rpi5-path-b: image-rpi5-touch
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-touch-path-b-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	cp "$(RPI5_TOUCH_IMG)" "$(SD_MOUNT)/aselsanos-rpi5-touch.img"
	cp "$(RPI5_TOUCH_DIR)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_TOUCH_DIR)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(RPI5_TOUCH_DIR)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(RPI5_TOUCH_SUMS)" "$(SD_MOUNT)/SHA256SUMS"
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-touch.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-touch.img değil"; exit 1; }
	sync
	@echo "✅ Path B touch imajı doğrulanmış FAT32 karta kopyalandı: $(SD_DISK)"
	@echo "   Şimdi kartı eject et, Pi 5'e tak ve UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-touch.img bytes 966352, SCREEN0, TOUCHREADY, TOUCHFRAME."
	@echo "   Panel Attempt-21 satırını gösterebilir (VERSION_A21); ayırt edici UART TOUCHREADY'dir."

# Attempt-29 writes aselsanos-rpi5-ios-home.img. It must not go through
# flash-rpi5-screen (A21), flash-rpi5-ui-server (A22) or flash-rpi5-path-b.
# Copies the frozen A29 package so a later live rebuild cannot silently replace it.
# A24/A26/A27/A28 freezes stay sealed and are no longer this flash gate.
flash-rpi5-ios-home:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-29-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	cp "$(A29_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A29_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A29_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A29_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A29_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	sync
	@echo "✅ Attempt-29 ios-home imajı doğrulanmış FAT32 karta kopyalandı: $(SD_DISK)"
	@echo "   Şimdi kartı eject et, Pi 5'e tak ve UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 2985680, SCREEN0, TOUCHREADY ACCEPTED=1,"
	@echo "   TOUCHFRAME EVENTS>0; sag ust kaydirma Kontrol Merkezi JPEG ayri kanit."

# Attempt-30 flash.  Copies the five frozen files, then writes the epoch blob
# with the host clock.  The blob is NOT in SHA256SUMS: it changes on every
# flash by design, which is exactly why the kernel image and the DTB do not.
flash-rpi5-ios-home-a31:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-31-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A31_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A31_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A31_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A31_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A31_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-31 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."

flash-rpi5-ios-home-a32:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-32-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A32_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A32_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A32_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A32_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A32_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-32 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."
	@echo "   Beklenen: PRESENT TARGET_HZ=60, her saniye PRESENT FRAMES/PERIOD_TICKS/MISSED."

flash-rpi5-ios-home-a33:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-33-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A33_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A33_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A33_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A33_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A33_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-33 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."
	@echo "   Beklenen: PRESENT PAINTED düşük boşta, titreme yok, PERIOD_TICKS≈900000."

flash-rpi5-ios-home-a34:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-34-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A34_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A34_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A34_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A34_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A34_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-34 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."
	@echo "   Beklenen: kaydirma sonrasi tap uygulamayi acar, duzenleme 800 ms."

flash-rpi5-ios-home-a35:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-35-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A35_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A35_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A35_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A35_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A35_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-35 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Capture: scripts/capture-rpi5-ios-home-uart.sh DEVICE OUTPUT (TOUCHREADY, 30s)."
	@echo "   Beklenen: TAP_SLOP=32, kacan RELEASE 2000 ms watchdog, TOUCHWATCHDOG UART."

verify-rpi5-screen-attempt-36-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-36.sh
	@sh scripts/freeze-rpi5-screen-attempt-36.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_36_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-36:
	@sh -n scripts/freeze-rpi5-screen-attempt-36.sh
	@sh scripts/freeze-rpi5-screen-attempt-36.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-36.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-36-candidate-freeze

flash-rpi5-ios-home-a36:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-36-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A36_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A36_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A36_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A36_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A36_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-36 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: ikon sürükleyip bırakınca yer değişir, sayfa kaymaz; titreme azalır."

verify-rpi5-screen-attempt-37-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-37.sh
	@sh scripts/freeze-rpi5-screen-attempt-37.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_37_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-37:
	@sh -n scripts/freeze-rpi5-screen-attempt-37.sh
	@sh scripts/freeze-rpi5-screen-attempt-37.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-37.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-37-candidate-freeze

flash-rpi5-ios-home-a37:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-37-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A37_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A37_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A37_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A37_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A37_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-37 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: sürükleme sırasında ikon sprite olarak takip eder, tam kare titreme yok."

verify-rpi5-screen-attempt-38-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-38.sh
	@sh scripts/freeze-rpi5-screen-attempt-38.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_38_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-38:
	@sh -n scripts/freeze-rpi5-screen-attempt-38.sh
	@sh scripts/freeze-rpi5-screen-attempt-38.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-38.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-38-candidate-freeze

flash-rpi5-ios-home-a38:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-38-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A38_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A38_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A38_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A38_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A38_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-38 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: ikonu bırakınca çerçeveler kalır, ikona dokununca program açılır."
	@echo "   UART: TOUCHFRAME EDIT=1 bırakma sonrası, dokunuştan sonra EDIT=0."

verify-rpi5-screen-attempt-39-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-39.sh
	@sh scripts/freeze-rpi5-screen-attempt-39.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_39_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-39:
	@sh -n scripts/freeze-rpi5-screen-attempt-39.sh
	@sh scripts/freeze-rpi5-screen-attempt-39.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-39.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-39-candidate-freeze

flash-rpi5-ios-home-a39:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-39-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A39_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A39_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A39_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A39_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A39_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-39 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: sürüklerken kirlenme/titreme yok; yerleştirme önizlemesi bırakınca uygulanır."
	@echo "   UART: taşıma penceresinde PRESENT PAINT_MAX sprite maliyetine düşmeli."

verify-rpi5-screen-attempt-40-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-40.sh
	@sh scripts/freeze-rpi5-screen-attempt-40.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_40_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-40:
	@sh -n scripts/freeze-rpi5-screen-attempt-40.sh
	@sh scripts/freeze-rpi5-screen-attempt-40.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-40.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-40-candidate-freeze

flash-rpi5-ios-home-a40:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-40-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A40_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A40_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A40_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A40_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A40_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-40 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: sürüklerken komşu ikonlar parmağı takip ederek kayar, kirlenme yok."
	@echo "   UART: taşıma penceresinde PAINT_MAX bir kare altında kalmalı (<900000 tick)."

verify-rpi5-screen-attempt-41-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-41.sh
	@sh scripts/freeze-rpi5-screen-attempt-41.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_41_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-41:
	@sh -n scripts/freeze-rpi5-screen-attempt-41.sh
	@sh scripts/freeze-rpi5-screen-attempt-41.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-41.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-41-candidate-freeze

flash-rpi5-ios-home-a41:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-41-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A41_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A41_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A41_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A41_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A41_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-41 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: kaldırma ve bırakma anındaki kısa titreme yarıya iner."
	@echo "   UART: kaldırma/bırakma penceresinde PAINT_MAX 4.4M -> ~1.75M tick olmalı."

verify-rpi5-screen-attempt-42-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-42.sh
	@sh scripts/freeze-rpi5-screen-attempt-42.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_42_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-42:
	@sh -n scripts/freeze-rpi5-screen-attempt-42.sh
	@sh scripts/freeze-rpi5-screen-attempt-42.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-42.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-42-candidate-freeze

flash-rpi5-ios-home-a42:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-42-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A42_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A42_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A42_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A42_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A42_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-42 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: kaldırma ve bırakma anında titreme HİÇ yok."
	@echo "   UART: PRESENT ... DOUBLEBUF=1 ve FLIP_BLIND=0 olmalı."

verify-rpi5-screen-attempt-43-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-43.sh
	@sh scripts/freeze-rpi5-screen-attempt-43.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_43_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-43:
	@sh -n scripts/freeze-rpi5-screen-attempt-43.sh
	@sh scripts/freeze-rpi5-screen-attempt-43.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-43.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-43-candidate-freeze

flash-rpi5-ios-home-a43:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-43-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A43_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A43_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A43_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A43_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A43_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-43 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: sürükleme alanındaki yatay bantlar YOK; kaldırma/bırakma da temiz."
	@echo "   UART: DOUBLEBUF=1, FLIP_BLIND=0, PAINT_MAX yine ~33 ms (artık bekleme dahil değil)."

verify-rpi5-screen-attempt-44-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-44.sh
	@sh scripts/freeze-rpi5-screen-attempt-44.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_44_candidate_freeze -- --test-threads=1

freeze-rpi5-screen-attempt-44:
	@sh -n scripts/freeze-rpi5-screen-attempt-44.sh
	@sh scripts/freeze-rpi5-screen-attempt-44.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-44.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-44-candidate-freeze

flash-rpi5-ios-home-a44:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-44-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A44_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A44_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A44_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A44_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A44_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-44 imajı + epoch blobu doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: AVUCU EKRANA KOY -- cihaz yasamaya devam etmeli, surukleme de bozulmamali."
	@echo "   UART: ASELSAN/TOUCHDROP FRAMES= gorunmeli, ASELSAN/TOUCHERR gorunmemeli."

# Attempt-45: AselBrowser telefon imajinin icinde.  Motor kernel'e no_std
# olarak bagli; ana ekrandaki Tarayici ikonu gercek tarayici gorunumunu aciyor.
verify-rpi5-screen-attempt-45-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-45.sh
	@sh scripts/freeze-rpi5-screen-attempt-45.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_45_candidate_freeze \
		--test rpi5_ios_home_browser -- --test-threads=1

freeze-rpi5-screen-attempt-45:
	@sh -n scripts/freeze-rpi5-screen-attempt-45.sh
	@sh scripts/freeze-rpi5-screen-attempt-45.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-45.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-45-candidate-freeze

flash-rpi5-ios-home-a45:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-45-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A45_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A45_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A45_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A45_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A45_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-45 imajı (AselBrowser imajın içinde) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3178200, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonuna dokun; PAGE=249 satırı ve tarayıcı ekranı."

# Attempt-46: tarayici referans yerlesimini giyiyor.  Orantili UI fontu,
# native yeni sekme sayfasi, referans menu ve ozellestirme sheet'leri, sekiz
# sekmelik izgara + sekme aramasi, Turkce klavye.  Cizilen ama calismayan her
# kontrol nedenini soyleyen bir kart aciyor.
verify-rpi5-screen-attempt-46-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-46.sh
	@sh scripts/freeze-rpi5-screen-attempt-46.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_46_candidate_freeze \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-46:
	@sh -n scripts/freeze-rpi5-screen-attempt-46.sh
	@sh scripts/freeze-rpi5-screen-attempt-46.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-46.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-46-candidate-freeze

flash-rpi5-ios-home-a46:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-46-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A46_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A46_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A46_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A46_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A46_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-46 imajı (referans yerleşimli tarayıcı) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3460824, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-47: A46'nin cihazda gösterdiği üç kusur kapatıldı — tarayıcı içi
# değişiklikler kareyi kirletiyor, kaydırma parmakla akıyor, sayfanın sonuna
# ulaşılabiliyor.  Ayrıca yeni sekme sayfası ölçülen referans metriklerine
# göre yeniden konumlandırıldı.
verify-rpi5-screen-attempt-47-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-47.sh
	@sh scripts/freeze-rpi5-screen-attempt-47.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_47_candidate_freeze \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-47:
	@sh -n scripts/freeze-rpi5-screen-attempt-47.sh
	@sh scripts/freeze-rpi5-screen-attempt-47.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-47.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-47-candidate-freeze

flash-rpi5-ios-home-a47:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-47-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A47_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A47_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A47_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A47_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A47_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-47 imajı (cihazın bulduğu kusurlar kapalı) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3481304, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-48: sayfa gorunumu referans kabugunu giydi (tek satirlik ust bant,
# ortalanmis adres kapsulu), sayfa govdesi orantili fonta gecti, adres ekrani
# tam ekran omnibox oldu ve cizim maliyeti bir kez daha dustu.
verify-rpi5-screen-attempt-48-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-48.sh
	@sh scripts/freeze-rpi5-screen-attempt-48.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_48_candidate_freeze \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-48:
	@sh -n scripts/freeze-rpi5-screen-attempt-48.sh
	@sh scripts/freeze-rpi5-screen-attempt-48.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-48.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-48-candidate-freeze

flash-rpi5-ios-home-a48:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-48-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A48_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A48_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A48_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A48_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A48_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-48 imajı (referans sayfa kabuğu + orantılı gövde) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3481304, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-49: A48 cihaz kosumunun bulduğu iki kusur kapandı — yerleşik olmayan
# bir ad artık ağa gidip motorun kendi reddini gösteriyor (eskiden "yerleşik
# sayfa yok" diyordu), ve 60 Hz kadansı faz kilitli (boşta bile ~56 Hz koşuyordu).
verify-rpi5-screen-attempt-49-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-49.sh
	@sh scripts/freeze-rpi5-screen-attempt-49.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_49_candidate_freeze \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_aselmotor \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-49:
	@sh -n scripts/freeze-rpi5-screen-attempt-49.sh
	@sh scripts/freeze-rpi5-screen-attempt-49.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-49.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-49-candidate-freeze

flash-rpi5-ios-home-a49:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-49-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A49_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A49_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A49_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A49_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A49_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-49 imajı (dürüst ret + faz kilitli kadans) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3489492, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-50: derleyici beş özel durum yerine TEK MODEL.  Her tampon kendi
# içeriğini taşır, ne yapılacağına saf bir fonksiyon karar verir ve o karar
# host'ta geçiş matrisiyle kanıtlanır: her (from, to) çifti için plan uygulanıp
# sonuç hedefin tam bestelemesiyle bayt bayt karşılaştırılır.  Hiçbir tampon
# kopyalanmaz.
verify-rpi5-screen-attempt-50-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-50.sh
	@sh scripts/freeze-rpi5-screen-attempt-50.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_50_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-50:
	@sh -n scripts/freeze-rpi5-screen-attempt-50.sh
	@sh scripts/freeze-rpi5-screen-attempt-50.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-50.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-50-candidate-freeze

flash-rpi5-ios-home-a50:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-50-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A50_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A50_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A50_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A50_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A50_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-50 imajı (her geçiş için tek model) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3485400, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-51: fazlar ölçülüyor (ASELSAN/PHASE), bekleyen flip vsync'ten hemen
# sonra emekliye ayrılıyor ve tam genişlikteki bant tek memmove.
verify-rpi5-screen-attempt-51-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-51.sh
	@sh scripts/freeze-rpi5-screen-attempt-51.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_51_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-51:
	@sh -n scripts/freeze-rpi5-screen-attempt-51.sh
	@sh scripts/freeze-rpi5-screen-attempt-51.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-51.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-51-candidate-freeze

flash-rpi5-ios-home-a51:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-51-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A51_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A51_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A51_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A51_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A51_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-51 imajı (fazlar ölçülüyor, tahmin edilmiyor) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3489496, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-52: ölçüm çizimi işaret etti — ekrana hiç ulaşmayan bir alan (canlı
# heap ölçüleri) ötelemeyi reddettiriyordu.  Ayrıca bir programda yatay
# sürükleme artık çıkarmaz; çıkış alttan yukarı sürüklemedir.
verify-rpi5-screen-attempt-52-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-52.sh
	@sh scripts/freeze-rpi5-screen-attempt-52.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_52_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-52:
	@sh -n scripts/freeze-rpi5-screen-attempt-52.sh
	@sh scripts/freeze-rpi5-screen-attempt-52.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-52.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-52-candidate-freeze

flash-rpi5-ios-home-a52:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-52-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A52_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A52_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A52_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A52_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A52_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-52 imajı (maliyet çizimde; yatay sürükleme programdan çıkarmaz) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3485400, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-53: değişmeyeni besteleme.  Plan modeline üçüncü adım eklendi —
# hasar dikdörtgeni.  Saat değişince yalnızca durum çubuğu, tuşa basınca
# yalnızca alan ve öneri listesi çizilir; klavye yerinde kalır.
verify-rpi5-screen-attempt-53-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-53.sh
	@sh scripts/freeze-rpi5-screen-attempt-53.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_53_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-53:
	@sh -n scripts/freeze-rpi5-screen-attempt-53.sh
	@sh scripts/freeze-rpi5-screen-attempt-53.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-53.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-53-candidate-freeze

flash-rpi5-ios-home-a53:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-53-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A53_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A53_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A53_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A53_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A53_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-53 imajı (değişmeyeni besteleme) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-54: A53 cihazda tarayıcı açılınca sustu.  Plan zinciri artık kare
# kopyalamıyor (referans + alan yıkımı) ve yığın derinliği ölçülüp
# ASELSAN/PHASE içinde STACK_USED olarak yayımlanıyor.
verify-rpi5-screen-attempt-54-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-54.sh
	@sh scripts/freeze-rpi5-screen-attempt-54.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_54_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-54:
	@sh -n scripts/freeze-rpi5-screen-attempt-54.sh
	@sh scripts/freeze-rpi5-screen-attempt-54.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-54.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-54-candidate-freeze

flash-rpi5-ios-home-a54:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-54-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A54_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A54_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A54_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A54_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A54_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-54 imajı (donan ekran + yığın göstergesi) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-55: A54'ün yığın boyaması canlı veriyi ezdi (deadline 0xA5A5...).
# Ölçüm artık pasif: yerel bir değişkenin adresi ile __stack_top farkı.
# A54'ün asıl işi duruyor: plan zinciri kare kopyalamıyor.
verify-rpi5-screen-attempt-55-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-55.sh
	@sh scripts/freeze-rpi5-screen-attempt-55.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_55_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-55:
	@sh -n scripts/freeze-rpi5-screen-attempt-55.sh
	@sh scripts/freeze-rpi5-screen-attempt-55.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-55.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-55-candidate-freeze

flash-rpi5-ios-home-a55:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-55-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A55_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A55_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A55_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A55_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A55_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-55 imajı (yığını oku, yazma) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-56: adres çubuğuna dokunmak metnin tamamını seçiyordu; imleç artık
# dokunulan yere gidiyor, yanıp sönüyor, ve yazma kipindeki dokunuşlar çizimle
# aynı dikdörtgenlere gidiyor (eskiden önceki yerleşimin dikdörtgenleri
# soruluyordu — panelde "dokunuşlar cevap vermiyor" buydu).
verify-rpi5-screen-attempt-56-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-56.sh
	@sh scripts/freeze-rpi5-screen-attempt-56.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_56_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-56:
	@sh -n scripts/freeze-rpi5-screen-attempt-56.sh
	@sh scripts/freeze-rpi5-screen-attempt-56.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-56.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-56-candidate-freeze

flash-rpi5-ios-home-a56:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-56-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A56_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A56_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A56_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A56_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A56_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-56 imajı (imleç dokunduğun yere gider) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-57: imleç yanıp sönmüyordu (faz dönüyor ama kare kirlenmiyordu),
# tuşların arasına dokunmak klavyeyi kapatıyordu, uzun adreste imleç alanın
# dışına kaçıyordu.  Üçü de kapandı ve davranışlar bir sözleşme olarak yazıldı.
verify-rpi5-screen-attempt-57-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-57.sh
	@sh scripts/freeze-rpi5-screen-attempt-57.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_57_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-57:
	@sh -n scripts/freeze-rpi5-screen-attempt-57.sh
	@sh scripts/freeze-rpi5-screen-attempt-57.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-57.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-57-candidate-freeze

flash-rpi5-ios-home-a57:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-57-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A57_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A57_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A57_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A57_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A57_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-57 imajı (metin alanı davranış sözleşmesi) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-58: kısayol şeridi sağa sola kaydırılabilir ve kartın içine kırpılır;
# beşinci kısayola artık ulaşılır.  Kartın yüksekliği 111 pt -> 96 pt.
verify-rpi5-screen-attempt-58-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-58.sh
	@sh scripts/freeze-rpi5-screen-attempt-58.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_58_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-58:
	@sh -n scripts/freeze-rpi5-screen-attempt-58.sh
	@sh scripts/freeze-rpi5-screen-attempt-58.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-58.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-58-candidate-freeze

flash-rpi5-ios-home-a58:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-58-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A58_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A58_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A58_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A58_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A58_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-58 imajı (kısayol şeridi kayar) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3493592, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-59: ana ekranda alttan yukarı sürükleme uygulama değiştiriciyi açar.
# Arka plandaki program canlı bir süreç değildir: listede duran şey 14 baytlık
# bir görünüm değeridir, hiçbir kare saklanmaz.
verify-rpi5-screen-attempt-59-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-59.sh
	@sh scripts/freeze-rpi5-screen-attempt-59.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_59_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-59:
	@sh -n scripts/freeze-rpi5-screen-attempt-59.sh
	@sh scripts/freeze-rpi5-screen-attempt-59.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-59.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-59-candidate-freeze

flash-rpi5-ios-home-a59:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-59-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A59_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A59_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A59_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A59_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A59_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-59 imajı (RAM yemeyen uygulama değiştirici) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3497688, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-60: arayüz Türkçe yazıldı (font zaten destekliyordu), geri tuşu
# gidilecek yer yokken sayfayı kapatmıyor.
verify-rpi5-screen-attempt-60-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-60.sh
	@sh scripts/freeze-rpi5-screen-attempt-60.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_60_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-60:
	@sh -n scripts/freeze-rpi5-screen-attempt-60.sh
	@sh scripts/freeze-rpi5-screen-attempt-60.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-60.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-60-candidate-freeze

flash-rpi5-ios-home-a60:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-60-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A60_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A60_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A60_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A60_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A60_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-60 imajı (Türkçe harfler) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3497688, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-61: basılan tuşun üstünde balon önizleme; ve ana ekran hareketi artık
# ASELSAN/GESTURE satırıyla ölçülüyor (iki koşumda tetiklenmedi, sebebi
# görünmüyordu).
verify-rpi5-screen-attempt-61-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-61.sh
	@sh scripts/freeze-rpi5-screen-attempt-61.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_61_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-61:
	@sh -n scripts/freeze-rpi5-screen-attempt-61.sh
	@sh scripts/freeze-rpi5-screen-attempt-61.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-61.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-61-candidate-freeze

flash-rpi5-ios-home-a61:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-61-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A61_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A61_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A61_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A61_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A61_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-61 imajı (tuş balonu + ölçülebilir hareket) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3497688, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."

# Attempt-62: ayarlar listesinin tipografisi referansa oturdu — 63 px'lik
# büyük başlık yüzü atlasa eklendi ve durum çubuğu orantılı fontla çiziliyor.
verify-rpi5-screen-attempt-62-candidate-freeze:
	@sh -n scripts/freeze-rpi5-screen-attempt-62.sh
	@sh scripts/freeze-rpi5-screen-attempt-62.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_screen_attempt_62_candidate_freeze \
		--test rpi5_aselmotor_plan \
		--test rpi5_aselmotor \
		--test rpi5_ios_home \
		--test rpi5_ios_home_browser \
		--test rpi5_browser_layout \
		--test rpi5_present_60hz_source \
		--test rpi5_ui_text -- --test-threads=1

freeze-rpi5-screen-attempt-62:
	@sh -n scripts/freeze-rpi5-screen-attempt-62.sh
	@sh scripts/freeze-rpi5-screen-attempt-62.sh --source-check
	@sh scripts/freeze-rpi5-screen-attempt-62.sh --freeze
	@$(MAKE) verify-rpi5-screen-attempt-62-candidate-freeze

flash-rpi5-ios-home-a62:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-screen-attempt-62-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(A62_IOS_HOME_PACKAGE)/aselsanos-rpi5-ios-home.img" "$(SD_MOUNT)/aselsanos-rpi5-ios-home.img"
	cp "$(A62_IOS_HOME_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(A62_IOS_HOME_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(A62_IOS_HOME_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(A62_IOS_HOME_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-ios-home.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-ios-home.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ Attempt-62 imajı (referansa oturan ayarlar listesi) doğrulanmış FAT32 karta yazıldı: $(SD_DISK)"
	@echo "   Kartı eject et, Pi 5'e tak, UART capture'ı ARM etmeden güç verme."
	@echo "   Beklenen: Read aselsanos-rpi5-ios-home.img bytes 3690200, SCREEN0, TOUCHREADY ACCEPTED=1."
	@echo "   Tarayıcı kabulü: sayfa 1'de Tarayici ikonu -> yeni sekme sayfası; PAGE=249 satırı."



# SD-A0: microSD SDHCI register envanteri. Tek yeni MMIO sayfasi, sifir komut,
# sifir yazma. Ayri imaj adi ve ayri target-dir: bir esleme hatasi donmus ekran
# ya da ios-home adaylarina ulasamaz.
RPI5_SD_PROFILE := firmware/rpi5-sd-profile.txt

# SD-C W3: karta yazabilen tek imaj.  Ayri target-dir ve ayri imaj adi:
# bir esleme hatasi yazma yetenekli bir cekirdegi salt-okunur bir adayin
# yerine koyamaz.
RPI5_SDW_TARGET_DIR := target/rpi5-sd-write
RPI5_SDW_ELF := $(RPI5_SDW_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel

# SD-C W4: superblok commit protokolu.  Ayri feature ve ayri target-dir:
# W3 imaji kanitlanabilir sekilde tek bir VERI sektoru yazar, W4 imaji
# kanitlanabilir sekilde superblok yazar ve hicbir veri sektorune dokunmaz.
RPI5_SDSB_TARGET_DIR := target/rpi5-sd-superblock
RPI5_SDSB_ELF := $(RPI5_SDSB_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel

# SD-C W5: kodeksiz toplu zamanlama.  Ayri feature, ayri target-dir.
RPI5_SDBK_TARGET_DIR := target/rpi5-sd-bulk
RPI5_SDBK_ELF := $(RPI5_SDBK_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel

# SD-C W6: CMD25, ayni 1024 sektor, en fazla bir kume.  Ayri feature, ayri dir.
RPI5_SDM_TARGET_DIR := target/rpi5-sd-multi
RPI5_SDM_ELF := $(RPI5_SDM_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_SD_W6_PROFILE := firmware/rpi5-sd-w6-profile.txt

# SD-C W7: bir gercek kare.  Scaler + RGB565 + ROW_RLE16.  Ayri feature, ayri dir.
RPI5_SDF_TARGET_DIR := target/rpi5-sd-frame
RPI5_SDF_ELF := $(RPI5_SDF_TARGET_DIR)/$(TARGET)/debug/aselsan_kernel
RPI5_SD_W7_PROFILE := firmware/rpi5-sd-w7-profile.txt

image-rpi5-sd-frame: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_W7_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SDF_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-write-frame
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı"; exit 1; \
	fi
	@mkdir -p $(RPI5_SD_DIR)
	@$(OBJCOPY) -O binary $(RPI5_SDF_ELF) $(RPI5_SD_IMG)
	@cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	@cp $(RPI5_SD_W7_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "SD-C W7 adayi: bir gercek kare, scaler+RGB565+ROW_RLE16, CMD25, 100% read-back."
	@echo "   Freeze: make freeze-rpi5-sd-attempt-w7. Flash: kart Mac'te, W6_PHYSICAL_PASS=yes."

image-rpi5-sd-multi: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_W6_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SDM_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-write-multi
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı"; exit 1; \
	fi
	@mkdir -p $(RPI5_SD_DIR)
	@$(OBJCOPY) -O binary $(RPI5_SDM_ELF) $(RPI5_SD_IMG)
	@cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	@cp $(RPI5_SD_W6_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "SD-C W6 adayi: ayni 1024 VERI sektoru, CMD25, burst <= 64, kosu sinirini gecmez."
	@echo "   Freeze: make freeze-rpi5-sd-attempt-w6. Flash: kart Mac'te, W5_PHYSICAL_PASS=yes."

image-rpi5-sd-bulk: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SDBK_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-write-bulk
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı"; exit 1; \
	fi
	@mkdir -p $(RPI5_SD_DIR)
	@$(OBJCOPY) -O binary $(RPI5_SDBK_ELF) $(RPI5_SD_IMG)
	@cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	@cp $(RPI5_SD_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "SD-C W5 adayi: bu imaj 1024 VERI sektoru yazar (dosya ofseti 64..1087)."

image-rpi5-sd-superblock: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SDSB_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-write-superblock
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı"; exit 1; \
	fi
	@mkdir -p $(RPI5_SD_DIR)
	@$(OBJCOPY) -O binary $(RPI5_SDSB_ELF) $(RPI5_SD_IMG)
	@cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	@cp $(RPI5_SD_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "SD-C W4 adayi: bu imaj SUPERBLOK yazar (sektor 0 ve 1)."

image-rpi5-sd-write: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SDW_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-write
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@mkdir -p $(RPI5_SD_DIR)
	@$(OBJCOPY) -O binary $(RPI5_SDW_ELF) $(RPI5_SD_IMG)
	@cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	@cp $(RPI5_SD_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "SD-C W3 adayi: $(RPI5_SD_IMG) -- bu imaj karta YAZABILIR."

# Radio chain: host pin of the DTB-derived addresses, of the exact write
# boundary, and a fail-closed AArch64 check of both profiles.  Not a flash
# image and not a radio PASS.
check-rpi5-radio-inventory:
	@$(CARGO) test -p aselsan_microkernel_simulation --test rpi5_radio_source -- --quiet
	@$(CARGO) test -p aselsan_microkernel_simulation --test rpi5_sd_source -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) check -p aselsan_kernel \
		--target $(TARGET) --no-default-features \
		--features board-rpi5,rpi5-ios-home-demo
	@CARGO_INCREMENTAL=0 $(CARGO) check -p aselsan_kernel \
		--target $(TARGET) --no-default-features \
		--features board-rpi5,rpi5-radio-inventory
	@echo "WIFI-A1/BT-A1 kaynak pini. Fiziksel radyo PASS değildir."

# Firmware sahipligi deneyi.  AYNI cekirdek: imaj YENIDEN DERLENMEZ ve
# sha'si dogrulanir; tek degisken overlay'dir.
#
# `.dtbo` olmadan config.txt'ye satir eklemek deney DEGILDIR: overlay sessizce
# yuklenmez, P30_HELD yine 0 cikar ve hipotez sinanmis gibi gorunur.  Bu hedef
# dosyalari karta koyar ve imzalarini kartta yeniden dogrular.
RPI5_RADIO_PINNED_SHA := 256104c4880f40bde9ab74f6ea6ebfbb988d2d7efa23f31979d9bc75af7487bd

flash-rpi5-radio-nowifi:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test -f "$(RPI5_RADIO_IMG)" || \
		{ echo "HATA: build/rpi5-radio yok; bu hedef IMAJ URETMEZ"; exit 1; }
	@SHA=$$(shasum -a 256 "$(RPI5_RADIO_IMG)" | cut -d' ' -f1); \
		[ "$$SHA" = "$(RPI5_RADIO_PINNED_SHA)" ] || \
		{ echo "HATA: cekirdek degismis. Beklenen $(RPI5_RADIO_PINNED_SHA), bulunan $$SHA"; \
		  echo "      Bu deneyin tek degiskeni overlay olmali."; exit 1; }
	@echo "   Cekirdek pinli sha ile ayni: yeniden derlenmedi."
	@cd firmware/overlays && shasum -a 256 -c SHA256SUMS
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img \
		aselsanos-rpi5-ios-home.img aselsanos-rpi5-sensors.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then rm -f "$(SD_MOUNT)/$$STALE"; fi; \
	done
	cp "$(RPI5_RADIO_IMG)" "$(SD_MOUNT)/aselsanos-rpi5-radio.img"
	cp "$(RPI5_DTB)" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_RADIO_PROFILE)" "$(SD_MOUNT)/PROFILE.txt"
	mkdir -p "$(SD_MOUNT)/overlays"
	cp firmware/overlays/disable-wifi.dtbo "$(SD_MOUNT)/overlays/disable-wifi.dtbo"
	cp firmware/overlays/disable-wifi-pi5.dtbo "$(SD_MOUNT)/overlays/disable-wifi-pi5.dtbo"
	@set -eu; TMP=$(SD_MOUNT)/config.txt.tmp; \
		trap 'rm -f "$$TMP"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-radio.img aselsanos-epoch.bin > "$$TMP"; \
		echo 'dtoverlay=disable-wifi-pi5' >> "$$TMP"; \
		mv "$$TMP" $(SD_MOUNT)/config.txt; \
		trap - EXIT HUP INT TERM
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	@$(MAKE) copy-rpi5-wifi-firmware SD_MOUNT="$(SD_MOUNT)"
	sync
	@grep -Fxq 'dtoverlay=disable-wifi-pi5' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: overlay satiri config.txt'de yok"; exit 1; }
	@grep -Fxq 'kernel=aselsanos-rpi5-radio.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel satiri yanlis"; exit 1; }
	@for F in disable-wifi.dtbo disable-wifi-pi5.dtbo; do \
		A=$$(shasum -a 256 "firmware/overlays/$$F" | cut -d' ' -f1); \
		B=$$(shasum -a 256 "$(SD_MOUNT)/overlays/$$F" | cut -d' ' -f1); \
		[ "$$A" = "$$B" ] || { echo "HATA: karttaki $$F imzasi tutmuyor"; exit 1; }; \
		echo "   kartta dogrulandi: overlays/$$F"; \
	done
	@SHA=$$(shasum -a 256 "$(SD_MOUNT)/aselsanos-rpi5-radio.img" | cut -d' ' -f1); \
		[ "$$SHA" = "$(RPI5_RADIO_PINNED_SHA)" ] || \
		{ echo "HATA: karttaki cekirdek pinli sha degil"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN kayboldu"; exit 1; }
	@echo "   Cekirdek: $(RPI5_RADIO_PINNED_SHA) (degismedi)"
	@echo "   KOSU GECERLILIK SARTI (R11 dersi):"
	@echo "     UART'ta 'disable-wifi-pi5.dtbo bytes      267' GORULMELI"
	@echo "     ve 'Failed to resolve overlay' GORULMEMELI."
	@echo "   R11'de genel ad kullanilmisti; overlay_map.dtb olmadigi icin"
	@echo "   firmware Pi 5 varyantina yonlendiremedi, 387 baytlik bcm2835"
	@echo "   dosyasini yukledi ve cozumleyemedi.  Overlay UYGULANMADI."
	@echo "   Varyant artik ADIYLA cagriliyor; bayt sayisi hangisinin"
	@echo "   yuklendigini tek basina soyler."

# C0/D0 yerlesim deneyi, basamak 1.  AYNI cekirdek (R13); tek degisken
# overlays/bcm2712d0.dtbo.  config.txt'ye dtoverlay=bcm2712d0 YAZILMAZ:
# firmware D0'da dosyayi kendisi arar (R11/R12: not found).  C0'da zorla
# uygulamak kelime 2'ye (C0'da PWR_GPIO) yanlis DTB yapistirir.
RPI5_RADIO_D0PROBE_SHA := 3820ef8396f5f47e904cca8dd9a5c7289cfd524fd600fa0fb17f2aa1e0c1dc9d

flash-rpi5-radio-d0probe:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test -f "$(RPI5_RADIO_IMG)" || \
		{ echo "HATA: build/rpi5-radio yok; bu hedef IMAJ URETMEZ"; exit 1; }
	@SHA=$$(shasum -a 256 "$(RPI5_RADIO_IMG)" | cut -d' ' -f1); \
		[ "$$SHA" = "$(RPI5_RADIO_D0PROBE_SHA)" ] || \
		{ echo "HATA: cekirdek R13 degil. Beklenen $(RPI5_RADIO_D0PROBE_SHA), bulunan $$SHA"; \
		  echo "      Basamak 1 tek degiskeni bcm2712d0.dtbo olmali."; exit 1; }
	@echo "   Cekirdek R13 pinli sha ile ayni: yeniden derlenmedi."
	@cd firmware/overlays && shasum -a 256 -c SHA256SUMS
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img \
		aselsanos-rpi5-ios-home.img aselsanos-rpi5-sensors.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then rm -f "$(SD_MOUNT)/$$STALE"; fi; \
	done
	cp "$(RPI5_RADIO_IMG)" "$(SD_MOUNT)/aselsanos-rpi5-radio.img"
	cp "$(RPI5_DTB)" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_RADIO_PROFILE)" "$(SD_MOUNT)/PROFILE.txt"
	mkdir -p "$(SD_MOUNT)/overlays"
	cp firmware/overlays/bcm2712d0.dtbo "$(SD_MOUNT)/overlays/bcm2712d0.dtbo"
	@set -eu; TMP=$(SD_MOUNT)/config.txt.tmp; \
		trap 'rm -f "$$TMP"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-radio.img aselsanos-epoch.bin > "$$TMP"; \
		mv "$$TMP" $(SD_MOUNT)/config.txt; \
		trap - EXIT HUP INT TERM
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	@$(MAKE) copy-rpi5-wifi-firmware SD_MOUNT="$(SD_MOUNT)"
	sync
	@grep -q 'dtoverlay=bcm2712d0' "$(SD_MOUNT)/config.txt" && \
		{ echo "HATA: dtoverlay=bcm2712d0 config'te; C0'da zorla uygulanamaz"; exit 1; } || true
	@grep -q 'dtoverlay=disable-wifi' "$(SD_MOUNT)/config.txt" && \
		{ echo "HATA: disable-wifi bu deneyin degiskeni degil"; exit 1; } || true
	@grep -Fxq 'kernel=aselsanos-rpi5-radio.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel satiri yanlis"; exit 1; }
	@A=$$(shasum -a 256 firmware/overlays/bcm2712d0.dtbo | cut -d' ' -f1); \
		B=$$(shasum -a 256 "$(SD_MOUNT)/overlays/bcm2712d0.dtbo" | cut -d' ' -f1); \
		[ "$$A" = "$$B" ] || { echo "HATA: karttaki bcm2712d0.dtbo imzasi tutmuyor"; exit 1; }; \
		echo "   kartta dogrulandi: overlays/bcm2712d0.dtbo"
	@SHA=$$(shasum -a 256 "$(SD_MOUNT)/aselsanos-rpi5-radio.img" | cut -d' ' -f1); \
		[ "$$SHA" = "$(RPI5_RADIO_D0PROBE_SHA)" ] || \
		{ echo "HATA: karttaki cekirdek pinli sha degil"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN kayboldu"; exit 1; }
	@echo "   Cekirdek: $(RPI5_RADIO_D0PROBE_SHA) (R13, degismedi)"
	@echo "   KOSU GECERLILIK SARTI:"
	@echo "     Loaded overlay 'bcm2712d0' → D0; C0 PIN_PLAN yanlis olabilir, kelime 2'ye YAZILMAZ."
	@echo "     dosya var, Loaded yok → firmware C0'da atladı; hipotez bu kartta duser."
	@echo "     hâlâ 'bcm2712d0.dtbo not found' → dosya karta girmedi; kosu gecersiz."

# Radyo adayini karta yazar ve firmware'i yaninda tasir.  Kaynak dondurulmus
# bir kanit paketi DEGIL: calisma agacindan taze kurulmus $(RPI5_RADIO_DIR).
flash-rpi5-radio:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test -f "$(RPI5_RADIO_IMG)" || \
		{ echo "HATA: once make image-rpi5-radio"; exit 1; }
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@cd $(RPI5_RADIO_DIR) && shasum -a 256 -c SHA256SUMS
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img \
		aselsanos-rpi5-ios-home.img aselsanos-rpi5-sensors.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(RPI5_RADIO_DIR)/aselsanos-rpi5-radio.img" "$(SD_MOUNT)/aselsanos-rpi5-radio.img"
	cp "$(RPI5_RADIO_DIR)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_RADIO_DIR)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(RPI5_RADIO_DIR)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(RPI5_RADIO_DIR)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin.tmp"
	@python3 scripts/build-boot-blob.py --epoch "$(SD_MOUNT)/aselsanos-epoch.bin.tmp" \
		--out "$(SD_MOUNT)/aselsanos-epoch.bin" \
		--manifest "$(SD_MOUNT)/BOOT_BLOB.txt" \
		--payload BRCMFW.BIN=firmware/wifi/BRCMFW.BIN \
		--payload BRCMNVR.TXT=firmware/wifi/BRCMNVR.TXT \
		--payload BRCMCLM.BLB=firmware/wifi/BRCMCLM.BLB
	@rm -f "$(SD_MOUNT)/aselsanos-epoch.bin.tmp"
	@$(MAKE) copy-rpi5-wifi-firmware SD_MOUNT="$(SD_MOUNT)"
	@mkdir -p "$(SD_MOUNT)/overlays"
	@test -f "$(SD_MOUNT)/overlays/bcm2712d0.dtbo" || \
		cp firmware/overlays/bcm2712d0.dtbo "$(SD_MOUNT)/overlays/bcm2712d0.dtbo"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-radio.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-radio.img degil"; exit 1; }
	@grep -q 'dtoverlay=bcm2712d0' "$(SD_MOUNT)/config.txt" && \
		{ echo "HATA: dtoverlay=bcm2712d0 config'te; C0'da zorla uygulanamaz"; exit 1; } || true
	@A=$$(shasum -a 256 firmware/overlays/bcm2712d0.dtbo | cut -d' ' -f1); \
		B=$$(shasum -a 256 "$(SD_MOUNT)/overlays/bcm2712d0.dtbo" | cut -d' ' -f1); \
		[ "$$A" = "$$B" ] || { echo "HATA: karttaki bcm2712d0.dtbo imzasi tutmuyor"; exit 1; }; \
		echo "   kartta dogrulandi: overlays/bcm2712d0.dtbo"
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazilirken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	@echo "   yazilan imaj sha256: $$(shasum -a 256 "$(SD_MOUNT)/aselsanos-rpi5-radio.img" | cut -d' ' -f1)"
	@echo "   Dosyalar karta yazildi; bu, Wi-Fi'nin calistigi anlamina gelmez."
	@echo "   Firmware baslatma ve ag tarama sonucu Pi'nin UART kaydindan okunmali."
	@echo "   Beklenen UART: ASELSAN/WIFICMD5, ASELSAN/WIFIBP, ASELSAN/WIFICMD53, ASELSAN/BTHCI."

# Sensor adayini karta yazar.  Kaynak, dondurulmus bir kanit paketi DEGIL:
# calisma agacindan taze kurulmus $(RPI5_SENSOR_DIR).  Bu yuzden hedef, hangi
# baytlarin yazildigini imza ve git durumu olarak EKRANA basar; bir UART
# kosusu ancak o kimlikle birlikte anlamlidir.
flash-rpi5-sensors:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@test -f "$(RPI5_SENSOR_IMG)" || \
		{ echo "HATA: önce make image-rpi5-sensors"; exit 1; }
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@cd $(RPI5_SENSOR_DIR) && shasum -a 256 -c SHA256SUMS
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-sd.img \
		aselsanos-rpi5-ios-home.img aselsanos-rpi5-radio.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(RPI5_SENSOR_DIR)/aselsanos-rpi5-sensors.img" "$(SD_MOUNT)/aselsanos-rpi5-sensors.img"
	cp "$(RPI5_SENSOR_DIR)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_SENSOR_DIR)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(RPI5_SENSOR_DIR)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(RPI5_SENSOR_DIR)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-sensors.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-sensors.img değil"; exit 1; }
	@grep -Fxq 'initramfs aselsanos-epoch.bin 0x10000000' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config epoch blob directive taşımıyor"; exit 1; }
	@test -f "$(SD_MOUNT)/aselsanos-epoch.bin" || \
		{ echo "HATA: epoch blob karta yazılmadı"; exit 1; }
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN karta yazılırken kayboldu"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	@echo "   yazılan imaj sha256: $$(shasum -a 256 "$(SD_MOUNT)/aselsanos-rpi5-sensors.img" | cut -d' ' -f1)"
	@echo "   kaynak git HEAD: $$(git rev-parse --short HEAD) ($$(git status --porcelain | wc -l | tr -d '[:space:]') dosya değişik)"
	@echo "   Sensör bloğu SCREEN0'dan ÖNCE koşar: orada takılırsa ekran siyah kalır."
	@echo "   Beklenen UART satırları: ASELSAN/PMU, ASELSAN/THERMAL, ASELSAN/RNG, ASELSAN/PWRBTN."

# Wi-Fi firmware ucuncu taraftir ve imaja GOMULMEZ.  Bu hedef yalnizca
# kimligini dogrular; hicbir sey indirmez ve hicbir sey calistirmaz.
verify-rpi5-wifi-firmware:
	@test -f firmware/wifi/BRCMFW.BIN || \
		{ echo "HATA: firmware/wifi/BRCMFW.BIN yok"; exit 1; }
	@cd firmware/wifi && shasum -a 256 -c SHA256SUMS
	@SIZE=$$(wc -c < firmware/wifi/BRCMFW.BIN | tr -d '[:space:]'); \
		[ "$$SIZE" -eq 609309 ] || \
		{ echo "HATA: BRCMFW.BIN 609309 bayt degil: $$SIZE"; exit 1; }
	@test -f firmware/wifi/LICENSE.txt || \
		{ echo "HATA: lisans metni dosyalarla birlikte tasinmali"; exit 1; }
	@grep -q "binary-redist-Cypress" firmware/wifi/LICENSE.txt || \
		{ echo "HATA: Cypress lisansi LICENSE.txt icinde yok"; exit 1; }
	@! LC_ALL=C strings build/rpi5-radio/aselsanos-rpi5-radio.img 2>/dev/null \
		| grep -q "bcm94345wlpagb" || \
		{ echo "HATA: firmware imaja gomulmus"; exit 1; }
	@echo "   Wi-Fi firmware kimligi dogrulandi. Imaja GOMULMEDI, indirilmedi."

# Firmware'i karta kopyalar.  Imaji ELLEMEZ: yalnizca uc dosyayi kartin
# kokune 8.3 adlariyla koyar, cekirdek onlari FAT32 locate() ile bulacak.
copy-rpi5-wifi-firmware: verify-rpi5-wifi-firmware
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test -f "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: bu bir AselsanOS karti degil: $(SD_MOUNT)"; exit 1; }
	cp firmware/wifi/BRCMFW.BIN  "$(SD_MOUNT)/BRCMFW.BIN"
	cp firmware/wifi/BRCMNVR.TXT "$(SD_MOUNT)/BRCMNVR.TXT"
	cp firmware/wifi/BRCMCLM.BLB "$(SD_MOUNT)/BRCMCLM.BLB"
	cp firmware/wifi/LICENSE.txt "$(SD_MOUNT)/BRCMLIC.TXT"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 BRCMFW.BIN | cut -d' ' -f1 | \
		grep -qx d608f866582519c0a28d86db43040f4f1b98dd1d153e72e9752586546b4a36c3 || \
		{ echo "HATA: karttaki BRCMFW.BIN beklenen imzada degil"; exit 1; }
	@echo "   Firmware dosyalari kartta. Cipte yukleme/baslatma/tarama ayrica dogrulanmali."

# Sensor chain: host pin of the DTB-derived addresses, of the DTB-derived
# temperature formula, and of the read-only boundary.  Not a flash image.
check-rpi5-sensors:
	@$(CARGO) test -p aselsan_microkernel_simulation --test rpi5_sensor_source -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) check -p aselsan_kernel \
		--target $(TARGET) --no-default-features \
		--features board-rpi5,rpi5-ios-home-demo
	@CARGO_INCREMENTAL=0 $(CARGO) check -p aselsan_kernel \
		--target $(TARGET) --no-default-features \
		--features board-rpi5,rpi5-sensors
	@echo "Sensör kaynak pini. Fiziksel PASS değildir."

# Sensor adayi: donanim RNG, CPU sicakligi, guc dugmesi ve PMU.  Uc sayfa
# haritalar; yalnizca RNG yazar ve yalnizca kendi blogunun kayitlarina.
image-rpi5-sensors: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SENSOR_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sensor_source --test rpi5_sd_source \
		--test rpi5_ios_home --test rpi5_screen_source -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SENSOR_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sensors
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_SENSOR_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: sensor image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/PMU IMP=" "ASELSAN/THERMAL RAW=" \
		"ASELSAN/RNG CTRL=" "ASELSAN/PWRBTN DATA=" "ASELSAN/SCREEN0 RP1="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_SENSOR_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: sensor marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@for DISCLAIMER in "DRBG=0 ENTROPY_ESTIMATE=0" "THROTTLE=0" \
		"POLLED=0 ACTION=0" "SAMPLED=0 IRQ=0"; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_SENSOR_ELF) | grep -Fo -- "$$DISCLAIMER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: sensor disclaimer exact-once değil: $$DISCLAIMER ($$COUNT)"; exit 1; }; \
	done
	@CARDWRITE=$$(LC_ALL=C strings $(RPI5_SENSOR_ELF) | grep -Eo -- "CMD24|CMD25|CMD32|CMD38" | wc -l | tr -d '[:space:]'); \
		[ "$$CARDWRITE" -eq 0 ] || \
		{ echo "HATA: sensör imajında kart yazma komutu dizesi var: $$CARDWRITE"; exit 1; }
	@echo "   Sensör sözleşmesi: sıcaklık/düğme/PMU salt okuma, yalnız RNG kendi bloğunu başlatır."
	@mkdir -p $(RPI5_SENSOR_DIR)
	$(OBJCOPY) -O binary $(RPI5_SENSOR_ELF) $(RPI5_SENSOR_IMG)
	@LC_ALL=C strings $(RPI5_SENSOR_IMG) | grep -Fq -- "ASELSAN/THERMAL RAW=" || \
		{ echo "HATA: THERMAL marker raw image içinde yok"; exit 1; }
	cp $(RPI5_DTB) $(RPI5_SENSOR_DIR)/bcm2712-rpi-5-b.dtb
	cp $(RPI5_SENSOR_PROFILE) $(RPI5_SENSOR_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SENSOR_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sensors.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SENSOR_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sensors.img' $(RPI5_SENSOR_DIR)/config.txt || \
		{ echo "HATA: sensor config kernel=aselsanos-rpi5-sensors.img değil"; exit 1; }
	@cd $(RPI5_SENSOR_DIR) && shasum -a 256 \
		aselsanos-rpi5-sensors.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SENSOR_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ Sensör adayı: $(RPI5_SENSOR_IMG)"
	@echo "   Sıcaklık, güç düğmesi ve PMU salt okuma; RNG yalnız kendi bloğunu başlatır."
	@echo "   Fiziksel PASS değildir; PMU/THERMAL/RNG/PWRBTN satırları cihazdan gerekir."

# R107 keeps the R106 BCDC/RX behavior frozen and exposes only the owned
# INTSTATUS Read32/CMD53 completion and R5/error receipt.
image-rpi5-wifi-scan-r107:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r107 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r107 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r107-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r107:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r107 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R108 preserves R107 wire behavior and adds only read-side timeout ownership
# receipts: pending-before-cleanup, clock/sleep/F0/F2, mailbox and INTSTATUS.
image-rpi5-wifi-scan-r108:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r108 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r108 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r108-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r108:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r108 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R109 preserves the R108 CMD53 primary path and adds only the measured
# DATA_CRC-specific checked CMD52x4 fallback for F1 Read32.
image-rpi5-wifi-scan-r109:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r109 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r109 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r109-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r109:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r109 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R110 widens the R109 fallback gate from exact 0x20 to the measured
# DATA_CRC bit mask, so combined 0x0060 is handled without broad fallback.
image-rpi5-wifi-scan-r110:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r110 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r110 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r110-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r110:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r110 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R111 adds one bounded retry for the measured D11 DATA_TIMEOUT before the
# existing R110 Read32 DATA_CRC-mask fallback is exercised.
image-rpi5-wifi-scan-r111:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r111 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r111 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r111-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r111:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r111 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R112 drains all currently pending SDPCM FIFO frames before every new
# initialization/scan/abort control request, matching Linux readframes/DPC
# ownership ordering observed on the same BCM43455 card.
image-rpi5-wifi-scan-r112:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r112 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r112 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r112-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r112:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r112 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R113 keeps R112's SDPCM FIFO ordering and broadens the first-D11 bounded
# retry from DATA_TIMEOUT to DATA_TIMEOUT|DATA_CRC. The R112 raw record was
# later reclassified as a CR4 activation error and is not covered by this gate.
image-rpi5-wifi-scan-r113:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r113 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r113 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r113-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r113:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r113 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

image-rpi5-wifi-scan-r114:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r114 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r114 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r114-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r114:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r114 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R115 keeps the R114 wire/register behavior frozen. It makes interrupt/FIFO
# counters request-local, captures terminal diagnostics before pending cleanup
# on non-timeout failures too, and accepts the existing CMD52x4 fallback only
# after a bounded passive CMD/DAT-inhibit + DAT0 host-idle check.
image-rpi5-wifi-scan-r115:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r115 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r115 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r115-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r115:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r115 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R116 keeps R115 firmware/wire behavior frozen. Only the physically measured
# F1 SDIO-core INTSTATUS pure DATA_CRC + exhausted host-idle branch may consume
# one host-only SDHCI DATA reset, followed by a checked CMD52x4 matching read.
image-rpi5-wifi-scan-r116:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r116 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r116 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r116-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r116:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r116 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R117 keeps R116 firmware/wire behaviour and the single owned DATA recovery
# frozen.  It adds only a once-per-bus, read-only probe matrix at the measured
# INTSTATUS failure moment: CMD52x4, flagged 4-byte byte-mode CMD53 and
# single-block 64-byte CMD53, all at ChipCommon chipid, in the window the
# failing read already selected.
image-rpi5-wifi-scan-r117:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r117 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r117 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r117-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r117:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r117 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R118 keeps R117 frozen and answers the question it created: inside the same
# once-per-bus read-only gate, read the polled SDIO-core INTSTATUS and a
# positive-control register through BOTH backplane access paths (unflagged,
# as the runtime fallback does, and flagged, as the failing CMD53 does).
# Command line only: four checked CMD52 bytes per read, no CMD53, no write.
image-rpi5-wifi-scan-r118:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r118 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r118 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r118-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r118:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r118 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R119 keeps everything else frozen and widens exactly one predicate: the
# single owned host-only DATA reset is admitted for DATA_CRC with or without
# DATA_END_BIT, so a measurement no longer depends on which branch a boot took.
image-rpi5-wifi-scan-r119:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r119 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r119 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r119-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r119:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r119 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R120 = R119 plus exactly one subtraction: BT-A1 bring_up (BT_ON + UARTA) is
# skipped via the rpi5-bt-isolate feature.  Read-only BT inventory is kept.
# Interpreted ONLY against R119, which differs by this feature alone.
image-rpi5-wifi-scan-r120:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r120 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r120 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r120-profile.txt \
		RPI5_RADIO_BTHCI_MARKER="ASELSAN/BTHCI SKIPPED=1" \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-bt-isolate RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r120:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r120 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R122 changes one byte: the function 1 F2 watermark (0x10008) goes from 0x60
# to 0x08, the value the sealed R80 Linux trace measured on this hardware one
# step before its first control frame (docs/radio/R121-...).  BT bring-up is
# restored (no rpi5-bt-isolate), because R120 measured isolation changes
# nothing.  The other three R121 differences are separate revisions.
image-rpi5-wifi-scan-r122:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r122 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r122 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r122-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r122:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r122 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R123 = R122 plus observation only.  The three SDIO primitives (CMD52, CMD53
# read, CMD53 write) get a thin counting wrapper and ASELSAN/WIFIBUSCENSUS is
# printed before every terminal branch, so a run yields a RATE regardless of
# which stage it fails at.  No retry, reset, write or relaxed gate.
image-rpi5-wifi-scan-r123:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r123 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r123 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r123-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r123:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r123 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R124 = R123 plus one measured R121 difference: function 0 CCCR INT_ENABLE
# is written 0x03 then 0x07 at Function2Ready, the Linux pair.  CMD52 census
# is split into STAGE (firmware/NVRAM) and OTHER; totals unchanged.
image-rpi5-wifi-scan-r124:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r124 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r124 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r124-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r124:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r124 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R126 = the R124/R125 image plus one measured R121 difference: function 1
# WAKEUPCTRL (0x1001e) is written 0x02 (HT-wait) in the SDPCM prereq block,
# between the R122 watermark and the R124 CCCR INT_ENABLE pair.  R125 opened
# the CCCR interrupt gate the way Linux opens it, the value stuck, and the
# first 48-byte control frame was still unanswered -- so that candidate is
# closed.  CCCR 0x000f0 = 0x06 stays unwritten; it is a separate revision.
image-rpi5-wifi-scan-r126:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r126 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r126 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r126-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan-r126:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r126 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R127 = the R126 image plus the opt-in one-boot prerequisite sweep.  Trial 0
# applies nothing, so trial 0 IS the R126 single-variable run on a virgin card;
# trials 1-11 then walk a bounded matrix in the SAME power cycle.  The sweep is
# a runtime capability that only this image arms, and the ELF gate above proves
# every other scan image is sweep-incapable rather than merely not using it.
image-rpi5-wifi-scan-r127:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r127 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r127 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r127-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1

flash-rpi5-wifi-scan-r127:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r127 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R128 = the R127 sweep with its matrix reordered and two receipt defects fixed.
# R127 measured the reason: its highest-prior profile ran second, cleared
# DEVICE_CTL bit 4, and the very next CMD53 write failed with a data CRC -- the
# only failing write of sixteen that boot.  A bus error is permanently terminal,
# so nine trials never asked their questions.  R128 orders by ascending risk,
# asks the never-executed CCCR 0x000f0 first and alone, takes its contamination
# control BEFORE the DEVICE_CTL family, and schedules full parity last.
image-rpi5-wifi-scan-r128:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r128 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r128 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r128-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1

flash-rpi5-wifi-scan-r128:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r128 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R129 = the R128 sweep plus ONE variable: a between-trial recovery.  R128
# refuted the DEVICE_CTL candidate and left one fact standing -- in two boots
# with two different profiles, the first control frame issued after an
# unanswered one failed to transmit, 1 of 16 CMD53 writes both times.  R129
# clears the core interrupt status and takes a single bounded first-64 read of
# the function-2 FIFO before the re-armed write.  Every step is best effort and
# recorded; none of them may fail a trial.  The matrix is unchanged.
image-rpi5-wifi-scan-r129:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r129 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r129 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r129-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1

flash-rpi5-wifi-scan-r129:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r129 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R130 = R129 plus ONE card-side action: after the existing interrupt/FIFO
# recovery and profile writes, issue CCCR IO_ABORT with function 2 selected.
# The outcome is receipted and failure remains best effort, so the measured
# boundary is still the immediately following, second function-2 write.
image-rpi5-wifi-scan-r130:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r130 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r130 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r130-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-abort \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_ABORT=1

flash-rpi5-wifi-scan-r130:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r130 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R131 = R129 recovery plus ONE stronger card-side mechanism: disable F2,
# observe IO_READY clear, re-enable F2, and observe IO_READY set.  R130's
# IO_ABORT and block-size reprogramming are deliberately absent.
image-rpi5-wifi-scan-r131:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r131 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r131 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r131-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-reenable \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1

flash-rpi5-wifi-scan-r131:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r131 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R132 = R131 plus ONE post-lifecycle action: sample core INTSTATUS, acknowledge
# HOST_INT 0x80 if present, and read back before the second function-2 write.
image-rpi5-wifi-scan-r132:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r132 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r132 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r132-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-post-irq \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1

flash-rpi5-wifi-scan-r132:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r132 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R133 = R132 plus ONE adjacent action: reassert the F2 block-size bytes as
# 0x0200, read them back, then issue the second function-2 write.
image-rpi5-wifi-scan-r133:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r133 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r133 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r133-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1

flash-rpi5-wifi-scan-r133:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r133 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R134 = R133 plus ONE host-side action: after the verified F2 block-size
# receipt, issue SDHCI SOFTWARE_RESET.DAT and wait boundedly for self-clear.
# It sends no card command and remains adjacent to the second F2 write.
image-rpi5-wifi-scan-r134:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r134 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r134 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r134-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-host-data-reset \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOST_DATA_RESET=1

flash-rpi5-wifi-scan-r134:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r134 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R135 = R133 chain with ONE host-RAM framing change: the re-armed control
# write uses Linux's measured 64-byte F2 short-write unit (16 zero-pad bytes).
# R134's eliminated send-boundary reset is not part of this image; the first
# write is byte-for-byte unchanged. No new card command, no host reset.
image-rpi5-wifi-scan-r135:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r135 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r135 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r135-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-write-64 \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_F2_WRITE_64=1

flash-rpi5-wifi-scan-r135:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r135 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R136 = R133 chain with ONE wire-layout change: the control frame uses the
# SDPCM glom layout measured from the working Linux driver on this same card
# (evidence/rpi5/radio/linux-r136-first-frame-v3/): 8-byte glom extension and
# the BCDC dcmd at offset 20 instead of 12.  R134's eliminated send-boundary
# reset and R135's eliminated 64-byte short-write unit are both absent, so the
# image is the R133 chain plus the measured layout correction only.
image-rpi5-wifi-scan-r136:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r136 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r136 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r136-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1

flash-rpi5-wifi-scan-r136:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r136 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R137 = R136 plus ONE read-only witness: sample the dongle's host-mailbox data
# (tohostmailboxdata) during the protocol phase and record DEVREADY/FWREADY/
# version transitions, acknowledging each change exactly as Linux does
# (SMB_INT_ACK to tosbmailbox).  No frame byte, register write, reset or command
# changes: R136's glom layout and the R133 chain are untouched.
image-rpi5-wifi-scan-r137:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r137 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r137 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r137-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1

flash-rpi5-wifi-scan-r137:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r137 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R138 = R137 plus ONE handshake-timing change: every sampled mailbox read is
# acknowledged (SMB_INT_ACK to tosbmailbox) and the protocol version is
# rewritten to tosbmailboxdata whenever DEVREADY/FWREADY is reported, exactly
# like Linux's brcmf_sdio_hostmail.  The R136 glom layout, the R133 chain, the
# bootstrap frame and every register/reset/command are frozen.
image-rpi5-wifi-scan-r138:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r138 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r138 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r138-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1

flash-rpi5-wifi-scan-r138:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r138 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R139 = R138 plus ONE transport change on the critical path: the CR4 reset
# vector is written with Linux's 4-byte flagged CMD53 at backplane address 0
# (brcmf_sdio_buscore_activate), with the validated CMD52 write kept as a
# bounded fallback.  Every other value and the whole R136/R138 chain are frozen.
image-rpi5-wifi-scan-r139:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r139 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r139 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r139-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53 \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1

flash-rpi5-wifi-scan-r139:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r139 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R140 = R139 plus ONE placement change on the host-ready handshake: the
# protocol version (SDPCM_PROT_VERSION << 16) is written to tosbmailboxdata
# (0x18004048) immediately after the CR4 release — Linux's position in
# brcmf_sdio_firmware_callback (sdio.c:4261-4262), measured at +74 us in the
# R139 wire trace, before F2 enable and before hostintmask — instead of seconds
# later in the protocol-phase mail watch.  The same feature adds a read-only
# early mailbox witness (600 ms window, zero writes) so the dongle's DEVREADY
# and FWREADY timings become visible.  Every other value, frame and reset is
# frozen; the watch keeps R138's acknowledgement but no longer repeats the
# version.
image-rpi5-wifi-scan-r140:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r140 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r140 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r140-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1

flash-rpi5-wifi-scan-r140:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r140 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R141 = R140 plus ONE answer: in the same early window where R140 only watched,
# the dongle's mailbox interrupt is served the way Linux's ISR serves it —
# tosbmailbox (0x18004040) <- SMB_INT_ACK after each read of tohostmailboxdata
# and intstatus (0x18004020) write-1-to-clear with the observed bits
# (brcmf_sdio_hostmail + brcmf_sdio_intr_rstatus).  R140 measured FWREADY at
# +30 ms and INTSTATUS 0x208000c0 with no answer, after which the mailbox fell
# back to DEVREADY; the window now closes as soon as the handshake settles.
# Every value, frame and reset stays frozen.
image-rpi5-wifi-scan-r141:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r141 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r141 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r141-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1

flash-rpi5-wifi-scan-r141:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r141 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R142 = R141 plus ONE value: the CCCR INT_ENABLE pair (F0 0x04) keeps its
# two-write shape but clears the master interrupt bit (0x03 -> 0x02 and
# 0x07 -> 0x06).  R141's failure receipt measured the card driving DAT1
# (HOST_CARD_INT=true) while SDHCI_INT_SIGNAL_ENABLE=0 and the F1 4-byte CMD53
# reads dying with data CRC (0x0020/0x0060); a polling design needs no DAT1.
# Function bits, frames, clocks, resets and every other value stay frozen.
image-rpi5-wifi-scan-r142:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r142 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r142 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r142-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1

flash-rpi5-wifi-scan-r142:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r142 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R143 = R142 plus ONE value: the SDIO core host interrupt mask (0x18004024) is
# written as 0x00000000 instead of Linux's 0x200000f0.  R142 cleared the CCCR
# master bit and the card still drove DAT1 (HOST_CARD_INT=true), which locates
# the gate here; a polling design reads intstatus directly and needs no line.
image-rpi5-wifi-scan-r143:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r143 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r143 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r143-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1

flash-rpi5-wifi-scan-r143:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r143 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R144 = R143 plus ONE error-path change: an intermittent data-line CRC on the
# poll's intstatus read no longer ends the trial.  The transport layer's bounded
# recovery (already validated: RECOVERY_OK=1 POST_READ_OK=1) is followed by ONE
# retry; only a second failure is fatal.  Every value, frame, clock and reset is
# frozen.
image-rpi5-wifi-scan-r144:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r144 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r144 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r144-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1

flash-rpi5-wifi-scan-r144:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r144 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R145 = R144 plus ONE error-path extension: the same single retry now covers
# the F2 frame reads.  R144 saw the dongle's interrupt for the first time and
# died on the first F2 read (Cmd53Read fn=2 addr=0x8000, bytes_read=64,
# error_status=0x20, timeout_transfer=true).  Read geometry, frames, clocks and
# resets are frozen.
image-rpi5-wifi-scan-r145:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r145 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r145 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r145-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1

flash-rpi5-wifi-scan-r145:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r145 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R146 = R145 plus ONE read-only witness: at the very end of the run the dongle's
# published SDPCM shared area is read once (pointer in the last 4 bytes of RAM,
# exactly brcmf_sdio_readshared), with the ChipCommon chipid as a before/after
# sentinel.  R145 left a transport that carries eight trials with the mailbox
# parked at DEVREADY and no interrupt, so the missing information is the
# dongle's own state (flags/trap/assert/console).  Nothing is written.
image-rpi5-wifi-scan-r146:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r146 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r146 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r146-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1

flash-rpi5-wifi-scan-r146:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r146 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R147 = R146 plus ONE read-only continuation: the firmware console R146 located
# (W5_CONSOLE) is dumped at the very end of the run — 16 header words, then 128
# bytes from the first aligned RAM pointer in that header (layout-independent)
# and 128 bytes from the console address itself, with the printable characters
# printed.  Nothing is written.
image-rpi5-wifi-scan-r147:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r147 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r147 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r147-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1

flash-rpi5-wifi-scan-r147:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r147 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R148 = R147 plus the FULL console log.  R147 read the first 128 bytes and found
# the firmware's wl0 lines; the header measured the buffer (0x0025dab4, size
# 0x400, index 0x177 = 367 bytes).  R148 reads the whole buffer and prints all
# printable text, with the chipid sentinel retried before the read.  Read-only.
image-rpi5-wifi-scan-r148:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r148 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r148 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r148-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1

flash-rpi5-wifi-scan-r148:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r148 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R149 = R148 plus ONE BIT: FORCE_HT (0x02) in CHIPCLKCSR, Linux's measured
# post-release value 0xd2 instead of 0xd0.  R148's firmware console said
# "No clock" and lost the SDPCM datapath exactly when our frame arrived.
image-rpi5-wifi-scan-r149:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r149 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r149 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r149-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1

flash-rpi5-wifi-scan-r149:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r149 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R150 = R149 plus ONE write: the D11 (PHY/TX) core's reset is released after the
# ioctl 0x07 configuration instead of being left asserted.  The R139 Linux wire
# trace has no D11 reset-control write at all, and the firmware's own console
# says "wlc_stf_txcore_shmem_write: No clock" — a core held in reset has none.
image-rpi5-wifi-scan-r150:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r150 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r150 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r150-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1

flash-rpi5-wifi-scan-r150:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r150 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R151 = R150 plus a HOST TIMELINE (measurement only): the CR4 release instant is
# recorded and the trial start/result, the between-trial recovery and the console
# read are stamped with ms since then, so the firmware's own Disable timestamps
# (6.082/9.048/12.014/14.979 s) can be aligned with our operations.
image-rpi5-wifi-scan-r151:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r151 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r151 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r151-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1

flash-rpi5-wifi-scan-r151:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r151 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R152 = R151 with the millisecond source fixed: host_now_ms() initialises the
# timer frequency itself, so the T_MS stamps the R151 image armed can actually be
# read and aligned with the firmware's own Disable timestamps.
image-rpi5-wifi-scan-r152:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r152 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r152 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r152-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1

flash-rpi5-wifi-scan-r152:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r152 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R153 = R152 plus ONE byte: the first control frame's SDPCM sequence is 0 instead
# of 255.  Linux's sealed first-frame measurement shows a small increasing value
# (byte4_seq=0x02) and brcmfmac increments before sending; R152's aligned
# timeline showed our frame is what makes the dongle disable the datapath.
image-rpi5-wifi-scan-r153:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r153 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r153 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r153-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1

flash-rpi5-wifi-scan-r153:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r153 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R154 = R153 plus ONE frame-content change: the session's FIRST control frame
# carries Linux's measured preinit request (SET cur_etheraddr, cmd=263, id=4,
# len=20) instead of this driver's GET.  Wire format stays R136's glom layout.
image-rpi5-wifi-scan-r154:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r154 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r154 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r154-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1

flash-rpi5-wifi-scan-r154:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r154 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R155 = R154 plus a TIMESTAMP on the read-error recovery receipts (measurement
# only): WIFIREAD_RECOVERY carries an SDHCI line reset, and without its time the
# dongle's repeating Disable cannot be attributed to the frame or to our reset.
image-rpi5-wifi-scan-r155:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r155 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r155 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r155-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1

flash-rpi5-wifi-scan-r155:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r155 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R157 = R156 plus Linux's measured preinit SEQUENCE: two PLAIN frames (GET
# ulp_sdioctrl, SET bus:rxglom=1) negotiate glom before the glom cur_etheraddr
# frame, instead of sending glom from the first frame.
image-rpi5-wifi-scan-r157:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r157 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r157 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r157-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1

flash-rpi5-wifi-scan-r157:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r157 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R158 = R157 plus "drain before write": the measured preinit sequence is sent
# only after the F2 queue is idle, because both R157 boots died on an F2 write
# (WriteFifo, F2 0x8000) while the dongle had frames indicated.
image-rpi5-wifi-scan-r158:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r158 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r158 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r158-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1

flash-rpi5-wifi-scan-r158:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r158 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R159 = R158 plus ONE write-geometry change: the plain pre-negotiation control
# frames go to F2 as Linux's measured 64-byte unit (they are 57/43 bytes and were
# 4-byte aligned to 60/44; that write is exactly the one that failed with
# WriteFifo, while 8-byte-aligned glom frames had been accepted).
image-rpi5-wifi-scan-r159:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r159 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r159 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r159-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1

flash-rpi5-wifi-scan-r159:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r159 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R160 = R159 plus ONE acceptance-rule change.  R159's sealed WIFIREAD receipt
# shows the first preinit F2 write was not refused by the card: the transfer
# completed with exactly 64 bytes, the R5 response has no error bit, and the only
# complaint is SDHCI's data-CRC flag (0x20).  Our own completeness predicate
# requires error_status == 0 and therefore kills the run on frame one.  R160
# accepts exactly that measured class (counted, printed, sealed) and keeps every
# other write failure fatal.
image-rpi5-wifi-scan-r160:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r160 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r160 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r160-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit,rpi5-wifi-f2-crc-accept \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1 RPI5_RADIO_F2_CRC_ACCEPT=1

flash-rpi5-wifi-scan-r160:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r160 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R161 = R160 plus ONE scope change: the acceptance rule that R160 verified for
# the preinit sequence (and that made SENT=3 and the console's "Disable" pattern
# disappear) now covers every SDPCM F2 write, including the ordinary control
# frame that killed R160's run with the identical measured class.
image-rpi5-wifi-scan-r161:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r161 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r161 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r161-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit,rpi5-wifi-f2-crc-accept,rpi5-wifi-f2-crc-scope \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1 RPI5_RADIO_F2_CRC_ACCEPT=1 \
		RPI5_RADIO_F2_CRC_SCOPE=1

flash-rpi5-wifi-scan-r161:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r161 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R162 = R161 plus ONE identity change: the control frames that follow the
# measured preinit sequence continue the dcmd id (5, 6, 7 ...) and never replay a
# request the dongle already received.  R160/R161 receipts show the same three
# requests going out twice (ids 2,3,4 then 4,2,3,4) while the sealed Linux frame
# list increments its id for every request - and at each of those repeated frames
# the dongle disabled its SDPCM TX.
image-rpi5-wifi-scan-r162:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r162 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r162 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r162-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit,rpi5-wifi-f2-crc-accept,rpi5-wifi-f2-crc-scope,rpi5-wifi-ctrl-id-continuation \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1 RPI5_RADIO_F2_CRC_ACCEPT=1 \
		RPI5_RADIO_F2_CRC_SCOPE=1 RPI5_RADIO_CTRL_ID_CONTINUATION=1

flash-rpi5-wifi-scan-r162:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r162 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R163 = R162 plus ONE change: the pre-write F2 lifecycle becomes verify-first.
# R162's sealed capture shows the toggle coinciding to the millisecond with the
# dongle's "sdpcmd_dpc: Disable" / "sdpcmd_tx: device disabled" /
# "sdpcmd_sendheader: tx submit failed!!" triple, once per trial; the preinit
# writes, which never toggle, produce no such triple.  R163 also carries the
# hands-free automation feature (rpi5-auto-reset) so the run can be reset from
# the Mac without touching the card; that feature touches no radio register and
# is declared in the receipt (RADIO_REGISTERS=0).
image-rpi5-wifi-scan-r163:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r163 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r163 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r163-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit,rpi5-wifi-f2-crc-accept,rpi5-wifi-f2-crc-scope,rpi5-wifi-ctrl-id-continuation,rpi5-wifi-f2-ready-first,rpi5-auto-reset \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1 RPI5_RADIO_F2_CRC_ACCEPT=1 \
		RPI5_RADIO_F2_CRC_SCOPE=1 RPI5_RADIO_CTRL_ID_CONTINUATION=1 \
		RPI5_RADIO_F2_READY_FIRST=1 RPI5_RADIO_AUTO_RESET=1

flash-rpi5-wifi-scan-r163:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r163 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# R164 = R163 plus ONE infrastructure fix (radio variable count: zero).  The
# netboot control boot measured FWREAD PART_LBA=0 VOL_OK=0: the kernel's SD read
# silently depended on the firmware having initialised the card, which is true
# on every SD boot and false on a network boot.  R164 tries the inherited state
# first and runs the SD specification's cold-card sequence only when it is
# unusable; on SD boots the branch never runs and no card write command exists.
image-rpi5-wifi-scan-r164:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r164 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r164 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r164-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan,rpi5-wifi-sweep,rpi5-wifi-f2-block-size,rpi5-wifi-hostmail-complete,rpi5-wifi-rstvec-cmd53,rpi5-wifi-hostready-at-start,rpi5-wifi-mailbox-answer-at-start,rpi5-wifi-int-enable-off,rpi5-wifi-hostintmask-off,rpi5-wifi-poll-retry,rpi5-wifi-fifo-retry,rpi5-wifi-shared-witness,rpi5-wifi-console-witness,rpi5-wifi-console-full,rpi5-wifi-force-ht,rpi5-wifi-d11-release,rpi5-wifi-host-timeline,rpi5-wifi-timeline-fix,rpi5-wifi-seq-zero,rpi5-wifi-preinit-first,rpi5-wifi-recovery-timeline,rpi5-wifi-glom-negotiation,rpi5-wifi-drain-first,rpi5-wifi-f2-write-unit,rpi5-wifi-f2-crc-accept,rpi5-wifi-f2-crc-scope,rpi5-wifi-ctrl-id-continuation,rpi5-wifi-f2-ready-first,rpi5-auto-reset,rpi5-fw-initramfs \
		RPI5_RADIO_SCAN=1 RPI5_RADIO_PREREQ_SWEEP=1 RPI5_RADIO_F2_REENABLE=1 \
		RPI5_RADIO_F2_POST_IRQ=1 RPI5_RADIO_F2_BLOCK_SIZE=1 \
		RPI5_RADIO_HOSTMAIL_COMPLETE=1 RPI5_RADIO_RSTVEC_CMD53=1 \
		RPI5_RADIO_HOSTREADY_AT_START=1 RPI5_RADIO_MAILBOX_ANSWER=1 \
		RPI5_RADIO_INT_ENABLE_OFF=1 RPI5_RADIO_HOSTINTMASK_OFF=1 \
		RPI5_RADIO_POLL_RETRY=1 RPI5_RADIO_FIFO_RETRY=1 \
		RPI5_RADIO_SHARED_WITNESS=1 RPI5_RADIO_CONSOLE_WITNESS=1 \
		RPI5_RADIO_CONSOLE_FULL=1 RPI5_RADIO_FORCE_HT=1 \
		RPI5_RADIO_D11_RELEASE=1 RPI5_RADIO_HOST_TIMELINE=1 \
		RPI5_RADIO_TIMELINE_FIX=1 RPI5_RADIO_SEQ_ZERO=1 \
		RPI5_RADIO_PREINIT_FIRST=1 RPI5_RADIO_RECOVERY_TIMELINE=1 \
		RPI5_RADIO_GLOM_NEGOTIATION=1 RPI5_RADIO_DRAIN_FIRST=1 \
		RPI5_RADIO_F2_WRITE_UNIT=1 RPI5_RADIO_F2_CRC_ACCEPT=1 \
		RPI5_RADIO_F2_CRC_SCOPE=1 RPI5_RADIO_CTRL_ID_CONTINUATION=1 \
		RPI5_RADIO_F2_READY_FIRST=1 RPI5_RADIO_AUTO_RESET=1 \
		RPI5_RADIO_FW_INITRAMFS=1

flash-rpi5-wifi-scan-r164:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r164 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# ---------------------------------------------------------------------------
# Hands-free radyo döngüsü (bkz. docs/radio/hands-free-loop.md)
#
# SD kartı her revizyonda çıkarıp takmak yerine: çekirdek TFTP'den gelir, kart
# Pi'de kalır (Wi-Fi firmware/NVRAM/CLM payload'ı oradan okunur ve sabittir).
# Reset yolu kernel PM watchdog'u ya da UART 'R' komutudur; ikisi de fiziksel
# müdahale gerektirmez. Hiçbir hedef mühürlü kanıtın üzerine yazmaz.
# ---------------------------------------------------------------------------
hands-free-setup:
	@test "$(origin IFACE)" = "command line" || \
		(echo "HATA: IFACE explicit verilmeli (ör. IFACE=en7)"; exit 1)
	@test "$(origin TFTP_ROOT)" = "command line" || \
		(echo "HATA: TFTP_ROOT explicit verilmeli"; exit 1)
	sh scripts/radio-netboot-setup.sh --iface "$(IFACE)" --root "$(TFTP_ROOT)"

eeprom-netboot:
	@test "$(origin CARD_MOUNT)" = "command line" || \
		(echo "HATA: CARD_MOUNT explicit verilmeli (ör. CARD_MOUNT=/Volumes/ASELSANBOOT)"; exit 1)
	sh scripts/radio-eeprom-boot-order.sh --card-mount "$(CARD_MOUNT)" \
		$(if $(BOOT_ORDER),--boot-order "$(BOOT_ORDER)",) \
		$(if $(TFTP_IP),--tftp-ip "$(TFTP_IP)",)

hands-free-publish:
	@test "$(origin REV)" = "command line" || \
		(echo "HATA: REV explicit verilmeli (ör. REV=r163)"; exit 1)
	@test "$(origin TFTP_ROOT)" = "command line" || \
		(echo "HATA: TFTP_ROOT explicit verilmeli"; exit 1)
	sh scripts/radio-netboot-publish.sh --rev "$(REV)" --root "$(TFTP_ROOT)" \
		$(if $(CARD_MOUNT),--card-mount "$(CARD_MOUNT)",)

hands-free-run:
	@test "$(origin REV)" = "command line" || \
		(echo "HATA: REV explicit verilmeli"; exit 1)
	@test "$(origin SLUG)" = "command line" || \
		(echo "HATA: SLUG explicit verilmeli (mühür dizini adı)"; exit 1)
	sh scripts/radio-auto-run.sh --rev "$(REV)" --slug "$(SLUG)" \
		--boot "$(or $(BOOT),1)" --transport "$(or $(TRANSPORT),netboot)" \
		--reset "$(or $(RESET),manual)" \
		$(if $(TFTP_ROOT),--tftp-root "$(TFTP_ROOT)",) \
		$(if $(CARD_MOUNT),--card-mount "$(CARD_MOUNT)",) \
		$(if $(DEVICE),--device "$(DEVICE)",) \
		$(if $(RESET_PATTERN),--reset-pattern "$(RESET_PATTERN)",) \
		$(if $(RELAY_DEVICE),--relay-device "$(RELAY_DEVICE)",)

hands-free-loop:
	sh scripts/radio-auto-loop.sh --transport "$(or $(TRANSPORT),netboot)" \
		--reset "$(or $(RESET),manual)" --max-boots "$(or $(MAX_BOOTS),3)" \
		$(if $(PLAN),--plan "$(PLAN)",) \
		$(if $(TFTP_ROOT),--tftp-root "$(TFTP_ROOT)",) \
		$(if $(CARD_MOUNT),--card-mount "$(CARD_MOUNT)",) \
		$(if $(DEVICE),--device "$(DEVICE)",) \
		$(if $(RESET_PATTERN),--reset-pattern "$(RESET_PATTERN)",) \
		$(if $(RELAY_DEVICE),--relay-device "$(RELAY_DEVICE)",)

check-hands-free:
	@for s in scripts/radio-netboot-setup.sh scripts/radio-netboot-publish.sh \
		scripts/seal-radio-evidence.sh scripts/radio-auto-run.sh \
		scripts/radio-auto-loop.sh scripts/radio-eeprom-boot-order.sh; do \
		sh -n $$s || { echo "HATA: sözdizimi: $$s"; exit 1; }; \
	done
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_hands_free_loop_source -- --quiet

# Scan runtime is packaged separately from the diagnostic radio image.
image-rpi5-wifi-scan:
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test brcmf_proto --test brcmf_sdio --test brcmf_sdio_adapter_source \
		--test brcmf_scan --test rpi5_wifi_scan_ui --test wifi_runtime \
		--test rpi5_wifi_scan_source -- --quiet
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

# R106 keeps the R105 image immutable and packages only the bounded RX/control
# ownership diagnostics. Physical flashing remains a separate explicit target.
image-rpi5-wifi-scan-r106:
	@$(MAKE) image-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r106 \
		RPI5_RADIO_TARGET_DIR=target/rpi5-wifi-scan-r106 \
		RPI5_RADIO_PROFILE=firmware/rpi5-wifi-scan-r106-profile.txt \
		RPI5_RADIO_FEATURES=board-rpi5,rpi5-wifi-scan RPI5_RADIO_SCAN=1

flash-rpi5-wifi-scan:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

flash-rpi5-wifi-scan-r106:
	@$(MAKE) flash-rpi5-radio RPI5_RADIO_DIR=build/rpi5-wifi-scan-r106 \
		SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"

# The BT-HCI receipt is exact-once checked in the ELF.  A revision that
# deliberately skips BT bring-up still owes a receipt, so it overrides this
# marker rather than dropping the check.
RPI5_RADIO_BTHCI_MARKER ?= ASELSAN/BTHCI GIO=

image-rpi5-radio: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_RADIO_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_radio_source --test rpi5_sd_source \
		--test rpi5_ios_home --test rpi5_screen_source -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_RADIO_TARGET_DIR) \
		--no-default-features --features $(RPI5_RADIO_FEATURES)
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@if [ -z "$(READOBJ)" ] || [ ! -x "$(READOBJ)" ]; then \
		echo "llvm-readobj bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_RADIO_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: radio image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/WIFIINV HOST=" "ASELSAN/WIFICMD5 RESET=" \
		"ASELSAN/BTINV BASE=" "$(RPI5_RADIO_BTHCI_MARKER)" \
		"ASELSAN/SCREEN0 RP1=" \
		"ASELSAN/ATTACH KSO_REV=" "ASELSAN/HTCLK REQ="; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: radio marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@for DISCLAIMER in "SCAN=0 FIRMWARE=0 SSID=0" "INQUIRY=0 FIRMWARE=0 DEVICES=0 PAIRED=0 PHYSICAL=0"; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fo -- "$$DISCLAIMER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: radio disclaimer exact-once değil: $$DISCLAIMER ($$COUNT)"; exit 1; }; \
	done
	@CARDWRITE=$$(LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Eo -- "CMD24|CMD25|CMD32|CMD38" | wc -l | tr -d '[:space:]'); \
		[ "$$CARDWRITE" -eq 0 ] || \
		{ echo "HATA: radyo imajında kart yazma komutu dizesi var: $$CARDWRITE"; exit 1; }
	@if [ "$(RPI5_RADIO_SCAN)" = 1 ]; then \
		BOTTOM=$$($(OBJDUMP) -t $(RPI5_RADIO_ELF) | awk '$$NF == "__stack_bottom" {print "0x" $$1}'); \
		TOP=$$($(OBJDUMP) -t $(RPI5_RADIO_ELF) | awk '$$NF == "__stack_top" {print "0x" $$1}'); \
		END=$$($(OBJDUMP) -t $(RPI5_RADIO_ELF) | awk '$$NF == "__kernel_end" {print "0x" $$1}'); \
		[ -n "$$BOTTOM" ] && [ -n "$$TOP" ] && [ -n "$$END" ] && \
			[ $$((TOP - BOTTOM)) -eq 131072 ] && [ $$((END)) -ge $$((TOP)) ] || \
			{ echo "HATA: scan stack 128KiB/reserved kernel sinirinda degil"; exit 1; }; \
		for MARKER in "ASELSAN/WIFIPROTO" "ASELSAN/WIFIBSS" \
			"ASELSAN/WIFICTRLTX_RAW" "ASELSAN/WIFIIRQWAIT" \
			"ASELSAN/WIFIFRAMECOUNT" "ASELSAN/WIFIREAD_FALLBACK" \
			"ASELSAN/WIFIREAD_RECOVERY" \
			"ASELSAN/WIFISCAN_RESULT"; do \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "$$MARKER" || \
				{ echo "HATA: scan marker yok: $$MARKER"; exit 1; }; \
		done; \
		if LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Eq 'ASELSAN/WIFISWEEP|ASELSAN/WIFIWRITE'; then \
			echo "HATA: tarama imaji post-boot RAM deneyini iceriyor"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_PREREQ_SWEEP)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFITRIAL" || \
				{ echo "HATA: sweep imajinda ASELSAN/WIFITRIAL yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFITRIAL"; then \
			echo "HATA: sweep etiketi sweep-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_ABORT)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2ABORT" || \
				{ echo "HATA: R130 imajinda ASELSAN/WIFIF2ABORT yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2ABORT"; then \
			echo "HATA: F2 abort etiketi R130-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_REENABLE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2REENABLE" || \
				{ echo "HATA: R131 imajinda ASELSAN/WIFIF2REENABLE yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2REENABLE"; then \
			echo "HATA: F2 re-enable etiketi R131-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_POST_IRQ)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2POSTIRQ" || \
				{ echo "HATA: R132 imajinda ASELSAN/WIFIF2POSTIRQ yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2POSTIRQ"; then \
			echo "HATA: post-lifecycle IRQ etiketi R132-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_BLOCK_SIZE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2BLKSZ" || \
				{ echo "HATA: R133 imajinda ASELSAN/WIFIF2BLKSZ yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2BLKSZ"; then \
			echo "HATA: F2 block-size etiketi R133-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_HOST_DATA_RESET)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTDATA" || \
				{ echo "HATA: R134 imajinda ASELSAN/WIFIHOSTDATA yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTDATA"; then \
			echo "HATA: host-only DATA etiketi R134-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_WRITE_64)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2WRITE64" || \
				{ echo "HATA: R135 imajinda ASELSAN/WIFIF2WRITE64 yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2WRITE64"; then \
			echo "HATA: F2 write-64 etiketi R135-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_RSTVEC_CMD53)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIRSTVEC_PLAN" || \
				{ echo "HATA: R139 imajinda ASELSAN/WIFIRSTVEC_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIRSTVEC_PLAN"; then \
			echo "HATA: rstvec-cmd53 etiketi R139-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_HOSTMAIL_COMPLETE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTMAIL_PLAN" || \
				{ echo "HATA: R138 imajinda ASELSAN/WIFIHOSTMAIL_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTMAIL_PLAN"; then \
			echo "HATA: hostmail-complete etiketi R138-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_WRITE_UNIT)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2UNIT_PLAN" || \
				{ echo "HATA: R159 imajinda ASELSAN/WIFIF2UNIT_PLAN yok"; exit 1; }; \
		fi; \
		if [ "$(RPI5_RADIO_FW_INITRAMFS)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/FWPAYLOAD PRESENT" || \
				{ echo "HATA: R164 imajinda ASELSAN/FWPAYLOAD yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/FWPAYLOAD PRESENT"; then \
			echo "HATA: fw-initramfs etiketi R164-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_READY_FIRST)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2READYFIRST_PLAN" || \
				{ echo "HATA: R163 imajinda ASELSAN/WIFIF2READYFIRST_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2READYFIRST_PLAN"; then \
			echo "HATA: f2-ready-first etiketi R163-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_AUTO_RESET)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIAUTORESET_PLAN" || \
				{ echo "HATA: R163 imajinda hands-free reset etiketi yok"; exit 1; }; \
		fi; \
		if [ "$(RPI5_RADIO_CTRL_ID_CONTINUATION)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFICTRLID_PLAN" || \
				{ echo "HATA: R162 imajinda ASELSAN/WIFICTRLID_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFICTRLID_PLAN"; then \
			echo "HATA: ctrl-id-continuation etiketi R162-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_CRC_SCOPE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2CRCSCOPE_PLAN" || \
				{ echo "HATA: R161 imajinda ASELSAN/WIFIF2CRCSCOPE_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2CRCSCOPE_PLAN"; then \
			echo "HATA: f2-crc-scope etiketi R161-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_F2_CRC_ACCEPT)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2CRC_PLAN" || \
				{ echo "HATA: R160 imajinda ASELSAN/WIFIF2CRC_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIF2CRC_PLAN"; then \
			echo "HATA: f2-crc-accept etiketi R160-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_DRAIN_FIRST)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIDRAINFIRST_PLAN" || \
				{ echo "HATA: R158 imajinda ASELSAN/WIFIDRAINFIRST_PLAN yok"; exit 1; }; \
		fi; \
		if [ "$(RPI5_RADIO_GLOM_NEGOTIATION)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPREINITSEQ_PLAN" || \
				{ echo "HATA: R157 imajinda ASELSAN/WIFIPREINITSEQ_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPREINITSEQ_PLAN"; then \
			echo "HATA: glom-negotiation etiketi R157-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_RECOVERY_TIMELINE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIRECOVERYTIME_PLAN" || \
				{ echo "HATA: R155 imajinda ASELSAN/WIFIRECOVERYTIME_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIRECOVERYTIME_PLAN"; then \
			echo "HATA: recovery-timeline etiketi R155-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_PREINIT_FIRST)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPREINIT_PLAN" || \
				{ echo "HATA: R154 imajinda ASELSAN/WIFIPREINIT_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPREINIT_PLAN"; then \
			echo "HATA: preinit-first etiketi R154-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_SEQ_ZERO)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISEQ_PLAN" || \
				{ echo "HATA: R153 imajinda ASELSAN/WIFISEQ_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISEQ_PLAN"; then \
			echo "HATA: seq-zero etiketi R153-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_TIMELINE_FIX)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFITIMELINE T0_MS=" || \
				{ echo "HATA: R152 imajinda ASELSAN/WIFITIMELINE yok"; exit 1; }; \
		fi; \
		if [ "$(RPI5_RADIO_HOST_TIMELINE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFITIMELINE T0_MS=" || \
				{ echo "HATA: R151 imajinda ASELSAN/WIFITIMELINE yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFITIMELINE T0_MS="; then \
			echo "HATA: host-timeline etiketi R151-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_D11_RELEASE)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFID11RELEASE_PLAN" || \
				{ echo "HATA: R150 imajinda ASELSAN/WIFID11RELEASE_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFID11RELEASE_PLAN"; then \
			echo "HATA: d11-release etiketi R150-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_FORCE_HT)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIFORCEHT_PLAN" || \
				{ echo "HATA: R149 imajinda ASELSAN/WIFIFORCEHT_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIFORCEHT_PLAN"; then \
			echo "HATA: force-ht etiketi R149-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_CONSOLE_FULL)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHAREDCONSOLEFULL_PLAN" || \
				{ echo "HATA: R148 imajinda ASELSAN/WIFISHAREDCONSOLEFULL_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHAREDCONSOLEFULL_PLAN"; then \
			echo "HATA: console-full etiketi R148-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_CONSOLE_WITNESS)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHAREDCONSOLE_PLAN" || \
				{ echo "HATA: R147 imajinda ASELSAN/WIFISHAREDCONSOLE_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHAREDCONSOLE_PLAN"; then \
			echo "HATA: console-witness etiketi R147-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_SHARED_WITNESS)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHARED_PLAN" || \
				{ echo "HATA: R146 imajinda ASELSAN/WIFISHARED_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFISHARED_PLAN"; then \
			echo "HATA: shared-witness etiketi R146-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_FIFO_RETRY)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIFIFORETRY_PLAN" || \
				{ echo "HATA: R145 imajinda ASELSAN/WIFIFIFORETRY_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIFIFORETRY_PLAN"; then \
			echo "HATA: fifo-retry etiketi R145-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_POLL_RETRY)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPOLLRETRY_PLAN" || \
				{ echo "HATA: R144 imajinda ASELSAN/WIFIPOLLRETRY_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIPOLLRETRY_PLAN"; then \
			echo "HATA: poll-retry etiketi R144-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_HOSTINTMASK_OFF)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTINTMASK_PLAN" || \
				{ echo "HATA: R143 imajinda ASELSAN/WIFIHOSTINTMASK_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTINTMASK_PLAN"; then \
			echo "HATA: hostintmask-off etiketi R143-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_INT_ENABLE_OFF)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIINTEN_PLAN" || \
				{ echo "HATA: R142 imajinda ASELSAN/WIFIINTEN_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIINTEN_PLAN"; then \
			echo "HATA: int-enable-off etiketi R142-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_MAILBOX_ANSWER)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIMBOXANSWER_PLAN" || \
				{ echo "HATA: R141 imajinda ASELSAN/WIFIMBOXANSWER_PLAN yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIMBOXANSWER_PLAN"; then \
			echo "HATA: mailbox-answer etiketi R141-disi tarama imajinda"; exit 1; \
		fi; \
		if [ "$(RPI5_RADIO_HOSTREADY_AT_START)" = 1 ]; then \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTREADY_PLAN" || \
				{ echo "HATA: R140 imajinda ASELSAN/WIFIHOSTREADY_PLAN yok"; exit 1; }; \
			LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIEARLYMBOX" || \
				{ echo "HATA: R140 imajinda ASELSAN/WIFIEARLYMBOX yok"; exit 1; }; \
		elif LC_ALL=C strings $(RPI5_RADIO_ELF) | grep -Fq -- "ASELSAN/WIFIHOSTREADY_PLAN"; then \
			echo "HATA: hostready-at-start etiketi R140-disi tarama imajinda"; exit 1; \
		fi; \
	fi
	@mkdir -p $(RPI5_RADIO_DIR)
	$(OBJCOPY) -O binary $(RPI5_RADIO_ELF) $(RPI5_RADIO_IMG)
	@LC_ALL=C strings $(RPI5_RADIO_IMG) | grep -Fq -- "$(RPI5_RADIO_BTHCI_MARKER)" || \
		{ echo "HATA: BTHCI marker raw image içinde yok: $(RPI5_RADIO_BTHCI_MARKER)"; exit 1; }
	cp $(RPI5_DTB) $(RPI5_RADIO_DIR)/bcm2712-rpi-5-b.dtb
	cp $(RPI5_RADIO_PROFILE) $(RPI5_RADIO_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_RADIO_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-radio.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_RADIO_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-radio.img' $(RPI5_RADIO_DIR)/config.txt || \
		{ echo "HATA: radio config kernel=aselsanos-rpi5-radio.img değil"; exit 1; }
	@cd $(RPI5_RADIO_DIR) && shasum -a 256 \
		aselsanos-rpi5-radio.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_RADIO_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ WIFI-A1/A2 + BT-A1 adayı: $(RPI5_RADIO_IMG)"
	@echo "   Bu imaj Wi-Fi SDHCI bankına ve BT UART + BT_ON hattına YAZAR."
	@if [ "$(RPI5_RADIO_SCAN)" = 1 ]; then \
		echo "   HT ve protokol hazirsa pasif Wi-Fi taramasi dener; bulunan aglari listeler."; \
	else \
		echo "   Tani imaji: ag taramasi yok."; \
	fi
	@echo "   Derleme veya firmware kopyasi, calisan Wi-Fi sonucu degildir."

image-rpi5-sd-inventory: $(RPI5_DTB) $(RPI5_CONFIG) $(RPI5_SD_PROFILE)
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_source --test rpi5_fat32 --test rpi5_aselrec \
		--test rpi5_ios_home --test rpi5_wallclock -- --quiet
	@CARGO_INCREMENTAL=0 $(CARGO) build -p aselsan_kernel \
		--target $(TARGET) --target-dir $(RPI5_SD_TARGET_DIR) \
		--no-default-features --features board-rpi5,rpi5-sd-read
	@if [ -z "$(OBJCOPY)" ] || [ ! -x "$(OBJCOPY)" ]; then \
		echo "llvm-objcopy bulunamadı. rustup component add llvm-tools-preview"; \
		exit 1; \
	fi
	@ENTRY=$$($(READOBJ) --file-headers $(RPI5_SD_ELF) | awk '/Entry:/ {print $$2; exit}'); \
		[ "$$ENTRY" = "$(RPI5_ENTRY)" ] || \
		(echo "HATA: sd image entry $(RPI5_ENTRY) değil: $$ENTRY"; exit 1)
	@for MARKER in "ASELSAN/SDINV HOST=" "ASELSAN/SDREAD PATH=INHERIT" "ASELSAN/SDFAT PART_LBA=" \
		"ASELSAN/SDFILE SHORT=ASELREC.BIN" \
		"ASELSAN/SCREEN0 RP1=" "ASELSAN/CLOCK SRC=EPOCH_BLOB"; do \
		COUNT=$$(LC_ALL=C strings $(RPI5_SD_ELF) | grep -Fo -- "$$MARKER" | wc -l | tr -d '[:space:]'); \
		[ "$$COUNT" -eq 1 ] || \
			{ echo "HATA: sd marker ELF içinde exact-once değil: $$MARKER ($$COUNT)"; exit 1; }; \
	done
	@CARDWRITE=$$(LC_ALL=C strings $(RPI5_SD_ELF) | grep -Eo -- "CMD24|CMD25|CMD32|CMD38" | wc -l | tr -d '[:space:]'); \
		[ "$$CARDWRITE" -eq 0 ] || \
		{ echo "HATA: imajda kart yazma komutu dizesi var: $$CARDWRITE"; exit 1; }
	@echo "   SD-A1 sözleşmesi: yalnız READ_SINGLE_BLOCK. Hiçbir kart yazma komutu yok."
	@mkdir -p $(RPI5_SD_DIR)
	$(OBJCOPY) -O binary $(RPI5_SD_ELF) $(RPI5_SD_IMG)
	@LC_ALL=C strings $(RPI5_SD_IMG) | grep -Fq -- "ASELSAN/SDINV HOST=" || \
		{ echo "HATA: SDINV marker raw image içinde yok"; exit 1; }
	cp $(RPI5_DTB) $(RPI5_SD_DIR)/bcm2712-rpi-5-b.dtb
	cp $(RPI5_SD_PROFILE) $(RPI5_SD_DIR)/PROFILE.txt
	@set -eu; TMP_CONFIG=$(RPI5_SD_DIR)/config.txt.tmp; \
		trap 'rm -f "$$TMP_CONFIG"' EXIT HUP INT TERM; \
		sh scripts/render-rpi5-rp1-handoff-config.sh \
			$(RPI5_CONFIG) aselsanos-rpi5-sd.img aselsanos-epoch.bin > "$$TMP_CONFIG"; \
		mv "$$TMP_CONFIG" $(RPI5_SD_DIR)/config.txt; \
		trap - EXIT HUP INT TERM
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' $(RPI5_SD_DIR)/config.txt || \
		{ echo "HATA: sd config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@cd $(RPI5_SD_DIR) && shasum -a 256 \
		aselsanos-rpi5-sd.img bcm2712-rpi-5-b.dtb config.txt PROFILE.txt > SHA256SUMS
	@cd $(RPI5_SD_DIR) && shasum -a 256 -c SHA256SUMS
	@echo "✅ SD-A1 ilk okuma adayı (+ A32 ray düzeltmesi): $(RPI5_SD_IMG)"
	@echo "   Yalnız okuma. Fiziksel PASS değildir; SDINV + SDREAD + SDFAT ve karta yazılmadığının kanıtı gerekir."

# Epoch blob'u tek basina tazele.  Cekirdegin duvar saati "blob + acilistan
# beri gecen sure"dir, yani blob ne zaman yazildiysa saat oradan baslar.  Kart
# flash'landiktan sonra beklerse, o bekleme suresi kadar geri kalir.  Bu hedef
# imaji hic ellemez: yalnizca 32 baytlik blobu yeniden yazar, saniyeler surer,
# ve kart cikarilmadan hemen once calistirilmalidir.
refresh-rpi5-epoch:
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test -f "$(SD_MOUNT)/aselsanos-rpi5-sd.img" || \
		{ echo "HATA: bu bir AselsanOS karti degil: $(SD_MOUNT)"; exit 1; }
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@echo "   Blob tazelendi.  Karti simdi cikar ve Pi'ye tak; her dakika bekleme"
	@echo "   ekrandaki saate bir dakika geri kalma olarak yansir."

# Bir paketin butunlugu ile su an yeniden turetilebilirligi FARKLI iddialardir.
# Flash paketi kopyalar, dolayisiyla flash kapisi paketi dogrular; build/rpi5-sd
# ile karsilastirma dondurma anina aittir ve bir sonraki asama derlendiginde
# dogal olarak bozulur.
verify-rpi5-sd-attempt-w5-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w5.sh
	@sh -n scripts/seal-check-rpi5-sd-w5.sh
	@sh scripts/freeze-rpi5-sd-attempt-w5.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w5_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w5-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w5.sh
	@sh scripts/freeze-rpi5-sd-attempt-w5.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w5_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w5:
	@sh -n scripts/freeze-rpi5-sd-attempt-w5.sh
	@sh scripts/seal-check-rpi5-sd-w5.sh
	@sh scripts/freeze-rpi5-sd-attempt-w5.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w5.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w5-candidate-freeze

flash-rpi5-sd-w5:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W4_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W5 1024 veri sektoru yazar. Once W4 fiziksel olarak gecmeli."; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w5-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	cp "$(SDCW5_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW5_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW5_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW5_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW5_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W5 imaji karta yazildi: bu imaj 1024 VERI sektoru yazar (64..1087)."

verify-rpi5-sd-attempt-w6-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w6.sh
	@sh -n scripts/seal-check-rpi5-sd-w6.sh
	@sh scripts/freeze-rpi5-sd-attempt-w6.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w6_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w6-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w6.sh
	@sh scripts/freeze-rpi5-sd-attempt-w6.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w6_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w6:
	@sh -n scripts/freeze-rpi5-sd-attempt-w6.sh
	@sh scripts/seal-check-rpi5-sd-w6.sh
	@sh scripts/freeze-rpi5-sd-attempt-w6.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w6.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w6-candidate-freeze

flash-rpi5-sd-w6:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W5_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W6 ayni 1024 veri sektorunu CMD25 ile yazar. Once W5 fiziksel olarak gecmeli."; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w6-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	cp "$(SDCW6_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW6_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW6_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW6_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW6_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W6 imaji karta yazildi: 1024 VERI sektoru, CMD25, burst <= 64."

verify-rpi5-sd-attempt-w7-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w7.sh
	@sh -n scripts/seal-check-rpi5-sd-w7.sh
	@sh scripts/freeze-rpi5-sd-attempt-w7.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w7_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w7-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w7.sh
	@sh scripts/freeze-rpi5-sd-attempt-w7.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w7_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w7:
	@sh -n scripts/freeze-rpi5-sd-attempt-w7.sh
	@sh scripts/seal-check-rpi5-sd-w7.sh
	@sh scripts/freeze-rpi5-sd-attempt-w7.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w7.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w7-candidate-freeze

flash-rpi5-sd-w7:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W6_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W7 bir gercek kare yazar. Once W6 fiziksel olarak gecmeli."; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w7-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	cp "$(SDCW7_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW7_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW7_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW7_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW7_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W7 imaji karta yazildi: bir gercek kare, CMD25, 100% read-back."

verify-rpi5-sd-attempt-w4-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w4.sh
	@sh -n scripts/seal-check-rpi5-sd-w4.sh
	@sh scripts/freeze-rpi5-sd-attempt-w4.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w4_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w4-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w4.sh
	@sh scripts/freeze-rpi5-sd-attempt-w4.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w4_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w4:
	@sh -n scripts/freeze-rpi5-sd-attempt-w4.sh
	@sh scripts/seal-check-rpi5-sd-w4.sh
	@sh scripts/freeze-rpi5-sd-attempt-w4.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w4.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w4-candidate-freeze

flash-rpi5-sd-w4:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W3_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W4 superbloklari yazar. Once W3 fiziksel olarak gecmeli."; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w4-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	cp "$(SDCW4_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW4_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW4_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW4_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW4_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W4 imaji karta yazildi: $(SD_DISK)"
	@echo "   Bu imaj yalnizca sektor 0 ve 1'e (superbloklar) yazar."

verify-rpi5-sd-attempt-w3b-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3b.sh
	@sh -n scripts/seal-check-rpi5-sd-w3b.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3b.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w3b_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w3b-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3b.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3b.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w3b_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w3b:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3b.sh
	@sh scripts/seal-check-rpi5-sd-w3b.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3b.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w3b.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w3b-candidate-freeze

flash-rpi5-sd-w3b:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W2_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W3b karta YAZAR. W2 fiziksel olarak gecmis olmali."; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w3b-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	cp "$(SDCW3B_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW3B_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW3B_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW3B_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW3B_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W3b imaji karta yazildi: $(SD_DISK)"

verify-rpi5-sd-attempt-w2-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w2.sh
	@sh scripts/freeze-rpi5-sd-attempt-w2.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w2_candidate_freeze -- --test-threads=1

verify-rpi5-sd-attempt-w3-package:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3.sh --verify-package
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w3_candidate_freeze -- --test-threads=1

# SD-C W3: karta yazabilen tek aday.  Flash hedefi, W2'nin fiziksel olarak
# gectigini operatorun acikca beyan etmesini ister -- kademelendirme kurali
# nesirde degil arac icinde durur.
verify-rpi5-sd-attempt-w3-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3.sh
	@sh -n scripts/seal-check-rpi5-sd-w3.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w3_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w3:
	@sh -n scripts/freeze-rpi5-sd-attempt-w3.sh
	@sh scripts/seal-check-rpi5-sd-w3.sh
	@sh scripts/freeze-rpi5-sd-attempt-w3.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w3.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w3-candidate-freeze

flash-rpi5-sd-w3:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@test "$(W2_PHYSICAL_PASS)" = "yes" || \
		(echo "HATA: W3 karta YAZAR. Once W2 fiziksel olarak gecmeli."; \
		 echo "      Gectiyse: make flash-rpi5-sd-w3 ... W2_PHYSICAL_PASS=yes"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w3-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	@test ! -f "$(SD_MOUNT)/PERTURB_JOURNAL.json" || \
		{ echo "HATA: kartta bozma gunlugu var; once perturb ... restore"; exit 1; }
	cp "$(SDCW3_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW3_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW3_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW3_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW3_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W3 imaji karta yazildi: $(SD_DISK)"
	@echo "   DIKKAT: bu imaj karta TEK BIR SEKTOR yazar (dosya ofseti 32767)."
	@echo "   Kosudan once: python3 scripts/sector-manifest-rpi5-card.py snapshot ..."

verify-rpi5-sd-attempt-w2-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w2.sh
	@sh -n scripts/seal-check-rpi5-sd-w2.sh
	@sh scripts/freeze-rpi5-sd-attempt-w2.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w2_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w2:
	@sh -n scripts/freeze-rpi5-sd-attempt-w2.sh
	@sh scripts/seal-check-rpi5-sd-w2.sh
	@sh scripts/freeze-rpi5-sd-attempt-w2.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w2.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w2-candidate-freeze

flash-rpi5-sd-w2:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w2-package
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	@test ! -f "$(SD_MOUNT)/PERTURB_JOURNAL.json" || \
		{ echo "HATA: kartta bozma gunlugu var; once perturb ... restore"; exit 1; }
	cp "$(SDCW2_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW2_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW2_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW2_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW2_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W2 imaji karta yazildi: $(SD_DISK)"

# SD-C W1: sahiplik kaniti.  FAT'in tamami ve dizin agaci taranir; hala sifir
# yazma.  "Bu sektor benim mi?" degil, "YALNIZCA benim mi?" sorusunu cevaplar.
verify-rpi5-sd-attempt-w1-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w1.sh
	@sh -n scripts/seal-check-rpi5-sd-w1.sh
	@sh scripts/freeze-rpi5-sd-attempt-w1.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w1_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w1:
	@sh -n scripts/freeze-rpi5-sd-attempt-w1.sh
	@sh -n scripts/seal-check-rpi5-sd-w1.sh
	@sh scripts/seal-check-rpi5-sd-w1.sh
	@sh scripts/freeze-rpi5-sd-attempt-w1.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w1.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w1-candidate-freeze

flash-rpi5-sd-w1:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w1-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil"; exit 1; }
	@test ! -f "$(SD_MOUNT)/PERTURB_JOURNAL.json" || \
		{ echo "HATA: kartta bozma gunlugu var; once perturb ... restore"; exit 1; }
	cp "$(SDCW1_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW1_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW1_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW1_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW1_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W1 imaji karta yazildi: $(SD_DISK)"
	@echo "   Karttan OKUR; hicbir kart yazma komutu icermez."

# SD-C W0: kayit biciminin okuma yolu.  Her sektor kendi kimligini tasir, yani
# dosya video ile dolduktan sonra da kendini kanitlar.  Sifir yazma: imajda
# hicbir kart yazma komut indeksi yoktur ve kaynak sozlesmesi bunu dogrular.
verify-rpi5-sd-attempt-w0-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-w0.sh
	@sh -n scripts/seal-check-rpi5-sd-w0.sh
	@sh scripts/freeze-rpi5-sd-attempt-w0.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_w0_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-w0:
	@sh -n scripts/freeze-rpi5-sd-attempt-w0.sh
	@sh -n scripts/seal-check-rpi5-sd-w0.sh
	@sh scripts/seal-check-rpi5-sd-w0.sh
	@sh scripts/freeze-rpi5-sd-attempt-w0.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-w0.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-w0-candidate-freeze

# W0 karta yazilmadan once kart ASELREC1 biciminde yeniden on-tahsis edilmelidir.
flash-rpi5-sd-w0:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-w0-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@grep -Fxq 'format=ASELREC1' "$(SD_MOUNT)/RECORDING_PLAN.txt" || \
		{ echo "HATA: kart ASELREC1 biciminde degil; once preallocate-rpi5-recording-v2.py"; exit 1; }
	cp "$(SDCW0_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDCW0_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDCW0_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDCW0_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDCW0_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-C W0 imaji karta yazildi: $(SD_DISK)"
	@echo "   Karttan OKUR; hicbir kart yazma komutu icermez."

# SD-B2: ayni okuma yolu, ama dosya FAT zinciri uzerinden adreslenir.  SD-B
# fiziksel kosusu kartin parcali oldugunu kanitladi (Fragmented, 512 kume);
# bitisiklik varsayimi kaldirildi, yerine kosu haritasi (FileMap) geldi.
verify-rpi5-sd-attempt-b2-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-b2.sh
	@sh -n scripts/seal-check-rpi5-sd-b2.sh
	@sh scripts/freeze-rpi5-sd-attempt-b2.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_b2_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-b2:
	@sh -n scripts/freeze-rpi5-sd-attempt-b2.sh
	@sh -n scripts/seal-check-rpi5-sd-b2.sh
	@sh scripts/seal-check-rpi5-sd-b2.sh
	@sh scripts/freeze-rpi5-sd-attempt-b2.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-b2.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-b2-candidate-freeze

flash-rpi5-sd-b2:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line degeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line degeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-b2-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN kartta yok; once preallocate-rpi5-recording.sh"; exit 1; }
	cp "$(SDB2_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDB2_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDB2_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDB2_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDB2_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "SD-B2 imaji karta yazildi: $(SD_DISK)"
	@echo "   Karttan OKUR; hicbir kart yazma komutu icermez."

verify-rpi5-sd-attempt-b-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-b.sh
	@sh scripts/freeze-rpi5-sd-attempt-b.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_b_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-b:
	@sh -n scripts/freeze-rpi5-sd-attempt-b.sh
	@sh scripts/freeze-rpi5-sd-attempt-b.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-b.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-b-candidate-freeze

flash-rpi5-sd-b:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-b-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@test -f "$(SD_MOUNT)/ASELREC.BIN" || \
		{ echo "HATA: ASELREC.BIN kartta yok; once preallocate-rpi5-recording.sh"; exit 1; }
	cp "$(SDB_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDB_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDB_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDB_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDB_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo "✅ SD-B imajı karta yazıldı: $(SD_DISK)"
	@echo "   Karttan OKUR; hiçbir kart yazma komutu içermez."

verify-rpi5-sd-attempt-a1-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-a1.sh
	@sh scripts/freeze-rpi5-sd-attempt-a1.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_a1_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-a1:
	@sh -n scripts/freeze-rpi5-sd-attempt-a1.sh
	@sh scripts/freeze-rpi5-sd-attempt-a1.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-a1.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-a1-candidate-freeze

flash-rpi5-sd-a1:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-a1-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	cp "$(SDA1_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDA1_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDA1_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDA1_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDA1_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ SD-A1 imajı karta yazıldı: $(SD_DISK)"
	@echo "   Bu imaj karttan OKUR; hiçbir kart yazma komutu içermez."

verify-rpi5-sd-attempt-a0-candidate-freeze:
	@sh -n scripts/freeze-rpi5-sd-attempt-a0.sh
	@sh scripts/freeze-rpi5-sd-attempt-a0.sh --verify-freeze
	@$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_sd_attempt_a0_candidate_freeze -- --test-threads=1

freeze-rpi5-sd-attempt-a0:
	@sh -n scripts/freeze-rpi5-sd-attempt-a0.sh
	@sh scripts/freeze-rpi5-sd-attempt-a0.sh --source-check
	@sh scripts/freeze-rpi5-sd-attempt-a0.sh --freeze
	@$(MAKE) verify-rpi5-sd-attempt-a0-candidate-freeze

# SD-A0 flash. Ayni epoch blobu yazilir; imaj kartin kendisine dokunmaz.
flash-rpi5-sd-a0:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-sd-attempt-a0-candidate-freeze
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@for STALE in aselsanos-rpi5-screen.img aselsanos-rpi5-touch.img \
		aselsanos-rpi5-ui-server.img aselsanos-rpi5.img aselsanos-rpi5-ios-home.img; do \
		if [ -f "$(SD_MOUNT)/$$STALE" ]; then \
			rm -f "$(SD_MOUNT)/$$STALE"; \
			echo "   eski payload silindi: $$STALE"; \
		fi; \
	done
	cp "$(SDA0_PACKAGE)/aselsanos-rpi5-sd.img" "$(SD_MOUNT)/aselsanos-rpi5-sd.img"
	cp "$(SDA0_PACKAGE)/bcm2712-rpi-5-b.dtb" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(SDA0_PACKAGE)/config.txt" "$(SD_MOUNT)/config.txt"
	cp "$(SDA0_PACKAGE)/PROFILE.txt" "$(SD_MOUNT)/PROFILE.txt"
	cp "$(SDA0_PACKAGE)/SHA256SUMS" "$(SD_MOUNT)/SHA256SUMS"
	@sh scripts/render-rpi5-epoch-blob.sh "$(SD_MOUNT)/aselsanos-epoch.bin"
	sync
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	@grep -Fxq 'kernel=aselsanos-rpi5-sd.img' "$(SD_MOUNT)/config.txt" || \
		{ echo "HATA: kart config kernel=aselsanos-rpi5-sd.img değil"; exit 1; }
	@ls -1 "$(SD_MOUNT)"/*.img | sed 's|.*/|   kartta kalan imaj: |'
	sync
	@echo "✅ SD-A0 envanter imajı karta yazıldı: $(SD_DISK)"
	@echo "   Bu imaj karta HİÇBİR SD komutu göndermez; kart yalnız firmware tarafından okunur."

$(RPI5_DTB): FORCE
	@mkdir -p firmware
	@if ! printf '%s  %s\n' "$(RPI5_DTB_SHA256)" "$@" | shasum -a 256 -c - >/dev/null 2>&1; then \
		TMP="$@.tmp"; \
		trap 'rm -f "$$TMP"' EXIT; \
		curl -fsSL -o "$$TMP" \
			"https://raw.githubusercontent.com/raspberrypi/firmware/$(RPI_FIRMWARE_REV)/boot/bcm2712-rpi-5-b.dtb"; \
		printf '%s  %s\n' "$(RPI5_DTB_SHA256)" "$$TMP" | shasum -a 256 -c -; \
		mv "$$TMP" "$@"; \
		trap - EXIT; \
	fi
	@printf '%s  %s\n' "$(RPI5_DTB_SHA256)" "$@" | shasum -a 256 -c -

FORCE:

# Destructive hedeflerin ortak, fail-closed whole-disk doğrulaması.
check-sd-rpi5:
	@test -n "$(SD_DISK)" || \
		(echo "HATA: SD_DISK zorunlu. Örnek: make $@ SD_DISK=/dev/disk4"; exit 1)
	@printf '%s\n' "$(SD_DISK)" | grep -Eq '^/dev/disk[0-9]+$$' || \
		(echo "HATA: SD_DISK whole disk biçiminde olmalı: /dev/diskN"; exit 1)
	@INFO=$$(mktemp -t aselsanos-sd); trap 'rm -f "$$INFO"' EXIT; \
		diskutil info -plist "$(SD_DISK)" > "$$INFO"; \
		[ "$$(plutil -extract DeviceNode raw -o - "$$INFO")" = "$(SD_DISK)" ] || \
			{ echo "HATA: DeviceNode eşleşmiyor"; exit 1; }; \
		[ "$$(plutil -extract WholeDisk raw -o - "$$INFO")" = "true" ] || \
			{ echo "HATA: $(SD_DISK) whole disk değil"; exit 1; }; \
		[ "$$(plutil -extract OSInternalMedia raw -o - "$$INFO")" = "false" ] || \
			{ echo "HATA: işletim sistemi dahili diski reddedildi"; exit 1; }; \
		[ "$$(plutil -extract RemovableMediaOrExternalDevice raw -o - "$$INFO")" = "true" ] || \
			{ echo "HATA: aygıt çıkarılabilir/harici değil"; exit 1; }; \
		[ "$$(plutil -extract BusProtocol raw -o - "$$INFO")" = "Secure Digital" ] || \
			{ echo "HATA: yalnızca Secure Digital veri yolu kabul edilir"; exit 1; }

verify-sd-volume-rpi5: check-sd-rpi5
	@test -n "$(SD_MOUNT)" && [ ! -L "$(SD_MOUNT)" ] && [ -d "$(SD_MOUNT)" ] || \
		(echo "HATA: geçerli, gerçek bir SD_MOUNT dizini gerekli"; exit 1)
	@case "$(SD_MOUNT)" in /Volumes/*) ;; \
		*) echo "HATA: SD_MOUNT /Volumes altında olmalı"; exit 1 ;; esac
	@INFO=$$(mktemp -t aselsanos-volume); trap 'rm -f "$$INFO"' EXIT; \
		diskutil info -plist "$(SD_MOUNT)" > "$$INFO"; \
		[ "$$(plutil -extract ParentWholeDisk raw -o - "$$INFO")" = "$(notdir $(SD_DISK))" ] || \
			{ echo "HATA: $(SD_MOUNT), $(SD_DISK) üzerinde değil"; exit 1; }; \
		[ "$$(plutil -extract MountPoint raw -o - "$$INFO")" = "$(SD_MOUNT)" ] || \
			{ echo "HATA: mount point eşleşmiyor"; exit 1; }; \
		[ "$$(plutil -extract FilesystemType raw -o - "$$INFO")" = "msdos" ] || \
			{ echo "HATA: boot bölümü FAT32/msdos değil"; exit 1; }; \
		[ "$$(plutil -extract VolumeName raw -o - "$$INFO")" = "ASELSANBOOT" ] || \
			{ echo "HATA: volume adı ASELSANBOOT değil"; exit 1; }; \
		[ "$$(plutil -extract WritableVolume raw -o - "$$INFO")" = "true" ] || \
			{ echo "HATA: volume yazılabilir değil"; exit 1; }

# Destructive: erases SD_DISK. Built-in SDXC slots report Internal=true, so
# safety is based on OSInternalMedia=false + removable + Secure Digital.
format-sd-rpi5: check-sd-rpi5
	@echo ">>> SD kart doğrulanıyor: $(SD_DISK)"
	@echo ">>> $(SD_DISK) siliniyor — MBR + FAT32 ASELSANBOOT (512M)"
	diskutil unmountDisk "$(SD_DISK)"
	diskutil partitionDisk "$(SD_DISK)" MBR FAT32 ASELSANBOOT 512M
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@echo "✅ FAT32 boot bölümü: $(SD_MOUNT)"

flash-rpi5: image-rpi5 verify-sd-volume-rpi5
	cp "$(RPI5_IMG)" "$(SD_MOUNT)/aselsanos-rpi5.img"
	cp "$(RPI5_PACKAGE_DTB)" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb"
	cp "$(RPI5_PACKAGE_CONFIG)" "$(SD_MOUNT)/config.txt"
	cp "$(RPI5_SUMS)" "$(SD_MOUNT)/SHA256SUMS"
	@cd "$(SD_MOUNT)" && shasum -a 256 -c SHA256SUMS
	sync
	@echo ""
	@echo "✅ Kart kökü:"
	@ls -lh "$(SD_MOUNT)/aselsanos-rpi5.img" "$(SD_MOUNT)/bcm2712-rpi-5-b.dtb" \
		"$(SD_MOUNT)/config.txt" "$(SD_MOUNT)/SHA256SUMS"
	@echo ""
	@echo "Şimdi: kartı güvenle çıkar, Pi 5'e tak, Debug Probe UART10, 27W güç."
	@echo "Beklenen terminal: ASELSAN/BOOT0 BCM2712 … ASELSAN/BOOT8F HANDOFF=POST_BOOT8E SOURCE=CPU0 TARGET=CPU1"
	@echo "Başarılı UART'ta G8FERR, panic ve unknown IRQ bulunmamalı."

verify-rpi5-g8g-staged-flash-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_staged_flash_source
	@sh -n scripts/flash-rpi5-g8g-staged.sh
	@sh scripts/flash-rpi5-g8g-staged.sh \
		--verify-source-only "$(RPI5_G8G_STAGED_PACKAGE)"

flash-rpi5-g8g-staged:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@$(MAKE) verify-rpi5-g8g-staged-flash-source
	@$(MAKE) verify-sd-volume-rpi5 SD_DISK="$(SD_DISK)" SD_MOUNT="$(SD_MOUNT)"
	@sh scripts/flash-rpi5-g8g-staged.sh "$(RPI5_G8G_STAGED_PACKAGE)" "$(SD_DISK)" "$(SD_MOUNT)"

# S110 S90 direct-test compatibility boundary begin.
# Yıkıcı olmayan tarihsel G8g hedef sınırı; make davranışı taşımaz.
# S110 S90 direct-test compatibility boundary end.

# Sıra 101 destructive yüzeyi bilinçli olarak izoledir: prerequisite taşımaz,
# default/broad verify/image zincirine bağlı değildir ve üç yetki girdisini
# yalnız command line origin'den kabul eder. Source target device-free'dir.
flash-rpi5-g8h-staged: export S101_ENV_SD_DISK := $(value SD_DISK)
flash-rpi5-g8h-staged: export S101_ENV_SD_MOUNT := $(value SD_MOUNT)
flash-rpi5-g8h-staged: export S101_ENV_FLASH_AUTH := $(value S101_FLASH_AUTH)
flash-rpi5-g8h-staged:
	@test "$(origin SD_DISK)" = "command line" || \
		(echo "HATA: SD_DISK explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin SD_MOUNT)" = "command line" || \
		(echo "HATA: SD_MOUNT explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin S101_FLASH_AUTH)" = "command line" || \
		(echo "HATA: S101_FLASH_AUTH explicit command-line değeri zorunlu"; exit 1)
	@test "$(origin S101_ENV_SD_DISK)" = "file" || \
		(echo "HATA: internal SD_DISK export override yasak"; exit 1)
	@test "$(origin S101_ENV_SD_MOUNT)" = "file" || \
		(echo "HATA: internal SD_MOUNT export override yasak"; exit 1)
	@test "$(origin S101_ENV_FLASH_AUTH)" = "file" || \
		(echo "HATA: internal authorization export override yasak"; exit 1)
	@$(MAKE) verify-rpi5-g8h-staged-flash-source
	@sh scripts/flash-rpi5-g8h-staged.sh --flash-from-env

verify-rpi5-g8g-capture-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_capture_source
	@$(MAKE) verify-rpi5-g8g-contract
	@set -eu; \
		capture_tmp=$$(mktemp -d /tmp/aselsanos-g8g-capture-source.XXXXXX); \
		trap '/bin/rm -rf "$$capture_tmp"' 0 1 2 15; \
		$(CC) -std=c11 -D_DARWIN_C_SOURCE -D_DEFAULT_SOURCE \
			-Wall -Wextra -Wpedantic -Werror -O2 \
			scripts/capture-rpi5-g8g-uart10.c \
			-o "$$capture_tmp/capture-rpi5-g8g-uart10"; \
		G8G_CAPTURE_HELPER="$$capture_tmp/capture-rpi5-g8g-uart10" \
		G8G_CAPTURE_PTY_RAW="$$capture_tmp/uart10.raw" \
			$(CARGO) test -p aselsan_microkernel_simulation \
			--test rpi5_g8g_capture_pty -- --test-threads=1; \
		$(CARGO) run --quiet -p aselsan_microkernel_simulation \
			--example verify_rpi5_g8g_log -- "$$capture_tmp/uart10.raw"

verify-rpi5-g8g-physical-raw-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8g_physical_raw_source \
		--test rpi5_g8g_physical_raw
	$(CARGO) check -p aselsan_microkernel_simulation \
		--example verify_rpi5_g8g_physical_raw
	@sh -n scripts/verify-rpi5-g8g-physical-raw.sh
	@sh scripts/verify-rpi5-g8g-physical-raw.sh --verify-source-only

# S121 host-only G8h capture/physical-raw preparation begin.
.PHONY: verify-rpi5-g8h-capture-source verify-rpi5-g8h-physical-raw-source

verify-rpi5-g8h-capture-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_capture_source
	@$(MAKE) verify-rpi5-g8h-contract
	@set -eu; \
		capture_tmp=$$(mktemp -d /tmp/aselsanos-g8h-capture-source.XXXXXX); \
		trap '/bin/rm -rf "$$capture_tmp"' 0 1 2 15; \
		$(CC) -std=c11 -D_DARWIN_C_SOURCE -D_DEFAULT_SOURCE \
			-Wall -Wextra -Wpedantic -Werror -O2 \
			scripts/capture-rpi5-g8h-uart10.c \
			-o "$$capture_tmp/capture-rpi5-g8h-uart10"; \
		G8H_CAPTURE_HELPER="$$capture_tmp/capture-rpi5-g8h-uart10" \
		G8H_CAPTURE_PTY_RAW="$$capture_tmp/uart10.raw" \
			$(CARGO) test -p aselsan_microkernel_simulation \
			--test rpi5_g8h_capture_pty -- --test-threads=1; \
		$(CARGO) run --quiet -p aselsan_microkernel_simulation \
			--example verify_rpi5_g8h_log -- "$$capture_tmp/uart10.raw"

verify-rpi5-g8h-physical-raw-source:
	$(CARGO) test -p aselsan_microkernel_simulation \
		--test rpi5_g8h_physical_raw_source \
		--test rpi5_g8h_physical_raw
	$(CARGO) check -p aselsan_microkernel_simulation \
		--example verify_rpi5_g8h_physical_raw
	@sh -n scripts/verify-rpi5-g8h-physical-raw.sh
	@sh scripts/verify-rpi5-g8h-physical-raw.sh --verify-source-only

# S122 trusted/stress hello binary split begin.
# Parse-time augmentation adds this phony prerequisite to the frozen
# userspace-binaries rule without changing the historical G7c-only
# userspace-hello dependency or creating a second textual rule definition.
.PHONY: userspace-hello-stress
S122_USERSPACE_BINARIES := userspace-binaries
$(eval $(S122_USERSPACE_BINARIES): userspace-hello-stress)

userspace-hello-stress:
	cd userspace/hello_stress && $(CARGO) build --target $(TARGET) --release
# S122 trusted/stress hello binary split end.
# S121 host-only G8h capture/physical-raw preparation end.

# Yıkıcı olmayan, CI/yerel tekrar üretilebilir doğrulama matrisi.
verify: verify-core verify-web

verify-core: userspace-binaries $(RPI5_DTB)
	$(CARGO) test --workspace
	@$(MAKE) kernel
	@$(MAKE) verify-qemu
	@$(MAKE) kernel-rpi4
	@$(MAKE) kernel-rpi5
	@$(MAKE) image-rpi5

verify-web:
	cd website && npm ci
	cd website && npm test
	cd website && npm run lint
	cd website && npx tsc --noEmit
	cd website && npm run build

verify-qemu: kernel
	QEMU="$(QEMU)" sh scripts/qemu-smoke.sh "$(ELF)"

run: kernel
	@echo ">>> QEMU aarch64 virt üzerinde kernel başlatılıyor..."
	qemu-system-aarch64 \
		-M virt \
		-cpu cortex-a72 \
		-smp 2 \
		-m 128M \
		-nographic \
		-serial mon:stdio \
		-kernel $(ELF)

run-rpi4:
	@echo ">>> Raspberry Pi 4 test rehberi:"
	@sed -n '1,60p' docs/M8.1-Raspberry-Pi-4-Testing-Guide.md

clean:
	cd $(KERNEL_DIR) && $(CARGO) clean
	rm -rf build/rpi5
	rm -rf target/qemu target/rpi4 target/rpi5

sim:
	$(CARGO) run --manifest-path simulation/Cargo.toml
snippet sha256: 7308784eb395file sha256: 7308784eb395
02 · Doğrulayan test kodu

Operations komutuna bağlı focused test

tam Rust öğesiL209–L224
simulation/tests/runtime_oom_reply_bridge.rs::s143_strict_image_is_built_embedded_and_linked_in_a_disjoint_window

#[test]
fn s143_strict_image_is_built_embedded_and_linked_in_a_disjoint_window() {
    let makefile = source("Makefile");
    let userspace = source("userspace/mod.rs");
    let supervisor = source("userspace/oom_reply_bridge_supervisor/src/main.rs");
    let linker = source("userspace/oom_reply_bridge_supervisor/linker.ld");

    assert!(makefile.contains("userspace-oom-reply-bridge-supervisor"));
    assert!(userspace.contains("OOM_REPLY_BRIDGE_SUPERVISOR_BINARY"));
    assert!(supervisor.contains("[K1-MEM2-S143] REPLY BRIDGE EL0 ACK=EXACT"));
    assert!(supervisor.contains("SYS_IPC_RECV"));
    assert!(supervisor.contains("SYS_IPC_REPLY"));
    assert!(supervisor.contains("ENDPOINT_CLOSE_HANDOFF"));
    assert!(linker.contains(". = 0x03c00000;"));
}
snippet sha256: 19254c0ef712file sha256: ab1298eeaedd
03 · Kapı kimlik kaydı

Operations sıra, kimlik ve başlık bağı

tam Operations kaydıL24855–L24994
website/src/lib/operations.ts::k1-mem0-mem1-mem2-k2-reply-derived-broker-commit-partial
  {
    id: "k1-mem0-mem1-mem2-k2-reply-derived-broker-commit-partial",
    date: "2026-08-24",
    sequence: 143,
    status: "passed",
    umbrella_status: "partial",
    title:
      "K1/MEM0–MEM2/K2: reply-derived broker ACK ve otomatik session close",
    summary:
      "S143, ordinary SYS_IPC_REPLY sonucunu exact task/cap/payload/session/lease authority ile audited broker ACK ve otomatik supervisor session-close commit'ine bağlar. Reply bridge IPC mutasyonundan önce preflight yapar, IPC reply başarıyla commit olduktan sonra broker ACK + close'u tek broker mutation epoch'unda uygular. Strict RuntimePmm EL0 supervisor task#50 gerçek kernel CALL'u ordinary SYS_IPC_RECV ile aldı ve ordinary SYS_IPC_REPLY ile yanıtladı; controller broker ACK veya session-close çağırmadı. Bound reply cap'in CALL-to-reply compatibility alias'ı fail-closed reddedilir. IPC ve broker ayrı lock domain'leri olduğundan cross-subsystem rollback iddia edilmez; beklenmeyen post-IPC invariant ihlali kernel fail-closed panic sınırındadır. K1/MEM0–MEM2/K2 PARTIAL kalır.",
    evidence: [
      "Implementation öncesi `runtime_oom_reply_bridge` bridge tipi, lifecycle wrapper'ları ve S143 strict image bulunmadığı için compile-time 0/8 RED verdi; final kaynak kapısı 8/8 PASS.",
      "Allocation-free bridge exact task, reply cap, ACK label/data, session ve delivery lease'i tek binding'de tutar. Foreign responder/payload non-mutating reddedilir; unrelated reply cap generic IPC olarak kalır; stale preflight ikinci kez commit edemez.",
      "Production lock sırası bridge→broker'dır. Task exit exact armed binding'i temizler; bound reply cap'in legacy SYS_IPC_CALL reply alias'ı InvalidCapability ile fail-closed reddedilir.",
      "S129–S143 exact envanteri 32 binary / 176 testtir; 176/176 PASS. İlk birleşik tur yalnız S141'de kalan tarihsel W^X 19/19 toplamını reddetti; exact eski marker'lar korunup kümülatif toplam 20/20'ye taşındı.",
      "AArch64 board-qemu, board-rpi4, board-rpi5 ve board-rpi5+smp applicability 4/4 PASS.",
      "QEMU controller/supervisor=32/50, domain=1330597186, endpoint/reply=45/46 ve SESSION=5. USER_REPLY=ORDINARY_SYS_IPC_REPLY, BRIDGE_PREFLIGHT=EXACT, REPLY_DERIVED_ACK=YES, SESSION_CLOSE=AUTOMATIC.",
      "BRIDGE_ACK_CALLS/BRIDGE_SESSION_CLOSE_CALLS=1/1; CONTROLLER_BROKER_ACK_CALLS/CONTROLLER_SESSION_CLOSE_CALLS=0/0; SYNTHETIC_ACK=NO, REPLY_ONESHOT=1/1, NORMAL_EXIT_RECOVERY=NONE ve BROKER_DRAINED=YES.",
      "Broker cumulative SESSIONS/CRASHES/ACKNOWLEDGED=5/2/3; bridge ARMED/COMMITTED/CANCELLED=1/1/0. Supervisor reclaim=5, free 6139→6134→6139, active 5→10→5, OWNER_EP_CLEANUP=1, KERNEL_FAULTS=0 ve EXECUTOR=PASS.",
      "QEMU strict ELF W^X 20/20, IPC reply 19/19, final RuntimePmm 6144→6144 / active 0→0 ve scheduler SEC5 birlikte PASS.",
      "Manuel 8 saniyelik QEMU log'u 483507 B / SHA-256 294b6376cf94cca989f8d37108b6587cb6402737bf7710e003e8e4ff269caa23 olarak ölçüldü.",
      "Tam workspace yalnız bağımsız frozen S96 exceptions.S SHA-256 uyuşmazlığında durdu: observed f7b47672…04fd, expected c0eed3e2…cb89; full GREEN iddia edilmedi.",
      "Fiziksel operatör runbook'u görünürdür: Gücü kapat → SD kartı Pi'den çıkar → SD kartı Mac'e tak → yetkili image/yazma ve read-back doğrulaması → SD kartı Mac'ten güvenli çıkar → SD kartı güçsüz Pi'ye tak → UART capture pre-arm/identity → Güç ver.",
      "Runbook S143'te uygulanmadı: physical/device operations=0, S124 archive/promotion STOP, son fiziksel boot/runtime PASS S92 BOOT8G ve son storage/media PASS S119.",
      "Güncel planlama tahmini S143 bazında R2 bitiş aralığı S327–383, risk-paylı merkez ≈S360'tır; taahhüt veya fiziksel PASS değildir.",
      "Yerel web kapıları: içerik 239/239, ESLint, TypeScript --noEmit ve Next.js static export 23/23 route / 191 file PASS.",
      "İlk S143 production yayını 140fe3bd.aselsan-microkernel.pages.dev kimliğiyle tamamlandı. Özel alan adı cache-bust ile yerel static çıktıya byte-exact doğrulandı: operations 4962280 B / 6a77531d…b697e, timeline 545870 B / 61b871a5…2adb, yol-haritasi 546080 B / 12e337d0…a7a7a. Üç route S143 runtime, açık fiziksel runbook, physical=0 ve S327–383 / ≈S360 marker'larını 19/19 taşıdı. Immutable deployment alt alanına current host'tan direct fetch connect timeout oldu ve buna dayanılarak PASS üretilmedi.",
      "Kalıcı kapsam: `docs/K1-S143-Reply-Derived-Broker-Commit-Proof.md`.",
    ],
    commands: [
      "cargo test -p aselsan_microkernel_simulation --test runtime_oom_reply_bridge -- --test-threads=1",
      "cargo test -p aselsan_microkernel_simulation [32 exact focused test binary] -- --test-threads=1",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none [board-qemu, board-rpi4, board-rpi5, board-rpi5+smp]",
      "make verify-qemu",
      "cargo test --workspace -- --test-threads=1",
      "python3 scripts/render-project-status.py --check",
      "cd website && npm test && npm run lint && npx tsc --noEmit && npm run build",
    ],
    terminalSessions: [
      {
        id: "s143-red-before-reply-bridge",
        title:
          "Reply-derived broker bridge kaynak kapısı: implementation öncesi RED",
        commandLines: [
          "cargo test -p aselsan_microkernel_simulation --test runtime_oom_reply_bridge -- --test-threads=1",
        ],
        outputLines: [
          "runtime_oom_reply_bridge: compile-time 0/8 before implementation",
          "missing: bridge types, lifecycle wrappers, ordinary-reply integration and strict S143 image",
          "no partial PASS accepted",
        ],
        exitCode: 101,
        outputMode: "selected",
      },
      {
        id: "s143-green-focused-aarch64-qemu",
        title: "Ordinary reply-derived ACK/session-close, AArch64 ve QEMU",
        commandLines: [
          "cargo test -p aselsan_microkernel_simulation [32 exact focused test binary] -- --test-threads=1",
          "cargo check -p aselsan_kernel --target aarch64-unknown-none [4 profiles]",
          "make verify-qemu",
        ],
        outputLines: [
          "runtime_oom_reply_bridge: 8/8 PASS",
          "combined exact focused inventory: 176/176 PASS · 32 binaries",
          "AArch64 compile profiles: 4/4 PASS",
          "[K1-MEM2-REPLY-BRIDGE] task=50 reply_cap=46 sequence=3 source_event=1 REPLY_DERIVED_BROKER_COMMIT=YES SESSION_CLOSE=AUTOMATIC",
          "[K1-MEM2-S143] REPLY BRIDGE EL0 ACK=EXACT",
          "[K1-MEM2-S143] SESSION=5 USER_REPLY=ORDINARY_SYS_IPC_REPLY BRIDGE_PREFLIGHT=EXACT CONTROLLER_BROKER_ACK_CALLS=0 CONTROLLER_SESSION_CLOSE_CALLS=0 BRIDGE_COMMITTED=1 RECLAIM=5 free=6139->6134->6139 active=5->10->5 EXECUTOR=PASS",
          "QEMU smoke PASS: strict ELF W^X 20/20 · IPC reply 19/19 · S143 PASS",
        ],
        exitCode: 0,
        outputMode: "selected",
      },
      {
        id: "s143-workspace-independent-history-red",
        title: "Tam workspace: S143 dışı frozen S96 identity kırmızısı",
        commandLines: ["cargo test --workspace -- --test-threads=1"],
        outputLines: [
          "rpi5_g8h_integration_source::wiring_does_not_mutate_timer_gic_boot_or_expand_runtime_scope: FAILED",
          "S96 exceptions.S SHA-256: observed f7b47672...04fd, frozen expected c0eed3e2...cb89",
          "full-workspace GREEN is not claimed",
        ],
        exitCode: 101,
        outputMode: "selected",
      },
      {
        id: "s143-local-web-gates",
        title:
          "İşlemler, Timeline, tahmin ve fiziksel runbook yerel web kapıları",
        commandLines: [
          "cd website && npm test",
          "cd website && npm run lint",
          "cd website && npx tsc --noEmit",
          "cd website && npm run build",
        ],
        outputLines: [
          "web content tests: 239/239 PASS",
          "ESLint: PASS · TypeScript --noEmit: PASS",
          "Next.js static export: 23/23 routes · 191 files PASS",
          "S143 reply-derived ACK/close, S327–383 / ≈S360 forecast and exact physical operator verbs are mandatory",
          "physical/device operations=0 · S124 archive/promotion STOP",
        ],
        exitCode: 0,
        outputMode: "selected",
      },
      {
        id: "s143-initial-production-publication",
        title: "İlk S143 production yayını ve özel alan adı exact doğrulaması",
        commandLines: [
          "cd website && npx wrangler pages deploy out --project-name=aselsan-microkernel --branch=main --commit-dirty=true",
          "curl --fail --location 'https://aselsan.kerege.net/{operations,timeline,yol-haritasi}/?s143=140fe3bd-<nonce>'",
          "cmp website/out/<route>/index.html <cache-busted-live-route>",
          "curl --connect-timeout 10 --max-time 20 'https://140fe3bd.aselsan-microkernel.pages.dev/operations/'",
        ],
        outputLines: [
          "deployment: https://140fe3bd.aselsan-microkernel.pages.dev",
          "custom-domain byte-exact: operations 4962280 B / 6a77531d...b697e",
          "custom-domain byte-exact: timeline 545870 B / 61b871a5...2adb",
          "custom-domain byte-exact: yol-haritasi 546080 B / 12e337d0...a7a7a",
          "live marker matrix: 19/19 on each of three routes",
          "immutable deployment direct fetch: connect timeout · no PASS claimed from that host",
          "physical/device operations=0 · S124 archive/promotion STOP",
        ],
        exitCode: 0,
        outputMode: "selected",
      },
    ],
    terminalSessionsNote:
      "S143 ordinary SYS_IPC_REPLY sonucunu exact broker ACK ve automatic session close'a bağlar; controller ACK/close çağrısı yoktur. Cross-subsystem rollback ve COMPLETE iddiası yoktur. Fiziksel runbook görünürdür ve uygulanmadı.",
    limitations: [
      "Tek reply binding ve tek in-flight event kanıtlandı; sekiz bağımsız concurrent victim/session/reply matrisi değildir.",
      "IPC ve broker ayrı lock domain'leridir; beklenmeyen post-IPC broker invariant failure fail-closed panic'tir, cross-subsystem rollback kanıtlanmadı.",
      "Instruction abort, alignment, undefined instruction ve concurrent multi-fault matrisi açıktır.",
      "Genel IPC syscall deadline/timer cancellation yolu bağlı değildir; product pressure eşikleri ölçülmüş veya imzalanmış değildir.",
      "CPU0-only kanıtıdır; Generic SMP cross-CPU stop/migration/TLB shootdown/reaper açıktır.",
      "Capability transfer, shared-memory loan ve bütün legacy/kernel kaynak üreticilerinin ortak reconciliation'ı açıktır.",
      "K1, MEM0, MEM1, MEM2 ve K2 COMPLETE değildir; S124 fiziksel archive/promotion STOP kalır.",
    ],
  },
snippet sha256: 2c382c6c94bffile sha256: 9726dbf00f84
Focused test komutu
cargo test -p aselsan_microkernel_simulation --test runtime_oom_reply_bridge -- --test-threads=1
proof: docs/K1-S143-Reply-Derived-Broker-Commit-Proof.md
Registry schema v5 · generator website/scripts/generate-code-gates.mjs · Tam SHA-256: 91d38c7b6222f0b4c117be786454853543da55a160e543d9b951057cc20dcc06