Дневник разработки

Решения, ошибки и результаты испытаний Guseva OS.

Из лаборатории

· Ядро

24 870 возвратов страниц в одном тесте

Как проверили очистку памяти и повторный запуск изолированных компонентов.

Ход проверки

При завершении компонента ядро освобождает его отображения и ресурсы. Обход карты страниц теперь пропускает целую группу, если для неё нет записей. В QEMU тест выделял 8 193 последовательные страницы, проверял разреженное отображение и учитывал четыре поколения компонентов, включая повторный запуск.

Счётчик зафиксировал 24 870 возвратов страниц. По завершении теста осталось 0 активных компонентов, полномочий, IPC-запросов, прав доступа к устройствам и ссылок на объекты. Это результат целевого прогона профиля памяти. Время очистки предстоит измерить отдельно.

· Графика

Почему открыть окно проще, чем правильно его закрыть

История 440 001 пикселя, потерянного перемещения мыши и проверки восстановления рабочего стола.

Ход проверки

Первое сравнение кадров показало 440 001 несовпадающий пиксель. В журнале приёмки записано, что кадр после попытки закрытия совпал с кадром открытого терминала. QEMU терял часть перемещений мыши, и щелчок попадал левее кнопки.

После изменения интервала подачи событий сценарий подтвердил закрытие терминала и полное совпадение кадра с исходным рабочим столом. Отдельный тест реестра окон проверил создание, закрытие и отказ при обращении по устаревшему дескриптору. Собственные пиксельные поверхности окон, перекрытие и фокус остаются в работе.

· Этап 236

«Хаб» стал отдельным окном

В Guseva OS можно открыть «Хаб», запустить из него командную строку и закрыть её. В испытании QEMU после закрытия рабочий стол полностью восстановился.

Теперь композитор хранит изображение окна отдельно от рабочего стола. При закрытии он может показать сохранённый фон под окном. В этом прогоне кадр после закрытия терминала совпал с исходным до пикселя.

Последовательность кадров из QEMU, этап 236. Рабочий стол → «Хаб» → терминал → восстановленный рабочий стол.

Встроенный терминал и «Хаб» пока работают внутри одного компонента рабочего стола. Окна независимых приложений ещё предстоит проверить в составе оболочки.

Читать технический отчёт этапа 236

Что показать в следующей демонстрации: работу с несколькими окнами, запуск приложения или загрузку ОС? Напишите в комментариях на главной.

Отчёты по этапам

Записей в архиве — 186. Результаты и ограничения в каждом отчёте относятся к указанной сборке.

Этап 237 — различение отказов физического распределителя

Прямая ссылка на отчёт

Статус: принят 13 ноября 2026 года в заявленных границах. Это ограниченный шаг MEM-16, не приёмка всей политики нехватки памяти.

Изменение

pmm_allocate теперь сразу возвращает отказ, если счётчик свободных страниц равен нулю, не просматривая регионы и bitmap. В заголовке PMM добавлены накопительные счётчики общего числа отказов, отказов при нулевом счётчике свободных страниц и промахов bitmap, когда счётчик обещает свободные страницы, но сканирование их не находит.

Существующий PMM self-test проверяет, что исчерпание двух тестовых страниц даёт ровно один отказ по нулевому счётчику и не увеличивает число промахов bitmap. После self-test PMM сбрасывается перед построением реальной карты.

Счётчики доступны наблюдателю и отображаются в Dev Shell в сводке памяти. Независимый валидатор проверяет согласованность счётчиков и ожидает нулевые отказы во время штатной загрузки.

Проверки и результат

  • Сборка python tools/host/build.py --platform-case workers прошла в канонической папке. Образ: build/host/windows-x86_64/debug/qemu-x86_64/platform-workers-n3/guseva-p0.img; SHA-256: 535c4bfe5f98c00d4e493012f1a9ec5844fdac2b91ee75404c9228220b0c21fd.
  • QEMU-сценарий qemu_acceptance.py вывел PMM: exhaustion and reuse verified, а затем PMM: verified с 19 213 управляемыми страницами, 19 212 свободными и одной занятой. Полный сценарий workers не завершился: после старта планировщика приёмка достигла тайм-аута на последующей работе платформы. Поэтому QEMU-сценарий не считается PASS и этап остаётся в работе.
  • py_compile для наблюдателя, Dev Shell, валидатора PMM и каталога выполнен; загрузка системного каталога подтвердила смещения 0, 8, 16, 24, 32, 40 и 48.

Границы

Здесь нет автоматического освобождения страниц других компонентов, выбора жертвы, сжатия, подкачки или согласования с владельцем. Нулевой счётчик свободных страниц фиксирует состояние учёта; он сам по себе не доказывает содержимое bitmap. Политика восстановления данных и проверка отказа полного приложения остаются открытыми.

Следующий шаг

MEM-16 остаётся в работе: отдельно определить и реализовать безопасную реакцию системы на исчерпание памяти без потери защищаемых данных. Эта задача не входила в этап 237.

Приёмка этапа 237 · 13 ноября 2026 года

Первоначальный результат выше сохранён как история первой попытки. Повторный разбор показал, что workers не зависал: приёмщик применял к нему две проверки из других профилей — ожидал 15 страниц очистки вместо 14 (одна страница заранее освобождается самим компонентом) и требовал данные резервирования виртуальной памяти, которого профиль workers не выполняет. Оба условия уточнены только в host-приёмщике.

  • Точечные проверки подтвердили декодирование счётчиков PMM из снимка и разбор фактических значений из загрузочного диагностического журнала. Обе проверки прошли.
  • Добавлен вывод счётчиков PMM self-test до сброса временного менеджера. На реальном QEMU-запуске журнал содержит allocation_failures=1, zero_free_count_failures=1, bitmap_scan_misses=0; наблюдатель разбирает их отдельно от текущих счётчиков реального PMM, а в сводке Dev Shell добавлены обе группы.
  • Свежая сборка профиля workers и QEMU-приёмка прошли: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; 3 компонента завершили ход с прогрессом 5, возврат очисткой — 42 страницы, faults и остаточные полномочия/IPC/device leases/object references — 0.
  • Проверенный образ: SHA-256 6374898ef4ba101a259c034039a87a3a25e9ab4092ff96c7a095f7b4b43e4f2a. Живая карта после загрузочного self-test содержит 19 212 управляемых страниц, 19 211 свободных и одну занятую; её runtime-счётчики отказов равны нулю. Это не скрывает и не включает в них временный отказ самопроверки.
  • py_compile для kernel_observer.py и dev_shell.py прошёл. Полная регрессия K8 не запускалась.

Этап принят в этих границах; MEM-16 в целом не закрыт.

Этап 236 — «Хаб» как отдельное окно композитора

Прямая ссылка на отчёт

Состояние: принят в целевых пределах 13 ноября 2026 года. Свежая штатная сборка рабочего стола прошла два адресных сценария QEMU. Это подтверждает появление отдельного окна «Хаба», запуск из него встроенного приложения и восстановление рабочего стола после закрытия терминала. B-04 остаётся открытым: независимое окно приложения с отдельным владельцем и полная интеграция оболочки ещё требуют общей приёмки.

Изменение

  • Рабочий стол больше не рисует панель «Хаба» в сохранённый нижний слой. Он создаёт отдельное окно через реестр CPL3-композитора, рисует элементы на принадлежащей окну поверхности и публикует кадр после завершения отрисовки.
  • Команда «Командная строка» закрывает «Хаб», открывает окно терминала, принимает ввод и при закрытии восстанавливает сохранённый рабочий стол.
  • Профиль запуска приложения из «Хаба» сохранил запуск пакета через действующий механизм READY.
  • В QEMU-приёмке уточнено ожидание фокуса: встроенный терминал и рабочий стол сейчас принадлежат одному CPL3-компоненту, поэтому клик в окно терминала не обязан менять компонент-владелец фокуса. Раздельное переключение владельцев остаётся отдельным сценарием focus-keyboard.

Сборка и проверка

Сборка из канонической папки проекта:

python tools/host/build.py --out TEMP/stage236-hub-window
  • Сборка: успешна, штатный профиль рабочий-стол, 7 компонентов.
  • Размер образа: 17 825 792 байта.
  • SHA-256 образа: d0d18435ad71f4eb6bb9e82299abc5b1df067d66fc5def837c561be9fd54ff6f.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.
  • Сквозной клик-сценарий: PASS. «Хаб» изменил 102 960 пикселей; терминал показан, ввод отображён (10 584 изменённых пикселя); владельцем фокуса оставался живой компонент рабочего стола ID 65540; после закрытия остаточных пикселей — 0; faults — 0.
  • Запуск встроенного приложения из «Хаба»: PASS. Пакет 8 запущен, READY получен рабочим столом, faults — 0.
  • Полная регрессия K8 не запускалась.

Файлы

  • src/apps/рабочий_стол.gsl — отдельная поверхность «Хаба», действия открытия/закрытия, публикация кадра и маршрутизация кликов.
  • tools/host/qemu_acceptance.py — адресная приёмка окна и корректная проверка владельца фокуса.
  • Свежие образ, экранные снимки и отчёт сборки: TEMP/stage236-hub-window/.

Границы результата

«Хаб» и встроенный терминал пока являются двумя окнами одного CPL3-компонента рабочего стола, а не двумя независимыми приложениями. Экранные подписи и визуальные ресурсы рабочего стола не пересматривались. Этап не закрывает UI-03…UI-06, B-04, безопасность SMP, файловую службу или KERNEL 1.0.

Этап 235 — соседний клиент композитора после отказа владельца

Прямая ссылка на отчёт

Состояние: принят в целевых пределах 13 ноября 2026 года. Свежий профиль композитор-сбой-соседа прошёл QEMU. Это закрывает проверку отказа владельца окна и продолжения работы независимого клиента; общий пункт B-04 остаётся открытым до завершения полной графической интеграции.

Задача

Проверить в одном сценарии, что композитор удаляет окно завершившегося с fault CPL3-клиента, продолжает обслуживать независимого соседнего клиента, а тот может создать и закрыть собственное окно.

Изменения

  • Добавлен второй независимый клиент сцены проверка_сцены_сосед.gsl. Он открывает своё окно, восемь раз проверяет его через hit-test, закрывает окно и сообщает код результата.
  • Добавлен профиль из трёх компонентов: композитор, исходный тестовый клиент сцены и соседний клиент.
  • В профиле композитор фиксирует момент очистки окна отказавшего владельца и отдельно считает ответы соседу после этой очистки. Успех требует ровно 10 ответов после события очистки.
  • Ядровая приёмка проверяет один ожидаемый CPL3 fault и флаг подтверждения соседних запросов.

Проверка сборки

Сборка из канонической папки проекта выполнена командой:

python tools/host/build.py --out TEMP/stage235-compositor-peer-fault --platform-case композитор-сбой-соседа
  • Сборка: успешна.
  • Профиль: композитор-сбой-соседа, компонентов: 3.
  • Размер образа: 17 825 792 байта.
  • SHA-256 образа: 1a5df458b061160c6804e15a3af30ce90df193c2aba2dc3fa23e1671e11bc7e9.
  • Отчёт сборки: build-report.json.

Что ещё требуется

Запустить этот свежий профиль в QEMU и подтвердить ожидаемый fault первого клиента, удаление его окна, 10 успешных ответов соседу после очистки, закрытие окна соседа и отсутствие остаточных объектов. До этой проверки профиль подтверждён только компилятором и сборщиком; исходный экран и прежние QEMU PASS доказательством не являются.

Повторная попытка 13 ноября 2026 года

  • В p_cap_destroy добавлено адресное пробуждение: оно выполняется только если активный владелец заблокирован на приёме именно отзываемого поколенческого полномочия. Это исключает побочное пробуждение службы при уничтожении другого её полномочия.
  • Свежая сборка того же профиля прошла: TEMP/stage235-compositor-peer-fault/guseva-p0.img, 17 825 792 байта; EFI SHA-256 b8ac37afdb2af15ce25b3604bd6017e53e1bde9f2fbb39e4814dc27126280ab4; образ SHA-256 320a84049667ddbacc5dce209a8534b521c93043e8ceca205e4dd2d968530119.
  • Целевой QEMU 11.1.0/q35/TCG, 128 МиБ, 1 CPU, запущен на этой сборке с тайм-аутом 90 секунд. Он вывел KERNEL-CPL3-FAULT-001 для компонента 65538, вектор 14, код ошибки 5, адрес 4096, RIP 34359738501, после чего приёмка завершилась тайм-аутом.
  • Удаление окна владельца, ответы соседа, закрытие соседнего окна и отсутствие остаточных объектов этим запуском не подтверждены. Этап 235 остаётся в работе, B-04 не закрыт.

Уточнение после целевого повтора

  • Имена новых локальных переменных в GSL приведены к русскому написанию; логика адресной проверки ожидания не менялась.
  • Временная трассировка показала многократные входы и выходы p_reap в цикле планировщика. Из-за слишком частого вывода в UART трассировочный запуск не годится для оценки времени и не заменяет целевую приёмку; отметки удалены из исходников.
  • После удаления отметок профиль заново собран из текущих исходников. Сборка прошла, SHA-256 образа остался 320a84049667ddbacc5dce209a8534b521c93043e8ceca205e4dd2d968530119.
  • Чистый QEMU-прогон этого fingerprint уже зафиксирован выше: ожидание 90 секунд, затем тайм-аут после KERNEL-CPL3-FAULT-001. Подтверждения очистки окна и прогресса соседа нет. Этап остаётся открытым.

Изменённый исходник этого продолжения: platform_core.gsl, текущий файл — 587 строк. Профиль и журнал загрузки находятся в TEMP/stage235-compositor-peer-fault/.

Приёмка 13 ноября 2026 года

Исправления сценария и валидатора

  • Клиент-сосед передавал композитору геометрию и hit-test координаты не в том поле сообщения. Поле id протокола является аргументом метода; исправлены аргументы создания окна и hit-test в проверка_сцены_сосед.gsl.
  • Композитор теперь фиксирует единственное удалённое окно после fault и ровно десять ответов клиенту-соседу; конечное условие проверяет уже зарегистрированное удаление, не ожидая повторной очистки.
  • Общая приёмка ошибочно требовала от этого сценария точный объём освобождения, параметры резервирования адресов и чтение таблиц страниц завершившегося fault-компонента. Для этого профиля оставлены проверки нижней границы возврата физических страниц и сохранённой записи fault; PTE уже отозваны, поэтому чтение их бывших физических адресов не является допустимым доказательством. Общие проверки утечек полномочий, IPC, leases, ссылок, окон и регистрации компонентов сохранены.
  • Экранный валидатор для профиля теперь проверяет штатный завершающий экран загрузки ядрового сценария, а не ожидает оставшийся на дисплее тестовый кадр CPL3-композитора.

Результат

Целевая приёмка запущена командой:

python tools/host/qemu_acceptance.py --build TEMP/stage235-compositor-peer-fault-accepted --timeout 90
  • Сборка перед запуском: успешна; профиль композитор-сбой-соседа, 3 компонента, образ 17 825 792 байта.
  • Образ SHA-256: 6f03358a00b4a15444dbd5b79346a8492d5c6c0e96a45fc568777cc8da6e3217.
  • QEMU 11.1.0, q35, TCG, 128 МиБ, 1 CPU: PASS, код завершения 0.
  • Fault-компонент 65538: вектор page fault 14; событие KERNEL-CPL3-FAULT-001 изолировано.
  • Композитор удалил окно отказавшего владельца: 1.
  • Независимый сосед получил после очистки ровно 10 ответов, закрыл своё окно с результатом 5; проверочный маркер 1.
  • После завершения обоих клиентов в реестре 0 поверхностей; живых полномочий, IPC-запросов, device leases и object references — 0.
  • Суммарный счётчик возврата физических страниц профиля — 1256. Он включает профильные поверхности и потому проверяется как нижняя граница, а не как фиксированный множитель страниц на компонент.
  • Журнал загрузки и машинный отчёт: boot.log, platform-report.json, build-report.json.

Граница

Принят только целевой однопроцессорный сценарий: изоляция CPL3 fault владельца окна, очистка его слоя и продолжение IPC/жизненного цикла окна независимого клиента. Полный B-04 не закрыт. Эта проверка не доказывает SMP-безопасность параллельного отзыва отображений и не заменяет контрольную регрессию K8.

Этап 234 — фокус окна в штатном рабочем столе

Прямая ссылка на отчёт

Целевая приёмка QEMU — PASS.

В штатном профиле рабочий-стол щелчок по окну терминала теперь назначает системный фокус его действующему поколенческому владельцу. Рабочий стол получает владельца из реестра окон композитора и вызывает системный механизм фокуса. Полномочие manage_input_focus выдано рабочему столу через политику компонента и доверенный каталог стартовых пакетов; другие компоненты этого полномочия не получают.

Результат QEMU

  • Профиль рабочий-стол, семь пакетов; порядок запуска 1, 3, 4, 2, 5, 6, 7.
  • «Хаб» открылся после щелчка: изменилось 49 815 пикселей.
  • Терминал стал видимым; сценарий ввёл контрольный текст.
  • Клик по окну назначил фокус компоненту 65540, слот 3. Счётчик изменений фокуса вырос 0 → 1; счётчик назначений рабочего стола вырос 0 → 1; владелец совпал с записью окна в композиторе.
  • Закрытие терминала восстановило рабочий стол; остаточных пикселей 0.
  • Изолированных faults: 0.

Сборка: python tools/host/build.py --out TEMP/stage234-desktop-focus-fixed --platform-case рабочий-стол.

Приёмка: python tools/host/qemu_acceptance.py --build TEMP/stage234-desktop-focus-fixed --timeout 45 --тест-кликов-рабочего-стола.

  • EFI SHA-256: d6db213697466823c881562b624f2ce8329dd7b631265f8cffbc315ddb6bf187.
  • Образ SHA-256: a76906295b64689b55c57ab0097814067a11d54da869506a67a98886c594c293.
  • Отчёт сборки · Отчёт QEMU · Экран после проверки.

Исправление проверки

Первый прогон дошёл до проверки закрытия и показал, что тестовый сценарий использовал устаревшие исходные координаты мыши после контрольного перемещения для проверки фокуса. Исправлена только начальная точка следующего перемещения в qemu_acceptance.py; повторная сборка и повторный QEMU-сценарий прошли.

Граница этапа

Подтверждены интеграция назначения фокуса в штатный рабочий стол и восстановление стола после штатного закрытия терминала. Этот этап не проверяет отказ одного окна при продолжающейся работе соседнего приложения; не является полной приёмкой B-04 или KERNEL 1.0.

Этап 233 — фокус по реестру окон

Прямая ссылка на отчёт

Целевая приёмка QEMU — PASS.

  • В профиле focus-keyboard два независимых CPL3-приложения создают собственные окна в одном композиторе. У окон разные владельцы. Менеджер окон получает владельца из реестра по координатам мыши и передаёт полный ID механизму фокуса ядра. Маршрутизатор доставляет клавиши по полномочию выбранного компонента.
  • Два щелчка выбрали владельцев 65539 и 65540. Первый получил два события мыши. Второй получил два события мыши и нажатие и отпускание клавиши A. Изолированных сбоев — 0. После выхода обоих владельцев фокус очистился, композитор снял два окна и восстановил область 256×128.
  • Сборка «python tools/host/build.py --out TEMP/stage233-focus --platform-case focus-keyboard». Приёмка «python tools/host/qemu_acceptance.py --build TEMP/stage233-focus --timeout 18».
  • SHA-256 EFI 6c5b4f42c66be3c403dd6c0f2dfa07cbeef2f68be6a88f72e860cf9287ad746b.
  • Приёмка · Срез гостя · Финальный кадр.

B-04 остаётся в работе. Это отдельный профиль с двумя заранее подключёнными приложениями. В штатном рабочем столе ещё требуется подключить маршрутизацию независимых окон и проверить переключение, перекрытие и продолжение работы соседа после сбоя в одном сквозном сценарии.

Этап 232 — выбор владельца по координатам окна

Прямая ссылка на отчёт

  • Метод 7 композитора возвращает дескриптор окна, поднимает его или возвращает полный ID владельца по координатам верхнего окна. Доступ ограничен доверенными отправителями текущего профиля. Вне окон возвращается IPC_EMPTY.
  • Рабочий стол проверяет по реестру, принадлежит ли точка нажатия видимому терминалу, перед закрытием окна.
  • QEMU, профиль «композитор», подтвердил пустую точку, затем окно 6 и его владельца 65538 на тех же координатах. Проверка изолированного сбоя и восстановления сцены тоже прошла.
  • QEMU, профиль «рабочий-стол», подтвердил открытие через «Хаб», закрытие по щелчку и 0 отличающихся пикселей после закрытия.
  • Команды сборки «python tools/host/build.py --out TEMP/stage232-compositor --platform-case композитор» и «python tools/host/build.py --out TEMP/stage232-desktop --platform-case рабочий-стол».
  • Команды проверки «python tools/host/qemu_acceptance.py --build TEMP/stage232-compositor --timeout 35» и «python tools/host/qemu_acceptance.py --build TEMP/stage232-desktop --timeout 35 --тест-кликов-рабочего-стола».
  • SHA-256 EFI композитора 3eac39bd380215490379d3b954d0729f6172248a20c3ccdc0d075ed402aa43c7.
  • Композитор · Рабочий стол.

B-04 остаётся в работе. Метод выбора владельца готов для маршрутизатора. Доставка клавиатуры двум независимым приложениям через этот реестр ещё требует подключения и сквозной проверки.

Этап 231 — восстановление сцены после сбоя владельца окна

Прямая ссылка на отчёт

  • Сценарий «композитор» создаёт шестое окно и проверяет его публикацию по контрольному пикселю. Затем тестовый владелец вызывает исключение CPL3. Окно остаётся открытым на момент исключения.
  • QEMU подтвердил один изолированный сбой компонента 65538, вектор 14. Композитор 65537 дошёл до завершения своего сценария, самостоятельно убрал один слой и вернул его память. Финальный кадр восстановился, живых поверхностей и остаточных объектов IPC нет. Счётчик платформы — 1 245 возвращённых страниц.
  • Сборка «python tools/host/build.py --out TEMP/stage231-compositor --platform-case композитор». Приёмка «python tools/host/qemu_acceptance.py --build TEMP/stage231-compositor --timeout 25».
  • SHA-256 EFI 39a255919fd3a39d41cbd5044410362c01906beb7b1aeea67f65eb679665a3e7.
  • Журнал гостя · Приёмка · Память гостя · Финальный кадр.

B-04 остаётся в работе. Проверены композитор и один владелец окон в целевом профиле. Для интерактивного сценария ещё требуется два независимых владельца, переключение фокуса по реестру, доставка клавиатуры и продолжение работы второго приложения.

Этап 230 — удаление окна при завершении владельца

Прямая ссылка на отчёт

  • Syscall 56 доступен компоненту с полномочием вывода. Он возвращает только признак активности указанного поколенческого ID. Вызов без полномочия отклоняется.
  • Композитор проверяет владельцев окон перед приёмом команд. В простое ожидание IPC ограничено десятью гостевыми тиками. После завершения владельца композитор снимает слой, восстанавливает видимую сцену и возвращает страницы и резерв.
  • Целевой профиль «композитор» прошёл в QEMU. CPL3-производитель оставил шестое окно открытым и завершился штатно. Композитор самостоятельно снял один слой. Финальный кадр подтвердил восстановление фона. Проверены отказ наблюдения без полномочия, отсутствие остаточных поверхностей и IPC-объектов. Счётчик платформы — 1 245 возвращённых страниц.
  • Профиль «рабочий-стол» также прошёл. После открытия через «Хаб» и закрытия терминала — 0 отличающихся пикселей, 0 изолированных сбоев.
  • Сборки «python tools/host/build.py --out TEMP/stage230-compositor --platform-case композитор» и «python tools/host/build.py --out TEMP/stage230-desktop --platform-case рабочий-стол».
  • Приёмка «python tools/host/qemu_acceptance.py --build TEMP/stage230-compositor --timeout 25» и «python tools/host/qemu_acceptance.py --build TEMP/stage230-desktop --timeout 35 --тест-кликов-рабочего-стола».
  • SHA-256 EFI профиля композитора f7f81f705967300bb1e69836d97335109be0f0c5e576591f7e2e05995aa3cc27.
  • Приёмка композитора · Память гостя · Кадр после очистки · Приёмка рабочего стола.

B-04 остаётся в работе. Штатный выход проверен в целевом профиле. Остаётся проверить аварийное завершение владельца и маршрутизацию фокуса и клавиатуры между независимыми окнами.

Этап 229 — рабочий стол и поверхность терминала

Прямая ссылка на отчёт

Приёмка графики — целевой сценарий штатного профиля «рабочий-стол» прошёл в QEMU.

  • Рабочий стол включает сохранённую сцену 1280×800, рисует фон через композитор и публикует собранный кадр. Терминал рисует прямоугольники и сглаженные глифы в отдельной поверхности. При закрытии композитор восстанавливает фон и возвращает память окна.
  • Для интерактивного композитора бюджет выбран в 1 664 страницы. Ядро начинает автоматический поиск динамических адресов после загрузочного стека. Это устраняет возможность захватить при выделении поверхности стартовую страницу стека, отсутствующую в учёте динамических отображений.
  • Входящие события, полученные во время синхронного запроса графики, подтверждаются и сохраняются в порядке получения в очереди рабочего стола. Очередь вмещает 32 записи и сообщает переполнение.
  • QEMU передал щелчки через PS/2. «Хаб» изменил 49 815 пикселей проверяемой области. Терминал открылся поверх стола и закрылся по щелчку. После закрытия из 1 024 000 пикселей кадра отличалось 0. Изолированных сбоев — 0.
  • Команды «python tools/host/build.py --out TEMP/stage229-desktop --platform-case рабочий-стол» и «python tools/host/qemu_acceptance.py --build TEMP/stage229-desktop --timeout 35 --тест-кликов-рабочего-стола». SHA-256 EFI d3c5ca31869eace71b1fb79ff0965171a4541d29442d8f9bbec2e65ca193b8b5.
  • Профиль «память» на свежей сборке также прошёл в QEMU. Подтверждены динамический диапазон, верхняя страница 1 ГиБ и возврат резерва. Нативный тест PlatformTests.test_common_objects_and_devices завершился исключением Windows 0xC0000096. Результат нативного теста остаётся открытым.
  • Сборка · QEMU рабочего стола · QEMU памяти · Нативный тест.
  • До открытия · С открытым терминалом · После закрытия.

Открыто в B-04. Терминал пока принадлежит компоненту рабочего стола. Остались фокус между окнами независимых приложений, проверка клавиатуры и уборка слоёв при отказе владельца. В этом прогоне проверялись мышь QEMU и гостевой кадр. Действия из окна Windows Dev Shell и весь набор K8 отдельно.

Этап 228 — полноэкранный сохранённый фон

Прямая ссылка на отчёт

Приёмка — целевой профиль «композитор» прошёл в QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

  • Методы 2 и 3 записывают прямоугольники и сглаженные глифы в сохранённый фон. Метод 10 публикует накопленные правки. До инициализации сцены методы 2 и 3 сохраняют прежнее поведение.
  • Композитор копирует фон парами пикселей и определяет верхнее окно только в диапазоне окон на строке. При пустом реестре полосы выводятся непосредственно из фоновой поверхности. Решение учитывает активную запись уже при первом появлении окна.
  • Проверены фон 1280×800, два перекрывающихся окна у нижней границы, появление первого окна, изменение и восстановление его штриха, поднятие и закрытие. Финальный кадр совпал с ожидаемыми фоном и прямоугольником за пределами области глифа. В области глифа обнаружено 668 изменённых пикселей. Промежуточные цвета контрольной точки подтверждены в памяти композитора.
  • Счётчик платформы показал 1 239 возвращённых страниц. Остаточные запросы, полномочия, аренды устройств, ссылки и изолированные сбои — 0.
  • Сборка «python tools/host/build.py --out TEMP/stage228-compositor --platform-case композитор». Проверка «python tools/host/qemu_acceptance.py --build TEMP/stage228-compositor --timeout 25».
  • SHA-256 EFI a96314e0f9eba457677ac64cfb2a8cc6eab5b5c175cb310cc4465408664e020c.
  • Сборка · Запуск · Данные гостя · Кадр.

Открыто в B-04. Тестовый компонент формирует сцену через IPC. Интерактивный рабочий стол пока не включает режим сохранённой сцены. Для его подключения нужно настроить квоту композитора в профиле загрузки и сгруппировать отрисовку в публикации. Ввод, фокус, окна разных владельцев и уборка при отказе владельца требуют сквозной проверки. Задержка интерактивного обновления отдельно не измерялась.

Этап 227 — многостраничные поверхности композитора

Прямая ссылка на отчёт

Приёмка — профиль «композитор» прошёл в QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

  • Композитор резервирует смежный виртуальный диапазон и отображает страницы по мере выделения. При частичном отказе он возвращает уже выделенные страницы и снимает резерв. Закрытие окна возвращает все страницы его поверхности. Если возврат оборвался, слот исключается из композиции и остаётся занятым до завершения композитора.
  • Полноразмерная геометрия допускается протоколом в пределах экрана 1280×800 и квоты компонента. Выходной буфер используется повторно для полос высотой до 64 строк. Результат вычисляется синхронно по полосам.
  • Проверены сцена 64×84, два перекрывающихся окна, штрих за первой страницей нижнего окна, его повторное появление при подъёме и восстановление всех 5 376 пикселей фона в итоговом кадре. При закрытии двух окон возвращены пять пиксельных страниц через syscall 36. Счётчик платформы показал 39 возвращённых страниц, включая снятие резервов и финальную очистку. Остаточных оконных поверхностей, IPC-запросов, полномочий, аренд устройств, ссылок и изолированных сбоев — 0.
  • Сборка «python tools/host/build.py --out TEMP/stage227-compositor --platform-case композитор». Приёмка «python tools/host/qemu_acceptance.py --build TEMP/stage227-compositor --timeout 90».
  • SHA-256 EFI a8189c2d374dd6589827856369055c1c58fb81041a74da6548c54a53c7bd17d4.
  • Сборка · Запуск · Срез гостя · Кадр.

Открыто в B-04. Подключение реального рабочего стола, проверка квоты и производительности на полном экране, маршрутизация фокуса и очистка окна при отказе владельца. Отказы выделения и вывода полос в данном профиле не моделировались. При сбое вывода в середине кадра уже опубликованные полосы могут остаться на экране до повторной перерисовки.

Этап 226 — сохранённые пиксели и композиция двух окон

Прямая ссылка на отчёт

Состояние — целевой профиль QEMU прошёл 13 ноября 2026 года.

Композитор CPL3 хранит пиксели окон, фон и выходной кадр в своих страницах. Он выбирает верхнее окно для каждого пикселя и публикует кадр через syscall 49. Закрытие исключает окно из сцены и освобождает его страницу. Для этого этапа выбрана непрозрачная плитка 32×24.

Приёмка

  • Свежая сборка из канонической папки. Команда «python tools/host/build.py --out TEMP/stage226-compositor --platform-case композитор».
  • Целевой запуск «python tools/host/qemu_acceptance.py --build TEMP/stage226-compositor --timeout 90». QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU, PASS.
  • Пиксель в перекрытии после создания нижнего окна, штриха, создания верхнего, поднятия нижнего и последовательного закрытия окон имел цвета 1056816 → 5267568 → 8425632 → 5267568 → 8425632 → 2636880. Финальный кадр содержит цвет фона во всех 768 пикселях плитки.
  • В реестре нет страниц закрытых окон. Syscall 36 вернул две страницы до завершения композитора, счётчик финальной очистки — 27. Изолированных сбоев и оставшихся IPC-запросов, полномочий, аренд устройств и ссылок — 0.
  • Первый запуск выявил старое ожидание валидатора, которое приравнивало накопленный возврат на компонент к итоговому счётчику платформы. После учёта двух штатных освобождений через syscall 36 свежий образ и тот же сценарий прошли.
  • SHA-256 EFI 0547add531c5cbeafff3d39d4a1a91d3e351581d7ebe2507c6ccd807e6649d6c.
  • Сборка · QEMU · Данные гостя · Финальный кадр.

Границы проверки

Профиль включает одного производителя сцены и композитор. Поверхности помещаются в одну страницу, площадь сцены ограничена 1 024 пикселями. Для B-04 остаются полноразмерная сцена, интеграция с реальными окнами и вводом, фокус и очистка при отказе владельца. Для промежуточных состояний проверялся пиксель выходной плитки из памяти композитора, для финального — область кадра из QEMU.

Этап 225 — hit-test и поднятие окна в реестре композитора

Прямая ссылка на отчёт

Состояние: целевой QEMU-сценарий принят 13 ноября 2026 года. Реализована следующая часть B-04: CPL3-композитор находит верхнее окно по координатам и по запросу меняет Z-порядок.

Изменения

  • Реестр хранит отдельный монотонный порядок окон; номер окна остаётся самостоятельным дескриптором.
  • Метод 7 принимает координаты X/Y в message; color=0 выполняет hit-test, color=1 поднимает найденное окно и возвращает его дескриптор.
  • Прямоугольники трактуются как полуоткрытые: левая/верхняя граница включена, правая/нижняя исключена.
  • Для точки вне всех активных окон возвращается IPC_EMPTY; неизвестное значение команды отклоняется.
  • Счётчик Z-порядка не переполняется: после исчерпания диапазона запрос подъёма получает IPC_LIMIT.

Приёмка

  • Сборка из канонической папки: python tools/host/build.py --out TEMP/stage225-hit-test --platform-case композитор — успешна.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: python tools/host/qemu_acceptance.py --build TEMP/stage225-hit-test --timeout 90 — PASS.
  • Два пересекающихся окна: до поднятия hit-test вернул дескриптор 2; запрос поднять окно 1 вернул 1; hit-test той же области после поднятия вернул 1.
  • Hit-test вне окон вернул IPC_EMPTY. Сценарий также проверил закрытие, повторное использование слота с дескриптором 3, отказ по старому дескриптору (IPC_STALE), продолжение производителя после ошибочной команды, 0 faults и 0 оставшихся IPC-запросов/полномочий/leases/references.
  • SHA-256 EFI-образа: 2927207fdacb0447d22ad4b248df310b2cf9a5c2ab5a461d091b51832215cb1e.
  • Отчёты: build-report.json, boot-report.json, platform-report.json.

Граница результата

Проверена логика реестра и выбор окна в IPC-сценарии. Этап не реализует сохранённые пиксельные поверхности, композицию кадров, перерисовку после закрытия, перемещение окон пользователем или маршрутизацию мыши рабочего стола. Метод 7 пока доступен отправителям текущего ограниченного профиля композитора; отдельная политика полномочий оконного менеджера остаётся частью интеграции B-04. Полный набор тестов не запускался.

Этап 224 — запуск доверенного приложения из «Хаба»

Прямая ссылка на отчёт

Состояние: принят 13 ноября 2026 года в границах сквозного запуска одного приложения из CPL3. Проверен путь: рабочий стол → IPC-диспетчер → доверенная запись каталога → создание отдельного CPL3-компонента → READY → ответ рабочему столу.

Что реализовано

  • Диспетчер src/services/диспетчер_запуска_приложений.gsl подключён к профилю рабочего стола и получает полномочие от загрузчика. Запрос содержит логический номер приложения; адрес образа и права берутся из доверенных данных каталога.
  • Пакет 8 собирается как отдельное приложение src/apps/демо_приложение.gsl. Он подтверждает READY с кодом 15 и остаётся отдельным CPL3-компонентом.
  • Диспетчер запускает пакет системным вызовом 30, сверяет ID, код и отправителя READY, подтверждает дочернее сообщение, затем отвечает рабочему столу.
  • Перед финальным ответом диспетчер восстанавливает в IPC-буфере ID и срок исходного запроса: до этого буфер содержал подтверждение READY дочерней службы, поэтому ядро отклоняло ответ как не совпадающий с запросом.
  • Запрос рабочего стола использует срок +100 тиков, соответствующий действующему ограничению IPC. Подтверждение посторонних сообщений сохраняет их исходный срок.
  • После позднего или неуспешного подтверждения собственного READY диспетчер остаётся в цикле обслуживания; решение о готовности загрузки принимает загрузочный граф.

Приёмка

  • Сборка профиля рабочий-стол прошла в канонической папке проекта: TEMP/stage224-accepted/build-report.json.
  • QEMU/Q35/TCG, 128 МиБ, 1 CPU: PASS. Рабочий стол получил успешный ответ после READY приложения; тест зафиксировал 912 изменённых пикселей уведомления. Запускался пакет 8 с READY-кодом 15, в графе было 7 стартовых служб, изолированных faults — 0.
  • Отчёт целевого сценария: TEMP/stage224-accepted/qemu-acceptance.json. Скриншот кадра после запуска: TEMP/stage224-accepted/app-launch-started.png.
  • SHA-256 образа: be17b36e43e64aa5eb578f031546666afd2de76806cc349bab019673887a9846.

Граница принятого результата

Подтверждён запуск одного доверенного приложения из «Хаба» как отдельного CPL3-компонента и обмен READY/ответом. Приложение пока не создаёт собственного окна; Z-порядок, отдельные поверхности и оконная композиция остаются вне этого этапа. Проверка считает появление уведомления по изменению пикселей и не подтверждает читаемость его кириллического текста. Не проверялись произвольные пакеты, установка программ, перенос состояния, полноценный каталог приложений или аппаратная конфигурация за пределами QEMU-профиля.

Этап 223 — передача IPC-полномочий дочернему компоненту (принят в указанной границе)

Прямая ссылка на отчёт

Цель

Подготовить ограниченный ядерный механизм, позволяющий уполномоченному диспетчеру передавать IPC-доступ новому CPL3-компоненту. Это один из недостающих механизмов для запуска приложений из «Хаба»: приложение должно получить собственный канал к композитору, а не рисовать от имени рабочего стола.

Изменения

  • Расширен syscall 40: прежний вызов с третьим аргументом 0 сохраняет поведение и возвращает созданное полномочие.
  • Добавлены целевые слоты +264, +280, +288; слот +288 получает полномочие с правами отправки и дальнейшей передачи.
  • Режим 284 трактует первый аргумент как дескриптор полномочия вызывающего и передаёт только его цель; для него требуется право передачи 4. В +280 получателя записывается новый IPC-дескриптор с правом отправки 1.
  • Проверка вызывающего через p_authorized(...,3), проверка поколения цели и выдача дескриптора остаются в ядре.

Фактическая проверка

  • Свежая сборка профиля рабочий-стол в основной папке проекта прошла: TEMP/ui05-app-launch-kernel-build.
  • SHA-256 свежего guseva-p0.img: 7ffaba05dff2f9284438fedf0e258a286ff5b4bc255760f07d55de9815c728b9.
  • QEMU-проверка рабочего стола с нажатием «Хаб» и открытием/закрытием терминала прошла. Старый вызов syscall 40 со слотом 0 не сломал этот сценарий.
  • Профильный нативный тест платформы не завершился: после исправления списка GSL-prelude он падает с ошибкой доступа в базовом цикле с одним компонентом, до нового сценария syscall 40. Это не PASS и не доказательство отказа нового кода; нативная адресная проверка остаётся незавершённой.
  • QEMU и нативная проверка не вызывают новые режимы 264/280/284/288. Их выдача, отказ при недостаточных правах, очистка и передача в отдельное приложение пока не приняты.

Граница этапа

Этап открыт. Новые режимы не подключены к загрузочному графу и «Хабу». Следующая работа — адресный CPL3/QEMU-сценарий: корректная цель и получатель, отказ по недостаточным правам/неверному поколению, отсутствие утечки cap при неудаче, затем подключение каталожного приложения через диспетчер запуска.

Этап не закрывает UI-05, SAFE-05 или KERNEL 1.0.

Дополнение — адресная проверка syscall 40 (13 ноября 2026 года)

  • В tests/kernel/test_platform.py добавлен отдельный сценарий, не зависящий от падающего широкого профиля. Он вызывает GSL-диспетчер p_syscall с номером 40, а не только внутреннюю функцию выдачи.
  • Подтверждены: прежний слот 0; выдача права отправки в слотах 264 и 280; выдача отправки и передачи в 288; передача только цели полномочия через 284; отказ компонента без manage_resources и start_service; отказ передачи без права 4; отказ устаревшего поколения; отказ на неизвестном слоте; отсутствие нового cap и записи в буфер при отказе; удаление пяти выданных cap без остатка в учёте.
  • Результат адресного сценария: PASS. Запись запуска: native-service-connect.txt.
  • Свежая сборка из этой же папки проекта: build-report.json, SHA-256 образа 7ffaba05dff2f9284438fedf0e258a286ff5b4bc255760f07d55de9815c728b9.
  • QEMU-запуск этого образа: interactive-report.json — PASS; мышь готова, окно «Хаба» открывается, терминал открывается и закрывается, остаточных пикселей 0, изолированных faults 0.
  • Граница: QEMU-сценарий рабочего стола не вызывает режимы 264/280/284/288; нативная DLL проверяет сам GSL-диспетчер, но не переход из CPL3 через аппаратный syscall entry. Поэтому сквозная гостевая проверка новых режимов остаётся незавершённой.

Этап 223 оставался в работе до сквозной проверки из CPL3. Итоговая приёмка приведена ниже; предыдущие записи сохраняют точное состояние на момент их создания.

Итоговая сквозная приёмка (13 ноября 2026 года)

  • В профиль передача-полномочия добавлен сценарий из трёх независимых CPL3-компонентов: управляющий компонент, получатель и служба. Проверка проходит через машинный syscall entry и диспетчер ядра, а не прямым вызовом внутренней функции.
  • Управляющий компонент получил отказ для неизвестного слота (IPC_BAD_MESSAGE) и при попытке передачи без права GRANT (IPC_DENIED). Разрешённая передача создала полномочие отправки к службе в пространстве получателя; повторный доступ после удаления дескриптора отклонён как IPC_STALE.
  • Получатель отправил запрос с ID 91001, методом 77 и значением 12345. Служба приняла все поля, ответила значением 67890, получатель подтвердил отправителя и ответ, затем освободил полномочие.
  • Валидатор сверил результаты всех компонентов по снимкам памяти гостя. Все три компонента завершились с прогрессом 5/5; faults — 0; после завершения live capabilities, IPC requests, device leases и object references — 0; возвращено 30 страниц.
  • Сборка из канонической папки: TEMP/stage223-capability-transfer/build-report.json. QEMU/Q35/TCG, 128 МиБ, 1 CPU: PASS, TEMP/stage223-capability-transfer/boot-report.json; профильный результат — platform-report.json.
  • SHA-256 проверенного образа: 9ff9865bdf4ea6195d590098382d94bf8cfc1ac9a527534da30e150ab33fb204.
  • Сценарий использует лимит срока IPC, установленный существующим ABI, и не изменяет сам контракт тайм-аутов.

Этап 223 принят в границах передачи полномочия syscall 40 из CPL3, проверки отказов, реального IPC-запроса/ответа и очистки ресурсов. Он не принимает запуск приложения из «Хаба», оконную композицию, SAFE-05 или KERNEL 1.0.

Этап 206 — SAFE-05: классификация адресов syscall 36

Прямая ссылка на отчёт

Статус: целевая приёмка workers, CPL3/QEMU пройдена. SAFE-05 остаётся в работе.

Цель

Проверить, что syscall 36 различает некорректный невыровненный адрес и выровненный адрес за пределом динамического окна компонента, не повреждая действующее отображение.

Реализация и результат

Первый запуск нового сценария выявил ошибку классификации: ядро возвращало IPC_DENIED для невыровненного адреса, поскольку заранее выставляло отказ по области до проверки выравнивания. В p_memory_release порядок уточнён: невыровненный адрес возвращает IPC_BAD_POINTER; выровненный адрес вне динамического окна — IPC_DENIED.

В повторном CPL3-сценарии каждый из трёх компонентов проверил адрес memory_page + 1 и адрес, равный верхней границе окна 35433480192. Получены соответственно IPC_BAD_POINTER и IPC_DENIED. Canary ранее выделенной динамической страницы сохранился; штатное выделение и освобождение продолжились. Сохранены проверки этапа 205 для кода и статических данных.

Приёмка

  • python -m py_compile tools/host/platform_check.py — PASS.
  • Свежая сборка python tools/host/build.py --out TEMP/safe05-release-address-check --platform-case workers — PASS.
  • python tools/host/test_boot.py --build TEMP/safe05-release-address-check --qemu <QEMU 11.1.0> — PASS.
  • QEMU: q35/TCG, 128 МиБ, 1 CPU; 3 компонента; 48 возвращённых страниц; 0 faults; 0 остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • SHA-256 образа: ce72081f746df3a8937d63bf6cfa335a8d14245f1641377c4f40cd59522343cb.
  • platform-report.json проверяет оба кода ответа и сохранность canary по каждому компоненту.

Артефакты

Полный каталог сборки и QEMU: TEMP/safe05-release-address-check/.

Границы

Проверены syscall 36 и перечисленные адресные случаи в профиле workers, на одном CPU. Остальной SAFE-05, гонки PTE, pinning, SMP и K8 этой приёмкой не закрыты.

Этап 205 — SAFE-05: syscall 36 не освобождает код и статические данные

Прямая ссылка на отчёт

Статус: целевая приёмка workers, CPL3/QEMU пройдена. SAFE-05 остаётся в работе.

Цель

Проверить с CPL3, что syscall 36 освобождает только страницы динамического окна компонента и не позволяет снять отображение его кода или статических данных.

Реализация и результат

Каждый из трёх компонентов в профиле workers попытался освободить выровненные страницы кода и статических данных через syscall 36. Оба вызова вернули IPC_DENIED. После отказа компонент прочитал контрольное значение из своей статической области; оно сохранилось. Затем штатные операции выделения, записи, чтения и освобождения динамической страницы продолжили работу.

Host-приёмщик проверил ответы и canary по снимкам CPL3 и записал их по каждому поколенческому ID компонента.

Приёмка

  • python -m py_compile tools/host/platform_check.py — PASS.
  • Свежая сборка python tools/host/build.py --out TEMP/safe05-release-protection --platform-case workers — PASS.
  • python tools/host/test_boot.py --build TEMP/safe05-release-protection --qemu <QEMU 11.1.0> — PASS.
  • QEMU: q35/TCG, 128 МиБ, 1 CPU; 3 компонента; 48 возвращённых страниц; 0 faults; 0 остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • SHA-256 образа: 1daa398958fe604044615518eb609aa872d597bb5b9007af4132b8a3ae25e5a7.
  • Host-отчёт platform-report.json содержит safe05_release_protection: оба адреса отклонены, canary сохранён для всех трёх компонентов.

Артефакты

Полный каталог свежей сборки и QEMU находится в TEMP/safe05-release-protection/.

Границы

Проверены только syscall 36 и разрешённые/запрещённые области в профиле workers, на одном CPU. Эта проба не закрывает аудит остальных публичных syscall, конкурентные изменения PTE, pinning, SMP или SAFE-05/K8 целиком.

Этап 204 — SAFE-05: атомарность syscall 72 на неполном диапазоне

Прямая ссылка на отчёт

Статус: целевая приёмка ipc-wait-any, CPL3/QEMU пройдена. SAFE-05 остаётся в работе.

Цель

Проверить, что syscall 72 не меняет права первой страницы, если запрошено изменение диапазона из 512 страниц, но отображена только первая.

Результат

Гостевой компонент вызвал system_call(72, адрес, 512, 0) и получил IPC_BAD_POINTER. Сразу после отказа он записал контрольное значение в первую страницу и прочитал его обратно. Запись и сравнение прошли, то есть доступность записи первой PTE сохранилась; частичное применение RO-защиты не произошло. Затем тот же профиль выполнил штатный путь syscall 72: страница переведена в RO/NX, прочитана syscall 54 и освобождена.

Host-приёмщик проверил код отказа и контрольное значение. QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU — PASS. В сценарии было 3 компонента, 49 возвращённых страниц, 0 изолированных faults и 0 остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.

SHA-256 образа: 013951e6616316bd26da3e549dcda38f65e77ba3ad1a91791c5983dc355d2978.

Артефакты

Полный каталог сборки и QEMU: TEMP/safe05-syscall72-atomic/. Включает отчёты, журнал загрузки, снимок экрана, карту памяти и PTE, диагностические снимки и образ.

Границы

Приёмка относится к syscall 72 в профиле ipc-wait-any на одном CPU. Она не доказывает безопасность при конкурентном изменении PTE, SMP или DMA; pinning и полный SAFE-05/K8 не проверялись.

Этап 203 — SAFE-05: верхние границы и переполнение syscall 72

Прямая ссылка на отчёт

Результаты относятся к сборке, указанной в отчёте. Материалы испытаний перенесены из рабочей копии.

Статус: целевая приёмка ipc-wait-any, CPL3/QEMU пройдена. SAFE-05 остаётся в работе.

Цель

Расширить проверку syscall 72 на арифметические и граничные входы: максимальный размер диапазона, выравнивание и переполнение при вычислении конца адресного интервала.

Проверки CPL3

В гостевом компоненте проверены следующие отказы:

  • число страниц 0 и 513, режим 2, невыровненный адрес → IPC_BAD_MESSAGE;
  • адрес с переполнением при прибавлении длины диапазона и адрес RX-кода вне разрешённого окна → IPC_BAD_POINTER;
  • canary в допустимой динамической RW/NX-странице не изменился после всех отказов;
  • затем успешно выполнены перевод страницы в RO/NX, чтение списка ожидания syscall 54 (индекс готового таймера 1), возврат записи и освобождение страницы/резерва.

Свежие сборка и QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. 3 компонента, 49 возвращённых страниц, 0 faults и остаточных IPC-запросов, полномочий, device leases и ссылок на объекты. SHA-256 образа: 27876be831b13a0fe0c4015d035891402292a874e5eb64e151e80e6fc68e807c.

Артефакты: build-report.json, boot-report.json, platform-report.json, screen.png, boot.log.

Границы

Это расширение приёмки syscall 72 в одном профиле на одном CPU, не полная проверка SAFE-05. PTE-гонки, pinning, SMP и контрольная регрессия K8 не проверялись.

Этап 202 — SAFE-05: границы и неверные аргументы syscall 72

Прямая ссылка на отчёт

Результаты относятся к сборке, указанной в отчёте. Материалы испытаний перенесены из рабочей копии.

Статус: целевая приёмка профиля ipc-wait-any, CPL3/QEMU пройдена. SAFE-05 остаётся в работе.

Цель

Проверить, что управление правом записи ограничено собственными динамическими страницами компонента, неверные параметры отклоняются до изменения отображений, а отказ не меняет доступное состояние.

Изменение механизма

В диспетчер_динамические_страницы_защищать разделены проверки формы аргументов и адресного диапазона. Невыровненный адрес, нулевое/слишком большое число страниц и неизвестный режим дают IPC_BAD_MESSAGE; адрес вне динамического пользовательского окна и неподходящее отображение дают IPC_BAD_POINTER; устаревшая идентичность остаётся IPC_STALE. Полный диапазон по-прежнему проверяется до изменения PTE.

Первая целевая QEMU-попытка выявила несоответствие: адрес RX-кода получал IPC_BAD_MESSAGE, потому что проверка диапазона была ошибочно включена в проверку формы параметров. Проверки разделены; образ пересобран, и тот же профиль повторён.

Гостевая приёмка

В профиле ipc-wait-any CPL3-компонент проверил:

  • syscall 72 с числом страниц 0 → IPC_BAD_MESSAGE;
  • syscall 72 с неизвестным режимом 2 → IPC_BAD_MESSAGE;
  • попытка защитить RX-страницу кода → IPC_BAD_POINTER;
  • контрольное значение в собственной RW/NX-странице осталось доступным и неизменным после отказов;
  • затем страница успешно переведена в RO/NX, syscall 54 прочитал список ожидания и вернул индекс готового таймера 1; право записи восстановлено, страница и резерв освобождены.

Свежая сборка и QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. 3 компонента, 49 возвращённых страниц, 0 faults; после завершения нет запросов IPC, полномочий, device leases и ссылок на объекты. SHA-256 образа: cc80ded02df63603a401ed2d50bc57fb2eb4b34b6180ad86f433f92957a14748.

Артефакты: build-report.json, boot-report.json, platform-report.json, screen.png, boot.log.

Границы

Проверены только три отказных входа syscall 72 и сохранность одной динамической страницы в одном профиле на одном CPU. Полный SAFE-05, PTE-гонки, pinning, SMP и контрольная регрессия K8 не проверялись.

Этап 201 — SAFE-05: syscall 54 читает список ожидания из User/RO/NX

Прямая ссылка на отчёт

Результаты относятся к сборке, указанной в отчёте. Материалы испытаний перенесены из рабочей копии.

Статус: целевая приёмка CPL3/QEMU профиля ipc-wait-any пройдена. SAFE-05 остаётся в работе.

Цель

Проверить положительный сценарий syscall 54 с массивом источников, который находится в отдельной динамической пользовательской странице без права записи. Вызов должен прочитать запись источника, дождаться готового таймера и не оставлять выделенную тестовую страницу после завершения.

Реализация

  • В роли 24 профиля ipc-wait-any выделяется одна динамическая страница; в ней размещается пара тип источника = 2, ID таймера.
  • Syscall 72 переводит страницу в User/RO/NX; после этого syscall 54 получает её адрес и должен вернуть индекс готового таймера 1.
  • Права записи восстанавливаются, затем тестовая страница и виртуальный резерв освобождаются. Результаты защиты, ожидания и очистки записываются в диагностический снимок компонента.
  • Существующие отказные сценарии syscall 54 на незамапленном адресе и при пересечении mapped/unmapped PTE сохранены.

Приёмка

  • Свежая сборка: python tools/host/build.py --out TEMP/safe05-syscall54-readonly --platform-case ipc-wait-any — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Syscall 72 вернул 0; syscall 54 на User/RO/NX-списке вернул индекс 1; восстановление RW/NX, освобождение физической страницы и снятие резерва вернули 0.
  • Отказы на unmapped-адресе и mapped/unmapped PTE сохранили IPC_BAD_POINTER; штатный IPC-сценарий после отказов завершился.
  • 3 компонента, 49 возвращённых страниц, 0 contained faults, остаточных запросов IPC, полномочий, device leases и ссылок на объекты нет.
  • SHA-256 образа: 4f7ba31173fb19b2fd360c9a3717928a0271588e4b1030121c71972945091ef6.
  • Результаты: build-report.json, boot-report.json, platform-report.json, screen.png, boot.log.

Уточнение проверяющего инструмента

Первая QEMU-сессия выполнила гостевой сценарий, но host-проверка остановилась на проверке содержимого кадров таблиц страниц после завершения компонентов. Эти кадры уже возвращены распределителю и могут быть повторно использованы; их последующее содержимое не является доказательством состояния таблиц живого процесса. Проверка для этого профиля теперь опирается на снимок результата syscall 54, подтверждение освобождения страницы/резерва и общий учёт очистки. Остальные профили и их проверки не менялись.

Границы

Подтверждён один входной список syscall 54 в одном профиле на одном CPU. Это не доказывает отсутствие PTE-гонок, pinning, SMP-безопасность или безопасность всех публичных syscall. SAFE-05 остаётся открытым; полная контрольная регрессия K8 не проводилась.

Этап 200 — SAFE-05: syscall 63 читает описатель и аргументы из read-only памяти

Прямая ссылка на отчёт

Результаты относятся к сборке, указанной в отчёте. Материалы испытаний перенесены из рабочей копии.

Статус: целевая приёмка CPL3/QEMU профиля process-dynamic-arguments пройдена. SAFE-05 остаётся в работе.

Изменение

В профиль process-dynamic-arguments добавлен положительный сценарий после отказных проверок mapped/unmapped границ. Описатель syscall 63 и вложенный массив четырёх аргументов располагаются в одной динамической странице. Syscall 72 переводит её в User/RO/NX, после чего syscall 63 должен прочитать оба диапазона и запустить потомка.

Значения аргументов остаются 11, 22, 33, 44; потомок должен завершиться кодом 7331. Код отказа syscall 72 проверяется отдельно до вызова syscall 63.

Приёмка

  • Свежая сборка python tools/host/build.py --out TEMP/safe05-syscall63-readonly --platform-case process-dynamic-arguments — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Syscall 72 успешно защитил страницу. Syscall 63 прочитал описатель и массив из User/RO/NX; потомок 65538 получил четыре ожидаемых аргумента и завершился с кодом 7331.
  • Существующие отказные сценарии 40-байтового описателя и массива на mapped/unmapped границе сохранили IPC_BAD_POINTER, неизменный доступный префикс и отсутствие лишнего потомка.
  • Всего 2 компонента, 31 возвращённая страница, 0 contained faults и остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • SHA-256 образа: 6b7a92afb6a8300cf57e23d5c31e56bae787ed25649cbc6c0ed6861ca1939e4f.
  • Машинные результаты: build-report.json, boot-report.json, platform-report.json, screen.png, boot.log.

Границы

Проверены только два пользовательских входа syscall 63 в одном CPL3/QEMU профиле и на одном CPU. NX-отказ отдельно не изолирован; PTE-гонки, pinning, SMP, остальные публичные syscall, SAFE-05 целиком и контрольная регрессия K8 остаются открытыми.

Этап 199 — SAFE-05: syscall 68 читает описатель из read-only памяти

Прямая ссылка на отчёт

Результаты относятся к сборке, указанной в отчёте. Материалы испытаний перенесены из рабочей копии.

Статус: целевая приёмка CPL3/QEMU профиля приём-пакета-supervisor пройдена. SAFE-05 остаётся в работе.

Изменение

Сценарий приёма GUP1 теперь выделяет 12 динамических страниц: первые 11 вмещают пакет максимального проверяемого размера, отдельная двенадцатая используется для описателя запуска.

После сборки пакета супервизор переводит страницу корректного 40-байтового описателя в режим User/RO/NX через syscall 72 и передаёт его syscall 68. Успешное создание дочернего компонента проверяет, что syscall 68 читает описатель и не требует права записи в него.

Проба этапа 198 сохранена: описатель, пересекающий mapped/unmapped PTE, должен вернуть IPC_BAD_POINTER. После неё выполняются read-only запуск GUP1 и ожидание дочернего кода выхода 7301.

Приёмка

  • Свежая сборка python tools/host/build.py --out TEMP/safe05-syscall68-readonly --platform-case приём-пакета-supervisor — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Syscall 72 успешно установил RO/NX; отказная cross-PTE проба syscall 68 завершилась ожидаемым IPC_BAD_POINTER; syscall 68 затем принял корректный read-only описатель и запустил ребёнка 65539, код выхода — 7301.
  • Всего 3 компонента, 48 возвращённых страниц, 0 contained faults; остаточных IPC-запросов, полномочий, device leases и ссылок на объекты нет.
  • SHA-256 образа: 3a70ab929806a27b757e5420f603d87fbb7a7981ce20b7ee9060cd3b0c1695c4.
  • Машинные результаты: build-report.json, boot-report.json, platform-report.json, screen.png, boot.log.

Границы

Проверен один пакетный профиль на одном CPU. Это подтверждает чтение описателя с Present/User, без права записи; отдельные NX- и PTE-гонки, pinning, SMP и полный SAFE-05 не проверялись. Полная регрессия K8 остаётся контрольным этапом.

Этап 198 — SAFE-05: syscall 68 отклоняет описатель через границу PTE

Прямая ссылка на отчёт

Статус: целевая приёмка CPL3/QEMU профиля приём-пакета-supervisor пройдена. SAFE-05 остаётся в работе.

Изменение

В пользовательский сценарий приёма GUP1 добавлена отказная проба syscall 68. После получения пакета супервизор размещает первые 32 байта 40-байтового описателя в конце последней выделенной динамической страницы. Оставшиеся 8 байт попадают в следующую незамапленную PTE. Ожидаемый результат — IPC_BAD_POINTER; при любом другом результате супервизор прекращает сценарий с диагностическим кодом 9020.

Затем супервизор вызывает syscall 68 с обычным полным описателем. Это проверяет, что отказная операция не помешала нормальному запуску.

Приёмка

  • Свежая сборка: python tools/host/build.py --out TEMP/safe05-syscall68-boundary --platform-case приём-пакета-supervisor — PASS.
  • QEMU: python tools/host/test_boot.py --build TEMP/safe05-syscall68-boundary --qemu <QEMU 11.1.0> — PASS; q35/TCG, 128 МиБ, 1 CPU.
  • Вызов с неполным описателем прошёл проверку супервизора как IPC_BAD_POINTER; затем корректный GUP1 v3 пакет запустил ребёнка 65539, завершившегося с кодом 7301, без перезапуска ядра.
  • В отчёте сценария: 3 компонента всего (2 исходных и 1 запущенный), 47 возвращённых страниц, 0 faults и 0 остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • SHA-256 образа: 114ef6f48230d4cfb3e579c06d603dff08ba8f6d0911d33510f790a9011df694.
  • Машинные результаты: boot-report.json, platform-report.json, screen.png.

Границы

Проверен отказ чтения полного 40-байтового описателя на mapped/unmapped границе и последующий штатный запуск только в данном профиле на одном CPU. Read-only описатель, конкурентное изменение PTE, pinning и SMP этим этапом не проверялись. SAFE-05 и полная регрессия K8 остаются открытыми.

Перенос в папку проекта пользователя

Сюда скопированы отчёт и артефакты проверки из рабочего дерева. Исходный код в этой папке не синхронизировался: срабочая копия и папка проекта имеют разный ABI.

Этап 197 — SAFE-05: графические syscall 32/33 отвергают неполный буфер до вывода

Прямая ссылка на отчёт

Статус: целевая приёмка профиля surface, CPL3/QEMU, один CPU — пройдена. SAFE-05 остаётся в работе.

Изменение и сценарий

Расширен существующий CPL3-профиль поверхности. Дескриптор syscall 32/33 и пиксельные данные (2080 байт) размещаются с адреса page + 3072 в одной выделенной динамической странице. Доступный префикс содержит ярко-красные пиксели, а конец буфера пересекает отсутствующую PTE. Оба системных вызова получают координаты прежнего изображения и должны отказать до записи в GOP.

Результат

  • Свежая сборка python tools/host/build.py --out TEMP/safe05-syscall32-33-atomic-cross-pte --platform-case surface — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU — PASS.
  • Syscall 32 и 33 вернули IPC_BAD_POINTER для буфера через mapped/unmapped PTE.
  • Проверка итогового кадра подтвердила, что пиксели после обоих отказов сохранили значения предыдущего корректного вывода syscall 51: (224,64,32), (224,64,32), (17,34,51). Контрастный доступный префикс не попал в GOP.
  • Один компонент, 0 faults, возвращено 11 страниц; остаточные IPC-запросы, полномочия, device leases и ссылки отсутствуют.
  • SHA-256 образа: 586452862823722a5488987eaee6cbc980073351e126d9572a077f7c306d962a.
  • Машинные результаты: boot-report.json, platform-report.json, screen.png.

Граница

Приёмка охватывает только отказные пути входных поверхностей syscall 32/33 в профиле surface. Она не доказывает атомарность прочих системных вызовов, PTE-гонки, pinning, SMP или полную регрессию K8. SAFE-05 остаётся открытым.

Перенос этапа 197

Отчёт и четыре артефакта приёмки скопированы сюда из рабочего дерева Codex 12.11.2026. Свежая сборка и QEMU были выполнены из C:\Users\User\.codex\worktrees\agentterra-os-core\osguseva; исходники этого этапа не переносились в эту копию, потому что ABI и platform_runtime.gsl здесь отличаются. Поэтому этот отчёт не утверждает, что образ из этой папки воспроизводит этап 197. Перед включением исходников требуется согласовать обновление кода с текущей веткой novaos\osguseva.

Этап 196 — SAFE-05: отказ syscall 51 не меняет уже показанную область

Прямая ссылка на отчёт

Статус: целевая приёмка профиля surface, CPL3/QEMU, один CPU — пройдена. SAFE-05 остаётся в работе.

Сценарий

Расширен существующий гостевой профиль вывода поверхности:

  1. CPL3-компонент показывает корректный 32×16 пиксельный буфер на позиции 400×300.
  2. В доступном префиксе следующего источника размещаются контрастные красные пиксели; источник начинается по адресу page + 3072 и заканчивается в отсутствующей PTE.
  3. Компонент передаёт этот источник syscall 51 с теми же размерами и координатами.
  4. Ядро возвращает IPC_BAD_POINTER. Итоговый кадр QEMU сравнивает точки внутри прежнего изображения и за его границей с ожидаемыми исходными цветами.

Так проверяется не только код отказа: частичный красный префикс не появился на экране.

Результат приёмки

  • Свежая сборка python tools/host/build.py --out TEMP/safe05-syscall51-atomic-cross-pte --platform-case surface — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU — PASS.
  • Syscall 51 на mapped/unmapped источнике вернул IPC_BAD_POINTER.
  • Пиксели (400,300) и (400,307) остались (224,64,32), (408,300) — (17,34,51); красная отображённая часть источника не попала на экран.
  • В той же сборке прошли RO/NX-источник syscall 51, восстановление права записи, четыре существующих отказа на незамапленных адресах, 0 faults и очистка IPC/полномочий/device leases/ссылок.
  • Возвращено 11 страниц; SHA-256 образа: eaf4b20d945d3dd2e643ed92b20e191c2cadb9d07e586af8bde21395d41c7b24.
  • Результаты: boot-report.json, platform-report.json, screen.png.

Граница

Подтверждён один путь syscall 51 в профиле surface. Это не закрывает SAFE-05 и не доказывает атомарность остальных syscall, стабильность PTE при конкурентных изменениях, pinning или SMP. Проверка подтверждает отказ и отсутствие частичного вывода в GOP; она не реализует сохранённые оконные слои или их композицию. Оконная композиция, Z-порядок, hit-test и восстановление закрытой области остаются задачей CPL3-композитора.

Состояние переноса в пользовательскую папку

Отчёт и QEMU-артефакты перенесены. Код проверялся в C:\Users\User.codex\worktrees\agentterra-os-core\osguseva; исходники ядра, тестового компонента и host-проверки в эту папку ещё не объединены. Причина и перечень несовпадающих файлов приведены в TEMP/stage-evidence/README.txt.

Этап 195 — SAFE-05: чтение поверхности из памяти RO/NX

Прямая ссылка на отчёт

Статус: целевая приёмка профиля surface, CPL3/QEMU, один CPU — пройдена. SAFE-05 остаётся в работе.

Что проверено

Добавлена гостевая проверка вывода пиксельной поверхности syscall 51 из динамической пользовательской страницы, переведённой syscall 72 в режим RO/NX.

  • syscall 72 успешно снял право записи с исходной страницы, оставив её пользовательской и NX;
  • syscall 51 прочитал поверхность и вернул успех;
  • право записи восстановлено syscall 72;
  • контрольное слово пикселей до и после вывода совпало;
  • существующие проверки выхода за границу и четырёх незамапленных адресов продолжили проходить.

Результат приёмки

  • Свежая сборка python tools/host/build.py --out TEMP/safe05-syscall51-readonly-source --platform-case surface — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU — PASS.
  • Образ: SHA-256 a5a8562dadee332cb8c979e2154bd34e1612a9e616de11e96bcd24c664ceafd4.
  • Один CPL3-компонент завершил профиль; faults — 0; остаточные IPC-запросы, полномочия, device leases и ссылки — 0.
  • Результаты: boot-report.json, platform-report.json, screen.png.

Уточнение интерфейсов и политики

В текущем ABI syscall 49 снимает резерв виртуального адреса, а syscall 51 выводит поверхность. syscall 51 читает источник из CPL3, поэтому для него требуются Present и User-доступ; RW и NX не являются необходимыми условиями чтения. RW/NX обязательны для syscall 71, который записывает в пользовательскую поверхность. Эти политики различаются по направлению доступа.

Профиль проверяет согласованность права чтения и успешное чтение при RO/NX. Он не проверяет составной отказ вывода поверхности с незамапленным хвостом и неизменность framebuffer при таком отказе; PTE-гонки, pinning, SMP и общая стабильность check/use также не проверялись.

Граница

Принят только этот профиль syscall 51. SAFE-05 остаётся открытым до завершения аудита остальных публичных буферов и предусмотренной приёмки. Этап не реализует композицию окон: сохранённые поверхности, Z-порядок, hit-test и восстановление нижнего слоя относятся к CPL3-композитору.

Состояние переноса в пользовательскую папку

Отчёт и QEMU-артефакты перенесены. Код проверялся в C:\Users\User.codex\worktrees\agentterra-os-core\osguseva; исходники ядра, тестового компонента и host-проверки в эту папку ещё не объединены. Причина и перечень несовпадающих файлов приведены в TEMP/stage-evidence/README.txt.

Этап 194 — SAFE-05: syscall 55 отклоняет буфер через границу PTE

Прямая ссылка на отчёт

Статус: целевая приёмка пройдена для профиля ipc-wait-any, CPL3/QEMU, один CPU. SAFE-05 остаётся в работе.

Реализация и сценарий

В гостевой профиль добавлена проверка syscall 55 (IPC_PAYLOAD_READ) с 131-байтовым назначением, начинающимся в отображённой динамической странице за 128 байт до её конца. Следующая PTE не отображена.

  • Ядро возвращает IPC_BAD_POINTER до копирования payload.
  • Контрольные слова в начале доступного префикса и у конца страницы остаются неизменными.
  • После отказа тот же талон остаётся действующим: штатное чтение в корректный буфер возвращает все 131 байт.
  • Тестовая динамическая страница освобождается, резерв снимается.

Приёмка

  • Свежая сборка: python tools/host/build.py --out TEMP/safe05-syscall55-cross-page --platform-case ipc-wait-any — PASS.
  • QEMU: python tools/host/test_boot.py --build TEMP/safe05-syscall55-cross-page --qemu <путь к QEMU 11.1.0> — PASS.
  • Конфигурация: QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU; три компонента завершили сценарий.
  • Faults — 0; возвращено 49 страниц; остаточные IPC-запросы, полномочия, device leases и ссылки — 0.
  • SHA-256 образа: 67346fba81cfbe2fcae635bd9f84cbb018cef94e9e76289c68b8c491a5109ec9.
  • Машинные результаты: boot-report.json, build-report.json, platform-report.json, screen.png.

Границы

Проверен один гостевой путь syscall 55 на одном CPU. Это не закрывает весь SAFE-05, не подтверждает атомарность всех syscall, не проверяет гонки PTE, pinning, SMP или полную регрессию K8.

Состояние переноса в пользовательскую папку

Отчёт и QEMU-артефакты перенесены. Код проверялся в C:\Users\User.codex\worktrees\agentterra-os-core\osguseva; исходники ядра, тестового компонента и host-проверки в эту папку ещё не объединены. Причина и перечень несовпадающих файлов приведены в TEMP/stage-evidence/README.txt.

Этап 173 — проверенный вывод пользовательской поверхности

Прямая ссылка на отчёт

Дата: 12 ноября 2026 года
Статус: ограниченный механизм принят в целевом профиле QEMU; B-04 остаётся в работе.

Результат

Syscall 49 выводит пиксельную поверхность CPL3-компонента в GOP. Ядро требует полномочие display_output, читает описатель из приватной страницы данных владельца и проверяет формат, размеры, шаг, экранные границы и весь диапазон буфера. Для каждой пользовательской страницы сверяются владелец в обратной карте, физический кадр и флаги P/RW/User/NX. После проверок пиксели синхронно копируются в framebuffer.

Профиль драйвера surface проверил:

  • успешный вывод динамически выделенного буфера;
  • отказ IPC_DENIED для поверхности за границами экрана;
  • отказ IPC_BAD_POINTER для адреса вне пользовательского отображения;
  • возврат буфера и очистку ресурсов компонента.

Приёмка

  • Сборка: TEMP/b04-surface-accepted-candidate-20261112, профиль surface.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: PASS, CPU остановлен тестовым завершением.
  • Образ SHA-256: 821b571d2a976e64cb0ba34b54561789a8a42ec862eb7ab189040706cb739c2d.
  • Один CPL3-компонент; 13 страниц возвращено; faults — 0; остаточные полномочия, IPC-запросы, leases и ссылки — 0.
  • Отчёты: сборка, загрузка/QEMU, платформенная приёмка, снимок.
  • Дополнительно проверен синтаксис tools/host/platform_check.py через python -m py_compile.

Предыдущая запись changelog описывает состояние на момент её создания, когда QEMU ещё не запускался. Этот этап фиксирует последующую целевую приёмку и не переписывает историю.

Граница результата

Проверен синхронный вывод поверхности в однопроцессорной конфигурации. Это не pinning и не гарантия от конкурентного изменения PTE на SMP. Буфер не становится сохраняемым слоем окна: поверхность пока выводится прямо в общий framebuffer. Перекрытие, Z-порядок, hit-test, связь фокуса с реестром окон и восстановление нижнего слоя не реализованы. Поэтому этап 173 не закрывает B-04 и не подтверждает завершённую интерактивную графическую оболочку.

Следующий шаг

Добавить принадлежащие композитору сохраняемые поверхности окон и композицию слоёв. Затем проверить три контрольных кадра до открытия, при открытом окне и после закрытия, включая восстановление сцены и очистку объектов.

Этап 172 — жизненный цикл записей окон

Прямая ссылка на отчёт

Дата: 12 ноября 2026 года
Статус: частичный механизм принят в целевом профиле QEMU; B-04 остаётся в работе.

Что изменено

  • В ограниченный реестр CPL3-композитора включён цикл создания и закрытия записи окна. Запись хранит полный ID владельца, геометрию и дескриптор.
  • При закрытии запись освобождается. Повторное использование слота выдаёт следующий дескриптор; старый дескриптор не находит активное окно и получает IPC_STALE.
  • Исправлена проверка создания: она передавала в поле геометрии значение цвета, хотя координаты уже были рассчитаны отдельно. Теперь в пакет уходит упакованная геометрия.
  • Контракт и границы реализации отражены в протоколе графического IPC.

Приёмка

  • Сборка: TEMP/window-registry-final2, профиль композитор, GSL 0.0.15, Clang 22.1.8.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: PASS.
  • Образ SHA-256: d75452f13d65eb1c2f235d6d3ccbc56c34bbb75776c98a2ce6ea8e70940b260a.
  • Один CPL3-производитель создал и закрыл два окна; дескрипторы 1 и 2, слот повторно использован, запрос к старому дескриптору получил IPC_STALE.
  • Оба компонента дошли до ожидаемого шага выполнения. Faults — 0; после остановки профиля активных IPC-запросов, полномочий, device leases и ссылок не осталось. Возвращено 24 страницы.
  • Отчёты: сборка, QEMU, проверка платформы.

Что этот результат не подтверждает

  • Окно пока не имеет собственной сохранённой пиксельной поверхности. Метод рисования проверяет запись/владельца/геометрию, но выводит в общий framebuffer.
  • Перекрытие, Z-порядок, hit-test и переключение фокуса по реальной геометрии окон не проверялись.
  • Этот тест не сравнивает контрольные кадры до открытия, при открытом окне и после закрытия. Он не подтверждает исправление восстановления изображения и не закрывает B-04.

Следующий блок

Реализовать сохранённую поверхность окна и сведение слоёв композитором. После этого сделать сквозной сценарий: сохранить три контрольных кадра, открыть и закрыть окно, сравнить ожидаемо восстановленные области, проверить фокус и отсутствие оставшихся оконных объектов/IPC. Только эти данные позволят определить, является ли прежнее число 440 001 дефектом композиции или включает ожидаемые динамические области.

Этап 171 — IPC-отрисовка глифа в поверхности композитора

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: В работе; целевой runtime-профиль композитор прошёл QEMU после исправления билета ответа. Интеграция продуктового рабочего стола остаётся незавершённой.

Изменения

  • В CPL3-композитор добавлен IPC-метод 9 для глифа в принадлежащей отправителю оконной поверхности. Он использует syscall 71 и не встраивает атлас в CPL3-образ.
  • Запрос несёт дескриптор, индекс глифа, локальные координаты, масштаб и начертание; RGB передаётся отдельно. Старшие резервные биты должны быть нулевыми.
  • Композитор сверяет поколенческий дескриптор и владельца, ограничивает текстовую область ниже заголовка и внутри рамок, формирует запись syscall 71. Ядро требует display_output и проверяет пользовательские RW/NX PTE целевой поверхности, используя общий сглаженный атлас ядра.
  • Результат успешного IPC содержит шаг глифа для размещения следующего символа.
  • Контракт описан в протоколе композитора.

Граница и следующий шаг

  • Первоначальная runtime-проверка выявила дефект ответа: ipc_packet обнулял поле билета, а syscall 8/ядро проверяет его совпадение с билетом принятого запроса. Композитор теперь восстанавливает билет запроса в заголовке ответа перед syscall 8.
  • Свежая сборка профиля композитор прошла: build_status=success, platform_count=3. QEMU 11.1.0, q35, TCG, 128 МиБ, 1 CPU: PASS. Образ SHA-256 d4db3937d8c15eca169cd3e4f50cbe3595f8086b6f3b15fed0dd77bc6966cdb3.
  • Отчёт QEMU подтвердил 29 команд сцены, 6 прямоугольников и 9 глифов, 4 созданных окна, 3 оконных рисунка, 3 активных окна с двумя владельцами, topmost hit-test перекрывающейся поверхности, отказ рисования за границами, отказ устаревшего дескриптора, 0 faults, 0 оставшихся полномочий, IPC-запросов, device leases и ссылок. Возвращено 224 страницы.
  • Клиент пока не использует метод 9; рабочий стол всё ещё рисует через syscall 42/43 напрямую.
  • Следом — перевести рабочий стол на оконные поверхности и IPC, подключив метод 9 для текста, затем проверить единый граф рабочего стола, композитора и оконных приложений. Этот профиль подтверждает композиторный IPC-механизм, но не готовность продуктового рабочего стола.

Этап 170 — GSL: глиф в память CPL3-поверхности

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: В работе. Компиляция CPL3-вызова и нативная запись глифа в буфер подтверждены 13 ноября 2026 года; интеграция с композитором и гостевая приёмка не выполнены.

Изменения в исходниках

  • В bootstrap-компиляторе добавлено выражение глиф_в_поверхность(адрес, размер, ширина, высота, шаг_строки, формат, номер_глифа, x, y, масштаб, цвет, насыщенность). Оно доступно как u64-выражение только из действия user и вызывает существующий растеризатор сглаженного глифа в памяти компонента.
  • Выражение доступно только из действия user. Оно использует уже встраиваемый сглаженный атлас и записывает глиф в переданную память компонента, не выполняя syscall вывода и не меняя framebuffer.
  • Проверяются ненулевой адрес и геометрия до 4096×2160, шаг строки до 8192 пикселей, формат 0/1, глиф 0–193, масштаб 1–4, насыщенность 0/1, вместимость буфера и границы глифа. Успех возвращает продвижение курсора в пикселях; отказ — 0.
  • Добавлено описание API в руководстве языка.

Граница

  • Изменённые файлы: src/compiler/bootstrap-python/framebuffer_codegen.py, src/compiler/bootstrap-python/gslc.py, docs/language/README.md.
  • python -m unittest tests.compiler.test_framebuffer -v — 3 проверки PASS: типизация пользовательского вызова, запрет kernel-контекста и нативная запись/отказ на границе буфера с canary-проверками. Результат подтверждает только примитив языка и его растеризатор.
  • Сборка образа и QEMU не запускались; гостевая интеграция и этап 170 в целом не приняты.
  • Указатель должен быть доступной CPL3-памятью текущего компонента. Примитив не отображает память другого компонента и не предоставляет shared memory.
  • Метод ещё не подключён к IPC композитора; рабочий стол по-прежнему рисует syscall 42/43 напрямую.

Следующий блок

Подключить глифовый примитив к сохранённым поверхностям CPL3-композитора, затем перевести рабочий стол на оконный IPC-контракт. После сборки выполнить адресную проверку границ поверхности и целевой граф QEMU; этап 170 закрывать только после интеграции и гостевого подтверждения.

Этап 169 — GUI: непрозрачные слои окон

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: В работе; целевой QEMU-сценарий не выполнен.

Изменения

  • Композитор хранит для каждого активного окна порядковый номер слоя. Перекрытие окон разрешено.
  • Перерисовка выводит непрозрачные поверхности от нижнего слоя к верхнему. После изменения поверхности или закрытия окна сцена собирается заново из сохранённых буферов, а не из пикселей framebuffer.
  • Hit-test выбирает активное окно с наибольшим Z-порядком среди окон, содержащих точку.
  • Hit-test разрешён только доверенному оконному менеджеру. Выбранное окно получает новый верхний слой; приложение не может самостоятельно переставить себя.
  • Сценарий композитор обновлён: создаёт пересекающееся окно 300×200, проверяет hit-test в пересечении и оставляет три окна двух владельцев после закрытия нижнего большого окна.

Выполнено

  • python -m py_compile tools/host/platform_check.py — успешно.
  • python tools/host/build.py --platform-case композитор --out work/control-panel-compositor-build — сборка PE32+ UEFI успешно завершена.
  • python tools/host/build.py --platform-case focus-compositor --out work/control-panel-focus-build — интегрированный граф с менеджером и двумя приложениями также собрался.
  • SHA-256 образов: композитор — 3826c8f0f47a8d48075eef7b4f072e4173f8ac9a27b5d421373b61074dbb971b; focus-compositor — 2d817214f1cd2b5e42294eaa3f1be14ce4037a87968eba129f5478c5d416706c.
  • Попытка адресного запуска python tools/host/qemu_acceptance.py --build work/control-panel-compositor-build остановилась до загрузки: QEMU в этой рабочей копии не найден (QEMU not found; pass --qemu PATH). Поэтому значения checker, смена слоя во время исполнения и запуск гостевых сценариев не считаются принятыми.

Что остаётся

  • Повторить ровно этот образ в QEMU и получить PASS целевого сценария.
  • Подтвердить в QEMU контролируемое поднятие выбранного окна через оконный менеджер.
  • Подключить рабочий стол как сохранённый нижний слой и связать его с текущим графом композитора и маршрутизацией ввода.
  • После этого реализовать окно CPL3/GSL «Управление системой» и открыть его из «Хаба».

Пока рабочий стол не подключён к композитору, его содержимое не сохраняется как фоновая поверхность этого графа. Этап не подтверждает готовое окно панели управления или пользовательскую интерактивность.

Этап 168 — SAFE-05: положительный запуск из динамической страницы

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят в заявленной границе; SAFE-05 остаётся в работе.

Реализация сценария

Добавлен отдельный профиль process-dynamic-arguments. CPL3-компонент резервирует динамический диапазон, обращается к одной странице вне исходной страницы данных и размещает в ней 40-байтовый дескриптор syscall 63 и четыре значения аргументов. Сценарий запускает дочерний компонент, который возвращает код 7331 только при получении значений 11, 22, 33, 44. Общий memory-stress участок platform_worker пропускается только для этой выделенной роли; он продолжает проверяться собственными профилями.

Приёмка

  • Свежая сборка: python -X utf8 tools/host/build.py --platform-case process-dynamic-arguments --out work/safe05-dynamic-arguments-20261111.
  • Целевой QEMU: python -X utf8 tests/kernel/test_boot.py --build work/safe05-dynamic-arguments-20261111 --qemu <QEMU 11.1.0> --timeout 180 — PASS, q35/TCG, 128 МиБ, 1 CPU.
  • Фактические адреса: дескриптор 34359824384, массив аргументов 34359824424; оба в динамической User/NX-области, за пределами начальной страницы данных.
  • Дочерний компонент 65538 получил четыре ожидаемых значения и завершился с кодом 7331.
  • Два компонента выполнены, ошибок и faults нет; освобождено 29 страниц. Суммарный счётчик включает родителя и ребёнка; дополнительная динамическая страница возвращена после завершения владельца. Незавершённых полномочий, IPC-запросов, device leases и ссылок на объекты нет.
  • SHA-256 проверенного образа: e8a909f8eb432b70c7cdb9e0804c04fcf7b9870fa7c06f52b2fe79fdbeb108a0.

Граница результата

Подтверждены descriptor и массив аргументов syscall 63 через существующий PTE-aware copy-in на действительном динамическом отображении. Это не подтверждает все остальные публичные буферы, конкурентные изменения PTE или SMP. Полный K8 не запускался.

Этап 167 — SAFE-05: адрес syscall 63 через проверяемые отображения

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: изменение ядра собрано; целевая проверка динамического буфера не завершена; SAFE-05 остаётся в работе.

Изменение

В p_spawn_with_arguments снято ограничение, привязывавшее указатель описателя запуска к первой странице данных компонента. Выравнивание сохраняется, а допустимость диапазона определяет общий copy-in по фактическим пользовательским PTE с проверкой User/NX и границ. Вложенный массив аргументов использует ту же проверку; максимум остаётся четыре аргумента, при нуле аргументов указатель обязан быть нулём.

Проверенная регрессия

  • Свежий профиль собран командой python -X utf8 tools/host/build.py --platform-case process-wait --out work/safe05-spawn-dynamic-buffer-20261111.
  • python tests/kernel/test_boot.py --build work/safe05-spawn-dynamic-buffer-20261111 --qemu <QEMU 11.1.0> — PASS: q35/TCG, 128 МиБ, 1 CPU.
  • В профиле сохранены проверки отказа на незамапленном описателе, формата аргументов, ожидания/тайм-аутов и очистки. Faults и остаточные IPC-запросы, полномочия, device leases и object references — 0; возвращено 70 страниц.
  • SHA-256 образа: 5f31e5ec1528c3bb1e1fc150ff9bfb120929deba0a5fa62e5a4d7e60b2502c01.

Не подтверждено

Этот QEMU-прогон не содержит положительного случая, где описание и массив аргументов расположены в динамических страницах. Поэтому новая возможность пока подтверждена изменением пути и регрессионным профилем, но не отдельной сквозной приёмкой. Следующий шаг — отдельный компактный профиль syscall 63 для динамического User/NX-буфера, без расширения большого platform_worker.

SAFE-05 остаётся открытым: другие публичные входы, конкурентные изменения PTE и SMP требуют отдельного решения в пределах контракта KERNEL 1.0. Полный K8 не запускался.

Последующее подтверждение

Положительный вызов syscall 63 с описателем и аргументами из динамической User/NX-страницы принят в этапе 168. SAFE-05 остаётся в работе за пределами этой проверки.

Этап 166 — SAFE-05: незамапленный описатель запуска компонента

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

В CPL3-профиль process-wait добавлен вызов syscall 63 с адресом незамапленной пользовательской страницы вместо описателя запуска. Вызов выполняет компонент с полномочием start_service; ожидаемый результат — IPC_BAD_POINTER, то есть отказ именно на адресе описателя, а не на проверке права.

После отказа существующий профиль продолжает обычный запуск дочернего компонента, проверку аргументов и резервного поля, ожидание/тайм-ауты, отмену ожидания и освобождение ресурсов.

Приёмка

  • python -X utf8 tools/host/build.py --platform-case process-wait --out work/safe05-spawn-descriptor-20261111 — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-spawn-descriptor-20261111 --qemu <QEMU 11.1.0> — PASS: q35, TCG, 128 МиБ, 1 CPU.
  • QEMU подтвердил IPC_BAD_POINTER для незамапленного описателя и штатный последующий жизненный цикл дочерних компонентов.
  • Faults: 0; остаточные IPC-запросы, полномочия, device leases и ссылки: 0; возвращено 70 страниц.
  • SHA-256 образа: bd9a139da1a6dfe96d27f192d326f1d7ce5f53209d1fd0f5484e00df0d98c0f8.

Граница результата

Проверен адрес самого описателя syscall 63 при действующем полномочии запуска. Вложенный указатель массива аргументов уже имеет отдельные проверки формата/границ; его незамапленный PTE в этом этапе не проверялся. SAFE-05 остаётся открыт для прочих публичных входов, конкурентных изменений PTE и SMP; полный K8 не выполнялся.

Этап 165 — SAFE-05: отказ буфера отправки IPC

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

В CPL3-профиль ipc-wait-any добавлен syscall 6 с действующим каналом и незамапленным адресом источника. Приложение проверяет IPC_BAD_POINTER, после чего выполняет уже существующую проверку чрезмерной длины и штатно отправляет запрос из корректного буфера. Получатель принимает запрос, отвечает, и профиль продолжает полный обмен.

Так проверяется, что отказ на чтении пользовательского буфера не ставит частичный запрос в IPC-очередь и не мешает следующей корректной отправке. Ядро и ABI не менялись.

Приёмка

  • python -X utf8 tools/host/build.py --platform-case ipc-wait-any --out work/safe05-send-buffer-20261111 — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-send-buffer-20261111 --qemu <QEMU 11.1.0> — PASS: q35, TCG, 128 МиБ, 1 CPU.
  • QEMU подтвердил IPC_BAD_POINTER для syscall 6 и успешную следующую отправку/приём/ответ; прошли восемь двусторонних IPC-обменов и предыдущие проверки syscall 7/8/54/55.
  • Компоненты: 3; faults: 0; остаточные IPC-запросы, полномочия, device leases и ссылки: 0; возвращено 43 страницы.
  • SHA-256 образа: 12c2f25efe8f6a8ba61c31d409e76c2fd4f5512d80897549665e1b5b80081ac6.

Граница результата

Проверен один отказ copy-in для syscall 6 и последующее штатное IPC. SAFE-05 остаётся открытым для прочих публичных входов, конкурентных изменений PTE и SMP; полный K8 не выполнялся.

Этап 164 — SAFE-05: отказ буфера назначения IPC-снимка

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

В CPL3-профиль ipc-wait-any добавлен syscall 55 с действительным IPC-билетом и незамапленным адресом назначения. Компонент проверяет IPC_BAD_POINTER, затем читает тот же 131-байтовый снимок в корректный буфер. Существующие проверки содержимого и защитного хвоста проходят, значит отказ не повредил право чтения или сохранённый снимок.

Ядро и ABI не менялись: проверяется уже существующий отказ до успешного последующего вызова.

Приёмка

  • python -X utf8 tools/host/build.py --platform-case ipc-wait-any --out work/safe05-payload-read-20261111 — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-payload-read-20261111 --qemu <QEMU 11.1.0> — PASS: q35, TCG, 128 МиБ, 1 CPU.
  • QEMU подтвердил IPC_BAD_POINTER для syscall 55 и последующее чтение 131 байта из того же IPC-снимка; остальные IPC, wait-any, таймеры и проверки очистки профиля также прошли.
  • Компоненты: 3; faults: 0; остаточные IPC-запросы, полномочия, device leases и ссылки: 0; возвращено 43 страницы.
  • SHA-256 образа: 9615d2fe38e7fd930a72ab18c395974b095bc7510c528cfc1f1e16d2e2c577ad.

Граница результата

Проверен один отказ copy-out для syscall 55 и сохранение последующего штатного чтения. SAFE-05 остаётся открытым для прочих публичных входов, конкурентных изменений PTE и SMP; полный K8 не выполнялся.

Этап 163 — SAFE-05: неверный список ожидания IPC

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

В CPL3-профиле ipc-wait-any добавлен вызов syscall 54 с незамапленным пользовательским адресом вместо массива источников. Компонент проверяет IPC_BAD_POINTER, после чего немедленно вызывает wait-any с корректным массивом из двух IPC-источников. Обычное ожидание завершается индексом готового источника 2, затем продолжается обмен запросом и ответом.

Это проверяет и отказ по адресу, и то, что неуспешное копирование не портит следующий корректный вызов ожидания. Ядро и ABI не менялись.

Приёмка

  • python -X utf8 tools/host/build.py --platform-case ipc-wait-any --out work/safe05-wait-any-20261111 — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-wait-any-20261111 --qemu <QEMU 11.1.0> — PASS: q35, TCG, 128 МиБ, 1 CPU.
  • QEMU проверил отказ syscall 54 как IPC_BAD_POINTER, успешный последующий wait-any (индекс 2), восемь двусторонних IPC-обменов, предыдущие проверки syscall 7/8 и очистку.
  • Компоненты: 3; faults: 0; остаточные IPC-запросы, полномочия, device leases и ссылки: 0; возвращено 43 страницы.
  • SHA-256 образа: ea1af310c24eb69aea7c5ab71191fe6e012d1d4f9edf59361c77e9b6ae9f1c8b.

Граница результата

Проверены незамапленные входы IPC syscall 7, 8 и 54 в одном целевом гостевом сценарии. SAFE-05 остаётся открытым для прочих публичных входов, конкурентных изменений PTE и SMP; полный K8 не выполнялся.

Этап 162 — SAFE-05: отказ неверных буферов приёма и ответа IPC

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

В CPL3-профиль ipc-wait-any добавлены вызовы syscall 7 и 8 с адресом последней допустимой пользовательской страницы, которая не отображена в таблицах процесса. После отказа сценарий продолжает нормальный путь: запрос успешно принимается, а полученный билет используется для ответа. Так проверяется, что отказ на буфере не потребил запрос и не погасил билет.

Приёмщик сверяет маркер ошибок GSL-сценария и штатное завершение. Проверка кадра платформенного профиля отделена от строгой палитры загрузочного экрана: проверяются размер 1280×800 и содержимое кадра без требования заставки другого профиля.

Приёмка

  • python tools/host/build.py --platform-case ipc-wait-any --out work/safe05-ipc-qemu-20261111-final — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-ipc-qemu-20261111-final --qemu <QEMU 11.1.0> — PASS: q35, TCG, 128 МиБ, 1 CPU.
  • QEMU подтвердил отказы syscall 7/8 на незамапленном адресе без ошибки CPL3; после них прошли приём и ответ IPC, восемь двусторонних обменов, проверка снимка 131 байта, таймеров и очистки.
  • SHA-256 образа: 43338be9f62ee97b2934785add93ff73cb838eb401f912280134d5770258cd1f.

Граница результата

Проверены два IPC-буфера в одном целевом CPL3/QEMU-сценарии. Остальные публичные входы SAFE-05, конкурентное изменение PTE, SMP и контрольная матрица K8 не закрыты. Код ядра и ABI не менялись.

Этап 161 — SAFE-05: адресные отказы syscall в QEMU

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят; SAFE-05 остаётся в работе.

Что добавлено

Гостевое CPL3-приложение профиля surface передаёт адрес за концом выделенного пользовательского буфера в syscall 18, 32, 33 и 51. Проверка проходит по настоящему пути системного вызова и таблицам страниц гостя. Все четыре вызова возвращают IPC_BAD_POINTER; компонент не получает fault и штатно завершает работу. Независимая проверка также подтверждает вывод разрешённой поверхности и отказ на выход за экранные границы.

Исправлен QEMU-приёмщик: профиль платформы не обязан печатать этапы отдельного загрузочного экрана, а surface проверяется по пикселям поверхности, а не по палитре диагностического экрана.

Приёмка

  • python tools/host/build.py --platform-case surface --out work/safe05-qemu-20261111 — сборка успешна.
  • python tests/kernel/test_boot.py --build work/safe05-qemu-20261111 --qemu <QEMU 11.1.0> — PASS на q35, TCG, 128 МиБ, 1 CPU.
  • Снимок гостевой памяти показал результаты syscall 18/32/33/51: 18446744073709551615 (IPC_BAD_POINTER); faults — 0; компонент завершился с прогрессом 5; экранная поверхность прошла проверку.
  • SHA-256 образа: 2014aae7588f9a21c3ab4b2d58fe73c0d6040db97b9fae5750e151ca133efa20.

Граница результата

Это адресная QEMU-проверка четырёх syscall на одном CPL3-компоненте. Она не принимает все публичные входы SAFE-05, не заменяет native fuzz и контроль read-only и не проверяет конкурентное изменение PTE, SMP или полный K8.

Этап 160 — SAFE-05: положительные входы с read-only PTE

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: часть SAFE-05 принята; общий пункт остаётся в работе.

Результат

В native-приёмке test_process_policy.py добавлены положительные контрольные случаи для пользовательских входов, отображённых как User/NX/Present без права записи:

  • syscall 18 прочитал 16-байтовый запрос из read-only PTE, затем отказал в изменении лимита без полномочия. Лимит компонента остался прежним.
  • syscall 32 и 33 скопировали read-only описание поверхности, затем вернули IPC_BAD_MESSAGE для недопустимой ширины. Ошибка адреса не подменяет ошибку содержимого.
  • syscall 51 скопировал read-only описание поверхности и вернул IPC_BAD_MESSAGE для пустого описания.

Так дополнены существующие отрицательные fuzz-проверки, которые ожидают IPC_BAD_POINTER и неизменность арены при пустой PTE-карте. Положительные случаи проверяют, что корректно отображённая страница доступна для чтения, но это не даёт приложению права на запись или управление чужими лимитами.

Проверка

python -m unittest tests.kernel.test_process_policy -v — 2 unittest PASS. Внутренний native-профиль GSL сообщил PASS для GUP1/манифеста, мутаций syscall, PTE copy-in/copy-out, границ страниц и очистки процесса.

Изменён только native-профиль проверки; исходники гостевого ядра не менялись. Сборка ОС и QEMU на этом этапе не запускались.

Граница

SAFE-05 остаётся незакрытым: ещё требуется расширить область проверки других публичных входов ядра и определить адресный QEMU-сценарий, который добавляет доказательство сверх native-профиля. Этот этап не является полным fuzz-тестированием ОС и не проверяет SMP.

Этап 159 — SAFE-04: аудит пользовательских буферов общего runtime

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: SAFE-04 принят в границах общего runtime этапа 7.1 и платформы с одним CPU.

Что сверено

В platform_dispatch проверены все syscall общего runtime, которые принимают пользовательские буферы: 6–8, 17–18, 32–33, 37, 45, 47, 51, 54–55, 61, 63 и 68. Они используют общий PTE-aware copy-in/copy-out либо проверку всех PTE поверхности до чтения/записи. Остальные аргументы этих syscall являются скалярами, поколенческими дескрипторами или полномочиями и не трактуются как адреса пользовательских буферов.

Для однопроцессорного профиля изменение PTE другим потоком во время syscall невозможно: входы ядра используют interrupt gate, а планировщик не переключает поток до возврата из обработчика. SMP и межъядерные гонки остаются отдельным будущим этапом и не входят в контракт KERNEL 1.0.

Проверки

  • python -m unittest tests.kernel.test_process_policy -v — 2 теста PASS: GUP1/манифест, повреждённые входы, copy-out syscall 17/37/45/47 и границы страниц.
  • GUSEVA_PLATFORM_TEST_COUNTS=1, GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY=1, PlatformTests.test_common_objects_and_devices — 1 тест PASS: syscall 18/32/33/51, атомарный отказ по PTE и read-only User/NX входы.
  • GUSEVA_PLATFORM_TEST_COUNTS=2, GUSEVA_PLATFORM_TEST_SAFE04_IPC_ONLY=1, тот же целевой тест — 1 тест PASS: syscall 6–8, сохранение IPC-состояния при отказе.
  • GUSEVA_PLATFORM_TEST_COUNTS=2, GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1, тот же целевой тест — 1 тест PASS: wait-any syscall 54 и проверка PTE.
  • Свежая сборка --platform-case surface прошла. QEMU 11.1.0, q35, TCG, 128 МиБ, 1 CPU — PASS; проверены UEFI-переход, защита страниц, CPL3-поверхность и границы вывода. SHA-256 образа: 734d907ed9c44d71656184cb3e2609e41b15899b6018e85cd8a940b12c30863f.

Границы принятия

SAFE-04 принят для общего runtime, который собирается по умолчанию. --legacy-runtime остаётся регрессионным адаптером и не является целевым runtime выпуска. Полная QEMU-матрица переносится в контрольную приёмку K8; QEMU не запускался отдельно для каждого адресного варианта, поскольку они проверены нативными адресными профилями. SMP не поддерживается контрактом KERNEL 1.0.

Этап 158 — SAFE-04: поверхность syscall 51 пересекает границу PTE

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой native-критерий принят.

Результат

Профиль поверхности расширен проверкой динамического буфера пикселей, начинающегося за 512 байт до границы двух страниц:

  • Описатель поверхности остаётся в начальной пользовательской странице; данные пикселей занимают обе динамические страницы.
  • При read-only User/NX первой странице и Present/Supervisor-only второй syscall 51 возвращает IPC_BAD_POINTER. Framebuffer остаётся неизменным, то есть отображение не началось до проверки полного диапазона.
  • После изменения второй PTE на read-only User/NX syscall 51 успешно отображает поверхность 32×16. Проверены ненулевые пиксели у конца первой страницы и конца второй.
  • В том же целевом профиле повторно прошли имеющиеся проверки PTE и прав для syscall 18, 32, 33 и 51.

Проверка:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
$env:GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Изменялась только native-тестовая фикстура; исходники гостевого ядра не менялись, сборка образа и QEMU не запускались.

Границы

Проверен syscall 51 в последовательной native PE-фикстуре, две PTE, отказ второй страницы до изменения framebuffer и успешное чтение обеих страниц. Гонки изменения PTE, SMP, QEMU-инъекция и полный SAFE-04 не проверены; SAFE-04 остаётся в работе.

Этап 157 — SAFE-04: copy-out метрик планировщика через границу страниц

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: адресный native-критерий syscall 61 принят.

Результат

Расширен профиль с полномочием manage_scheduling для syscall 61:

  • При writable User/NX первой странице и read-only User/NX второй странице 32-байтовый выходной диапазон, пересекающий границу страниц, возвращает IPC_BAD_POINTER.
  • Все байты назначения, включая первые 16 байт на writable-странице и защитный хвост, остаются без изменений: ядро проверяет полный диапазон до copy-out.
  • После изменения второй PTE на writable User/NX syscall успешно выдаёт метрики двух потоков (123, 7, 45, 3) через границу, не меняя защитный хвост.
  • Прежние одностраничные read-only-отказ и writable-успех также прошли в том же профиле.

Команда:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
$env:GUSEVA_PLATFORM_TEST_SAFE04_SCHEDULER_METRICS_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Гостевой код не менялся; QEMU не запускался.

Границы

Проверены syscall 61, вывод 32 байта, две смежные PTE в последовательной native PE-фикстуре и полномочие manage_scheduling. Гонки PTE, SMP, QEMU-инъекция и полный SAFE-04 не проверялись.

Этап 156 — SAFE-04: copy-out IPC payload через границу страниц

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: адресный native-критерий syscall 55 принят.

Результат

В двухкомпонентном native-профиле wait-any расширена проверка syscall 55:

  • 131-байтовый ответ копируется в пользовательский диапазон, пересекающий границу двух страниц.
  • Если первая PTE writable User/NX, а вторая read-only User/NX, syscall возвращает IPC_BAD_POINTER; все 131 байт назначения и защитный хвост остаются неизменными. Это подтверждает предварительную проверку всего диапазона до первой записи.
  • После выдачи второй странице writable User/NX тот же payload успешно копируется через границу страниц; контрольный хвост после диапазона сохраняется.
  • Соседние проверки отказа read-only назначения в одной странице, штатного копирования, IPC reply и очистки ресурсов прошли в том же целевом профиле.

Команда:

$env:GUSEVA_PLATFORM_TEST_COUNTS='2'
$env:GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Гостевой код не менялся; QEMU не запускался.

Границы

Проверены syscall 55, payload 131 байт, две смежные PTE в последовательной native PE-фикстуре. Максимальная длина payload, гонка при изменении PTE, SMP и полный SAFE-04 не проверялись. SAFE-04 остаётся открытым.

Этап 155 — SAFE-04: PTE-проверки syscall 54

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: адресный критерий native-профиля принят.

Изменение и результат

В существующем двухкомпонентном профиле wait-any проверен 16-байтовый входной источник syscall 54:

  • Present/Supervisor-only PTE возвращает IPC_BAD_POINTER; scratch ядра, запись wait-any и запись ожидания компонента не меняются.
  • Read-only User/NX PTE проходит copy-in с действительным таймером как источником. При нулевом ожидании syscall возвращает IPC_EMPTY; запись ожидания очищена, таймер штатно отменён.
  • 16-байтовый дескриптор, пересекающий границу страниц, отвергается атомарно, если первая страница read-only User/NX, а вторая — Present/Supervisor-only. Scratch и записи ожидания остаются неизменными. После замены второй PTE на read-only User/NX тот же запрос проходит copy-in и возвращает IPC_EMPTY.
  • Существующая проверка unmapped-адреса syscall 54 и остальные проверки этого целевого профиля прошли.

Проверка:

$env:GUSEVA_PLATFORM_TEST_COUNTS='2'
$env:GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Гостевой исходный код не менялся; QEMU не запускался.

Границы

Проверены один компонент-ожидающий, один 16-байтовый таймерный источник и конкретные состояния PTE в последовательной native PE-фикстуре, включая диапазон через границу страниц. Готовность уже истёкшего таймера, IRQ/IPC через read-only вход, конкурентное изменение PTE, SMP и полный SAFE-04 не проверялись.

Этап 154 — SAFE-04: PTE-проверки syscall 18

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой native-сценарий принят.

Изменение и результат

Расширен целевой профиль syscall 18, который принимает из пользовательского адресного пространства пару «вид ресурса + новый лимит»:

  • Незамаппированный и Present/Supervisor-only входы возвращают IPC_BAD_POINTER; scratch ядра и действующий лимит не меняются.
  • Read-only User/NX вход принят. Лимит ресурса вида 2 изменился с 4 на 3.
  • После изменения новый незамаппированный вход снова отклонён, а лимит остался равен 3.
  • В этом же профиле повторно прошли проверки syscall 32, 33 и 51.

Проверка:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
$env:GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Гостевой исходный код не менялся; QEMU не запускался.

Границы

Проверен один компонент в последовательной native PE-фикстуре и один входной буфер 16 байт. Граничные значения всех видов лимитов, конкурентная смена PTE, SMP и полный SAFE-04 не проверялись.

Этап 153 — SAFE-04: PTE-проверки syscall 51

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой native-сценарий принят.

Изменение и результат

В адресный профиль поверхности добавлены проверки syscall 51 — показа кадра по описателю и динамическому буферу пикселей:

  • Незамаппированный и Present/Supervisor-only описатели возвращают IPC_BAD_POINTER; зарезервированная область scratch ядра не меняется.
  • Read-only User/NX описатель допустим для copy-in.
  • Незамаппированный и supervisor-only динамические буферы пикселей отклоняются до записи пикселей во framebuffer.
  • Read-only User/NX поверхность принимается и отображается.
  • Существующие проверки syscall 32 и 33 в этом же профиле также прошли.

Проверка:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
$env:GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY='1'
python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: 1 unittest PASS. Гостевой исходный код не менялся; QEMU не запускался.

Границы

Проверен один компонент в последовательной native PE-фикстуре, один кадр поверхности и конкретные PTE-состояния. Это не проверяет конкурентную смену PTE, SMP, все размеры/границы syscall 51 или полный SAFE-04. SAFE-04 остаётся в работе.

Этап 152 — SAFE-04: PTE-проверки прямого вывода поверхности

Прямая ссылка на отчёт

Состояние: адресный native-критерий syscall 32 принят; SAFE-04 остаётся в работе.

Результат

  • Syscall 32 отклоняет незамаппированный и Present/Supervisor-only 2080-байтовые буферы как IPC_BAD_POINTER; scratch ядра и framebuffer остаются неизменными.
  • Буфер с Present/User/NX без Writable принимается как вход: кадр успешно выводится в framebuffer, контрольный пиксель изменён.
  • Проверка выполняется в том же целевом сценарии, что и syscall 33; для syscall 33 сохранены проверки незамаппированного/supervisor отказа, атомарности и успешного read-only User/NX ввода.
  • Команда: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY='1'; python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v — 1 unittest PASS.

Границы

Проверены syscall 32/33 с одним буфером поверхности 32×16, framebuffer 320×200, один компонент и последовательная native PE-фикстура. QEMU-инъекция, PTE-гонка, SMP и полный SAFE-04 не проверялись.

Этап 151 — SAFE-04: PTE-проверка IPC payload

Прямая ссылка на отчёт

Состояние: адресный native-критерий переменного payload syscall 6 и чтения syscall 55 принят; SAFE-04 остаётся в работе.

Результат

  • Syscall 6 отправляет 131-байтовый payload со второй виртуальной страницы, отображённой Present/User/NX без Writable. Заголовок запроса остаётся на отдельной writable User/NX странице.
  • При PTE payload без User syscall возвращает IPC_BAD_POINTER; запрос не появляется, учёт страниц/ссылок отправителя и получателя не меняется. Заголовок уже скопирован во внутреннюю scratch-область до проверки следующей страницы — её неизменность здесь не заявляется.
  • При read-only User/NX payload запрос успешно создаётся. После перезаписи исходной страницы получатель получает исходные 131 байт через syscall 55; read-only output PTE отклоняется без изменения выходного буфера, writable PTE принимает payload и сохраняет 8 контрольных байт за его концом.
  • После завершения компонентов возвращённый payload-кадр снова доступен PMM; capability, ссылки и учёт очищены.
  • Целевая команда: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_IPC_ONLY='1'; python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v — 1 unittest PASS.

Границы

Проверен один последовательный native IPC payload длиной 131 байт, пересекающий границу страниц; сценарий использует один CPU. Максимальный payload, конкурентное изменение PTE, SMP и отказные PTE в QEMU не проверялись. Полный SAFE-04 остаётся открытым.

Этап 150 — SAFE-04: PTE-проверки IPC syscall 6–8

Прямая ссылка на отчёт

Состояние: адресная native-приёмка пользовательских заголовков IPC принята; SAFE-04 остаётся в работе.

Результат

  • Syscall 6 (отправка): незамаппированный, Present/Supervisor-only и read-only User/NX буферы отклоняются как IPC_BAD_POINTER. Таблица запросов, учёт ресурсов и kernel scratch остаются без изменений. Writable User/NX заголовок принимается, создаётся запрос и в буфер записывается поколенческий токен.
  • Syscall 7 (получение): при незамаппированном, supervisor-only или read-only User/NX output PTE вызов отклоняется до потребления запроса; запись запроса и 64-байтовый буфер получателя не меняются. После восстановления writable PTE тот же запрос успешно принимается.
  • Syscall 8 (ответ): незамаппированный и supervisor-only input PTE отклоняются без изменения запроса и scratch. Read-only User/NX заголовок допустим; ответ доставлен отправителю, который получил ожидаемые ID, значение, отправителя и флаг ответа.
  • Обмен завершён; capability и ссылки очищены, инварианты учёта ресурсов соблюдены.
  • Целевая команда: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_IPC_ONLY='1'; python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v — 1 unittest PASS.

Границы

Проверены только 64-байтовые заголовки и последовательный двухкомпонентный сценарий в нативной PE-фикстуре. Переменный IPC payload, изменение PTE между проверкой и копированием, SMP и отказные PTE в QEMU не проверялись. Полный SAFE-04 не закрыт.

Этап 149 — SAFE-04: PTE-проверки масштабируемой поверхности

Прямая ссылка на отчёт

Состояние: адресный native-критерий syscall 33 принят; SAFE-04 остаётся в работе.

Результат

  • Syscall 33 (scaled surface) возвращает IPC_BAD_POINTER для незамаппированного входного буфера и для PTE без User-бита.
  • В обоих отказных случаях 2080 байт ядрового scratch и весь framebuffer остаются неизменными.
  • Read-only Present/User/NX PTE принимается как входная поверхность. Вызов успешно копирует и рисует масштабированный кадр; проверены ненулевой пиксель и изменение framebuffer.
  • Один компонент, faults и остаточные ссылки — 0.
  • Приёмка: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_SCALED_SURFACE_ONLY='1'; python tests/kernel/test_platform.py PlatformTests.test_common_objects_and_devices -v — 1 unittest PASS.

Границы

Проверен нативный путь syscall 33 с поверхностью 32×16, масштабом 2 и framebuffer 320×200. Гостевой код не менялся; QEMU-инъекция для syscall 33, смена PTE во время копирования, SMP и полный SAFE-04 не проверены.

Этап 148 — SAFE-04: PTE-проверки аргументов запуска

Прямая ссылка на отчёт

Состояние: адресный native-критерий syscall 63 принят; SAFE-04 остаётся в работе.

Результат

  • Syscall 63 (p_spawn_with_arguments) возвращает IPC_BAD_POINTER для незамаппированного описателя и для PTE без User-бита.
  • При обоих отказах 80 байт ядрового scratch остаются неизменными: частичного copy-in нет.
  • Read-only Present/User/NX PTE принимается для входа. Описатель и отдельный массив аргументов копируются в ядровую память; затем намеренно некорректный пакет отклоняется.
  • Проверено, что дочерний компонент не создан, число активных компонентов не изменилось, faults и остаточные IPC-ссылки отсутствуют.
  • Приёмка: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_SPAWN_ARGS_ONLY='1'; python tests/kernel/test_platform.py PlatformTests.test_common_objects_and_devices -v — 1 unittest PASS.

Границы

Это нативная адресная проверка копирования описателя и аргументов. Штатный путь запуска syscall 63 ранее прошёл свежую QEMU-приёмку этапа 129; QEMU-инъекция отказного PTE для syscall 63 здесь не проводилась. Конкурентное изменение PTE, SMP и полный аудит SAFE-04 не проверены.

Этап 147 — SAFE-04: PTE-права для метрик планировщика

Прямая ссылка на отчёт

Состояние: целевой нативный критерий принят; SAFE-04 остаётся в работе.

Результат

  • Адресный сценарий вызывает syscall 61 с разрешением manage_scheduling; выдаются метрики обоих потоков целевого компонента.
  • При PTE Present/User/NX без Writable syscall возвращает IPC_BAD_POINTER. Весь 4096-байтовый кадр назначения побайтно совпадает со снимком до вызова — частичной записи нет.
  • После установки Writable на той же PTE syscall возвращает успех и записывает ожидаемые метрики (123, 7, 45, 3).
  • Компонент остаётся один, новые компоненты и запросы не появляются, faults — 0.
  • Целевая команда: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_SCHEDULER_METRICS_ONLY='1'; python tests/kernel/test_platform.py — 2 unittest PASS.

Границы

Native-проверка syscall 61 на текущем GSL-коде. QEMU-профиль для read-only PTE, гонка изменения PTE, SMP и полный аудит SAFE-04 не проверялись. Гостевой код не менялся.

Этап 146 — SAFE-04: права PTE описателя syscall 68

Прямая ссылка на отчёт

Состояние: целевой нативный сценарий принят; SAFE-04 остаётся в работе.

Результат

  • Исправлена тестовая фикстура: PTE записывается по смещению относительно фактически выровненного адреса таблицы, а не от начала выделенного буфера. Это существенно: прежняя фикстура этапа 135 могла проверять отсутствующую запись, а не установленную PTE без User-бита.
  • Повторный адресный сценарий подтверждает, что syscall 68 отклоняет начальный data-адрес с Present/NX, но без User-бита. Дочерний компонент и ресурсы не создаются.
  • Для PTE Present/User/NX без Writable общий copy-in успешно копирует 40-байтовый описатель. Чтобы отличить это от отказа на копировании, перед syscall scratch намеренно заполнен маркером; после вызова в нём обнаружены все пять полей изменённого описателя. Затем syscall ожидаемо отклоняет адрес самого пакета, поскольку он не отображён в динамическом диапазоне. Это отказ следующего этапа проверки, а не отказ чтения описателя.
  • Дочерних компонентов, выделений ресурсов и faults не появилось.
  • Адресная команда: $env:GUSEVA_PLATFORM_TEST_COUNTS='1'; $env:GUSEVA_PLATFORM_TEST_SAFE04_PACKAGE_DESCRIPTOR_ONLY='1'; python tests/kernel/test_platform.py — 2 unittest PASS.

Границы

Проверка нативная, на текущем GSL-коде ядра; пакет намеренно не отображён, поэтому успешный запуск через read-only описатель не заявляется. Свежая QEMU-инъекция, конкурентная смена PTE, SMP и полный SAFE-04 не проверялись. Этап 135 не следует считать независимым доказательством до исправления фикстуры; корректная повторная проверка описана здесь.

Этап 145 — SAFE-04: copy-in через границу страниц

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • Нативная PE-фикстура напрямую вызывает GSL helper диспетчер_копировать_из_пользователя на двух смежных пользовательских страницах с Present/User/NX, без Writable.
  • Проверены длины 9–15 байт: начало за 8 байт до границы страниц; хвост 1–7 байт копируется точно, остаток последнего слова в scratch обнуляется.
  • Когда вторая страница не отображена, helper отказывает до записи в scratch; 16 байт scratch сравниваются до и после вызова.
  • python tests/kernel/test_process_policy.py — 2 unittest PASS; прежние проверки syscall 17/37/45/47, cross-page отказов/успехов и 3 840 детерминированных SAFE-05 случаев сохранены.
  • Гостевой код не менялся; QEMU не запускался.

Границы

Проверен общий copy-in helper напрямую, не каждый syscall-потребитель. Конкурентное изменение PTE, SMP и полный аудит указателей остаются незавершёнными; SAFE-04 открыт.

Этап 144 — SAFE-04: отказные снимки через границу страниц

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • Для syscall 17, 37, 45 и 47 проверен буфер снимка, начинающийся за 8 байт до границы двух страниц.
  • Первая страница имела Present/User/NX/Writable, вторая — Present/User/NX без Writable. Все четыре syscall вернули IPC_BAD_POINTER.
  • До и после каждого отказа сравнивались полные 4096-байтовые кадры обеих страниц: частичной записи не было. Для syscall 37 первая страница и часть второй дополнительно использовались как читаемый входной курсор.
  • Последующий writable-вариант тех же четырёх syscall завершился успешно; проверены размеры, заголовки и guard-байты.
  • python tests/kernel/test_process_policy.py — 2 unittest PASS; гостевой код не менялся, QEMU не запускался.

Границы

Приёмка выполнена в native PE-фикстуре с двумя смежными страницами. Конкурентная смена PTE, SMP и полный аудит остальных публичных указателей не проверены. SAFE-04 остаётся открытым.

Этап 143 — SAFE-04: интеграционные снимки через границу страниц

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • В PE-фикстуре выходной диапазон начинается за 8 байт до границы страниц; обе страницы отображены как User/Present/NX/Writable.
  • Syscall 17, 37, 45 и 47 успешно записали снимки длиной 160, 448, 64 и 32 байта. Для каждого проверены длина результата, версия и полный ID компонента в заголовке, неизменность байтов до и после назначения.
  • Syscall 37 дополнительно скопировал входной 64-байтовый курсор, пересекающий ту же границу, перед выдачей снимка.
  • python tests/kernel/test_process_policy.py — 2 unittest PASS; профиль также сохраняет короткие хвосты copy-out 1–7 байт и 3 840 детерминированных SAFE-05 случаев.
  • Гостевой код не изменялся; QEMU и полная матрица не запускались.

Границы

Проверена нативная PE-фикстура с двумя смежными отображениями и четырьмя snapshot syscall. Изменения PTE между проверкой и копированием, SMP и полный аудит пользовательских буферов не проверены. SAFE-04 остаётся открытым.

Этап 142 — SAFE-04: короткий хвост copy-out через границу страниц

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • Нативная фикстура вызывает общий GSL helper диспетчер_копировать_пользователю для длин 9–15 байт. Начало диапазона находится за 8 байт до конца первой страницы, поэтому хвост длиной 1–7 байт приходится на вторую страницу.
  • Для каждого случая проверены записанные байты, сохранность незапрошенной части последнего 8-байтового слова и неизменность остальной части второго кадра.
  • python tests/kernel/test_process_policy.py — 2 unittest PASS; сохранены 3 840 детерминированных SAFE-05 случаев и проверки syscall 17 на двух страницах.
  • Гостевой код не менялся; QEMU и полный набор не запускались.

Границы

Проверен прямой вызов внутреннего helper в нативной PE-фикстуре с двумя writable-отображениями. Это подтверждает обработку короткого хвоста, но не закрывает аудит всех указателей syscall, конкурентные изменения PTE или SMP. SAFE-04 остаётся открытым.

Этап 141 — SAFE-04: атомарность copy-out на границе страниц

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • Syscall 17 копирует снимок 160 байт из середины первой страницы через границу в следующую.
  • При writable первой и read-only второй странице вызов возвращает IPC_BAD_POINTER; оба физических кадра полностью остаются неизменными. Это подтверждает предварительную проверку всего выходного диапазона до записи.
  • При двух writable страницах syscall возвращает 160; версия и полный ID компонента корректны, байты перед диапазоном и после него остаются 0xA5.
  • Предыдущие четыре успеха и четыре read-only-отказа syscall 17/37/45/47, а также 3 840 детерминированных SAFE-05 случаев сохранены.
  • python tests/kernel/test_process_policy.py: 2 unittest PASS.

Границы

Проверен один двухстраничный native-сценарий syscall 17. Три и более страниц, смена PTE между проверкой и копированием, конкурентные потоки и QEMU этим этапом не приняты. Гостевой код не менялся, сборка ОС и QEMU не запускались. SAFE-04 остаётся открытым.

Этап 140 — SAFE-04: успешный copy-out в writable PTE

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • Та же пользовательская страница DATA_VA переключена с read-only PTE на Present/User/Writable/NX.
  • Syscall 17, 37, 45 и 47 успешно записали снимки длиной 160, 448, 64 и 32 байта; вернулись соответствующие длины.
  • Для каждого снимка проверены версия и полный ID компонента в заголовке. Байты кадра после объявленной длины остались заполнены контрольным значением 0xA5.
  • Сохранены четыре отказных read-only проверки этапа 139 и native fuzz-профиль SAFE-05 из 3 840 детерминированных случаев.
  • python tests/kernel/test_process_policy.py: 2 unittest PASS.

Границы

Проверен native-путь одного отображённого кадра и четырёх copy-out syscall. Частично пересекающиеся страницы, writable-страница после незамапленного хвоста, параллельное изменение PTE и QEMU этим этапом не приняты. Гостевой код не менялся, сборка ОС и QEMU не запускались. SAFE-04 остаётся открытым.

Этап 139 — SAFE-04: отказ copy-out на read-only PTE

Прямая ссылка на отчёт

Состояние: целевой native-критерий принят; SAFE-04 остаётся в работе.

Результат

  • В native-профиле создано отображение пользовательского VA DATA_VA на выровненный 4-КиБ кадр с флагами Present, User и NX, без Writable.
  • Syscall 17, 37, 45 и 47 вызваны для собственного компонента с форматами снимков 160, 448, 64 и 32 байта. Каждый отказал с IPC_BAD_POINTER.
  • Перед каждым вызовом и после него сравнён весь кадр назначения: ядро не записало ни одного байта через read-only PTE.
  • python tests/kernel/test_process_policy.py завершился успешно: 2 unittest PASS. Прежний профиль из 3 840 детерминированных случаев сохранён.

Границы

Проверен отказ четырёх syscall copy-out на одном read-only отображении в native-сборке. Успешная запись в writable PTE, частично пересекающиеся отображения, конкурентное изменение PTE и QEMU этим этапом не приняты. Гостевой код не менялся, сборка ОС и QEMU не запускались. SAFE-04 остаётся открытым.

Этап 138 — SAFE-05: fuzz-граничные проверки графических syscall

Прямая ссылка на отчёт

Состояние: целевой native-профиль принят; SAFE-05 и SAFE-04 остаются в работе.

Результат

  • Профиль этапа 137 расширен ещё на 768 детерминированных вызовов: по 256 для syscall 32, 33 и 51.
  • Фикстура создаёт зарегистрированный компонент с полномочием display_output, но без отображённых пользовательских PTE. Для syscall 51 также задаётся корректный указатель на область данных компонента, чтобы вызов дошёл до проверки буфера.
  • Для граничных и псевдослучайных адресов каждый вызов обязан вернуть IPC_BAD_POINTER; полная 64-КиБ арена ядра сравнивается до и после вызова.
  • Итоговый профиль python tests/kernel/test_process_policy.py: 2 unittest PASS; 3 840 детерминированных проверок по четырём syscall и двум парсерам, плюс проверки создания/отката/очистки процесса.

Границы

Проверен только отказ на незамапленных PTE. Успешные графические буферы, read-only отображения, конкурентная смена PTE, остальные публичные syscall и QEMU этим этапом не приняты. Изменений гостевого кода нет, сборка ОС не запускалась. SAFE-05 и SAFE-04 остаются открыты.

Этап 137 — SAFE-05: воспроизводимые мутации GUP1

Прямая ссылка на отчёт

Состояние: целевой профиль принят; SAFE-05 в целом остаётся в работе.

Результат

  • В native-приёмку добавлен детерминированный профиль из 1 024 мутаций GUP1 v1/v2/v3, 1 024 мутаций загрузочного манифеста и 1 024 вызовов syscall 18 от зарегистрированного компонента без полномочий.
  • Мутации парсеров GSL сравниваются с независимой host-проверкой формата. Для syscall 18 проверяются случайные и граничные значения kind/адреса при пустой PTE-карте: ожидается IPC_BAD_POINTER, вся арена ядра остаётся неизменной.
  • Проверяются короткие и превышающие формат длины. Буферы фикстур выделяются не меньше заявленной длины, чтобы тест не создавал собственное чтение за границей.
  • Короткий манифест выявил дефект порядка проверок: GSL читал заголовок до требования минимальных 32 байт. Парсер теперь отклоняет короткий ввод до чтения полей.
  • Исправлен состав prelude тестовой сборки: добавлен service_routes.gsl, обязательный для актуального platform_core.gsl.
  • Команда python tests/kernel/test_process_policy.py завершилась успешно: 2 unittest, 3 072 детерминированных fuzz-вызова и проверки создания, отката и очистки процесса.

Границы

Это воспроизводимый native-профиль двух парсеров и одного отказа syscall на неотображённом пользовательском адресе, а не длительный случайный прогон и не fuzz всей ОС. QEMU не запускался. Действительные отображения, повреждённые таблицы страниц, синхронизация, длительное fuzz-нагружение и измерение покрытия не проверялись. SAFE-05 остаётся открытым.

Этап 136 — SAFE-04: повторная адресная проверка IPC и снимков

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Состояние: целевой native-профиль на двух компонентах пройден; SAFE-04 остаётся в работе.

Исправление проверки

Профиль SAFE04_WAITANY_ONLY ранее останавливался до проверки p_send: тест ожидал IPC_BAD_POINTER для syscall 54 с адресом вне разрешённого ABI-буфера. Реальный ответ ядра — IPC_BAD_MESSAGE, поскольку такой адрес не является допустимым буфером этого вызова. Ожидание проверки приведено к действующему ABI-коду; механизм ядра не менялся.

Приёмка

$env:GUSEVA_PLATFORM_TEST_COUNTS='2'
$env:GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY='1'
python tests/kernel/test_platform.py

Результат: 2 unittest — PASS. В адресном профиле участвовали два разных компонента. Проверены отказ и штатное копирование для wait-any, отказы read-only PTE и успешный copy-out для снимков памяти/ресурсов, затем IPC send/receive/reply с отдельными PTE отправителя и получателя. Профиль завершился PASS без остаточных запросов, полномочий, device leases, ссылок на объекты или нарушений инвариантов.

Границы

Это native-приёмка существующего SAFE-04 механизма и исправление ложного ожидания теста. Свежая QEMU-сборка именно этого профиля не выполнялась; этап не проверяет конкурентное изменение PTE, SMP и все сочетания пользовательских буферов. SAFE-04 не закрыт.

Этап 135 — SAFE-04: отказ syscall 68 при PTE без доступа CPL3

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Состояние: целевой нативный сценарий пройден; SAFE-04 остаётся в работе.

Изменение

В tests/kernel/test_platform.py добавлен адресный профиль для syscall 68. Он вызывает системный вызов через p_syscall, передавая адрес описателя внутри допустимого начального диапазона данных компонента. Таблица страниц намеренно содержит PTE без бита User, поэтому адрес проходит проверку виртуального диапазона, но не является доступным CPL3 буфером.

Приёмка

Команда:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
$env:GUSEVA_PLATFORM_TEST_SAFE04_PACKAGE_DESCRIPTOR_ONLY='1'
python tests/kernel/test_platform.py

Результат: PlatformTests.test_common_objects_and_devices и PlatformTests.test_irq04_timer_tick_saturation — PASS. Адресный профиль вывел:

SAFE-04 syscall 68 rejected descriptor without user PTE; no child or resource change PASS

Отклонённое описание не создало дочерний компонент: число занятых слотов осталось равным 1; нарушения инвариантов — 0. Проверка использовала один компонент и намеренно изменённую host-side таблицу PTE.

Границы

Это нативная проверка отказа syscall 68 для PTE без User. Она не является гостевой QEMU-инъекцией, не проверяет все виды недействительных PTE, конкурентное изменение отображения или SMP. Свежая QEMU-проверка этого отказа и полный аудит SAFE-04 не выполнялись.

Уточнение этапа 146

Переприёмка выявила дефект адресации фикстуры: запись PTE шла от начала сырого буфера, хотя таблица могла начинаться со смещения после выравнивания. Поэтому исходный PASS этапа 135 сам по себе не доказывает отказ именно для установленной PTE без User-бита. Исправленная фикстура и повторное подтверждение приведены в этапе 146. Исторический результат сохранён, но его доказательная сила уточнена.

Этап 134 — SAFE-04: копирование в кадр и IPC payload

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Состояние: целевая нативная проверка копирования в кадр и свежий QEMU ipc-wait-any пройдены. SAFE-04 остаётся в работе.

Результат

Уточнён native-сценарий прямого копирования CPL3-буфера в выделенный кадр ядра. В однослотовой фикстуре отправитель и получатель совпадали, а таблица страниц отправителя подменялась таблицей получателя. Поэтому прежнее сообщение «копировщик вернул успех, данные не появились» описывало неверно подготовленное отображение. При явном выборе PTE отправителя кадр-источник совпал с ожидаемой страницей; 131 байт скопировались без расхождений.

Успех самого копирования не закрывает весь прежний native-профиль: он по-прежнему останавливается позднее на отдельном вызове p_send. Для интеграционной проверки использован предназначенный для этой задачи QEMU-сценарий с тремя независимыми компонентами.

Проверки

  • Native GUSEVA_PLATFORM_TEST_COUNTS=1, GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1, GUSEVA_PLATFORM_TEST_FRAME_COPY_ONLY=1; целевой unittest PlatformTests.test_common_objects_and_devices — PASS: SAFE-04 direct user-frame copy PASS.
  • Native GUSEVA_PLATFORM_TEST_COUNTS=1, GUSEVA_PLATFORM_TEST_COPY_BOUNDS_ONLY=1; тот же целевой unittest — PASS: проверка полного диапазона, отказа без частичной записи, 131 байта и хвоста.
  • Свежая сборка python tools/host/build.py --out %TEMP%\guseva-safe04-ipc-wait-any-20261111 --platform-case ipc-wait-any — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Образ SHA-256: c64aa55eb91ad63e3908188713c41a8a784a25c3e01b98d164924228800b68e9.
  • QEMU-приёмка проверила три компонента, 8 двусторонних циклов, payload 131 байт, неизменяемый снимок, отказ неавторизованному читателю, недопустимый диапазон и несовпадение длины. Faults — 0; остаточные IPC-запросы, полномочия, device leases и ссылки — 0; возвращено 43 страницы.

Граница

Это подтверждает адресное копирование в кадр и текущий QEMU-путь IPC payload. Это не полный аудит всех syscall, read-only-отказов, гонок PTE или SMP. Более широкий native-профиль не считается пройденным; SAFE-04 не закрыт.

Этап 133 — SAFE-04: предварительная проверка полного диапазона copy-in

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Состояние: адресный профиль и свежая QEMU-приёмка surface пройдены. SAFE-04 остаётся в работе.

Изменение

Общий copy-in сначала проверяет весь округлённый до 8 байт диапазон пользовательского буфера по PTE, включая право чтения. Только после успешной проверки начинается копирование в scratch-область ядра. Поэтому незамапленный хвост диапазона не оставляет частично скопированные данные в scratch.

Обновлён адресный native-сценарий SAFE-04. Он проверяет отказ на границе отображения без изменения scratch, копирование 131 байта, нулевой частичный хвост последнего слова, сохранение следующих байтов, а также отклонение длин 3073 и u64::MAX без изменения scratch.

Проверки

  • python -m py_compile tests/kernel/test_platform.py — PASS.
  • GUSEVA_PLATFORM_TEST_COUNTS=1, GUSEVA_PLATFORM_TEST_COPY_BOUNDS_ONLY=1, целевой unittest PlatformTests.test_common_objects_and_devices — PASS; вывод native-сценария: SAFE-04 copy-in range and tail checks PASS.
  • Свежая сборка профиля surface через python tools/host/build.py --out %TEMP%\safe04-copyin-preflight-20261111 --platform-case surface — PASS.
  • QEMU 11.1.0, q35, TCG, 128 МиБ, 1 CPU — PASS. Образ SHA-256: e1b3d0f0ed4028decd9c657e3599a6e0ee83fb6a995f32bb3d1eedd72ee475b3.
  • В QEMU surface принят с результатом 0; выход за экран отклонён как IPC_DENIED; незамапленный дескриптор syscall 51 отклонён как IPC_BAD_POINTER. Faults, остаточные полномочия, IPC-запросы, device leases и ссылки на объекты — 0; освобождено 11 страниц.

Ограничения

Дополнительный более широкий native-профиль SAFE04_WAITANY_ONLY не прошёл: прямой копировщик вернул успех, но контрольные байты не появились в целевом кадре. Это отдельный дефект/расхождение проверки, требующее разбора; профиль не считается пройденным. Полный аудит публичных syscall с пользовательскими буферами, read-only-отказы всех путей, параллельное изменение PTE и SMP не проверены. SAFE-04 не закрыт.

Уточнение по результату native-профиля

Этап 134 установил, что отсутствие байтов было вызвано подготовкой однослотовой фикстуры: в слоте компонента находилась таблица PTE получателя, указывавшая на другую страницу. При явной привязке таблицы отправителя целевая проверка копирования 131 байта прошла. Более широкий профиль всё ещё не принят, поскольку после этого останавливается на отдельной проверке p_send; см. этап 134.

Этап 132 — SAFE-04: отказ syscall 51 на незамапленном дескрипторе

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: целевой сценарий принят в QEMU.

Изменение

  • CPL3-профиль surface дополнен вызовом syscall 51 с дескриптором в незамапленной странице.
  • Проверяется именно результат IPC_BAD_POINTER; успешный штатный вывод и отказ выхода за границы экрана остаются обязательными условиями.
  • Host-проверка сохраняет отдельное поле unmapped_descriptor_result и отклоняет сборку, если этот отказ не получен.

Проверка

  • Сборка: python tools/host/build.py --out work/safe04-syscall51-unmapped-20261111 --platform-case surface — успешно.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Обычный вывод 0, выход за экран IPC_DENIED, незамапленный дескриптор IPC_BAD_POINTER; CPL3 faults — 0; остаточных IPC, полномочий, device leases и object references — 0; возвращено 11 страниц.
  • SHA-256 образа: 060ffd90bc859bb893db948cb4f5020141bda65e3d6eae509754e58888955cd6.

Граница результата

Проверен отказ syscall 51 на незамапленном входном дескрипторе. Отказ на прочитанной, но неразрешённой PTE, изменение PTE конкурентом, SMP и остальные пути пользовательских буферов остаются вне этой приёмки. SAFE-04 не закрыт.

Этап 131 — SAFE-04: точные границы общих копировщиков

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: механизм обновлён; целевой QEMU-сценарий поверхности принят в указанной границе.

Изменение

  • Проверка пользовательского диапазона учитывает исходную длину и отклоняет её свыше 4096 байт до обхода диапазона. Переполнение длина + 7 не может превратить такой запрос в допустимый нулевой или малый диапазон.
  • Copy-in и copy-out scratch-области ядра ограничены 3072 байтами — размером области [62464, 65536). Общая PTE-проверка допускает диапазоны до 4096 байт, поэтому копировщики применяют более узкую собственную границу.
  • Copy-in обрабатывает только объявленные байты и обнуляет неиспользуемый хвост последнего внутреннего слова.
  • Copy-out сохраняет байты назначения за объявленной длиной последнего слова.
  • Копирование IPC payload в кадр обрабатывает только объявленную длину; неполное последнее слово дополняется нулями.

Проверка

  • Сборка профиля surface завершилась успешно: python tools/host/build.py --out work/safe04-buffer-boundary-20261111 --platform-case surface.
  • Свежая приёмка QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Syscall 51 представил частную поверхность (present_result=0), отказ выхода за экран сохранён; faults и остаточные объекты — 0.
  • Свежая приёмка профиля ipc-wait-any — PASS. Передан payload длиной 131 байт; снимок неизменяем, чужой читатель и выход за пределы отвергнуты; восемь повторов отвергнуты, faults и остаточные IPC/полномочия/device leases/ссылки — 0.
  • SHA-256 образа: cb551304fe440de929f5b7e9f9781b4a4ccd070bb7af91c0bf33f9fdcc740746.
  • SHA-256 образа ipc-wait-any: 35b1fe1aefe4ca38d66bf0d3eb0e6f9f747fbe237d2b1f376dc2fdfe8f79dbcf.

Граница результата

Профили surface и ipc-wait-any подтверждают затронутые пути вывода поверхности и передачи payload переменной длины, но не передают произвольную длину в scratch copy-out. Переполненные/сверхлимитные длины и сохранение хвоста частичного слова не имеют отдельного исполняемого негативного сценария. SAFE-04 остаётся открытым до аудита остальных путей пользовательских буферов и адресных отказов; конкурентное изменение PTE и SMP не проверялись.

Этап 130 — SAFE-04: PTE-проверка буфера графической поверхности

Прямая ссылка на отчёт

Статус: syscall 51 принят в одном целевом профиле QEMU; SAFE-04 остаётся в работе.

Изменение

Syscall 51 получает дескриптор поверхности из пользовательского адресного пространства. Ядро проверяет диапазон дескриптора, копирует его через общий PTE copy-in в зарезервированную память ядра и затем проверяет PTE каждой страницы пиксельного буфера до чтения. Буфер должен принадлежать вызывающему CPL3-компоненту и иметь пользовательское чтение. Вывод по-прежнему ограничен размерами экрана и полномочием display_output.

Гостевой сценарий surface теперь создаёт буфер в лениво отображаемой пользовательской странице, заполняет 32×16 пикселей, передаёт отдельный дескриптор syscall 51 и проверяет успешный результат. Сценарий также сохраняет проверки прежнего syscall 32 и отказа координат за экраном. При очистке компонент вернул 11 физических страниц: десять стартовых и одну динамически отображённую страницу поверхности.

В ходе целевой проверки обнаружено и исправлено смещение границы цикла выделения страниц в p_spawn: после исправления подготовка адресного пространства снова выполняется после завершения цикла выделения, а не внутри него.

Приёмка

  • Сборка: python tools/host/build.py --out work/safe04-syscall51-surface-accepted-20261111 --platform-case surface — PASS.
  • QEMU: python tools/host/qemu_acceptance.py --qemu <QEMU 11.1.0> --build work/safe04-syscall51-surface-accepted-20261111 --timeout 45 — PASS; q35/TCG, 128 МиБ, 1 CPU.
  • SHA-256 образа: e7cde67bd0951a4091ad6e8337ac070c4b5ec4f6a16bad0b6e5bb5646e03775f.
  • Результаты: syscall 51 — 0; syscall 32 commit — 0; выход за экран — IPC_DENIED; faults — 0; возвращено 11 страниц; остаточных IPC-запросов, полномочий, device leases и ссылок на объекты — 0.
  • Экранный снимок QEMU подтверждает пиксели поверхности в заданной области кадра. Машинный отчёт: platform-report.json, снимок: screen.png, сведения о сборке: build-report.json.

Границы

Принят только штатный syscall 51 в профиле surface. В этом профиле не проверялись специально поддельный/read-only PTE дескриптора, незамапленный источник пикселей, конкурентное изменение PTE и SMP. Остальные публичные syscall с пользовательскими буферами требуют дальнейшего аудита. Полный набор тестов не запускался. SAFE-04 не закрыт.

Этап 129 — SAFE-04: аргументы запуска через проверенные PTE

Прямая ссылка на отчёт

Статус: целевой путь принят в QEMU; SAFE-04 остаётся в работе.

Изменение

Syscall 63 запускает дочерний компонент по описателю и массиву аргументов из памяти вызывающего. Ранее после базовой проверки диапазона значения читались напрямую через пользовательский адрес. Теперь ядро копирует описатель и массив через общий PTE-проверяющий copy-in, разбирает только снимок в памяти ядра и переносит аргументы дочернему компоненту из этого снимка.

Проверяются право вызывающего на запуск, выравнивание и границы описателя, число аргументов (не более четырёх), диапазон и PTE каждого пользовательского буфера. Сохранены проверки пакета, поколенческой идентичности и политики полномочий дочернего компонента. Адрес массива 64-битных аргументов должен быть выровнен на 8 байт.

В целевом сценарии также обнаружено устаревшее ожидание драйвера: проверка числа страниц допускала только <14, хотя текущая сборка рабочего компонента законно использует больше страниц. Предел сценария расширен до <20; это синхронизация проверки с актуальным пакетом, а не изменение квот ядра.

Приёмка

  • Сборка: python tools/host/build.py --platform-case process-wait --out work/safe04-process-args-20261111 — PASS.
  • QEMU-приёмка: python tools/host/qemu_acceptance.py --build work/safe04-process-args-20261111 --qemu <QEMU 11.1.0> --firmware-dir <EDK2> --timeout 60 --ram 128 — PASS; q35/TCG, 128 МиБ, 1 CPU.
  • SHA-256 образа: 55b6f4637a72ae69b3d56b7e25dc7a169017b450724ff6d175cf6c74faaeb02e.
  • process-wait подтвердил успешный запуск с аргументами, блокирующее ожидание и код завершения 7331, тайм-аут, отказ от устаревшего поколения и самонаблюдения, отказ непривилегированному вызывающему и очистку после отмены ожидающего компонента.
  • Создано 5 дочерних запусков; возвращено 70 страниц; faults — 0; очистка подтверждена; остаточных IPC-запросов, полномочий, device leases и ссылок на объекты — 0.
  • Отчёты: сборка, загрузка, компоненты.

Границы

Принят штатный путь syscall 63 в одном сценарии QEMU. Отдельный QEMU-ввод с незамапленным или read-only PTE именно для описателя/массива syscall 63 не выполнялся. Конкурентное изменение PTE и SMP не проверялись. Полный набор тестов не запускался. SAFE-04 не закрыт.

Этап 128 — SAFE-04: PTE-копирование описателя пакета

Прямая ссылка на отчёт

Статус: адресный механизм принят в целевом QEMU; SAFE-04 остаётся в работе.

Изменение

Syscall 68 раньше проверял диапазон описателя GUP1 по ожидаемому адресу начальной области данных, затем разбирал поля из сохранённой страницы данных компонента. Теперь после проверки выравнивания и диапазона ядро выполняет общий copy-in на 40 байт. Общий механизм проверяет фактические PTE пользовательского адреса, включая доступ пользователя, NX и полноту диапазона; дальнейшая проверка полей читает только копию в памяти ядра.

Проверка самого пакета сохраняется: его диапазон должен принадлежать отображённым страницам вызывающего компонента, формат GUP1 проверяется до создания дочернего компонента, а пакет не может назначать ему полномочия.

Приёмка

  • Свежая сборка приём-пакета-supervisor — PASS. SHA-256 образа: 30dd103a6defff86c6ee594e802ee0167aeb71cb467bd3c86438c48c283b4ad3.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Через ограниченные IPC-порции передан GUP1 v3 размером 13 312 байт; супервизор успешно вызвал syscall 68, дочерний CPL3-компонент 65539 завершился с кодом 7301 без перезапуска ядра.
  • Faults — 0; возвращено 47 страниц; остаточные IPC-запросы, полномочия, device leases и ссылки на объекты — 0. Ресурсная очистка принята.
  • Отчёты: QEMU, платформа, сборка.

Границы

Профиль доказывает штатный путь копирования описателя и запуска пакета. Отдельная инъекция незамапленного или read-only адреса именно в аргумент-описатель syscall 68 не выполнялась. Конкурентное изменение PTE и SMP не проверялись. SAFE-04 не закрыт.

Этап 127 — SAFE-04: проверка пользовательского запроса лимита

Прямая ссылка на отчёт

Статус: целевой сценарий syscall 18 принят в QEMU. SAFE-04 остаётся в работе.

Изменение

Добавлен отдельный профиль resource-limit, использующий общий CPL3-компонент platform_worker. Ему выдано только полномочие manage_resources. Компонент меняет лимит ресурса вида 2 на 3 через syscall 18, читает снимок через syscall 17 и проверяет версию и полный ID цели. Затем он передаёт syscall 18 начало незамапленного адресного диапазона, ожидает IPC_BAD_POINTER и повторно читает снимок, чтобы проверить, что отказ не изменил лимит.

Проверка результата включена в отчёт platform_check.py. Для специального профиля убрано несвязанное ожидание числа оставшихся страниц; остальные общие проверки завершения и очистки сохранены.

Приёмка

  • python -m py_compile tools/host/build_impl.py tools/host/platform_check.py — PASS.
  • Сборка python tools/host/build.py --platform-case resource-limit --out work/safe04-resource-limit-20261111c — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Полный образ SHA-256: be4a8e7461364d2c1400799ed6d01b3dec133ccb1c7a8c9339ff1f5c13808ef9.
  • syscall 18: изменение лимита принято; syscall 17 дважды подтвердил версию 2, ID компонента 65537 и итоговый лимит 3.
  • Незамапленный вход syscall 18 вернул IPC_BAD_POINTER; лимит после отказа остался 3; CPL3 faults — 0.
  • Один компонент завершён с пятью шагами прогресса; возвращено 14 страниц; остаточные IPC-запросы, полномочия, device leases и ссылки — 0.
  • Отчёты: сводка QEMU, сводка компонента.

Граница

Подтверждена одна CPL3-проверка успешного изменения лимита и отказа на незамапленном адресе syscall 18. Это не закрывает аудит остальных пользовательских буферов, конкурирующих изменений PTE, SMP или полный SAFE-04.

Этап 126 — SAFE-04: копирование буферов учёта ресурсов

Прямая ссылка на отчёт

Статус: syscall 17 принят в сценарии workers; syscall 18 собран, но отдельная гостевая проверка ещё нужна. SAFE-04 остаётся в работе.

Изменение

Syscall 17 формирует снимок квот в выделенной области ядра и копирует 160 байт в адрес назначения через проверенные PTE. Это сохраняет возможность supervisor читать снимок другого компонента, но уже не записывает данные напрямую через p_data.

Syscall 18 сначала копирует 16-байтовый запрос лимита из CPL3 через PTE-проверку и только затем читает тип и значение лимита в памяти ядра. ABI и полномочия supervisor сохранены.

Компонент workers проверяет не только длину ответа syscall 17, но также версию снимка и полный ID целевого компонента в скопированном буфере.

Сборка и ограничение проверки

  • Свежая сборка профиля workers завершилась успешно. Образ SHA-256: ccb8c5f32bbd9fa2c60315b9ba9bfcb74f6e663b1220df727cae818418c07acd.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: PASS. Три компонента завершились; workers подтвердил syscall 17, длину 160 байт, версию снимка 2 и совпадение полного ID целевого компонента. CPL3 faults — 0, возвращено 39 страниц, остаточные IPC-запросы/capability/device lease/ссылки — 0. Отчёт загрузки, отчёт платформы.

Граница

Для syscall 17 подтверждён целевой путь снимка лимитов в workers. Syscall 18 прошёл сборку, но требует отдельного QEMU-сценария корректного изменения лимита и отказа по недопустимому/незаписанному пользовательскому диапазону. SAFE-04 не закрыт.

Этап 125 — SAFE-04: право на прямой вывод поверхности

Прямая ссылка на отчёт

Статус: адресная приёмка syscall 32 пройдена; SAFE-04 остаётся в работе.

Изменение

Syscall 32 теперь требует явное полномочие display_output до чтения описателя/пикселей и до записи в framebuffer. Проверка PTE и копирование буфера в память ядра из этапа 124 сохраняются. Отказ в полномочии возвращает IPC_DENIED без CPL3 fault.

Добавлен отдельный CPL3-сценарий surface-denied. Он запускает компонент без display_output, выполняет syscall 32 и сохраняет результат в собственной странице. Проверяющий код подтверждает одновременно отсутствие права в политике и результат отказа в пользовательской памяти. Разрешённый профиль surface выдаёт право тестовому компоненту и проверяет успешный показ и отказ выхода за границу GOP.

Приёмка

  • python -m py_compile tools/host/build_impl.py tools/host/platform_check.py — PASS.
  • Свежая сборка surface и QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Поверхность 32×16 выведена, выход за экран возвращает IPC_DENIED, CPL3 faults — 0, освобождено 10 страниц, остаточные capability/IPC/device lease/ссылки — 0. SHA-256 образа: 4f8101de487ed86903bd6749469dcd3d13e357285d45268aee4ad771201bea69. Отчёт загрузки, отчёт сценария.
  • Свежая сборка surface-denied и QEMU с теми же параметрами — PASS. display_output отсутствует, syscall 32 вернул IPC_DENIED, CPL3 faults — 0, освобождено 10 страниц, остаточные capability/IPC/device lease/ссылки — 0. SHA-256 образа: d0924d9f45c0062cf7e2aabce0e9650aa1e6fc02ce73e5db612ce8215f6ba5af. Отчёт загрузки, отчёт сценария.

Граница

Проверены разрешённый и запрещённый пути syscall 32 на одном CPU. Syscall 33 сохраняет собственную проверку display_output; этап не является аудитом всех публичных syscall, не проверяет SMP или конкурентное изменение отображений и не закрывает SAFE-04.

Этап 124 — SAFE-04: безопасное чтение графических буферов

Прямая ссылка на отчёт

Статус: адресное продвижение SAFE-04; пункт остаётся в работе.

Изменение

Syscall 32 и 33 до разбора описателя поверхности и чтения пикселей проверяют пользовательский диапазон и копируют 2080 байт через проверенные PTE в ограниченную scratch-область ядра. Разбор и отрисовка используют только копию ядра; отказ адреса или формата не даёт ядру читать указатель напрямую.

Исправлена проверка приёмки поверхности: ранее она брала адрес кадра выполнения из записи компонента, а не физический кадр пользовательских данных. Теперь данные захватываются по карте страниц компонента. Это изменение валидатора устранило ложный отказ и проверяет фактическую приватную страницу приложения.

Приёмка

  • python -m py_compile tools/host/platform_check.py — PASS.
  • Свежая сборка python tools/host/build.py --platform-case surface --out work/safe04-display-buffer-20261111 — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU, профиль surface — PASS. CPL3-приложение успешно передало поверхность 32×16, запрос за границей отклонён как IPC_DENIED, проверены сохранение исходных данных, отсутствие faults и очистка компонента: 10 страниц возвращено, остаточных IPC/полномочий/device leases/ссылок нет.
  • SHA-256 образа: ef68df4b86e2070b6ce34479300d7d1c4f658855950aea5379e3849dce300ecd. Отчёт загрузки, отчёт платформы.

Граница

Проверен только целевой профиль поверхности на одном CPU. Этот этап не подтверждает аудит всех syscall, конкурентные изменения PTE, SMP или закрытие SAFE-04. Прочие пользовательские адреса и структуры остаются в очереди аудита.

Этап 123 — SAFE-04: безопасная выдача метрик планировщика

Прямая ссылка на отчёт

Статус: адресное продвижение SAFE-04; пункт остаётся в работе.

Изменение

Syscall 61 (диспетчер_задержку_прочитать) теперь проверяет полный 32-байтовый выходной диапазон по writable PTE вызывающего компонента, собирает пару метрик для двух потоков во временной области ядра и выполняет copy-out через общий проверенный путь. Проверка полномочия manage_scheduling и полный поколенческий ID цели сохранены.

В нативную адресную приёмку добавлен вызов из авторизованного supervisor: значения максимального ожидания и числа выборов обоих потоков возвращаются в пользовательский буфер. Отказ вызова от компонента без права управления расписанием уже покрывается профилем scheduler-latency.

Приёмка

  • GUSEVA_PLATFORM_TEST_COUNTS=2, GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1, python tests/kernel/test_platform.py PlatformTests.test_common_objects_and_devices -v — PASS; целевая native-проверка завершилась за 7,675 с.
  • Свежая сборка: python tools/host/build.py --platform-case scheduler-latency --out work/safe04-sched-metrics-20261111 — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: профиль scheduler-latency — PASS. Метрики: максимальное ожидание 1/1 PIT-тик, выборы 27 982/7 145 у приоритетов 7/0; низкоприоритетный поток продвинулся; неавторизованное чтение запрещено. Три CPL3-компонента завершились, faults и остаточные IPC/полномочия/device leases/ссылки — 0; возвращено 32 страницы.
  • SHA-256 образа: a1721a1f076c3c98e92e4fb937be8d7866313381defcb5541124cb1c4cc0436e. Отчёт загрузки, отчёт планировщика.

Граница

Проверен только целевой профиль на одном CPU. Параллельное изменение отображений и SMP не проверялись. SAFE-04 остаётся открытым до аудита остальных syscall, принимающих пользовательские адреса или структуры.

Этап 122 — SAFE-04: безопасная выдача снимков учёта памяти

Прямая ссылка на отчёт

Статус: адресное продвижение SAFE-04; пункт остаётся в работе.

Изменение

Syscall 45 (снимок виртуального/физического учёта) и syscall 47 (счётчики нехватки кадров и возврата чистых страниц) больше не записывают результат через p_data. Каждый вызов проверяет полный выходной диапазон по PTE вызывающего компонента и его право записи, собирает структуру во временной области ядра и передаёт её через общий PTE copy-out. Проверка цели, полномочия просмотра и прежний формат ABI сохранены.

Приёмка

  • Адресный нативный PlatformTests.test_common_objects_and_devices проверил для обоих syscall: read-only PTE отклоняется до изменения 64- и 32-байтового буфера; writable PTE принимает корректный заголовок.
  • Свежая сборка python tools/host/build.py --platform-case workers --out work/safe04-accounting-20261111 — PASS.
  • Целевой QEMU workers — PASS на QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; SHA-256 образа 2e13db86109a9c7d9201f7b8e2bbb3ef355452a5efa4e0dd6e96cf7c2de2e597. Все три CPL3-компонента вызвали syscall 45 и 47 и проверили версии, идентификаторы цели и поля снимков; компоненты завершились, faults и остаточные IPC/полномочия/device leases/ссылки — 0, возвращено 39 страниц.
  • По коду и сценарию закреплена семантика syscall 47: обычный явный release не увеличивает счётчик возврата чистых страниц. В этой пробе счётчики давления и возврата ожидаемо равны нулю.
  • Отчёт загрузки и приёмки, отчёт компонентов.

Граница

Приёмка относится к одному CPU. SMP и параллельное изменение отображений не проверялись. Другие публичные syscall со структурами или буферами пользователя ещё требуют аудита; SAFE-04 не закрыт.

Этап 121 — SAFE-04: снимок памяти через проверенные PTE

Прямая ссылка на отчёт

Статус: адресное продвижение SAFE-04; пункт остаётся в работе.

Изменение

Syscall 37 (p_memory_snapshot) больше не пишет результат по адресу, полученному через прямой доступ к p_data. Перед формированием снимка ядро проверяет все 448 байт выходного диапазона по PTE вызывающего компонента: страницы должны быть пользовательскими, доступными для записи и допустимыми по NX. 64-байтовые входные поля читаются через общий PTE copy-in. Снимок собирается во временной области ядра, затем передаётся через общий PTE copy-out. Полномочие на просмотр и проверка целевого компонента сохранены.

Приёмка

  • Адресный нативный сценарий PlatformTests.test_common_objects_and_devices проверил syscall 37: read-only PTE отклоняется до изменения буфера; writable PTE принимает полный снимок; заголовок содержит версию и ID цели, количество строк не превышает ёмкость формата.
  • Свежая сборка python tools/host/build.py --platform-case workers --out work/safe04-snapshot-20261111 — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; целевой профиль workers — PASS на образе SHA-256 da5aaa4281586820302aa1752b6456abf0917b4368ad3ca6c43cc5306407ed46. Профиль вызывает syscall 37 для снимка памяти каждого worker-компонента и проверяет результат и освобождение страницы; три компонента завершились, faults и остаточные IPC/полномочия/device leases/ссылки — 0, возвращено 39 страниц.
  • Отчёт загрузки и приёмки, отчёт компонентов.

Граница

Проверена целевая конфигурация с одним CPU. Одновременное изменение таблиц отображения с другого CPU не проверялось. Другие публичные syscall со структурами или буферами пользователя всё ещё требуют аудита; SAFE-04 не закрыт.

Этап 120 — SAFE-04: безопасное чтение IPC-payload

Прямая ссылка на отчёт

Статус: частичное продвижение SAFE-04; SAFE-04 остаётся в работе.

Изменение

Syscall 55 больше не пишет в буфер компонента через прямой адрес p_data. Он проверяет фактические PTE всех страниц назначения, включая user/NX и право записи, затем копирует из ядрового кадра IPC в разрешённые пользовательские отображения. Допускаются начальные и динамические отображения, которые распознаёт общий PTE-проверяющий механизм. Длина payload может быть произвольной; байты после последнего неполного слова сохраняются.

Приёмка

  • Целевой нативный PlatformTests.test_common_objects_and_devices с GUSEVA_PLATFORM_TEST_COUNTS=2 и GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1 — PASS. Проверен syscall 55: read-only PTE отклонён до записи, writable PTE принимает 131 байт, защитный хвост после payload не меняется.
  • Свежая сборка python tools/host/build.py --platform-case ipc-wait-any --out work/safe04-ipc-read-20261111 — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; целевой ipc-wait-any — PASS. Профиль использовал syscall 55, подтвердил 131-байтовый неизменяемый снимок, отказ неавторизованному читателю, неверному диапазону и несовпадению длины. Восемь повторов отклонены; cleanup подтверждён, faults и остаточные IPC/полномочия/device leases/ссылки — 0; возвращено 40 страниц.
  • SHA-256 образа: 47584aca88f50e6d452301e058a6fe5b0d7c1149b937c068565d74257104469a.
  • Отчёт загрузки и приёмки, отчёт IPC.

Граница

Приёмка адресно подтверждает IPC send/receive/reply (syscall 6–8), wait-any (54) и чтение payload (55). Syscall отмены 53 не принимает пользовательский буфер. Другие публичные syscall с пользовательскими буферами и структурами ещё требуют проверки и перевода на общий copy-in/copy-out. Не проверены SMP и параллельное изменение отображений во время копирования. SAFE-04 остаётся незавершённым.

Этап 119 — SAFE-04: PTE-проверка IPC-буферов

Прямая ссылка на отчёт

Статус: частичное продвижение SAFE-04; SAFE-04 остаётся в работе.

Изменение

Проверка пользовательских буферов теперь учитывает реальные отображения PTE для IPC send, receive и reply. Для чтения требуются присутствующая пользовательская страница и NX; для записи дополнительно требуется разрешение записи. Диапазон проверяется целиком до копирования, в том числе когда буфер пересекает границу страниц. Передача payload копирует байты из пользовательских кадров в принадлежащий ядру кадр сообщения, а не сохраняет пользовательский указатель.

Проверка принимает произвольную длину в байтах, включая неполное последнее 8-байтовое слово. Для текущей реализации сохраняются пределы ABI: до 4032 байт IPC-payload и до 65536 байт для внутренней проверки диапазона. Временный буфер копирования остаётся общим и рассчитан на принятую конфигурацию с одним CPU и обработчиком syscall с IF=0.

Приёмка

  • Нативная адресная проверка PlatformTests.test_common_objects_and_devices с GUSEVA_PLATFORM_TEST_COUNTS=2 и GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1 — PASS. Проверены IPC copy-in/copy-out, разрешения записи и копирование payload с неполным хвостом.
  • В гостевом профиле проверен 131-байтовый payload. Также зафиксированы immutable_snapshot=true, отказ неавторизованному читателю, отклонение выхода за диапазон и несовпадения длины.
  • Свежая сборка python tools/host/build.py --platform-case ipc-wait-any --out work/safe04-ipc-pte-20261111 — PASS.
  • Целевая QEMU-приёмка QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Восемь повторных запросов отклонены, отмена и таймеры отработали, очистка подтверждена; faults, незавершённые IPC-запросы, полномочия, device leases и ссылки на объекты — 0; возвращено 40 страниц.
  • SHA-256 образа: c95c45c3ef8f259aa01b430d19b18daab8e749a756dd106044733f7b99d7ae6d.
  • Отчёт загрузки и приёмки, отчёт IPC.

Граница

SAFE-04 не завершён: проверка не подключена ко всем публичным syscall с пользовательскими буферами и структурами. Нативная проверка и профиль QEMU не доказывают безопасность всех ABI-входов, SMP и параллельного изменения отображений во время копирования. Следующий шаг — инвентаризировать оставшиеся syscall, переводить их на единые проверяемые операции копирования и адресно принимать каждый затронутый путь.

Этап 118 — SAFE-04: копирование списка ожидания через PTE

Прямая ссылка на отчёт

Статус: частичный шаг SAFE-04; SAFE-04 остаётся в работе.

Изменение

Для входного списка syscall 54 (wait-any) добавлен путь копирования из пользовательского адресного пространства в зарезервированную область ядра. Для каждого слова ядро получает физический кадр по фактической таблице отображения компонента и требует одновременно present, user и NX. Неотображённый адрес, кодовая страница и адрес вне областей данных/динамических отображений не принимаются.

Объём копирования ограничен 3072 байтами; wait-any копирует не более четырёх 16-байтовых описателей. Буфер и длина должны быть выровнены на 8 байт. Общая временная область находится в конце 64-КиБ состояния ядра (62464..65535). В текущем контракте один CPU, а IDT использует interrupt gate (0x8E): IF очищается до выполнения обработчика syscall. Это не является SMP-safe реализацией.

Приёмка

  • Нативный целевой тест PlatformTests.test_common_objects_and_devices, GUSEVA_PLATFORM_TEST_COUNTS=2, GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY=1 — PASS.
  • Проверено: немаппированный начальный адрес отклонён; список, пересекающий границу двух пользовательских PTE, успешно скопирован и затем отклонён по намеренно неверному типу источника; запись ожидания, ссылки и ресурсы не остаются.
  • Свежая сборка: python tools/host/build.py --platform-case ipc-wait-any --out work/safe04-pte-copy-20261111 — PASS. SHA-256 образа 491a88155c20edd9e66cd51002e9c71299870eac27def69bc4b950e4df3a1421.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: профиль ipc-wait-any — PASS; обычные IPC, ответы, отмена, таймеры и очистка подтверждены. Отчёт запуска, сценарий IPC.

Граница

Этот путь включён только для входного списка syscall 54. Другие syscall с буферами пока не используют общий copy-in/copy-out, поэтому этап не доказывает полноту SAFE-04. Нативный тест напрямую проверил границу двух отображённых страниц; QEMU подтвердил штатный путь на свежем образе, но не внедрял вредоносный указатель в гостевую ОС. Не проверялись SMP, параллельное исполнение двух потоков во время копирования, полный диапазон прав на запись и все структуры syscall.

Этап 117 — SAFE-04: границы пользовательских буферов syscall

Прямая ссылка на отчёт

Статус: частичный шаг SAFE-04; сам SAFE-04 остаётся в работе.

Что изменено

Добавлена общая GSL-проверка диапазон_буфера_данных_пользователя. Она сначала проверяет допустимый пользовательский диапазон, затем требует, чтобы буфер целиком помещался в начальной 4-КиБ странице данных, на которую указывает p_data.

Проверка подключена ко всем существующим syscall-путям, которые читают/записывают пользовательские буферы через этот физический кадр: IPC, ожидание источников, снимки ресурсов и памяти, дисплейные описатели/поверхности, управление службами и диагностика.

Причина исправления: прежний user_range разрешал любой адрес в пользовательском окне, но последующий доступ использовал физический кадр начальной страницы. Адрес за этой страницей мог пройти проверку и вызвать фатальный bounds guard ядра вместо обычного отказа syscall.

Приёмка

  • Нативный целевой сценарий:

    $env:GUSEVA_PLATFORM_TEST_COUNTS='2'
    $env:GUSEVA_PLATFORM_TEST_SAFE04_WAITANY_ONLY='1'
    python tests/kernel/test_platform.py PlatformTests.test_common_objects_and_devices -v
    

    PASS: syscall 54 отклоняет указатель за первой страницей и диапазон, пересекающий её конец; неверный тип источника в допустимом буфере также отклонён; запись ожидания, ссылки и ресурсы очищены.

  • Свежая сборка:

    python tools/host/build.py --platform-case ipc-wait-any --out work/safe04-user-buffer-20261111
    

    PASS; SHA-256 образа e3c672838c4b69d3b5767758954289727c8584628b33f68d733f9c592e38adb7.

  • Свежая QEMU-проверка образа: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; профиль ipc-wait-any завершился PASS, CPU остановлен штатно, остаточные IPC-запросы, полномочия, device leases и ссылки — 0.

    Машинный отчёт: boot-report.json.

Ограничения

  • Это не полный приёмочный прогон SAFE-04: номера, все размеры, поколения, переполнения и каждый syscall отдельно ещё не проверены.
  • Ядро пока не копирует пользовательские буферы через таблицы страниц. Буферы в дополнительных отображённых страницах отклоняются; для поддержки таких буферов нужен отдельный безопасный механизм перевода/копирования.
  • Отрицательная проверка адресов выполнена нативно; QEMU проверил свежую сборку и обычный IPC/таймерный путь, но не вызывал намеренно повреждённый указатель.
  • SMP, длительный стресс и полный набор тестов не запускались.

Этап 116 — IRQ-07: переходы ожидания и прерываний

Прямая ссылка на отчёт

Статус: принят для одноядерной границы.

Что изменено

В p_wait_any_ready источник с типом 0 теперь считается отключённым элементом списка. Раньше отмена таймера очищала соответствующий элемент, после чего повторная проверка принимала этот пустой слот за IPC_BAD_MESSAGE и завершала весь wait-any, даже когда оставался действительный источник IRQ.

В tests/kernel/test_platform.py добавлен отдельный целевой сценарий IRQ-07, который не проходит через длинные IPC-петли общего сценария.

Приёмка

  • Нативный GSL-сценарий: два компонента; событие IRQ уже ожидает до постановки wait-any — возвращается правильный индекс без сна.
  • Созданный таймер отменён, пока компонент ожидает таймер или IRQ. Список сохраняет ожидание по IRQ; последующий IRQ завершает его с индексом 2.
  • Повторный вызов завершения после пробуждения не меняет результат и не снимает ссылку повторно.
  • Завершение компонента во время ожидания очищает записи ожидания и ссылки до возврата слота; старый ID не действует на новое поколение.
  • Команда нативной проверки: $env:GUSEVA_PLATFORM_TEST_COUNTS='2'; $env:GUSEVA_PLATFORM_TEST_IRQ07_ONLY='1'; python tests/kernel/test_platform.py PlatformTests.test_common_objects_and_devices -v — PASS.
  • Свежая сборка python tools/host/build.py --platform-case ipc-wait-any --out work/irq07-wait-cancel-20261111 — PASS.
  • Свежий QEMU boot-тест python tools/host/test_boot.py --build work/irq07-wait-cancel-20261111 --qemu <QEMU 11.1.0> --firmware-dir <EDK2> --timeout 45 --ram 128 — PASS. QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; образ SHA-256 50244709b9eef6261b6830b01cfd61d76fbdfc08f60f0cd05471581b6f1e3776.

Машинный отчёт: boot-report.json; полный журнал: boot.log.

Границы результата

Приёмка подтверждает упорядоченные переходы для текущего одноядерного ядра. Она не является проверкой реального параллельного исполнения нескольких CPU, SMP-блокировок, случайного стресса или длительной нагрузки; это область IRQ-08 и последующих испытаний.

Этап 115 — IRQ-06: сериализация ядровых входов на одном CPU

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: принят для целевой конфигурации KERNEL 1.0 — x86-64, 1 CPU
Задача: исключить параллельное изменение общих структур ядра обработчиками IRQ и системных вызовов в одноядерной конфигурации.

Решение

Для одного CPU отдельный spinlock не нужен: ядровой обработчик не может выполняться одновременно с другим обработчиком или syscall на том же процессоре. IDT использует interrupt gates, которые очищают IF на входе; маскируемые прерывания остаются выключенными до iretq. Все пути системных вызовов, PIT и планировщика используют этот режим входа.

Явно названы атрибуты шлюзов в генераторе IDT: INTERRUPT_GATE_KERNEL = 0x8E, INTERRUPT_GATE_USER = 0xEE. Второй атрибут оставляет syscall доступным CPL3, сохраняя тип interrupt gate. В idle применяется sti; hlt: архитектурная пара позволяет принять ожидающее прерывание, не оставляя окна между проверкой готовности и остановкой CPU.

Это правило относится только к одному CPU. NMI и фатальные исключения идут в аварийный путь, который останавливает CPU; они не продолжают параллельно менять обычные структуры ядра. При переходе к SMP понадобятся межъядерные блокировки/атомарные протоколы, отдельный планировщик по CPU и IRQ-08.

Проверка

Сборка целевого профиля ipc-wait-any прошла. QEMU-приёмка свежего образа — PASS, QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

Подтверждено в отчёте:

  • Все 256 IDT-записей проверены при загрузке; kernel gates имеют атрибут 0x8E, syscall vector 128 — 0xEE.
  • 80 PIT ticks и 80 EOI, 17 переключений; проверены 40 idle ticks и 40 вытеснений занятого потока.
  • Событие разбудило ожидающий поток, отдельное ожидание завершилось по тайм-ауту; ожидающий поток завершился до отмены занятого.
  • Профиль ipc-wait-any: отмена и отклонение устаревшего таймерного дескриптора, сохранение дедлайна, IPC и восемь отказов повторного запроса.
  • Три компонента завершились; faults, незакрытые IPC-запросы, полномочия, device leases и ссылки — 0; возвращено 40 страниц.

Команды:

python -X utf8 tools/host/build.py --out work/irq06-up-serialization-20261111 --platform-case ipc-wait-any
python -X utf8 tools/host/test_boot.py --build work/irq06-up-serialization-20261111 --qemu <QEMU 11.1.0> --firmware-dir <EDK2 share> --timeout 40 --ram 128

SHA-256 образа: 810d829ccf2bc99db9d57b18d8652eb920f5795167b8df466edf8491b1b0772c
Машинный отчёт: boot-report.json
Отчёт компонентов: platform-report.json

Граница

Приёмка доказывает сериализацию на одном CPU в указанном QEMU-профиле. Она не реализует spinlock, не проверяет гонки между несколькими CPU и не закрывает IRQ-08. Синхронизация общего heap между потоками также остаётся отдельным ограничением.

Этап 114 — IRQ-05: одноразовые таймеры в ожидании событий

Прямая ссылка на отчёт

Дата: 11 ноября 2026 года
Статус: принят в целевой границе
Задача: добавить компонентный одноразовый таймер, отмену с защитой поколения и подключение таймера к wait-any.

Реализация

  • Syscall 69 создаёт одноразовый таймер на относительное число PIT-тиков. Syscall 70 отменяет его. Источник типа 2 в syscall 54 ожидает таймер вместе с уже поддерживаемыми IPC- и IRQ-источниками.
  • Дескриптор кодирует поколение и слот владельца. Чужой или устаревший дескриптор не может отменить новый таймер.
  • На компонент допускается один активный таймер. Он учитывается как объект ресурса. Отмена, срабатывание и завершение компонента снимают этот учёт.
  • Чтобы не расширять ядровую арену состояния размером 64 КиБ, метаданные таймера размещены в свободных полях записи ожидания компонента; поколение сохраняется при очистке ожидания.

Приёмка

Свежая сборка профиля ipc-wait-any прошла; затем свежий образ принят целевой проверкой QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

Команды:

python -X utf8 tools/host/build.py --out work/irq05-timer-generation-20261111 --platform-case ipc-wait-any
python -X utf8 tools/host/test_boot.py --qemu <QEMU 11.1.0> --firmware-dir <каталог прошивки EDK2> --build work/irq05-timer-generation-20261111 --timeout 40 --ram 128

Подтверждённые значения: первая отмена — дескриптор 65, результат 0; повторная отмена — IPC_STALE; следующий таймер — дескриптор 129. Ожидание этого таймера сначала завершилось IPC_TIMEOUT после 1 тика, затем повторное ожидание того же дескриптора вернуло индекс источника 1 после 20 тиков от контрольного снимка. Это подтверждает сохранение дедлайна при очистке списка ожидания. В том же сценарии сохранены восемь IPC-обменов и восемь отказов повторных запросов. Все три компонента завершились; faults, активные IPC-запросы, полномочия, device leases и ссылки — 0; возвращено 40 страниц.

SHA-256 образа: 810d829ccf2bc99db9d57b18d8652eb920f5795167b8df466edf8491b1b0772c
Машинный отчёт: platform-report.json

Границы

Приёмка подтверждает один активный таймер на компонент, его отмену, защиту поколения, сохранение дедлайна через завершённое ожидание и истечение в wait-any. Она не проверяет несколько одновременно активных таймеров на компонент, гонки отмены/срабатывания между потоками, отдельную стресс-нагрузку, SMP или календарное время.

Во время приёмки устранены две проблемы тестового пути: запись повторного IPC_STALE перенесена, чтобы не затирать контрольный ID владельца; затем обнаружено, что очистка списка ожидания сбрасывала дедлайн ещё активного таймера. Очистка теперь сохраняет и поколение, и дедлайн. Проверка специально делает короткое ожидание до срока таймера и затем ждёт тот же дескриптор до его исходного срока.

Этап 113 — сквозная переприёмка IPC-05/06/08

Прямая ссылка на отчёт

Статус: принят в указанной целевой границе QEMU, 11 ноября 2026 года.

Исправление сценария

  • Ответы GSL-компонента формируются через ipc_packet, который обнуляет поле билета. Получатель теперь возвращает исходный билет в поле 40 перед syscall 8; это применяется к первому ответу и ко всем восьми последующим обменам.
  • Первичный запрос получил дедлайн 1000 тиков, а ожидание syscall 54 разбито на повторы по 100 тиков (не более десяти попыток). Так профиль выдерживает проверку снимка IPC и сохраняет установленный предел тайм-аутов ABI.
  • Пакет отмены — только заголовок длиной 64 байта. Host-приёмка теперь учитывает одну страницу payload, выделенную для запроса с 131-байтовым хвостом; короткий пакет отмены дополнительную страницу не создаёт.
  • Проверки содержимого снимка, неверной длины и границы назначения выполняются до ответа, пока билет действителен. Host-проверка независимо сверяет все 131 байт, сохранение хвостовых байтов назначения, отказ постороннему читателю, результат ответа и отмены.

Приёмка

  • Сборка: python -X utf8 tools/host/build.py --out work/ipc05-cancel-final --platform-case ipc-wait-any — PASS.
  • Свежий образ прошёл целевой QEMU-профиль ipc-wait-any: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.
  • Syscall 54 выбрал второй источник; ответ 9201 содержит значение 72, флаг 1 и полный ID отправителя 65539.
  • Syscall 53 успешно отменил ещё не доставленный запрос. Получено уведомление 9202 с IPC_CANCELLED, флагом 2 и отправителем 65539.
  • Восемь двусторонних обменов продолжились после отмены; восемь повторов ID отклонены как IPC_DUPLICATE.
  • Три компонента завершились, возвращено 40 страниц; faults, IPC-запросы, полномочия, device leases и ссылки на объекты — 0.
  • SHA-256 образа: c1a7b9aeda08d78590f90bba1c3091e5621363f8de456407eec418b69f562d27.
  • Машинный отчёт: platform-report.json; QEMU-журнал: boot.log.

Границы

Это адресная интеграционная переприёмка IPC-05/06/08. Полный набор, SMP, нагрузка свыше восьми обменов, длительный soak и проверка на физическом компьютере не выполнялись. Ограничения IPC-05–08 из чек-листа остаются в силе.

Этап 112 — B-06: повторная приёмка IPC под нагрузкой планировщика

Прямая ссылка на отчёт

Статус: принята в целевой границе QEMU.

Исправление

После изменения контракта p_reply проверяет, что ответ содержит исходный выданный талон и исходный дедлайн. Тестовый supervisor формировал ответ через ipc_packet; этот помощник очищает поля талона и флагов. Supervisor не возвращал талон после формирования пакета, поэтому каждый ответ отклонялся, запросы истекали, а свежий повтор B-06 завершался ошибкой.

В platform_scheduler_latency.gsl после ipc_packet талон восстанавливается в поле 40 перед syscall 8. Окно обслуживания 300 тиков и ожидание ответа worker 100 тиков оставлены в исходных целевых границах. Контракт ядра не ослаблялся.

Приёмка

  • Сборка: python tools/host/build.py --out work/b06-ticket-fix --platform-case scheduler-latency — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; целевой scheduler-latency — PASS.
  • Два CPL3-компонента завершили по 8 IPC round-trip. Supervisor ответил на все 16 запросов; все 16 флагов ответа равны 1.
  • Приоритеты 7 и 0 сохранили прогресс; максимум наблюдаемого ожидания готового потока составил 1 PIT-тик у обоих профилей. Дополнительные потоки завершились, их стеки очищены.
  • Faults, активные IPC-запросы, полномочия, device leases и ссылки на объекты после очистки — 0; возвращено 32 страницы.
  • Образ work/b06-ticket-fix/guseva-p0.img, SHA-256: e3add185fc2301b89655de9a58f416b8a5884b0c21874226bec48e35512a7398.
  • Машинный отчёт: platform-report.json; QEMU-журнал: boot.log.

Границы

Это повторная целевая проверка B-06 на одной конфигурации QEMU. Полный набор, многочасовой soak, SMP, реальный компьютер и гарантии реального времени не проверялись. Исторический отчёт 106 не изменён.

Этап 111 — IRQ-04: PIT-тиковый счётчик доступен компонентам CPL3

Прямая ссылка на отчёт

Статус: принят для текущей однопроцессорной конфигурации x86-64 в QEMU.

Что добавлено

  • В общем проверочном компоненте platform_worker.gsl добавлена короткая гостевая проба: прочитать монотонный счётчик через syscall 5, уснуть на один тик через syscall 3 и снова прочитать счётчик.
  • Профиль workers запускает эту пробу для трёх независимых CPL3-компонентов. Значения и результат сна сохраняются в пользовательских данных.
  • platform_check.py проверяет, что у каждого компонента второй отсчёт больше первого, и заносит исходные числа в platform-report.json. Проверка не полагается на текст UART-журнала.

Приёмка

  • Свежая сборка: python tools/host/build.py --out work/irq04-worker-final --platform-case workers — PASS.
  • QEMU: python tools/host/test_boot.py --build work/irq04-worker-final --qemu <QEMU 11.1.0> --timeout 40 — PASS.
  • Платформа: QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU; UEFI завершил Boot Services, ядро выполнило PIT/PIC-планировщик.
  • Все три CPL3-компонента наблюдали syscall 5: 0 → 1 вокруг syscall 3(1); результат сна каждого равен 0.
  • Завершились три компонента; возвращено 39 страниц; faults, активные IPC-запросы, полномочия, device leases и ссылки на объекты — 0.
  • SHA-256 проверенного образа: 42f5b510aa019ae960a12f9b9d5f988e26b5ac545ee2c5637def2d353184cff7.
  • Машинный результат: platform-report.json; сводка загрузки и QEMU — boot-report.json.

Ограничения и найденная проблема

  • Это доказывает монотонное продвижение PIT-тиков и наблюдение значения через CPL3 ABI. Это не календарные часы, не проверка точности миллисекунд и не SMP-сценарий.
  • При дополнительном адресном повторе scheduler-latency на текущем дереве компонент 65538 завершился с ошибкой 227 во время IPC round-trip. Эта проверка не относится к критерию IRQ-04, но означает, что B-06 нужно повторно принять после выяснения изменения IPC. Исторический PASS этапа 106 не переписан и не используется как доказательство нового прогона.
  • Полная регрессия не запускалась.

Этап 110 — передача GUP1 супервизору через IPC

Прямая ссылка на отчёт

Состояние: целевой профиль QEMU принят. HUP-03 продвинут; COMP-07 остаётся открытым.

Цель

Проверить на работающем ядре передачу пакета от одного CPL3-компонента другому, последующий запуск проверенного GUP1 v3 и очистку ресурсов без перезапуска ядра.

Реализация

  • Добавлен CPL3-супервизор приёма пакетов. UART-драйвер отправляет ему объявление и порции данных как сообщения IPC с полезной нагрузкой.
  • Супервизор читает неизменяемый снимок IPC через syscall 55 в собственную разрешённую область данных, переносит порцию в выделенные страницы, собирает пакет и запускает его через syscall 68.
  • Супервизор ожидает полный поколенческий ID дочернего компонента syscall 62 и проверяет код выхода 7301.
  • Тестовый профиль выдаёт супервизору необходимые явные полномочия; права дочернего пакета остаются нулевыми.
  • Приёмщик проверяет различные форматы и таблицы страниц для исходных компонентов GUP1 v1/v2 и дочернего GUP1 v3. Диагностический отчёт больше не маркирует фактически исполненный дочерний пакет как «не запускался».

Приёмка

  • Сборка приём-пакета-supervisor: PASS, свежий x86-64 EFI образ SHA-256 58dbc069b2113843a58828346600d0076f62747eef25eaf6db6c3b5fef376def.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: PASS.
  • Через IPC передан пакет GUP1 v3 размером 13 312 байт. Запущен дочерний компонент ID 65539; он завершился с кодом 7301.
  • Три компонента завершены штатно. faults=0; остаточные полномочия, IPC-запросы, device leases и ссылки равны нулю; подтверждено возвращение 47 страниц.
  • Ядро продолжало работу всё время; число перезапусков равно 0.
  • Целевой запуск: python tools/host/build.py --out TEMP/hup03-supervisor --platform-case приём-пакета-supervisor, затем python tools/host/qemu_acceptance.py --qemu <QEMU 11.1.0> --firmware-dir <EDK2> --build TEMP/hup03-supervisor --timeout 60 --ram 128.

Границы

Пакет подаётся через UART тестового стенда, а не динамически из Dev Shell. Супервизор пока не выполняет подготовку READY и регистрацию новой версии под стабильным ключом. Не реализованы атомарное переключение новых запросов, drain активных запросов старого компонента, перенос состояния, восстановление предыдущей версии и rollback. Поэтому это не горячая замена и этап не закрывает COMP-07.

Этап 109 — запуск проверенного GUP1-пакета

Прямая ссылка на отчёт

Состояние: целевая приёмка пройдена в профиле QEMU приём-пакета; HUP-03 частично выполнен.

Изменение

Добавлен syscall 68 для запуска пакета GUP1, уже находящегося в пользовательской области вызывающего компонента. Перед созданием потомка ядро проверяет:

  • полномочие start_service;
  • нулевые резервные аргументы и флаги;
  • выровненный пользовательский дескриптор полного размера;
  • длину пакета в допустимом диапазоне и кратность 8;
  • единственный поток у вызывающего;
  • допустимые binding/alias;
  • наличие отображения каждого пакета-страницы в пространстве вызывающего;
  • формат GUP1 штатным механизмом загрузки.

Пакет не выбирает полномочия. Потомок запускается с нулевыми правами, а его поколенческий ID возвращается вызывающему. Источник копируется при создании потомка, поэтому последующее освобождение буфера UART не меняет образ уже запущенного компонента.

Тестовый пакет — отдельная CPL3-программа, завершающаяся кодом 7301. UART-приёмник формирует дескриптор, вызывает syscall 68, ожидает точный ID через syscall 62 и записывает UART:SPAWN:PASS только при ожидаемом коде выхода.

Приёмка

  • Сборка: python tools/host/build.py --platform-case приём-пакета --out work/hup03-launch — PASS.
  • QEMU: python tools/host/qemu_acceptance.py --qemu <QEMU 11.1.0> --firmware-dir <EDK2> --build work/hup03-launch --timeout 60 --ram 128 — PASS.
  • Конфигурация: q35, TCG, 128 МиБ, 1 CPU; образ SHA-256: 7b0f3e8a2b4db34a95de99d34f229d529840543a202b1a7baba354fb255326ee.
  • Приёмник передал пакет GUP1 v3 размером 13 312 байт; дочерний компонент завершился с кодом 7301. Проверены разрешения RX/RW-NX, границы кода/данных/стека и отсутствие остаточных IPC, полномочий, device leases и ссылок.
  • Ресурсная запись потомка: 10 выделенных / 10 возвращённых страниц; запись очищена. Ресурсная запись приёмника: 22 / 22.
  • Общий диагностический released pages равен 21. Он не равен сумме локальных счётчиков. Приёмка не трактует эти величины как одну метрику; смысл агрегатного расхождения требует отдельной сверки.

Границы результата

В этом профиле пакет запускает UART-приёмник напрямую. Нет отдельного supervisor, IPC-передачи пакета supervisor, запуска из интерактивного Dev Shell, READY, замены активного владельца, переключения маршрута, drain старых запросов и отката. Это не горячая замена и не закрывает COMP-07. Syscall 68 пока не включён в интерактивный сценарий.

В рамках последующих изменений syscall 68 должен использоваться supervisor после получения проверенного объекта пакета через ограниченный IPC. Передавать простую пару «адрес/длина» между компонентами нельзя без явного механизма совместного отображения или копирования; текущий вызов специально принимает только собственные отображённые страницы вызывающего.

Этап 108 — полномочие IPC через поколенческий маршрут

Прямая ссылка на отчёт

Статус: целевой сценарий принят; COMP-07/HUP-04 остаются открытыми.

Что создано

  • Добавлена выдача клиенту ограниченного полномочия отправки по стабильному ключу службы. Клиент не получает прямого полномочия на конкретное поколение; ядро разрешает текущего владельца маршрута при каждой отправке.
  • Проверено, что прежнее поколение получает запрос до фиксации нового, а после фиксации тот же клиентский дескриптор доставляет запрос новому поколению.
  • Ответы проверяются по билету конкретного IPC-запроса. Общая проверка запроса продолжает требовать нулевой билет; для ответов добавлена отдельная проверка ipc_reply_message_valid, принимающая только ожидаемый билет.
  • Исправлена причина отказа ответа: прежняя общая проверка отклоняла ненулевой билет, хотя именно его ядро выдаёт получателю для безопасного ответа.

Целевая приёмка

Сборка: python tools/host/build.py --out work/service-route-cap-ticket-final --platform-case service-route — PASS.

Приёмка: python tools/host/test_boot.py --qemu <QEMU 11.1.0> --firmware-dir <EDK2 share> --build work/service-route-cap-ticket-final --timeout 60 --ram 128 — PASS. QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Образ SHA-256: 485f846e7c0fdca9ecb7d15ca660cab72eaeeed7d4d9e40ce9f73b365328bad7.

Подтверждены: отправка по одному и тому же полномочию, получение 64-байтового запроса, полный ответ со значением 44 от поколения 65538 до фиксации и значением 45 от поколения 65539 после фиксации. Вернуто 39 страниц; faults, IPC-запросы, полномочия, device leases и ссылки на объекты очищены.

Границы

Это проверяет маршрутизацию IPC по активному поколению и проверку билета ответа. Отдельная попытка запуска legacy-профиля --legacy-runtime --ipc-case exchange не принята: ядро получило page fault в CPL0 после входа тестового процесса в CPL3, до диагностик IPC; этот прогон не подтверждает и не опровергает работу обмена в профиле этапа 108 и требует отдельного разбора. Dev Shell ещё не передаёт пакет в работающую ОС; нет запуска нового кода из переданных байтов, протокола READY/rollback, очереди drain и проверки конкурентных запросов на границе переключения. Этап не закрывает COMP-07/HUP-04 и не является горячей заменой пользовательского компонента.

Этап 107 — базовый реестр маршрутов служб

Прямая ссылка на отчёт

Статус: целевой сценарий принят; COMP-07 и горячая замена остаются в работе.

Что создано

  • Добавлен ограниченный реестр маршрутов по стабильному ключу службы.
  • Подготовка кандидата отделена от фиксации переключения. Фиксация сверяет ожидаемое поколение прежнего владельца и полный ID кандидата.
  • Поиск возвращает активного владельца. Неверный кандидат отклоняется, устаревшее сравнение не меняет маршрут.
  • При завершении владельца очищаются только связанные с ним активные или подготовленные записи. Завершение прежнего экземпляра после переключения не удаляет маршрут нового.
  • Добавлены русские имена GSL-действий и русские диагностические сообщения для этого механизма.

Целевая приёмка

Сборка: python tools/host/build.py --platform-case service-route --out work/service-route-fix-20261111-final — PASS.

Приёмка: python tools/host/test_boot.py --build work/service-route-fix-20261111-final --qemu <QEMU 11.1.0> --timeout 30 — PASS. QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Образ SHA-256: a8012d0e41877314e8f233a9777e778738c9a74d22c151ea32d3a34c76fa4245.

Сценарий проверил ключ 5001, прежнее поколение 65538 и кандидата 65539: до фиксации поиск возвращал старое поколение; неверный кандидат получил IPC_STALE; устаревшее сравнение — IPC_DUPLICATE; допустимая фиксация переключила поиск на 65539; завершение старого экземпляра сохранило новый маршрут; завершение нового удалило маршрут. Ядро подтвердило три запуска компонентов, возврат 39 страниц, ноль faults и нулевые остатки IPC-запросов, полномочий, device leases и ссылок на объекты.

Границы

Это проверка ядрового реестра маршрутов, не сквозная горячая замена. Передача пакета Dev Shell в уже работающую ОС, исполнение полученных байтов, READY, переключение реальных запросов приложения, drain старого экземпляра, конкурентный трафик и откат здесь не проверялись. Поэтому этап не закрывает COMP-07 и HUP-04 целиком; дальнейшая работа продолжается по плану обновления компонентов.

Этап 106 — B-06: совместная нагрузка планировщика, потоков и IPC

Прямая ссылка на отчёт

Статус: принят в ограниченной целевой границе QEMU.

Что изменено

  • Целевой профиль scheduler-latency запускает supervisor и два независимых CPL3-компонента. Supervisor задаёт приоритеты 7 и 0, обслуживает IPC-запросы и возвращает результат по исходному поколенческому талону.
  • Каждый worker создаёт один дополнительный поток. Основной поток выполняет восемь IPC request/reply обменов, проверяет отказ неавторизованного изменения приоритета и продолжает работу под нагрузкой; дополнительный поток выполняется независимо и завершает работу по сигналу/условию ожидания.
  • В ответе supervisor сохраняет дедлайн исходного запроса. Повторное вычисление дедлайна меняло поле протокола, которое p_reply сверяет с исходной записью, и приводило к ошибочному IPC-ответу.
  • Проверка сохраняет флаги всех восьми ответов на каждом worker; host-приёмка подтверждает 16 значений 1. При отказе сценария ядро сохраняет диагностический снимок и выводит значения флагов.

Приёмка

  • Сборка: python tools/host/build.py --platform-case scheduler-latency --out work/b06-integrated-load-20261111 — PASS.
  • QEMU: 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Запуск python tools/host/test_boot.py --build work/b06-integrated-load-20261111 --qemu <QEMU 11.1.0> --timeout 30 — PASS.
  • Длительность сценария: 600 PIT-тика на каждый worker; окно замера готовности планировщика — 300 тиков. Максимальное наблюдаемое ожидание приоритетов 7 и 0 — 1 и 1 тик; оба компонента получили тысячи запусков планировщика и продвинулись до завершения.
  • Два компонента создали по одному дополнительному потоку и завершили по восемь IPC-обменов; supervisor успешно ответил на все 16 запросов. Все ответные флаги — 1. Неавторизованная смена приоритета отклонена. Вторые потоки завершились, их стеки и таблицы отображения очищены.
  • Всего возвращено 32 физических страницы. Faults, активные IPC-запросы, полномочия, device leases и ссылки на объекты после очистки — 0.
  • Образ work/b06-integrated-load-20261111/guseva-p0.img, SHA-256: e554b814e06e4ad7a344edab072b9569dd41b199c6a5f1fb4b2526d312197980. EFI SHA-256: 0bd026172669c434d490d69c00fc0959ee73a2fb5285b7d977961b15e7ef470b.
  • Машинный отчёт: platform-report.json. QEMU-журнал: b06-qemu.log.

Границы

Приёмка ограничена одной конфигурацией QEMU и 600 PIT-тиками нагрузки; это не многочасовой soak, не SMP и не реальный компьютер. Нагрузка 6 000 тиков превышала заданный 60-секундный предел QEMU, поэтому она не включена в результат. Heap между потоками, общая синхронизация и гарантии реального времени не проверялись.

Этап 105 — B-05: увеличение предела поверхности до размера GOP

Прямая ссылка на отчёт

Статус: B-05 принят по целевому сценарию QEMU.

Изменение

Композитор больше не ограничивает ширину и высоту окна значениями 400×300. Верхняя граница теперь соответствует GOP 1280×800. Существующие проверки минимального размера, чётной ширины, переполнения координат и выхода окна за экран сохранены.

Полноэкранная поверхность 1280×800 занимает 4 096 000 байт, то есть ровно 1 000 страниц по 4 КиБ. Для адресной приёмки использована поверхность 1024×521: 2 134 016 байт, 521 страница — на 17 страниц больше прежнего предела.

Проверка

  • python tools/host/build.py --platform-case композитор --out work/b05-surface-522-pages — PASS.
  • Образ SHA-256: 4413dac7301716dd451e8e35da3ca1702853cd32fccb5a07f38a0633377bb98d.
  • Целевая приёмка через tools/host/test_boot.py, QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Проверены три завершившихся CPL3-компонента, отсутствие faults и остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • Проверка сцены подтвердила выделение 521 страницы, запись и чтение последнего пикселя, успешное закрытие окна, успешные вызовы возврата страниц и снятия виртуального резерва. Накопительный счётчик освобождённых страниц компонента-композитора — 666 при ожидаемых как минимум 663 страницах трёх поверхностей. В p_memory_release PTE обнуляется до возврата кадра; повторная активация корня адресного пространства выполняется перед возвратом.

Граница результата

Проверена поверхность 521 страницы, не полноэкранная поверхность в 1000 страниц. Возврат подтверждён успешными гостевыми вызовами и счётчиком ресурса; отдельный QMP-снимок каждой PTE сразу после закрытия не снимался. Общая очистка таблиц страниц при завершении компонентов проверяется существующими механизмами reap, но этот сценарий не является отдельной проверкой каждого PTE после закрытия окна.

Этап 104 — IRQ-04: адресная проверка PIT-счётчика

Прямая ссылка на отчёт

Статус: native-проверка реального перехода состояния и сборка пройдены; гостевая проверка ожидает QEMU. IRQ-04 не закрыт.

Что подтверждено

  • IRQ0 и тест используют одну GSL-операцию диспетчер_тик_продвинуть: она читает поле тика из записи состояния, насыщаемо увеличивает его и записывает обратно. Проверены переходы 0 → 1, MAX−1 → MAX, MAX → MAX, включая фактическое значение в памяти после вызова.
  • Проверена арифметика дедлайна: обычное сложение и переполнение с насыщением в u64::MAX.
  • python -m unittest tests.kernel.test_platform.PlatformTests.test_irq04_timer_tick_saturation -v — PASS, 1 тест за 7,2 с.
  • Свежая сборка shell-live в work/irq04-state-transition имеет build_status=success; образ guseva-p0.img, SHA-256 abd9dceceee1dc9d04002e974f8ff43b374faba8c167855f25bf8442e9275be4.

Граница

Native-вызов подтверждает математику helper-функций, но не аппаратную доставку IRQ0 и не наблюдение счётчика через syscall 5. QEMU в текущей рабочей среде не найден, поэтому проверка IRQ0 → счётчик → syscall 5 не выполнялась. Ранее упавшее общее native-упражнение остановилось в независимой проверке IPC p_send; оно не заменяет этот адресный результат.

Остаётся выполнить целевую гостевую проверку на свежем образе, после чего обновить критерий IRQ-04. Полная регрессия не запускалась.

Этап 103 — B-04/UI-05: отказ владельца окна и сохранение второго окна

Прямая ссылка на отчёт

Статус: целевая QEMU-приёмка пройдена; B-04/UI-05 остаётся в работе.

Цель

Проверить в одном интегрированном графе, что аварийный CPL3 fault владельца окна изолируется, его поверхность удаляется, а другое окно продолжает принимать ввод и штатно закрывается.

Изменения

  • Добавлен сценарий сборки focus-owner-fault, включающий общий загрузчик, оконный менеджер, два CPL3-приложения, маршрутизатор ввода, контроллер PS/2 и композитор.
  • Ожидаемым считается только fault первого оконного приложения: вектор 14 с диагностическим ID 6202, кодом ошибки 5 и адресом 4096. Ядро сохраняет снимок данных компонента до освобождения его страниц, чтобы приёмщик мог проверить результат после очистки.
  • Композитор удаляет окно завершённого владельца. Исправлен двойной учёт закрытия окна при hit-test: общий счётчик увеличивает процедура очистки владельца.
  • Приёмщик ждёт готовности драйвера мыши (MOUSE:READY) перед вводом, проверяет продолжение hit-test и событий для второго владельца, а также отсутствие остаточных ресурсов.

Приёмка

  • Сборка focus-owner-fault — PASS; целевой QEMU-профиль — PASS на QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.
  • Образ: work/ui05-owner-fault/guseva-p0.img; SHA-256 290851dbf72feff8ac8e437553d0e44ac47aaadaaa18e09a1a76691f08a3fd6e.
  • В графе семь компонентов. Зафиксирован один изолированный CPL3 page fault: владелец окна 65539, вектор 14, диагностический ID 6202. Второй владелец 65540 продолжил получать события и штатно закрыл своё окно.
  • Композитор создал и закрыл оба окна; после первого закрытия состоялся hit-test оставшегося окна. Ввод: 4 пакета мыши, 2 события клавиатуры make/break; 14 IRQ подтверждены 14 ACK.
  • Возвращено 77 страниц; остаточные полномочия, IPC-запросы, device leases и ссылки на объекты — 0; внутренних ошибок компонентов — 0. Машинные результаты: platform-report.json, boot-report.json.

Границы результата

Подтверждено аварийное закрытие владельца и продолжение работы второго окна в тестовом графе. Это не подключает граф к продуктовому рабочему столу или «Хабу», не доказывает запуск приложений из установленной ОС и не подтверждает физический ввод на ноутбуке. Полный набор K8 и матрица регрессии не запускались.

Следующая работа B-04/UI-05 — подключить продуктовый рабочий стол к проверенному оконному графу. До этого этап не закрывает пользовательский путь и не меняет критерии KERNEL 1.0.

Этап 102 — B-04/UI-05: закрытие окна владельцем и сохранение второго окна

Прямая ссылка на отчёт

Статус: целевая QEMU-приёмка пройдена; B-04/UI-05 остаётся в работе.

Результат

Продолжен профиль focus-compositor. После обработки назначенных ему событий каждое CPL3-приложение отправляет композитору запрос закрытия своего окна. Композитор проверяет владельца и поколенческий дескриптор, очищает поверхность и удаляет окно из активного реестра.

Сценарий проверяет продолжение общего графа после первого закрытия: второй щелчок проходит hit-test по актуальному реестру, выбирает оставшееся окно, а оконный менеджер и маршрутизатор доставляют события его владельцу. После завершения профиля активных окон не остаётся.

Изменения реализации и приёмки

  • Клиентский профиль формирует запрос закрытия с дескриптором окна в полезной нагрузке IPC. Исправлена обработка композитора: метод закрытия передаёт операции дескриптор из полезной нагрузки, а не ID запроса.
  • Для приложения установлен многостраничный GUP1 v2 только если скомпилированный код превышает одну страницу; иначе сборщик повторно компилирует его по одностраничному адресу и сохраняет GUP1 v1.
  • Счётчики профиля фиксируют число закрытых окон, оставшиеся активные записи и hit-test после первого закрытия. Валидатор проверяет успешную отправку запросов, закрытие двух окон и продолжение маршрутизации.

Проверка

  • python -m py_compile tools/host/platform_check.py tools/host/build_impl.py — PASS.
  • python tools/host/build.py --platform-case focus-compositor --out work/ui05-registry-handshake — PASS.
  • python tools/host/qemu_acceptance.py --build work/ui05-registry-handshake --qemu <QEMU 11.1.0> --firmware-dir <каталог share> --timeout 45 — PASS; QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.
  • SHA-256 образа: 0dfab326daf37e9cc0b3972c46a583b99c9b3b90eb4bba5cb2b92b2fb2e80af4.
  • В графе семь компонентов; два окна владельцев 65539 и 65540; события приложений [2,4]; фокус и hit-test выбрали владельца 65540, дескриптор 258.
  • Оконный менеджер обработал 4 события указателя; драйвер — 4 пакета мыши и 2 события клавиатуры make/break; маршрутизатор и контроллер обработали по 6 сообщений. IRQ/ACK — 14/14.
  • Приложения отправили два успешных запроса закрытия; композитор закрыл 2 окна, после первого закрытия выполнил успешный hit-test оставшегося окна. Активных окон после завершения — 0.
  • Faults, внутренние ошибки компонентов, остаточные IPC-запросы, полномочия, device leases и ссылки на объекты — 0. Возвращено 75 физических страниц.
  • Машинный отчёт: platform-report.json. Снимок двух окон до ввода: focus-compositor-before-input.png.

Границы

  • Проверено штатное закрытие по запросу владельца; аварийный fault владельца и продолжение второго окна после такого отказа ещё не проверены.
  • После первого закрытия проверены hit-test и последующая маршрутизация событий во второе окно. Отдельный снимок экрана после закрытия не является критерием этого профиля.
  • Продуктовый рабочий стол, «Хаб» и запуск приложений ещё не подключены к этому тестовому графу.
  • Полная регрессия K8 и полный набор тестов не запускались; выполнена только проверка синтаксиса затронутых host-инструментов, сборка и целевая QEMU-приёмка.

Дальше

Для B-04/UI-05 остаются два пункта: изолированный аварийный отказ владельца с сохранением второго окна и подключение продуктового рабочего стола к оконному графу. Этап не закрывает UI-05 и не меняет критерии KERNEL 1.0.

Этап 101 — B-04/UI-05: два окна и адресный ввод в общем графе

Прямая ссылка на отчёт

Статус: частичная целевая приёмка пройдена; B-04/UI-05 остаётся в работе.

Цель

Проверить в одном свежем образе уже существующие CPL3-композитор, оконный менеджер, маршрутизатор ввода, драйвер контроллера и два клиентских приложения. Этот этап не заменяет продуктовый рабочий стол и не закрывает поведение при завершении окна.

Изменение проверки

Валидатор ранее сохранял ссылки на снимки диагностических страниц до того, как для каждого пакета вычислялось фактическое число страниц кода. Из-за этого страницы router/controller/compositor могли указывать на предыдущий компонент. Ссылки перенесены после вычисления реальной пользовательской страницы данных. Проверка теперь сопоставляет данные компонентов с глобальным состоянием ядра и проверяет последовательность IRQ, регистрацию окон, hit-test, текущий фокус и адресную доставку.

Проверка

  • python -m py_compile tools/host/platform_check.py tools/host/qemu_acceptance.py — PASS.
  • Сборка: python tools/host/build.py --platform-case focus-compositor --out work/ui05-registry-handshake — PASS.
  • QEMU 11.1.0, q35, TCG, 128 МиБ, 1 CPU — PASS; процессор штатно достиг halt после приёмки.
  • Образ: SHA-256 2de1b5d78a1cc60a71200b5b025883cb732b0d788e95fc0ddeab0822a67bd6b4.
  • В одном графе зарегистрированы два независимых окна; снимок до ввода содержит оба окна с различимым содержимым. Геометрия: (500,367,180,130) и (690,367,180,130).
  • Щелчки мыши выбрали второе окно по реестру композитора: полный ID владельца 65540, дескриптор 258; оконный менеджер обработал 4 события указателя.
  • Клавиатурный make/break (скан-код 30) доставлен выбранному CPL3-приложению; события приложений — [2,4], маршрутизатор и контроллер обработали по 6 сообщений, контроллер учёл 4 пакета мыши и 2 события клавиатуры.
  • Прерывания мыши/клавиатуры: 14/14 доставлено и подтверждено. Faults — 0; незавершённые IPC, живые полномочия, device leases и ссылки на объекты — 0. Возвращено 121 физических страниц после завершения тестовых компонентов.
  • Машинный отчёт: platform-report.json; снимок сцены до ввода: ../../work/ui05-registry-handshake/focus-compositor-before-input.png.

Что пока не доказано

  • Закрытие или аварийный отказ первого владельца с очисткой его поверхности в этом общем графе.
  • Продолжение видимого второго окна и доставка ему ввода после такого завершения.
  • Интеграция тестового графа с продуктовыми компонентами рабочего стола, «Хаба» и запуском приложений.
  • Реальное взаимодействие мышью через окно Dev Shell; эта проверка управляет QEMU через QMP.
  • Полная регрессия K8 и полный набор тестов не запускались.

Следующий шаг B-04 — отдельный сквозной сценарий завершения/отказа владельца и продолжения второго окна, затем включение продуктового рабочего стола в принятый граф.

Этап 100 — исправление приёмки композитора и актуальная сборка оболочки

Прямая ссылка на отчёт

Статус: целевые профили композитор и shell-live собраны и прошли QEMU-приёмку в рабочей копии agentterra-os-core/osguseva.

Исправления

  • В профиле композитора тестовый клиент был добавлен в отдельную ячейку данных наблюдателя реестра. Смещение 32 занято кодом ошибки компонента и вызывало ложный отказ; используется свободное для этого профиля смещение 240.
  • Проверка старого дескриптора повторяла идентичный IPC-запрос. Защита от дубликатов закономерно вернула сохранённый успешный ответ предыдущей отрисовки. Повторное обращение теперь имеет новое сообщение-запрос, сохраняя тот же старый дескриптор и проверяя отказ по поколению.

Приёмка

  • work/ui05-registry-hit-test: свежая сборка профиля композитор; QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Проверены 29 команд, два владельца окон, hit-test, границы, перекрытие, закрытие и отклонение старого дескриптора; faults, незавершённые запросы, полномочия и ссылки — 0. SHA-256 образа: 2f635961a08ddb4d303dbc54ceebd639daf57fe37734c05cfa2769512aaddd38.
  • work/desktop-current: свежая сборка профиля shell-live; QEMU — PASS. Подтверждены готовность мыши, доставка события IRQ → пакет → IPC → рабочий стол, выбор карточки 2 и видимое подтверждение, открытое меню «Хаб». SHA-256 образа: 387688e9ca163799bf92f5268bcf4a796c446cabb0dc58c9fc28bec9257fccec.

Граница

Это два целевых сценария, не единый интегрированный граф композитора, рабочего стола, оконного менеджера и нескольких приложений. Реальное открытие программ по клику и ручной щелчок через окно Dev Shell не подтверждены; B-04/UI-05 остаётся в работе.

В предоставленном пользователем логе из Documents\Codex\2026-11-03\novaos\osguseva указан устаревший/отсутствующий образ. Эта другая копия не изменялась. В текущем checkout профиль называется shell-live; рабочий-стол не является допустимым значением --platform-case.

Этап 099 — согласование координат мыши Dev Shell

Прямая ссылка на отчёт

Статус: механизм координат и гостевой путь проверены в целевой QEMU-приёмке; ручной физический щелчок через окно Dev Shell отдельно не проверен.

Изменение

  • При входе курсора на уменьшенное изображение стенд переводит позицию указателя в координаты кадра QEMU. Гостевая мышь начинает с центра экрана; стенд хранит её текущую позицию и сбрасывает её при перезапуске гостя.
  • Относительные события QMP теперь используют ту же ориентацию Y, что и экран стенда. Обратное направление, ожидаемое PS/2-протоколом, уже преобразует QEMU.
  • Приёмочный сценарий проверяет щелчок после вертикального перемещения на 100 пикселей вверх и ждёт подтверждений нажатия и отпускания.

Проверка

  • python -m py_compile tools/host/dev_shell.py tools/host/qemu_acceptance.py — PASS.
  • Адресная проверка преобразования координат на уменьшенном изображении с поддельной QMP-сессией — PASS: вход в точку (100, 700), последующее движение и направления X/Y.
  • Свежая сборка shell-live в %TEMP%\guseva-mouse-sync-20261110 — PASS. QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU; qemu_acceptance.py — PASS. Подтверждены IRQ мыши, полный пакет, IPC, ответ рабочего стола, бирюзовый индикатор и выделение второй карточки в точке (500, 300).
  • SHA-256 образа: 707c461ab1564e364a6408aeb78b2a25c52a0b1bab486d621d5f4e9786bc179a.
  • Сводка QEMU сохранена в %TEMP%\guseva-mouse-sync-20261110\interactive-report.json.

Граница

QEMU проверил синтетический QMP-ввод и обработку рабочим столом. Проверка преобразования на стороне Dev Shell использовала поддельный транспорт. Реальное перемещение и щелчок мышью в окне приложения стенда требуют отдельной ручной проверки. Карточки по-прежнему не запускают приложения; интеграция композитора, оконного менеджера, рабочего стола и приложений UI-05 остаётся открытой.

Этап 098 — COMP-08: повторное использование компонентов и граница поколений

Прямая ссылка на отчёт

Состояние: принята ограниченная проверка COMP-08, 10 ноября 2026 года. Проверены фактические GSL-функции жизненного цикла нативным исполнителем и свежий QEMU-профиль заполнения/очистки таблицы из COMP-06.

Результат

  • Нативная проверка текущего lifecycle.gsl выполнила 2 000 циклов повторного использования слотов. Между экземплярами идентичность менялась; старые ID не разрешались, права и ссылки не наследовались, завершённые экземпляры очищались.
  • На последнем представимом 48-битном поколении запись была переведена в состояние retired; поколение не переполнилось и прежний ID не был выдан повторно. Следующий экземпляр занял другой слот.
  • Свежий QEMU-профиль process-capacity занял все 32 записи, отказал следующему запуску как IPC_LIMIT, завершил 31 дочерний компонент и вернул 384 страницы. Faults и остаточные IPC/полномочия/device leases/ссылки — 0.

Проверки

  • python -X utf8 tests/kernel/test_lifecycle.py — PASS: один целевой нативный тест, включая 2 000 повторных выдач и границу поколения.
  • Свежая QEMU-сборка и адресная приёмка — PASS; конфигурация и SHA-256 образа описаны в этапе 097. Машинные отчёты: platform-report.json и boot-report.json.

Граница

Это не длительный QEMU soak и не испытание SMP. Циклы повторного использования и максимальное поколение проверены нативным исполнением текущих функций GSL; полная ёмкость и очистка — гостевым QEMU. Проверка не доказывает поведение при произвольной конкурентной нагрузке.

Этап 097 — COMP-06: отказ при заполнении таблицы компонентов

Прямая ссылка на отчёт

Состояние: целевая приёмка принята. Профиль process-capacity заполнил всю таблицу 32 компонентами через syscall 63, проверил отказ следующего запуска и очистил все дочерние компоненты.

Исправление

При заполнении таблицы внутренний p_spawn возвращал ноль, а syscall 63 передавал его вызывающему компоненту как результат. Это неоднозначно: ноль мог восприниматься как успешное значение, хотя дочерний компонент не создан. В p_spawn_with_arguments отказ внутреннего запуска теперь преобразуется в IPC_LIMIT; успешный запуск возвращает полный поколенческий ID.

Результат

  • Supervisor запустил 31 независимый экземпляр: вместе с ним заняты все 32 слота.
  • Следующий запуск получил IPC_LIMIT; счётчик отказов заполненной таблицы увеличился на один.
  • Supervisor завершил все 31 дочерний компонент. Все 32 записи были возвращены, полномочия, IPC, device leases, ссылки и выделенные страницы очищены.
  • Возвращено 384 страницы; faults — 0.

Проверка

  • Сборка: python tools/host/build.py --out work/comp06-capacity --platform-case process-capacity — успешно.
  • Приёмка: python tools/host/qemu_acceptance.py --qemu <QEMU 11.1.0> --build work/comp06-capacity — PASS.
  • Конфигурация: QEMU 11.1.0, q35, TCG, 128 МиБ, один CPU.
  • SHA-256 образа: 5571f83f61309e75d499f0c42e52ca73b8fc7f61471d90da646b3e0a7e26c0ee.
  • Машинный отчёт: platform-report.json; загрузка: boot-report.json.

Граница

Профиль доказывает отказ из-за исчерпания общей таблицы компонентов, но не исчерпание физической памяти или индивидуальной квоты. Запуск из произвольного дискового каталога и строковые аргументы не входят в syscall 63: он принимает до четырёх чисел из ограниченного каталога текущего загрузочного профиля. Иные части ядра и полная регрессия K8 этим профилем не принимались.

Этап 096 — COMP-06: отмена ожидания и отказы запуска

Прямая ссылка на отчёт

Состояние: целевой профиль принят; COMP-06 остаётся в работе. В одном свежем профиле process-wait проверены отмена ожидания при завершении ожидающего компонента и дополнительные отказы syscall 63.

Результат

  • Ожидающий компонент вошёл в блокирующий syscall 62: в его записи ядра зафиксированы два выбора планировщика и нулевой прогресс после блокировки.
  • Supervisor завершил ожидающего с кодом 99. Ожидающая запись очищена; независимая целевая служба продолжила работу и завершилась с кодом 7440.
  • Повторное ожидание вернуло сохранённый код 99; цель вернула 7440. Проверка завершилась без оставшихся IPC-запросов, полномочий, device leases, ссылок и fault.
  • Syscall 63 отклонил количество аргументов 5 и ненулевое резервное поле с IPC_BAD_MESSAGE. CPL3-компонент без start_service попытался запустить пакет и получил IPC_DENIED; он завершился ожидаемым диагностическим кодом 7661.
  • Основной сценарий по-прежнему проверил передачу 11,22,33,44, блокирующее/повторное ожидание с кодом 7331, тайм-аут, активное неблокирующее ожидание, старое поколение и запрет самоожидания.
  • Всего завершено пять запусков компонентов; возвращено 60 физических страниц. В финальном снимке остались три записи завершённых компонентов, а все ресурсы очищены.

Проверка

  • Сборка: python tools/host/build.py --out work/comp06-wait-branches --platform-case process-wait — успешно.
  • Приёмка: python tools/host/qemu_acceptance.py --qemu <QEMU 11.1.0> --build work/comp06-wait-branches — PASS.
  • Конфигурация: QEMU 11.1.0, q35, TCG, 128 МиБ, один CPU.
  • SHA-256 образа: a77f45cc4364a3c4f72bf17f39a3c4e7045836b015e98d7b8ad18bbc3ef0c34e.
  • Машинный отчёт: platform-report.json; загрузка: boot-report.json.

Граница

Профиль проверил отказ по полномочию, но не запуск при заполненной таблице компонентов или при исчерпании квоты/физической памяти. Не проверялись строковые аргументы. Эти случаи остаются вне текущего контракта ограниченных четырёх целочисленных аргументов; поведение отказа из-за доступной ёмкости остаётся открытой частью COMP-06. Полная регрессия K8 не запускалась.

Этап 095 — COMP-06: аргументы запуска и чтение результата завершения

Прямая ссылка на отчёт

Состояние: целевой профиль принят; COMP-06 остаётся в работе. Свежая сборка проверила ограниченную передачу аргументов при запуске, блокирующее и повторное ожидание дочернего компонента, тайм-аут и обработку неверных идентичностей.

Реализация

  • Добавлен syscall 63: полномочный компонент может запустить пакет из каталога сборки с дескриптором и до четырёх целочисленных аргументов. Ядро проверяет полномочие start_service, индекс пакета, размер/адрес дескриптора, адрес и количество аргументов, а также нулевые резервные поля. Проверка диапазона включает последний допустимый массив в странице и отклоняет массив на одно 8-байтовое слово за его концом.
  • Дочерний компонент получает число аргументов и значения в своей области данных. Это ограниченный целочисленный ABI; строки, переменное окружение, произвольный argv и запуск с диска не поддерживаются.
  • Syscall 62 сохраняет код выхода последнего завершённого поколения в записи слота. Родитель может прочитать его после очистки дочернего компонента; старый ID после повторного использования/очистки записи не превращается в новую идентичность.
  • Исправлен host-валидатор: для завершённой цели ожидания он больше не требует выполнения обычных пяти циклов рабочего компонента. Её результат отдельно сверяется по сохранённым данным ожидающего.

Приёмка

  • Сборка: python tools/host/build.py --out work/comp06-wait-branches --platform-case process-wait — успешно.
  • Адресный QEMU-профиль: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Проверены: активная цель без блокировки (IPC_EMPTY), истёкший тайм-аут (IPC_TIMEOUT), блокирующее ожидание и повторное чтение кода 7331, устаревшее поколение (IPC_STALE), самонаблюдение (IPC_BAD_MESSAGE), доставка четырёх значений 11, 22, 33, 44 дочернему компоненту, последний допустимый адрес массива, отказ для адреса на слово за границей и отказ для дескриптора за границей.
  • Faults — 0; после завершения нет остаточных IPC-запросов, полномочий, device leases и ссылок на объекты. Дочерний компонент завершился, родитель продолжил работу.
  • SHA-256 образа: 881fdda4790a0641a10c27e38ebe0c8711ce27d1ada712d6c50d56d3c1f4e722.
  • Машинные отчёты: work/comp06-wait-branches/platform-report.json, work/comp06-wait-branches/boot-report.json.

Граница

Не проверялись в этом профиле: отмена ожидания при завершении самого ожидающего компонента, неверное число аргументов, отказ запуска из-за недостатка полномочий или ресурсов и выдача аргументов типа строка. Передача ограничена четырьмя числами и каталогом текущего загрузочного профиля. Поэтому COMP-06 не закрыт.

Этап 094 — COMP-06: ожидание завершения компонента

Прямая ссылка на отчёт

Состояние: целевая приёмка завершена; COMP-06 остаётся в работе. Добавлен блокирующий системный вызов ожидания и отдельный QEMU-профиль, который проверяет реальное продолжение родительского компонента после выхода дочернего.

Реализация

  • Добавлен p_wait_component: цель задаётся полным поколенческим ID; самонаблюдение запрещено. Завершённая цель возвращает сохранённый код выхода, активная цель блокирует вызывающий компонент до завершения или ограниченного тайм-аута.
  • Пока ожидание активно, ядро удерживает ссылки на ожидающего и цель. Они освобождаются при завершении, тайм-ауте и очистке ожидания после завершения вызывающего компонента.
  • Добавлен системный вызов 62, который возвращает результат ожидания.
  • Добавлен профиль process-wait: CPL3-компонент запускает ребёнка, ждёт его завершения и записывает ID ребёнка и полученный код выхода в собственную область данных.

Приёмка

  • Свежая сборка: python tools/host/build.py --out work/comp06-process-wait --platform-case process-wait — успешно.
  • Целевой запуск QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Родитель 65537 дождался дочернего 65538; код выхода — 0. Оба компонента завершили работу (progress=5).
  • Faults — 0; остаточные IPC-запросы, полномочия, device leases и ссылки — 0.
  • SHA-256 образа: e15d0bb54853ffb823f9d643c32b517c922862626aa240fefcc4c0601730cb5f.
  • QEMU-отчёт: work/comp06-process-wait/platform-report.json; сводка загрузки и сборки — в том же каталоге.

Граница

Передача аргументов при запуске ещё не реализована. В этой приёмке не проверялись отдельными профилями немедленный возврат уже завершённого процесса, тайм-аут, ожидание неверного поколения и отмена ожидания при завершении родителя. Поэтому COMP-06 не закрыт; эти ветви и аргументы остаются следующими работами этапа.

Этап 093 — COMP-05: граничные области GUP1 v3

Прямая ссылка на отчёт

Состояние: целевая приёмка принята. Проверены минимальный и максимальный допустимые размеры данных и стека на реально исполняемых CPL3-компонентах.

Реализация

  • Добавлен профиль границы-областей: один компонент запускается с 1 страницей данных и 1 страницей стека, второй — с 3 страницами данных и 4 страницами стека.
  • Сгенерированный CPL3-код записывает маркер в последнюю объявленную страницу данных, касается нижней страницы стека и сохраняет прочитанное значение в области данных. Проверяется штатное завершение обоих компонентов и возврат принадлежащих им страниц.
  • Загрузка GUP1 v3 использует прежний адрес кода, NX-отображение данных и стека и защиту незанятых областей. Изменений ABI ядра для этого профиля не потребовалось.

Приёмка

  • Свежая сборка: python tools/host/build.py --out work/comp05-v3-boundaries --platform-case границы-областей — успешно.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Исполнены размеры 1+1 и 3+4; оба компонента достигли контрольного состояния, faults — 0.
  • Возвращено 19 физических кадров: 7 для минимального компонента и 12 для максимального. Остаточные IPC-запросы, полномочия, device leases и object references — 0.
  • SHA-256 образа: ce79b6a449971f3b53a947936ccc4a9b1b76e5542d58f8bef667415ebbff2d84.
  • Машинные данные: work/comp05-v3-boundaries/platform-report.json, work/comp05-v3-boundaries/boot-report.json, work/comp05-v3-boundaries/build-report.json.

Граница

Вместе с этапом 092 проверены три профиля v3: 1+1, 3+2 и 3+4 страницы данных/стека. Все 12 сочетаний отдельно не запускались. Этот этап проверяет запуск и исполнение; он не доказывает безопасность исполнения произвольного пакета, полученного по UART.

Этап 092 — COMP-05: переменные области данных и стека GUP1 v3

Прямая ссылка на отчёт

Состояние: целевая сборка и QEMU-сценарий приняты; COMP-05 остаётся в работе. Общий загрузчик CPL3-компонентов теперь выделяет размеры начальных областей данных и стека из заголовка пакета GUP1 v3.

Реализация

  • GUP1 v3 кодирует число страниц данных в младших 32 битах поля флагов, число страниц стека — в старших 32 битах. Допустимы 1–3 страницы данных и 1–4 страницы стека.
  • GSL package_valid проверяет версию, ёмкость данных, размеры областей и полную длину пакета до выделения памяти.
  • Общий p_spawn выделяет соответствующее число кадров, отображает данные и стек с правами RW/NX, копирует начальный блок по страницам и задаёт стек в прежней верхней точке. Версии v1/v2 сохраняют прежнее поведение.
  • Host-сборщик пакетов принимает --data-pages и --stack-pages совместно. Добавлен профиль области-данных-и-стека.

Проверка

  • Целевые unittest для сборщика GUP1 и native-проверки GSL — 2 теста, PASS. Проверены корректные поля v3, предельная ёмкость и отказы для нулевого/слишком большого числа страниц и превышения объявленной ёмкости данных.
  • Свежая сборка python tools/host/build.py --out work/comp05-variable-regions --platform-case области-данных-и-стека — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Первый CPL3-компонент прочитал маркер с третьей страницы данных, записал во вторую и обратился к нижней странице двухстраничного стека; оба соседних компонента завершили работу. Создано 3 компонента, возвращено 34 физических кадра, faults — 0, остаточные IPC-запросы, полномочия, device leases и ссылки на объекты — 0.
  • SHA-256 проверенного образа: 3b10516cde12c1fd3d09d7f1187283b75432ec9516e2c7b85109ca1ba2ca868c.
  • Машинные доказательства: platform-report.json, boot-report.json, build-report.json.

Граница

Принята одна адресная конфигурация v3 — 3 страницы данных и 2 страницы стека. Все сочетания границ 1–3 и 1–4 отдельной гостевой матрицей не проверялись. UART-приёмник горячей передачи пакетов остаётся на GUP1 v1. Поэтому COMP-05 не закрыт.

Этап 091 — COMP-05: исполнение крайней точки входа GUP1 v2

Прямая ссылка на отчёт

Состояние: целевой сценарий QEMU принят; COMP-05 остаётся в работе. Свежий образ исполнил инструкцию из последнего допустимого байта семистраничного CPL3-кода и безопасно завершил только компонент-виновник.

Реализация

  • Добавлен профиль сборки крайняя-точка-входа, пакет GUP1 v2 с длиной кода 28 672 байта и смещением входа 28 671.
  • Последний байт содержит однобайтовую привилегированную HLT. На CPL3 она вызывает #GP; IDT не ослаблялась для пользовательских программных прерываний.
  • Профиль получил отдельный режим ядра 28 и роль устройства, не пересекаясь с ранее назначенными режимами.
  • Приёмка подтверждает #GP (вектор 13), диагностический ID 6200, RIP 0x800016fff, полную карту RX-кода и правильный сохранённый fault-контекст. Два соседних компонента должны завершиться обычным путём.

Проверка

  • python -m py_compile tools/host/build_impl.py tools/host/platform_check.py — PASS.
  • Свежая сборка python tools/host/build.py --out work/comp05-entry-boundary --platform-case крайняя-точка-входа — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS; образ SHA-256 0db57f642337af05ee17e4f446e58dad66bc34fd4ab3aafd97c611075edf8c03.
  • Faults — 1 (ожидаемый CPL3 #GP), оба соседних компонента завершены, возвращено 40 страниц, IPC/capabilities/device leases/object references — 0.

Граница

Принята только гостевая проверка крайнего допустимого смещения. Область данных по-прежнему ограничена одной страницей, стек — четырьмя страницами; UART-приёмник принимает GUP1 v1. Переменные размеры данных/стека и перенос этих пакетов через UART остаются незавершёнными; COMP-05 не закрыт.

Этап 090 — COMP-05: крайняя точка входа GUP1 v2

Прямая ссылка на отчёт

Состояние: проверка разбора пакета подтверждена; COMP-05 остаётся в работе. GSL-функция package_valid принимает максимально допустимый для GUP1 v2 код длиной 28 672 байта с точкой входа в последнем байте (28 671) и отклоняет точку входа ровно за границей (28 672). Гостевое исполнение крайнего байта добавлено позднее и записано отдельно в этапе 091.

Изменение приёмки

  • В существующую native-проверку GSL-контракта добавлены два вызова настоящей скомпилированной функции package_valid: допустимый крайний адрес и недопустимый адрес за концом кода.
  • Это закрывает пробел между тестом сборщика пакетов и проверкой границ в GSL-загрузчике. Аллокация и запуск кода с этой конкретной точки входа в гостевой ОС отдельно не проверялись.

Проверка

  • python -m unittest tests.kernel.test_process_policy.ProcessPolicyTests.test_native_validation_and_cleanup -v — PASS. Проверена GSL-реализация скомпилированная в native DLL; также прошли существующие проверки диапазонов, испорченных заголовков, отката выделения, создания и очистки процесса.
  • На момент этого этапа новая гостевая сборка не выполнялась: исходный код ядра не менялся, а ранее принятый QEMU-профиль проверял исполнение на седьмой странице, но не крайний байтовый адрес.

Что остаётся в COMP-05

Данные ограничены одной страницей, стек — четырьмя страницами; UART-приёмник поддерживает только GUP1 v1. Нужны динамическое расширение данных/стека и отдельная гостевая проверка исполнения из последнего допустимого смещения. Поэтому COMP-05 не закрыт. Базовый многостраничный механизм и прежние QEMU-результаты описаны в этапе 074.

Этап 089 — SCHED-07: задержка и прогресс под нагрузкой

Прямая ссылка на отчёт

Состояние: SCHED-07 принят в целевой границе. Планировщик считает максимальный интервал между готовностью потока и его выбором. Метрики доступны только supervisor с полномочием manage_scheduling; CPL3-компоненты без этого полномочия получают отказ.

Реализация

  • Для каждого из 64 контекстов (основной и дополнительный потоки 32 компонентов) ведутся время начала ожидания, максимальное ожидание в тиках и число выборов.
  • Время передаётся в общий планировщик явно: ядровой контур и runtime компонентов используют собственный монотонный счётчик тиков. Это исключает ошибочное чтение часов из неподходящего участка состояния.
  • Счётчики сбрасываются при создании компонента и повторном использовании слота.
  • Syscall 61 предоставляет supervisor снимок обеих нитей указанного компонента. Проверка полномочия и копирование в пользовательский буфер остаются в платформенном runtime, общий планировщик от них не зависит.
  • Профиль scheduler-latency запускает supervisor и два компонента с приоритетами 7 и 0. Они работают в течение 600 тиков при окне наблюдения 300 тиков; профиль проверяет прогресс, защищённость чтения метрик и очистку ресурсов.

Фактическая проверка

  • python tests/kernel/test_component_scheduler.py — PASS: составы 1/3/7/32, поворот равных кандидатов, старение, полномочия, ожидание/пробуждение и повторное использование ID.
  • python -m py_compile tools/host/build_impl.py tools/host/platform_check.py — PASS.
  • python tools/host/build.py --out work/sched07-latency --platform-case scheduler-latency — PASS; свежий образ SHA-256 b71d69913f84bb5e77a9ee3a5e6ceede892ef9c2c9e2e29e8dfb782416b29885.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — целевой сценарий PASS на том же SHA-256.
  • Приоритет 7: максимальное наблюдаемое ожидание 1 тик, 55 923 выбора. Приоритет 0: 1 тик, 9 321 выбор; низкоприоритетный компонент выполнил работу и завершился. Supervisor успешно прочитал оба снимка; чтение и изменение планирования обычными компонентами отклонены.
  • Faults — 0; возвращено 30 страниц; незавершённых IPC-запросов, полномочий, device leases и ссылок на объекты — 0. Машинные отчёты: сценарий, загрузка, планировщик.

Граница результата

Приёмка подтверждает отсутствие голодания и задержку не более одного PIT-тика в указанной нагрузке QEMU, на одном CPU и в 300-тиковом окне наблюдения. Это дискретная метрика планировщика, а не реальное время, CPU-квота или гарантия доли процессора. Не проверялись SMP, физические машины и задержки за пределами сценария.

Этап 088 — SCHED-06: приоритеты и старение

Прямая ссылка на отчёт

Состояние: SCHED-06 принят в проверенной границе. Реализована базовая политика распределения процессорного времени и проверена сквозным CPL3-профилем в QEMU. SCHED-07 — отдельный следующий пункт дорожной карты.

Реализация

  • У каждого из 32 слотов есть базовый приоритет 0–7.
  • Для каждого из 64 потоков (основной и дополнительный для каждого компонента) отдельно накапливается возраст ожидания до 8.
  • Планировщик выбирает готовый поток с наибольшей суммой «приоритет + возраст ожидания». Равные значения разрешаются круговым обходом после предыдущего выбора.
  • Возраст ожидания перекрывает максимальную разницу базовых приоритетов. Поэтому при постоянной готовности низкоприоритетный поток в конечном счёте получает процессор.
  • Syscall 60 задаёт приоритет только при наличии у вызывающего компонента полномочия manage_scheduling. Диапазон вне 0–7 отклоняется.
  • Новая задача и повторно используемый слот начинают с приоритета 0 и очищенного возраста.

Фактическая проверка

  • python tests/kernel/test_component_scheduler.py — PASS. Проверены составы 1/3/7/32, поворот равных кандидатов, преимущество высокого приоритета при ненулевом прогрессе низкого, отказ без полномочия, диапазон, ожидание/пробуждение и устаревшая идентичность.
  • python -m unittest discover -s tests/kernel -p test_components.py -v — 8 проверок PASS: кодирование полномочий, отказ неверной политики, реестр компонентов.
  • python tools/host/build.py --out work/sched06-workers --platform-case workers — свежая сборка PASS. SHA-256 образа: 724378bdd391e3c187892c955cea01d2c5586926e2d603f883f5a248be051e8d.
  • Первая попытка запуска сценария workers остановилась до запуска виртуальной машины: тогда QEMU не был найден в PATH или локальном work. Этот блокер устранён перед финальной приёмкой ниже.
  • Добавлен профиль scheduler-priority: supervisor CPL3 с одним полномочием manage_scheduling задаёт двум CPL3-работникам приоритеты 7 и 0. Оба выполняют равную по длительности готовую нагрузку, затем завершаются штатно; каждый работник отдельно проверяет, что syscall 60 ему запрещён. Проверка снимков требует большего числа выборов у приоритета 7, ненулевого числа у приоритета 0, 80 тиков работы каждого, отсутствия ошибок и утечек.
  • python -m py_compile tools/host/build_impl.py tools/host/platform_check.py — PASS. python tools/host/build.py --out work/sched06-priority-guest --platform-case scheduler-priority — PASS; образ SHA-256 55e3f3c05eb515fc158a72ff48b97ee99057618559cfc3bb2716aa45d4432259.
  • Сборка запущена в обычном QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU, с EDK2. Итог qemu_acceptance.py — PASS; образ совпал по SHA-256 55e3f3c05eb515fc158a72ff48b97ee99057618559cfc3bb2716aa45d4432259.
  • Supervisor CPL3 установил приоритет 7 компоненту 65538 и 0 компоненту 65539; его полномочия равны 256, у обоих работников полномочий изменения планирования нет. Самовольная смена приоритета обоими работниками отклонена.
  • За 80 тиков высокий приоритет получил 18 761 выбор, низкий — 2 686. Низкоприоритетный компонент продолжил прогресс; checker подтвердил продвижение обоих, штатное завершение и очистку. Faults — 0, возвращено страниц — 30, незавершённые capabilities/IPC/device leases/object references — 0.
  • Машинный отчёт сохранён в work/sched06-priority-guest/platform-report.json, отчёт загрузки — work/sched06-priority-guest/boot-report.json.

Следующий пункт дорожной карты

SCHED-06 завершён в указанной границе. Следом — отдельный SCHED-07: измерить задержку получения CPU и проверить ограниченное старение под более длительной конкурирующей нагрузкой. Не трактовать результаты этого 80-тикового профиля как измерение реального времени или гарантию доли CPU.

Предел реализации: один CPU, два потока на компонент, дискретные уровни приоритета и aging по решениям планировщика. Это не CPU-квоты и не гарантия доли времени в процентах.

Этап 087 — SCHED-05: изоляция x87/SSE-контекста потоков

Прямая ссылка на отчёт

Состояние: принят в целевой границе 2026-11-10. x86-64 мост планировщика сохраняет и восстанавливает FP/SSE-контекст CPL3-компонента при переходах между основным потоком и одним дополнительным.

Реализация

  • Для каждого из 32 компонентных слотов выделено по два выровненных 512-байтовых состояния FXSAVE: основное и дочернее. Маска валидности не позволяет восстанавливать неинициализированные данные; первый запуск получает начальное состояние, повторное использование потока очищает соответствующий признак.
  • На аппаратных переходах между пользовательскими потоками используются FXSAVE64/FXRSTOR64; перед возвратом в контекст ядра загружается безопасное значение MXCSR. CR4.OSXSAVE оставлен выключенным, AVX/XSAVE не входят в этот этап.
  • Исправлено сохранение номера IRQ в x86-мосте: помощник FP-контекста использует регистры общего назначения, поэтому номер вектора сохраняется в кадре до вызова и восстанавливается перед GSL-диспетчером.
  • Добавлен отдельный профиль сборки threads-fp и CPL3-проба. Основной и дочерний потоки удерживали разные значения XMM0 на протяжении повторных системных вызовов и переключений; основной дождался завершения дочернего и проверил маркеры результата.

Приёмка

Свежий образ work/sched05-fp-context собран и прошёл целевой QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. SHA-256 образа: 9e8bff930b2f66e265e34830aa142c4a10e13d856d974e1f24e126ae5b7bfe23.

  • Профиль: threads-fp; компонент 65537; 138 выборов планировщика; прогресс — 5.
  • Проверки регистров: основной и дочерний потоки сохранили разные XMM0, отдельно сохранены и проверены различные x87-значения (1.0 и 0.0); маркеры ошибок — 0.
  • Дочерний поток завершён, его стек и таблица отображения освобождены; faults — 0; выделенные/возвращённые страницы компонента сходятся (11/11); остаточных capabilities, IPC, device leases и object references — 0.
  • Машиночитаемый отчёт: platform-report.json; загрузка: boot-report.json.

Границы

Проверена изоляция XMM0 и x87-регистров на CPL3, а также общий путь FXSAVE/FXRSTOR на одном CPU в QEMU. MXCSR и x87-арифметика не тестировались. AVX/XSAVE, SMP, более двух потоков и физическое оборудование не проверялись. SCHED-06/07, синхронизация heap между потоками и голодание планировщика остаются отдельными задачами.

Этап 086 — SCHED-04: два потока на компоненте

Прямая ссылка на отчёт

Состояние: принят в целевой границе 2026-11-10. Ядро запускает основной и один дополнительный целочисленный поток в одном CPL3-компоненте, переключает их контексты и завершает дополнительный поток независимо от основного.

Реализация

  • Контексты сохраняются в отдельной ядерной области: по 320 байт на компонент, по 160 байт на каждый из двух потоков. Аппаратный кадр IRETQ формируется мостом отдельно от сохранённого кадра регистров.
  • Дополнительный поток получает две пользовательские страницы стека и страницу-ограждение. После выхода освобождаются страницы и таблица отображения стека; счётчики выделения и возврата физической памяти сходятся.
  • Запись процесса ведёт число выборов планировщиком. Сценарий threads раздельно фиксирует результат основного и дочернего потоков, проверяет запуск, независимое завершение и продолжение основного.

Приёмка

Свежий образ work/sched04-threads-targeted прошёл threads на QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

  • Оба потока исполнились; дочерний поток завершился, основной продолжил работу.
  • Ошибки компонентов и faults ядра: 0.
  • Учёт страниц компонента: 16 выделено / 16 возвращено; таблица отображения стека освобождена.
  • SHA-256 образа: f82020c169dda52edb516230738956c0a709cbd5c2aee6b8b9edd0535e91c033.

После этого свежий образ work/sched04-workers-dependent прошёл workers на той же конфигурации:

  • 3 компонента завершились; возвращено 36 страниц.
  • Ошибки, faults и оставшиеся IPC-запросы, полномочия, device leases и ссылки на объекты: 0.
  • SHA-256 образа: 347b8ba3302c89546eecf85acd84d3505fb9f41fb453038288444982e8dbf15c.

Границы

Подтверждены два целочисленных потока на компоненте и один CPU. FP/SIMD-контекст, синхронизация heap между потоками, больше двух потоков, приоритеты, отсутствие голодания и SMP в этом этапе не проверялись. Старые записи о промежуточных сбоях в CHANGELOG остаются историей; результаты этого отчёта относятся к двум хешам выше.

Этап 085 — IPC-08: защита от повторной доставки запроса

Прямая ссылка на отчёт

Состояние: принят в целевой границе 2026-11-10. Ядро запоминает доставленные запросы, поэтому повтор того же ID не попадает получателю второй раз после завершения исходного обмена.

Реализация

  • В платформенном runtime выделен ограниченный журнал из 160 записей. Ключ состоит из полного поколенческого ID отправителя, полного ID получателя и ID запроса. Один и тот же ID с иным содержимым также считается повтором.
  • При принятии запроса журнал резервируется. В момент первой выдачи получателю запись становится закреплённой. Повторный syscall 6 с тем же ключом завершается IPC_DUPLICATE до создания новой записи очереди.
  • Если запрос не был доставлен, отмена, тайм-аут, отзыв или завершение участника снимают резерв, чтобы запрос можно было безопасно повторить. После доставки запись сохраняется до завершения отправителя или получателя; при освобождении компонентов ключи с их полным ID удаляются.
  • Если журнал заполнен, ядро возвращает IPC_FULL: оно не вытесняет ключи и не разрешает повторное выполнение из-за нехватки места.

Целевая приёмка

Свежий профиль ipc-wait-any собран и прошёл QEMU 11.1.0 на q35/TCG, 128 МиБ, 1 CPU.

  • Отменённый запрос повторно принят и отменён, не занимая постоянный ключ. Все восемь завершённых двусторонних запросов были повторно отправлены тем же ID; каждый повтор получил IPC_DUPLICATE.
  • Все восемь следующих обменов продолжили работу; оба CPL3-компонента завершились без ошибки.
  • Завершились 3 компонента; возвращено 35 страниц; faults, остаточные IPC-запросы, полномочия, device leases и ссылки на объекты — 0.
  • Хеш образа: d9e4fe7d57e715fecea1ce58e02eaa84638fba646395e8476a0d5d3f567cd6cb.
  • Полный отчёт: boot-report.json.

Границы

Журнал вмещает 160 одновременно зарезервированных или сохранённых ключей на весь runtime. ID должен быть уникален для пары полных поколенческих ID участников в течение времени их жизни. После доставки ядро исключает повторную доставку, но не может атомарно объединить побочный эффект приложения с ответом: если получатель аварийно завершится посередине действия, приложение должно само определять безопасное восстановление. Транзакционная фиксация и повторная выдача сохранённого ответа не входят в IPC-08. SMP и конкурентные гонки не проверялись.

Этап 084 — IPC-07: повторный обмен, отмена и восстановление участника

Прямая ссылка на отчёт

Состояние: принят в целевой границе 2026-11-10. Общий срок IPC-обмена и приёма ограничен 1000 тиками; проверены повторные ответы, отмена, отказ CPL3-компонента и повторный запуск службы с новым поколением ID.

Изменения

  • Максимальный срок IPC-запроса увеличен со 100 до 1000 тиков. Отдельное ожидание приёма также допускает до 1000 тиков. Ограничение остаётся конечным; нулевой и неверный сроки продолжают обрабатываться существующими правилами.
  • Гостевой профиль IPC расширен до восьми последовательных двусторонних циклов запроса/ответа. В том же запуске он проверяет выбор готового IPC-источника, отмену ещё не доставленного запроса, уведомление об отмене, неизменяемый снимок буфера и освобождение страниц.
  • Профиль перезапуска теперь проверяет ответ после передачи старого и нового полномочий, поколенческую замену службы и отказ старого полномочия после очистки. Ответ уже является завершением запроса; отправлять на него второй reply не требуется.
  • Драйвер platform_worker.gsl превысил одну страницу кода и собирается как GUP1 v2 с несколькими RX-страницами. Сборщик и проверяющий теперь учитывают многостраничный код, его страницу данных и возврат дополнительных кадров в профилях повторного запуска и родственных сценариях.
  • При ошибке профиля перезапуска ядро дополнительно сообщает код и прогресс второго участника, чтобы отказ не скрывал состояние собеседника.

Целевая приёмка QEMU

Все три сборки выполнены заново на QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU.

Профиль Результат Проверенное свойство SHA-256 образа
ipc-wait-any PASS 8 двусторонних циклов; отмена возвращает 0; ошибки обоих участников 0; 35 страниц возвращено; остаточные IPC/права/устройства/ссылки — 0 30872d470b11ebad9f22f83b295921101aa2968b3f7df087f974aca88872a423
spawn --platform-count 2 PASS Служба 65539 заменена на 131075; клиент получил две привязки; старое полномочие отклонено; 44 страницы возвращено; остатки — 0 c5ecd87c73baaf7b64c202e773a2800bc546fcfde4cd98088b133b3a2fa4fcc9
fault PASS Один CPL3-компонент получил fault; два соседних завершились; 33 страницы возвращено; остатки — 0 73487ac51fb6bdd30cc92a8ec1304c27c128f657f5275dfa316b38ed14520185

Отчёты: IPC-обмен, перезапуск участника, отказ компонента.

Граница

Приняты именно три указанных QEMU-профиля. Максимальная полезная нагрузка 4032 байта, конкурентные потоки, SMP и длительная нагрузка за пределами восьми циклов здесь не проверялись. IPC-08 — защита от повторного выполнения побочных эффектов при повторной доставке — остаётся открытой задачей.

Этап 083 — IPC-06: передача ограниченного буфера через IPC

Прямая ссылка на отчёт

Состояние: принято в описанной границе. Новый код GSL собран; целевой профиль ipc-wait-any прошёл свежую сквозную приёмку QEMU.

Реализовано

  • Syscall 6 принимает обычное сообщение в 64 байта либо сообщение с хвостом данных; общий размер ограничен одной пользовательской страницей — 4096 байт, из них до 4032 байт полезной нагрузки.
  • Ядро копирует хвост в отдельную физическую страницу при отправке. Последующее изменение исходного буфера отправителем не меняет уже отправленный снимок. Страница учитывается за отправителем и освобождается вместе с поколенческой записью запроса.
  • Syscall 55 (IPC_PAYLOAD_READ) копирует снимок только компоненту-получателю после доставки запроса. Проверяются поколение токена, статус и владелец, точная длина, выравнивание и диапазон буфера получателя. Запись неполного последнего машинного слова сохраняет байты за границей назначения.
  • Приёмка проверила чтение не владельцем, длину не по контракту, выход исходного диапазона отправителя и диапазона назначения получателя за страницу, ответ и отмену с возвратом обеих страниц payload.

Целевая приёмка

  • Образ собран командой python -X utf8 tools/host/build.py --out work/ipc06-payload --platform-case ipc-wait-any.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU; результат — PASS; 3 CPL3-компонента, 0 component errors/faults, 0 остаточных IPC-запросов, полномочий, device leases и ссылок на объекты.
  • Получатель прочитал 131-байтовый неизменённый снимок после перезаписи отправителем исходных байтов. Попытка чтения посторонним отклонена; неправильная длина и выход исходного и целевого буферов за границу страницы отклонены; байты назначения за концом данных сохранены.
  • Возвращено 35 физических страниц всего в сценарии; две страницы payload (ответ и отмена) учтены как освобождённые.
  • SHA-256 образа: 376bae815113a61f8c7e983b908f763f9b120d9d2e530f6e05cd554836c5c76d.
  • Отчёты: QEMU, платформенный сценарий.

Граница

Проверен полезный буфер 131 байт, а не максимальные 4032 байта. Буфер передаётся одной страницей; общая память и передача нескольких страниц не добавлены. Не проверялись многопоточные гонки и длительная нагрузка. Успешный QEMU-сценарий не закрывает IPC-07/08.

Этап 082 — IPC-05: ожидание нескольких источников событий

Прямая ссылка на отчёт

Состояние: IPC-05 принят в описанной границе. Механизмы syscall 53/54 прошли адресную native-проверку и сквозную CPL3/QEMU-приёмку на свежем образе.

Контракт syscall 54

Компонент вызывает system_call(54, адрес_списка, число_источников, тайм-аут).

Список расположен в пользовательской памяти и состоит из записей по 16 байт: два u64 — вид источника и дескриптор. Ядро копирует записи до блокировки, поэтому последующие изменения списка вызывающим компонентом не меняют уже ожидающую операцию.

Вид Источник Проверка
1 Входящий IPC или завершение исходного запроса Входящий: право приёма на собственную конечную точку; ответ: право отправки по конкретному каналу, которым отправлен запрос
3 IRQ Действующий выданный дескриптор IRQ

Допускается от одного до четырёх источников. Тайм-аут — до 100 тиков. Успех возвращает 1..4: индекс готового источника, начиная с единицы. При одновременной готовности выбирается первый в списке. Тайм-аут 0 означает только опрос: если источники не готовы, возвращается IPC_EMPTY. При блокирующем ожидании истечение срока возвращает IPC_TIMEOUT. Неверная запись, устаревший дескриптор и отсутствие права завершают вызов соответствующим IPC-кодом.

Реализация

  • src/kernel/core/platform_core.gsl: копирование и валидация списка, проверка готовности IPC/IRQ, регистрация блокировки и пробуждение по событию/тайм-ауту. Ответ сопоставляется с индексом и поколением исходного права-канала; p_send теперь сохраняет поколение права, а не поколения записи запроса. Дополнительная таблица ограничена четырьмя источниками на компонент.
  • src/kernel/core/platform_runtime.gsl: syscall 54.
  • p_finish_wait очищает скопированный список при пробуждении; p_end очищает его при завершении компонента.
  • Профиль ipc-wait-any запускает три независимых CPL3-компонента. До освобождения памяти ядро сохраняет диагностические снимки компонентов; проверяются фактические данные обмена, ошибки приложений и cleanup, а не временная трассировка syscall.
  • tests/kernel/test_platform.py: целевой сценарий проверяет ожидание двух источников, пробуждение по IRQ и IPC с соответствующими индексами, ответ по выбранному исходящему каналу, отсутствие пробуждения по ответу другого канала, неблокирующий опрос, тайм-аут, неверный тип источника, очистку ожидания и сохранение учёта ссылок.

Фактическая проверка

  • GUSEVA_PLATFORM_TEST_COUNTS=2, GUSEVA_PLATFORM_TEST_EVENT_WAIT_ONLY=1, python -X utf8 -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices — PASS (1 targeted native test; сценарий отмены IPC, расположенный перед ним в том же тесте, также пройден).
  • Свежая сборка python tools/host/build.py --out work/ipc05-waitany-build --platform-case ipc-wait-any — PASS. Образ work/ipc05-waitany-build/guseva-p0.img, SHA-256 c2e533176bd1fe57958a32d72019bce6c08150add86b2943b098b6002ce8b607; EFI SHA-256 64b9bef3b595b52194ea0fae130009c6d49c9b7db0f7ad6cbda92b8dd5c3d306; GSL 0.0.15 → C → Clang → rust-lld.
  • python -X utf8 tools/host/qemu_acceptance.py --build work/ipc05-waitany-build --qemu <QEMU 11.1.0> — PASS на q35/TCG, 128 МиБ, 1 CPU. Три компонента завершились, faults и остаточные IPC/capability/device/object references — 0, возвращено 33 страницы.
  • Проверено из снимков CPL3: syscall 54 вернул индекс 2 из двух источников; ответ id=9201, value=72, flags=1, отправитель 65539; syscall 53 вернул 0; уведомление отмены id=9202, код IPC_CANCELLED, flags=2, отправитель 65539. Ошибки отправителя и получателя — 0. QEMU-маркер: IPC-05: syscall 54 выбрал нужный канал; syscall 53 отменил запрос.
  • Отчёт приёмки — platform-report.json; полный журнал загрузки — boot.log.

Граница принятия

IPC-05 закрыт в границах одного отправителя, одного получателя, двух IPC-источников, трёх CPL3-компонентов и указанной конфигурации QEMU. Полная QEMU-матрица, IRQ wait-any в гостевой приёмке, многопоточные гонки, передача больших буферов и устойчивость длительной нагрузки остаются вне этого этапа и выполняются по своим пунктам плана.

Этап 081 — IPC-05: отмена ожидающего запроса

Прямая ссылка на отчёт

Состояние: в работе. Реализован первый законченный механизм IPC-05: отправитель может отменить собственный запрос, пока получатель его ещё не принял.

Контракт

  • Успешный syscall 6 записывает в поле 56 исходного буфера непрозрачный токен: поколение записи запроса и номер слота.
  • syscall 53(token) отменяет запрос только от его полного поколения отправителя и только в состоянии очереди (status=1). Результат операции поступает отправителю как IPC_CANCELLED через обычный syscall 7.
  • Повторная отмена до чтения результата идемпотентна. После освобождения записи прежний токен возвращает IPC_STALE.
  • Чужой отправитель получает IPC_DENIED. Если запрос уже доставлен (status=2), отмена отклоняется: ядро не может обещать отсутствие уже начатого побочного эффекта.
  • Освобождение ссылки, квот и записи выполняется существующим путём p_receive/p_release_request, а не самой командой отмены.

Изменения

  • src/kernel/core/ipc_abi.gsl: добавлен код результата IPC_CANCELLED.
  • src/kernel/core/platform_core.gsl: добавлены поколенческий токен и проверка права/состояния отменяемого запроса.
  • src/kernel/core/platform_runtime.gsl: добавлен syscall 53.
  • tests/kernel/test_platform.py: добавлен адресный native-сценарий до/после доставки.

Приёмка и граница

  • Сборка workers прошла: work/ipc05-cancel-build/guseva-p0.img, SHA-256 a8b535186f0edebbfd36999fe6abacf91431fc13362fb2a67ddd6ca9dd9d9e8b; GSL 0.0.15 → C → Clang → rust-lld.
  • Целевой native-сценарий с двумя компонентами прошёл: проверены отмена до доставки, отказ чужому владельцу, повторная отмена, устаревший токен, запрет отмены принятого запроса и завершение обычным ответом.
  • QEMU-приёмка syscall 53 не запускалась. Полная регрессия платформы и QEMU-матрица не являются частью этой итерации. Ожидание нескольких источников событий остаётся незавершённой частью IPC-05.

Этап 080 — hit-test реестра CPL3-композитора

Прямая ссылка на отчёт

Состояние: принято в указанной границе.
Дата: 9 ноября 2026 года.

Цель

Проверить, что CPL3-композитор находит окно по координатам из собственного актуального реестра, возвращает полный ID владельца вместе с поколенческим дескриптором, а закрытое окно больше не выбирается.

Реализация

  • В src/services/композитор.gsl добавлен единый hit-test по 16 записям оконного реестра.
  • Проверочный клиент отправляет координатные запросы после закрытия первого окна; второй независимый клиент проверяет hit-test собственного окна.
  • Валидатор проверяет, что закрытое окно не найдено и что оба результата содержат ожидаемые полные ID компонентов и поколенческие дескрипторы.
  • Счётчик сценария синхронизирован с 29 IPC-командами сцены.

Приёмка

  • Сборка: python tools/host/build.py --platform-case композитор --out work/compositor-current — PASS.
  • QEMU: python tools/host/qemu_acceptance.py --build work/compositor-current --qemu 'C:\Users\User\Documents\Codex\2026-11-03\novaos-sync\tools\qemu\qemu\qemu-system-x86_64.exe' --timeout 30 — PASS.
  • Среда: QEMU 11.1.0, q35, TCG, 128 МиБ RAM, 1 CPU.
  • SHA-256 образа: 2c14ea231397c3d09da4caebca0f707e7e6ca9f502119ddafd87178579a165c0.
  • Результат: два независимых активных окна; hit-test обоих владельцев вернул полный поколенческий ID; закрытое окно не найдено; отказ границ, перекрытия и устаревшего дескриптора проверен; 0 faults и остаточных IPC/capability/device/object-ссылок.

Граница

Это приёмка самостоятельного композитора и его реестра. Рабочий стол, менеджер окон, драйверы мыши/клавиатуры и приложения пока не подключены к нему в одном загрузочном графе. Этап не закрывает B-04/UI-05 и не подтверждает интерактивную оболочку.

Этап 079 — разреженная очистка `p_reap`

Прямая ссылка на отчёт

Статус: принят 9 ноября 2026 года в проверенных сценариях. Адресный native-сценарий и свежая QEMU-приёмка прошли. Изолированное время p_reap измерено в native-сценарии; QEMU-профиль проверяет корректность очистки, но не измеряет отдельно длительность p_reap внутри гостя.

Причина

После завершения компонента p_reap перебирал все 262 136 виртуальных страниц, хотя большая часть адресного окна могла не иметь таблиц PTE. Для разреженных отображений это создавало лишнюю работу, пропорциональную полному окну адресов.

Изменение

  • Обход теперь сначала проверяет 512 указателей таблиц процесса.
  • Отсутствующая таблица пропускается целиком. В каждой существующей таблице просматриваются 512 PTE.
  • Записи PTE 0–7 по-прежнему зарезервированы заголовком карты и не затрагиваются.
  • Присутствующие динамические кадры возвращаются, маркеры отложенного нулевого отображения очищаются, а исполняемые страницы остаются исключёнными из динамического освобождения.
  • Таблица PTE №0 сохраняется до завершения обхода; остальные таблицы освобождаются после очистки их записей.

Для адресного пространства с T существующими таблицами обход проверяет 512 указателей и до 512 × T записей вместо 262 136 записей независимо от разреженности. Это оценка количества проверок по структуре алгоритма, не результат замера времени.

Проверка

Native-приёмка:

python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

PASS, один целевой тест. Он оставляет живое отображение в таблице PTE №511 до завершения компонента и проверяет очистку, возврат физических страниц, компонентного слота и связанных ресурсов. Замер одного вызова p_reap после завершения трёх компонентов — 163,3 мкс на native-хосте. Это единичный замер текущей сборки; он не является универсальной задержкой или замером гостевого QEMU.

Свежая сборка и QEMU-приёмка:

python tools/host/build.py --platform-case память --out work/reap-sparse-final
python tools/host/qemu_acceptance.py --build work/reap-sparse-final --qemu <QEMU 11.1.0> --timeout 90

PASS, QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Три CPL3-компонента одновременно использовали по 521 динамическому отображению, включая адрес 0x83ffff000 в таблице №511. После завершения checker прочитал таблицу карт страниц: все 512 указателей PTE-таблиц в каждом из трёх слотов обнулены. Возвращено 1594 страницы; faults, capability, IPC, device lease и object reference остатки — 0. Полное наблюдаемое время сценария QEMU — 0,805 с; это время всей загрузки/нагрузки, а не отдельного p_reap.

Образ SHA-256: 6d29f933e372799a506449792daf011eb736cc4082ec1d836306d6c872195452.

Артефакты: QEMU-отчёт, проверка платформы, сборка.

Границы

  • QEMU-профиль памяти подтвердил очищение всех ссылок на таблицы PTE после завершения; отдельный гостевой тайминг p_reap не снимался. Native-замер выше относится только к текущей Windows-хостовой сборке и трём завершённым компонентам.
  • Проверен кодовый путь TLB: p_reap сначала переключается на корневые таблицы ядра; обычное освобождение собственной активной страницы перезагружает CR3 через activate_paging, который временно снимает PGE и восстанавливает его, чтобы сбросить также глобальные записи. При возвращении в компонент ассемблерный мост загружает CR3 выбранного контекста. Это анализ кода, не отдельное гостевое испытание; SMP и PCID не входят в текущую однопроцессорную конфигурацию.
  • Политика планировщика и ABI потоков не менялись.

Этап принят для текущей конфигурации x86-64/QEMU и native-проверки. SMP, PCID, другое оборудование и отдельный гостевой профилировщик времени не входят в эту приёмку.

Дополнительная проверка 12 ноября 2026 года

После принятия этапа изменён поиск динамических записей p_reap: отсутствующая группа метаданных теперь пропускается целиком, максимум 256 записей. Это сохраняет очистку существующих отображений и не меняет ABI или планировщик.

Профиль память собран и принят целевым QEMU-прогоном из основной папки проекта. Две CPL3-нагрузки проверили по 8 193 последовательные страницы, запись/чтение крайней страницы и дополнительное разреженное отображение 0x800200000. Четыре поколения компонентов завершились без faults и утечек полномочий, IPC, device leases или ссылок; PMM сверил bitmap и оставил только одну закреплённую загрузочную страницу. Образ SHA-256: 5f1b918f3615e3cd2386cb973dcfe911e9b6a3eed119fcd67d3cf671c237b9a4.

Артефакты новой приёмки: QEMU, платформа, PMM, сборка. Отдельное время этой редакции p_reap не измерено; исторический native-замер выше не переносится на новую редакцию.

Этап 078 — исправление очистки `p_reap`

Прямая ссылка на отчёт

Статус: проверено адресным native-test. QEMU и полный набор не запускались.

Причина

p_spawn сохранял базу и размер кода в process+72 и process+96. При этом process+96 также хранит RIP последнего fault, который записывает диагностический механизм. p_reap принимал RIP за размер кода. После диагностической записи, например RIP 0x800001234, вычисленная длина исполняемого диапазона ошибочно исключала динамические PTE из очистки. Аналогичное неверное поле использовалось при проверке RIP в platform_dispatch.

Это объясняет прежний отказ: динамические страницы оставались учтёнными, поэтому component_reclaim не мог освободить запись компонента.

Изменение

  • База и размер исполняемого диапазона теперь хранятся в заголовке карты процесса: page_map+8 и page_map+16.
  • p_spawn записывает эти метаданные туда; p_reap использует их при сохранении загрузочных отображений, а platform_dispatch — при проверке границ исполнения.
  • process+96 остаётся полем RIP диагностики. Начальный счётчик страниц отделён от высокого адреса и хранится в page_map+4096.
  • Удалена временная диагностика. Перебор таблиц PTE оставлен без изменений.

Проверка

Запущена адресная команда:

python -m unittest tests.kernel.test_platform.PlatformTests.test_common_objects_and_devices -v

Результат: PASS. Компилятор собрал native-test из текущих исходников; интегрированный сценарий проверил динамические отображения, fault-диагностику с RIP 0x800001234, завершение трёх компонентов и p_reap. После очистки компонентный учёт достиг нуля, запись компонента была возвращена, PMM восстановил 516 кадров, остаточные component/capability/IPC/device/object ресурсы отсутствовали.

Границы

  • Проверен native-test платформы, не гостевая QEMU-сборка.
  • Полная регрессия K8 не запускалась.
  • Результат закрывает только найденную ошибку совместного использования полей и целевой сценарий очистки; он не является доказательством остальных свойств KERNEL 1.0.

Этап 077 — адресный выбор карточки рабочего стола

Прямая ссылка на отчёт

Статус: завершён в пределах проверки выбора карточки и видимого отклика мыши в shell-live; запуск приложений карточками и UI-05 остаются отдельными задачами.

Реализация

  • Рабочий стол проверяет координаты указателя при нажатии левой кнопки. Попадание в одну из трёх информационных карточек выделяет её рамкой; прежнее выделение снимается. Перенос выбора на нажатие нужен для немедленного отклика в живом цикле ввода.
  • Результаты очистки экрана и операций рисования учитываются в общем счётчике ошибок начального кадра.
  • Размер кода рабочего стола превысил одностраничный профиль. Сборка shell-live теперь помещает его в многостраничный пакет GUP1 v2.
  • Карточки пока не запускают приложения. Отрисовка по-прежнему идёт напрямую через syscall 42/43. Частный ABI одной поверхности syscall 32/33 уже существует, но отдельные независимые поверхности окон под управлением композитора не реализованы.

Проверка

  • Свежая сборка: python tools/host/build.py --out work/init04-shell-live-final --platform-case shell-live — PASS.
  • Свежий QEMU 11.1.0/q35/TCG: python tools/host/qemu_acceptance.py --qemu <путь-к-qemu-system-x86_64.exe> --build work/init04-shell-live-final --timeout 60 — PASS.
  • Проверена цепочка IRQ → полный пакет PS/2 → IPC → ответ рабочего стола; кадр 1280×800 содержит визуальный отклик и подсветку второй карточки.
  • SHA-256 проверенного образа: 939f045fa07206bfbe32142c24392d6bdc353a37e467d67edfaeeb9117978be3. Отчёт: interactive-report.json.
  • Предыдущая запись о недоступном QEMU относится к первоначальному поиску; позднее бинарник найден в соседнем проектном checkout.

Следующий шаг и граница

Карточки пока не запускают приложения, а рабочий стол рисует напрямую через syscall 42/43. Следующий графический блок — подключить приложения к отдельным поверхностям и свести их с маршрутизацией ввода в работающем пути композитора. Проверка shell-live не закрывает INIT-04 (физический ввод через окно Dev Shell и K8) и UI-05 (композиция независимых окон и отказоустойчивость).

Этап 076 — понятный отклик на ввод мыши

Прямая ссылка на отчёт

Статус: проверен синтетическим щелчком QMP в QEMU. Физический клик из окна Dev Shell не проверялся.

Результат

  • Рабочий стол CPL3 явно подтверждает принятый щелчок: строка состояния окрашивается в бирюзовый цвет и показывает «ПРИНЯТ»; индикатор мыши увеличен до 40×40 пикселей.
  • Ранее проверялся только небольшой индикатор, поэтому пользователь мог не заметить обработку ввода. Теперь QEMU-приёмка проверяет цвет индикатора и пиксель широкой строки состояния.
  • Карточки «Компоненты», «Память» и «Устройства» остаются информационными: щелчок подтверждается, но карточка пока не открывает приложение или отдельный экран.

Проверка

  • Свежий образ собран командой python tools/host/build.py --out work/click-feedback-release --platform-case shell-live.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU: shell-live — PASS; BOOT.MAN загружен, MOUSE:READY, событие дошло по цепочке IRQ → пакет мыши → IPC → ответ рабочего стола.
  • Размер кадра 1280×800. Проверены цвет индикатора в (500, 628) и бирюзовая строка состояния в (222, 606); индикатор отделён от строки, чтобы отклик читался как два ясных элемента.
  • SHA-256 образа: 3d040260623b93ff6f6268451e8c03e395f655865ab602860af0f5b0c5488f32.
  • Отчёт QEMU · кадр после щелчка.

Граница

QMP подал синтетическое событие. Этот результат не доказывает работу физического щелчка пользователя через окно Dev Shell. Путь передачи относительного движения мыши из Dev Shell остаётся отдельной приёмкой; INIT-04 не закрыт.

Этап 075 — видимый отклик рабочего стола на мышь

Прямая ссылка на отчёт

Статус: проверен в QEMU; настоящая мышь пользователя через Dev Shell отдельно не проверялась.

Изменение

  • Рабочий стол CPL3 показывает метку «ВВОД МЫШИ» и индикатор состояния: серый до события, янтарный при нажатой кнопке и бирюзовый после отпускания.
  • При событии рабочий стол по-прежнему сохраняет координаты и состояние кнопки в своей странице данных. Остальная сцена не очищается и не перерисовывается.
  • Приёмочный сценарий shell-live дополнительно проверяет конечный цвет индикатора в кадре QEMU. Теперь успешная доставка IPC сама по себе недостаточна для PASS: нужен также видимый пиксельный отклик.

Проверка

  • python -m py_compile tools/host/qemu_acceptance.py — PASS.
  • Свежая сборка shell-live и QEMU 11.1.0/q35/TCG, 128 МиБ, 1 CPU — PASS.
  • Проверена цепочка IRQ → полный пакет мыши → IPC → ответ рабочего стола; экран 1280×800; точка индикатора после клика и отпускания равна бирюзовому цвету активного состояния.
  • SHA-256 образа: cd660739ee9ae849d4b8022cb3598345dcb64bbe2df0873379a64cfa17687f85.
  • Отчёт QEMU, кадр экрана.

Границы

  • Индикатор доказывает, что событие дошло до рабочего стола. Он пока не делает карточки приложений действующими кнопками и не запускает программы.
  • QEMU передал синтетическое нажатие через QMP. Клик физической мышью из пользовательского окна Dev Shell ещё не принимался.
  • Отдельная попытка профиля shell-input завершилась тайм-аутом до MOUSE:READY; Dev Shell запускает shell-live, который прошёл. Причина тайм-аута shell-input не исследовалась и остаётся отдельной задачей.

Этап 074 — многостраничный код в общем загрузчике CPL3

Прямая ссылка на отчёт

Статус: общий многостраничный код принят до предела GUP1 v2; COMP-05 остаётся открыт.

Цель

Снять одностраничное ограничение исполняемого кода для общего механизма spawn, сохранив GUP1 версии 1 и старую раскладку без изменений.

Реализация

  • Формат GUP1 версии 2 разрешает код размером 4097–28672 байт; точка входа остаётся смещением от начала кода.
  • Host-сборщик умеет линковать такой образ по адресу диапазона кода версии 2 и упаковывать его.
  • package_valid принимает обе версии с отдельными пределами. Статический legacy-загрузчик явно оставлен на версии 1.
  • Общий p_spawn выделяет кадры с учётом количества страниц кода, отображает код страницами RX и записывает фактическую границу кода в запись компонента.
  • Проверка возврата из CPL3 использует границу кода экземпляра, а p_reap не освобождает страницы кода дважды при обходе динамических отображений.
  • Список кадров, которыми владеет компонент, хранится в его карте страниц (page_map+64), отдельно от диагностических счётчиков записи процесса. Чтение списка при создании, очистке и снимке отображений использует одно расположение.
  • Данные и стек сохраняют прежнюю раскладку: одна RW/NX-страница данных и четыре RW/NX-страницы стека.

Проверка

  • python -m unittest tests.kernel.test_process_policy.ProcessPolicyTests.test_package_builder_matches_guest_gup1_contract — PASS (1 тест).
  • python -m py_compile tools/host/platform_check.py tools/host/build_impl.py tools/host/app_build.py tools/host/build_component_package.py — PASS.
  • Старый формат проверен заново: workers в QEMU 11.1.0/q35/TCG, 128 МиБ, 1 CPU — PASS; 3 компонента завершились, 30 принадлежащих им страниц возвращены, faults и остаточные capability/IPC/device/object ссылки равны 0. SHA-256 образа 05b83d65bc4902267ea9a2b76d26b8a4926e225121488a26359dac12fbf57216.
  • Новый формат проверен в QEMU 11.1.0/q35/TCG, 128 МиБ, 1 CPU — PASS; код из второй страницы исполнился, компонент завершился, возвращены 11 принадлежащих ему кадров, faults и остаточные capability/IPC/device/object ссылки равны 0. SHA-256 образа 782239652b58b0fef62d0f13a89bf5e2c33986f4ac77649e1eeafbb85399159b.
  • После увеличения пакета до предельных 28 672 байт (7 страниц кода) QEMU исполнил точку входа на седьмой странице, проверил RW/NX-данные, завершение и возврат 16 кадров: PASS, 0 faults и остаточных ссылок. SHA-256 образа 35c82b7d4703d7fa3e00ac2f0b073829c9de23a4ee555ad03fa4ab42c235487c; отчёт предельного пакета.
  • При приёмке предельного пакета обнаружилось пересечение расширенного списка кадров с полями record+232/+240/+248, которые используются очисткой и диагностикой давления памяти. Список перенесён в page_map+64; syscall 37 также переведён на это расположение. Свежий регрессионный workers в QEMU прошёл: 3 компонента, 30 возвращённых кадров, 0 faults и остатков. SHA-256 a7146fc5850afb06086f6711bb3328358d380e1bc16f5242429e899ca8539deb; отчёт workers после исправления.
  • Проверка контракта сборщика python -m unittest tests.kernel.test_process_policy.ProcessPolicyTests.test_package_builder_matches_guest_gup1_contract -v — PASS (1 тест). Отчёты прежних проверок: workers v1 и исполнение со второй страницы.

Ограничения

  • Общий список владения содержит 16 кадров; при четырёх таблицах страниц, одной странице данных и четырёх страницах стека это ограничивает код семью страницами.
  • Динамические данные и стек, а также UART-приём версии 2 не реализованы.
  • QEMU проверил размер кода 4097 байт и предельный размер 28672 байта с исполнением на седьмой странице; отдельные тесты точного максимального смещения точки входа и каждого промежуточного размера не проводились.
  • Текущий этап открывает общий путь отображения многостраничного кода, но не закрывает COMP-05.

Этап 073 — переменная длина начальных данных GUP1

Прямая ссылка на отчёт

Статус: проверен в ограниченном объёме.

Изменение

  • Host-сборщик GUP1 принимает начальные данные длиной от 0 до 4096 байт и дополняет их только до границы 8 байт.
  • build_component_package.py без --initial-data формирует пакет без блока начальных данных; при заданном файле сохраняет только его содержимое с минимальным выравниванием.
  • Старые вызовы make_user_package(..., initial_data=None) оставлены совместимыми и продолжают формировать 4096 нулевых байтов.
  • Документированы поля формата и границы: код остаётся одностраничным, данные и стек при исполнении также имеют фиксированное размещение.

Проверка

  • python -m unittest tests.kernel.test_process_policy.ProcessPolicyTests.test_package_builder_matches_guest_gup1_contract — PASS.
  • python -m unittest tests.kernel.test_live_package_protocol — 5 тестов PASS, включая пакет с нулевым блоком данных.

Сборка образа и QEMU не запускались: изменён только host-сборщик и его контрактный тест; гостевой валидатор уже принимал длину данных от 0 до 4096 байт.

Ограничения

Это частичная работа COMP-05. Снято фиксированное хранение полного блока данных в пакете, но не фиксированные размеры и адреса кода, отображённой области данных и стека. Полноценное расширение требует общего описания сегментов и безопасного отображения/освобождения переменного числа страниц в обоих путях запуска.

Этап 072 — критичность и отказы графа загрузки

Прямая ссылка на отчёт

Состояние: INIT-05 принят, 9 ноября 2026 года. Проверены манифест BOOT.MAN версии 2 с критичностью, топологический запуск, необязательный отказ, критический отказ, блокировка зависимого узла и очистка ресурсов. INIT-04 остаётся в работе: проверка физического клика сохранения диагностики в Dev Shell и контрольная регрессия K8 не выполнялись.

Реализация

  • BOOT.MAN версии 2 добавляет флаг критичности к каждой записи; загрузчик сохраняет чтение версии 1. Валидатор принимает только значения критичности 0 и 1.
  • Общая запись графа расширена до 32 байт: поколенческая идентичность узла, зависимости, состояние и критичность.
  • При отказе необязательной службы её потомки блокируются, но независимые и уже готовые компоненты сохраняют работу. Критический отказ закрывает граф с кодом диспетчера 7409; причина исходного отказа остаётся у компонента.
  • Исправлен проверочный пакетный профиль: второй READY-компонент теперь получает собственную роль вместо копии с нулевой ролью. Диагностические счётчики перемещены за пределы таблицы из четырёх узлов, чтобы не затирать последнее состояние графа.

Приёмка

  • Свежая сборка work/init05-boot-manifest-final, QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. Встроенный манифест: 160 байт. Два READY-обмена выполнены в порядке зависимости, хотя зависимый пакет стоит первым в файле; цикл, повтор ID, неверная длина и критичность 2 отклонены. Итог: 3 созданных компонента, 30 освобождённых страниц, 0 faults, 0 незавершённых IPC-запросов. Состояния графа: готово, отказ, готово, заблокировано. SHA-256 образа 54000cf7e8e7b48ade6ade06341c289f999c584b8d5449c1c28faeb680524024. Отчёт QEMU · проверка графа.
  • Свежая сборка work/init05-optional-final — PASS. Необязательная мышь остановлена с INIT-READY-REFUSED-7401; диспетчер и рабочий стол активны, IPC-запросов 0. SHA-256 238184ebb1b18ed617fe052eb85f41af5099a11dc9a1406dba170d01347ec703. Отчёт отказа.
  • Свежая сборка work/init05-critical-final — PASS. Критический отказ INIT-READY-REPLY-FAILED-7406 сохранён, диспетчер завершён с 7409, рабочий стол и диспетчер остановлены, IPC-запросов 0. SHA-256 df47013a7a67463d79bf82adb8d5cfb6768ad247ac670cd8b9a507aa8ce71d91. Отчёт отказа.
  • py_compile для затронутых host-модулей и git diff --check прошли. У git diff --check только предупреждения Git о переводах строк в уже изменённых файлах.

Границы

  • Это адресная приёмка INIT-05, а не полный K8 и не проверка на физическом компьютере.
  • Проверен граф из четырёх узлов в автомате и две реально запущенные службы в сквозном сценарии; загрузка 32 служб и чтение каталога пакетов с пользовательского тома сюда не входят.
  • INIT-04 остаётся незакрытым до UI-клика по сохранению диагностики и полной контрольной регрессии K8.

Этап 071 — интерактивный запуск по графу BOOT.MAN

Прямая ссылка на отчёт

Текущее состояние: INIT-04 частично принят, 9 ноября 2026 года. QEMU подтвердил интерактивную загрузку и коды 7401–7408 отдельными сценариями; сохранение диагностического ZIP проверено вызовом обработчика команды в живой headless-сессии. Физический щелчок в окне намеренно не эмулировался; полная K8-регрессия не запускалась. INIT-04 остаётся в работе до этих двух пунктов.

Изменение

  • Устранено нецелевое подключение GSL-библиотеки кучи ко всем приложениям и службам. Теперь её подключают явно только приложения, которые используют память. Обычное демонстрационное приложение сохраняет библиотеку; оболочка, загрузочный диспетчер и IPC-пробы не получают неиспользуемый код.
  • Из-за лишней библиотеки интерактивный рабочий стол превышал лимит кода пакета в 4 КиБ: 4154 байта. Без неё размер .text рабочего стола — 2679 байт. Сама модель загрузки пользовательского кода по-прежнему ограничена одной страницей; этот этап её не расширяет.
  • Интерактивный shell-live использует манифест BOOT.MAN: запись мыши стоит перед записью рабочего стола, но объявляет рабочий стол зависимостью. Диспетчер запускает рабочий стол первым, принимает его READY, затем запускает драйвер мыши и принимает READY.

Приёмка

  • python tools/host/build.py --out work/init04-shell-live --platform-case shell-live — PASS.
  • python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/init04-shell-live --timeout 90 --ram 128 — PASS.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: манифест загружен; мышь сообщила READY; контрольное QMP-событие дошло по цепочке IRQ → пакет → IPC → ответ рабочего стола. Счётчики пути: IRQ=3, полный пакет=1, IPC=1, ответ=1. Получен экран 1280×800.
  • Образ SHA-256: bdce547a3e5cd176a64a27b1f3e7efb510b5e44b1504c1bbd342a39815282460. Свежий отчёт: interactive-report.json, build-report.json.

Граница

Приёмка подтверждает только штатный двухузловой граф интерактивной сборки. Отдельные причины отказа READY, истечение срока READY, повреждённый граф в интерактивном пути, отказ критической/необязательной службы и полная регрессия K8 не проверялись. Поэтому INIT-04 и INIT-05 остаются незакрытыми.

Дополнение: диагностика READY

  • Диспетчер возвращает отдельные коды 7401–7408 для отказа службы, тайм-аута, закрытия канала, неправильного сообщения, ошибки подключения/ответа, запуска пакета и остановки графа. Нормальный READY сохраняет прежний ответ с дескриптором канала зависимости.
  • При неуспехе диспетчер просит ядро завершить ещё живого дочернего компонента с той же причиной; затем завершает себя с тем же кодом. Ядро уже сохраняет причину завершения в записи процесса.
  • diagnostic_catalog.py расшифровывает коды. kernel_observer.py включает причину завершения в снимок компонента; Dev Shell показывает стабильный ID и русское описание.
  • Нативная проверка декодирования: python -m unittest tests.integration.test_kernel_observer — 10 PASS. После этой правки повторно собран образ work/init04-status-codes; штатный сценарий test_boot.py прошёл с образом SHA-256 6bde63b80b12ecf7c98cabc7a2030a1e6f15cba29b7ccee8fda0b69f5d93328c.
  • Не проверены в госте остальные причины отказа и фактическое отображение сохранённого кода на аварийном срезе. Это остаётся работой INIT-04.

Дополнение: гостевые отказ и тайм-аут READY

  • Добавлены отдельные сценарии интерактивной загрузки: зависимая служба отвечает явным отказом READY, либо остаётся активной и не отправляет READY.
  • Первый запуск выявил две ошибки сценария: проба отправляла срок IPC выше разрешённого значения, а диспетчер затирал исходную причину отказа общим кодом остановившегося графа. Проба теперь укладывается в предел IPC, а код 7408 назначается только если более конкретная ошибка не возникла.
  • Свежие образы проверены в QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Оба сценария завершились PASS: отказ получил ID INIT-READY-REFUSED-7401, тайм-аут — INIT-READY-TIMEOUT-7402; в обоих случаях причина сохранена у диспетчера и дочерней службы, рабочий стол остался активен, незавершённых IPC-запросов — 0, экран — 1280×800.
  • Хеши образов: отказ 489372cd8e74e03688ccec1d9a2180cc76ce332823328c1b2f27647c6cda6f23; тайм-аут 94ded6a0f7e08d7c5aee87b09b196d01276a424ccc7e5ee817a0906bcdf48de4. Отчёты: отказ READY и тайм-аут READY.
  • INIT-04 остаётся в работе: в госте не проверены закрытие канала, неверная структура READY, остальные коды подключения/ответа/запуска/остановки графа и фактический аварийный срез Dev Shell. Полная регрессия K8 не запускалась.

Дополнение: завершение дочерней службы до READY

  • Проверка обнаружила границу общего IPC-mailbox: служба отправляет READY в очередь родителя, поэтому завершение одного отправителя не закрывает саму очередь, пока у неё есть другие отправители. Обычное ожидание receive не может само по себе определить, что завершился именно ожидаемый дочерний компонент.
  • Добавлен supervisor-only syscall 50. Аргумент — полный поколенческий ID компонента; результат 0 означает, что компонент активен, IPC_PEER_CLOSED — что он завершён или ID устарел, отказ полномочий возвращается отдельно. Диспетчер готовности чередует проверку этого ID с коротким ожиданием IPC, сохраняя общий предел ожидания в 100 тиков.
  • Свежая сборка: python tools/host/build.py --platform-case оболочка-готовность-закрытие --out work/init04-closed-channel-fixed (Clang 22.1.8, rust-lld), результат PASS. QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU: INIT-READY-PEER-CLOSED-7403; диспетчер завершён с причиной 7403, проба — с причиной 0, рабочий стол активен, активных IPC-запросов 0, экран 1280×800.
  • Дополнительно проба CPL3 без права запуска служб вызвала syscall 50; QEMU-сценарий подтвердил отказ IPC_DENIED.
  • SHA-256 образа: fa9dfab08fc3698e3f0f305b77763f43a80f3effe20471abb9bd04a0febabab1. Отчёт закрытия до READY.
  • Ограничение: syscall 50 разрешён только компоненту с правом запуска служб и сообщает только состояние переданного полного ID. Эта приёмка не покрывает неверный READY, прочие коды отказа и снимок Dev Shell; полной регрессии K8 нет.

Дополнение: неверная структура READY

  • Добавлена изолированная проба, отправляющая сообщение READY с неподдерживаемым методом. Диспетчер отклоняет пакет с диагностическим кодом 7404 и завершает дочернюю службу с той же причиной.
  • Свежая сборка work/init04-malformed-ready и адресный QEMU 11.1.0/q35/TCG/128 МиБ/1 CPU — PASS: причины завершения [7404, 7404], рабочий стол активен, незавершённых IPC-запросов 0, экран 1280×800.
  • SHA-256 образа: c112beba9bdfc70af885cc00a8c0e98e3b441931b367fb4a8701f6d0bbbe97d7. Отчёт проверки.
  • Ограничение: проверен неверный метод READY; прочие некорректные поля и коды отказа, аварийный снимок Dev Shell и полная регрессия K8 не проверялись.

Дополнение: отказ запуска пакета службы

  • Добавлен профиль с повреждённой сигнатурой GUP1 у дочернего пакета. Манифест остаётся структурно допустимым; ядро отклоняет запуск пакета, а диспетчер сохраняет диагностическую причину 7407.
  • Свежая сборка work/init04-start-failure и QEMU 11.1.0/q35/TCG/128 МиБ/1 CPU — PASS: диспетчер завершён с кодом 7407, рабочий стол активен, незавершённых IPC-запросов нет, экран 1280×800.
  • Диагностический ID согласован с каталогом: INIT-SERVICE-START-FAILED-7407. SHA-256 образа a03e62ac59d0bf79dd56845f24874742106eabf3cf57ab67090110d187dcef6a. Отчёт.
  • Ограничение: проверен только отказ пакета из-за неверной сигнатуры; ошибки подключения/ответа и остановившийся граф ещё не проверены.

Дополнение: аварийный снимок до READY

  • В platform_acceptance добавлена русская точка ПЛАТФОРМА: среда компонентов готова к запуску служб после инициализации таблиц и до запуска служб. Наблюдатель Dev Shell принимает эту отметку как безопасный момент для чтения компонентной диагностики.
  • Проверен реальный путь QemuSession → действие сохранения диагностики на работающей QEMU-сборке с отказом 7407. Архив содержит screen.ppm, снимок компонентов, журнал и отчёт сборки; JSON читается как UTF-8, все SHA-256 из манифеста совпали.
  • В архиве зафиксированы освобождённый компонент 65537 с причиной INIT-SERVICE-START-FAILED-7407, ожидающий рабочий стол 65538 и 0 незавершённых IPC-запросов. Сквозная QEMU-приёмка подтвердила активность рабочего стола.
  • Образ SHA-256 d474c928fb57be16184a0d9016e2c94dc49085d46777ee9d1ca0abfdcbc40e5d. Отчёт проверки архива · архив снимка.
  • Ограничение: сохранение вызвано через кодовый QemuSession без клика по окну Dev Shell; ошибки подключения/ответа, код 7408 и полная регрессия K8 не проверялись.

Дополнение: ошибки соединения и подтверждения READY

  • Добавлены адресные профили 7405 и 7406. Для 7405 квота полномочий дочернего компонента доводится до текущего расхода; снимок подтвердил реальный отказ syscall соединения IPC_LIMIT. QEMU 11.1.0/q35/TCG/128 МиБ/1 CPU — PASS: причины [7405, 7405], остановлены диспетчер и мышь, рабочий стол активен, IPC-запросов 0, экран 1280×800. SHA-256 1a0efbbbb378fe0cc98996068ae6a60d4ef615e47542d26f8ec559ab812cee6e; отчёт 7405.
  • Для 7406 проверяется недействительный билет самого системного вызова ответа, а не поле билета внутри пакета. QEMU 11.1.0/q35/TCG/128 МиБ/1 CPU — PASS: сохранён INIT-READY-REPLY-FAILED-7406, граф завершён с причинами [7406, 7406], остаточных IPC-запросов нет. Рабочий стол уже не активен; последний кадр остался на экране 1280×800. Это подтверждает аварийное завершение графа, а не доступность оболочки после ошибки. SHA-256 2bcb445d591aa64dfd9903c902b78b1399fa9dec316b8bd145814d641dcd577c; отчёт 7406.
  • INIT-04 остаётся в работе: не приняты 7408, проверка клика по сохранению диагностики в живом Dev Shell и полная регрессия K8.

Дополнение: защита от остановившегося графа

  • Штатный BOOT.MAN проверяется ядром до старта службы, поэтому отдельный профиль меняет только CPL3-копию записи после проверки: узел мыши начинает зависеть от самого себя. Проверка графа диспетчера обнаруживает цикл и возвращает 7408 без зависания и без запуска ошибочной службы.
  • Свежая сборка work/init04-graph-stall, QEMU 11.1.0/q35/TCG/128 МиБ/1 CPU — PASS: INIT-GRAPH-STALLED-7408, диспетчер завершён с причиной 7408, рабочий стол активен, активных IPC-запросов 0, экран 1280×800. SHA-256 fe1354513a10fa4face009d3cdb403b8b9a26b091f4f0c1aa845ec5f97c7f34a; отчёт 7408.
  • Это приёмка защитной ветви после изменения пользовательской копии, а не проверка загрузки испорченного файла: исходный манифест по-прежнему отклоняется проверкой ядра до запуска.
  • INIT-04 остаётся в работе: нужно проверить клик по сохранению диагностики в живом Dev Shell и выполнить полную регрессию K8.

Дополнение: команда сохранения диагностики через обработчик Dev Shell

  • На свежей сборке с отказом запуска службы 7407 программно вызван тот же DevShell._save_diagnostics, который подключён к кнопке, в активной QemuSession; GUI и компьютер пользователя не управлялись.
  • Экспорт завершился PASS: ZIP содержит 16 файлов, все SHA-256 совпали, присутствуют экран и состояние компонентов; сохранена русская диагностическая заметка.
  • Ограничение: реальный щелчок по кнопке в окне не проверялся; K8-регрессия не выполнялась.

Этап 070 — динамические отображения без предела 504 слота

Прямая ссылка на отчёт

Состояние: в работе. Запись от 9 ноября 2026 года.

Цель

Сделать заявленное окно MEM-11 на 262 136 страниц реально доступным, а не ограниченным вспомогательной таблицей размером 504 записи.

Изменения

  • PTE текущего адресного пространства стал источником истины для динамических отображений. Убрана зависимость операций выделения, возврата, повторной материализации, резервирования, снимков памяти и уборки компонента от 504-элементного списка.
  • Исправлен порядок завершения компонента: динамические PTE и дополнительные таблицы очищаются до возврата закреплённых кадров, содержащих базовую таблицу PTE. Ссылка на базовую таблицу удаляется из метаданных слота до возврата кадра.
  • Устаревший предел квоты 514 страниц заменён пределом 262 657 страниц: 10 закреплённых кадров, 262 136 страниц динамического окна и до 511 дополнительных таблиц PTE. Тестовый запуск выставляет каждому из трёх компонентов квоту 520 страниц — этого хватает для 505 обычных страниц, верхней страницы окна и дополнительных таблиц; физическую выдачу по-прежнему ограничивает PMM.
  • Таблица страниц определяется из номера виртуальной страницы; отсутствующая таблица создаётся по требованию. Для адреса, чей кадр вернули распределителю, используется программная метка PTE 0x200: адрес остаётся зарезервированным и может быть материализован повторно.
  • Подсказка ближайшего свободного адреса хранится в метаданных, чтобы последовательно размещать страницы и повторно использовать освобождённые дыры без полного сканирования окна на каждом запросе.
  • Наблюдатель Dev Shell читает кадры и права из PTE, учитывает метки возвращённых страниц, high-water и таблицы страниц; QMP-сборщик получает указатели таблиц независимо от прежнего списка отображений.
  • Профиль --memory-test больше не включает supervisor-сценарии. Они не относятся к испытанию памяти и ранее блокировали образ при превышении одностраничного лимита managed_client.gsl.

Целевые проверки

  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS. Сценарий создаёт 505 динамических страниц одновременно, проверяет переход через PTE №511 во вторую таблицу (запись №512), затем проверяет освобождение/повторное размещение, возврат чистых страниц и давление PMM.
  • Тот же адресный нативный сценарий повторно прошёл после изменения порядка очистки p_reap.
  • Проверено изменение предела p_limit: максимальная допустимая квота 262 657 принимается, 262 658 отклоняется.
  • python -m unittest tests.integration.test_kernel_observer — 9 PASS, включая извлечение отображений из PTE, маркеры возвращённых страниц, некорректные права и адрес выше high-water.
  • Свежая сборка python tools/host/build.py --out work/mem17-pte-truth --memory-test — PASS.
    • EFI SHA-256: bf5c6a445f70b49a57ef9529e1f56f977ad827b583588f28246f938ae92a6510.
    • Образ SHA-256: 345e04f4274be930cc3e1754c4a280205c8361665cf1a20d400014f99a4a18c6.
  • Дополнительно собран целевой гостевой сценарий трёх компонентов: python tools/host/build.py --out work/mem17-platform-memory --platform-case память — PASS.
    • EFI SHA-256: 0a5a7756c8f8680fe9a6a55ea770eafe81a7c9518fc38df5735c7060c072b015.
    • Образ SHA-256: d52bda8f281ef523b89cdebc7586c47c14b4ef151c73326f88908bdbc2fa0ab6.
  • Гостевая программа и валидатор расширены: каждый из трёх компонентов запрашивает 505 последовательных страниц, записывает и проверяет их значения; дополнительно трогает последний VA 0x83ffff000. Валидатор требует сохранённые счётчик/контрольную сумму и проверяет баланс возврата кадров. После расширения квоты и порядка p_reap профиль пересобран: EFI SHA-256 1daacf410c183e529f4942f272da98c73ef54c5e0ccdd4649b8c7ac4b8190673, образ SHA-256 da23f74c0a4a76c09728a763ec7b779a9804b817eb248d3362dad5cc9d59feb6.

Границы

Нативные проверки и сборки подтверждают код и упаковку, но не запуск гостевой ОС. Для закрытия связанных пунктов MEM-11/13 нужно запустить свежий fingerprint в QEMU и получить PASS нового сценария: 505 одновременно отображённых страниц в каждом из трёх компонентов, чтение/запись через границу таблиц, доступ к последней странице окна, очистка PTE при завершении, возврат физических кадров и отсутствие повреждения соседних компонентов.

QEMU в рамках первоначальной записи не запускался. Не заявляются завершённая работа с 1 ГиБ физической RAM, подкачка, сжатие, вытеснение изменённых данных или общий heap для нескольких потоков.

Дополнение от 9 ноября 2026 года — целевая QEMU-приёмка

QEMU 11.1.0 обнаружен в локальной установленной среде. Свежие образы активной копии запущены на q35/TCG с 128 МиБ и одним CPU.

MEM-11: разреженное окно CPL3

  • python tools/host/build.py --out work/mem17-demand-fault-accepted --platform-case память — сборка PASS.
  • python tools/host/test_boot.py --qemu <локальный qemu-system-x86_64.exe> --build work/mem17-demand-fault-accepted --timeout 60 --ram 128 — QEMU PASS.
  • Каждый из трёх изолированных компонентов записал и прочитал 505 последовательных страниц, включая переход к следующей таблице PTE, а затем проверил последний адрес своего окна 0x83ffff000. Гостевой результат содержал число страниц 505 и контрольную сумму 6 361 485; общий учёт подтвердил возврат 1 548 динамических кадров.
  • SHA-256 образа: f2a6457b7258d0d83c9bfc455a4f81b69744b4fef412b13a724fbbb0f5387999.

MEM-12: изоляция аппаратного отказа CPL3

  • Профиль fault намеренно читает supervisor-only адрес 0x1000. QEMU подтвердил page fault: вектор 14, ID 6202, код CPU 5 (страница присутствует, доступ из user mode запрещён), адрес 4096.
  • Отказавший компонент не продолжил исполнение; два соседних компонента завершили пять шагов каждый. Возвращены все 30 стартовых страниц, живых capability, IPC-запросов, device lease и object reference не осталось.
  • Исправлен общий критерий GSL-сценария: намеренно faulted компонент не должен выдавать обычный progress=5. Исправлена ошибка host-проверки, которая ожидала код 4 вместо аппаратного кода 5 и пыталась читать динамические страницы после их возврата распределителю.
  • Свежая сборка work/mem17-context-fault-verified — QEMU PASS; SHA-256 образа f11dbc5114d0959afd726b08944e4d83e69c01335db6d055debd4da025be7d42.

Статус и границы

MEM-11, MEM-12 и MEM-13 приняты в указанных границах. MEM-10 закрыт отдельной QMP-приёмкой: снимок живого компонента ID 65537 показал high-water 262146 и 521 динамическое отображение; физическая память QEMU подтвердила таблицы PTE 0, 1 и 511, три контрольных VA и полное совпадение карты с PTE. Снимок, результат и хеш образа записаны в отчёте этапа 066 и mem10-live-snapshot.json. Полная матрица K8 и проверка на физическом компьютере не проводились.

После добавления MEM-15 workload на новом образе сделана повторная QMP-сверка: ID 65537 имел 522 динамических отображения, таблицы 0/1/511 совпали с картой, замечаний нет. PTE повторно материализованной чистой страницы присутствовал с аппаратным dirty=0; полный отчёт — в приёмке MEM-15.

Этап 069 — MEM-13: общий пользовательский heap для окна 1 ГиБ

Прямая ссылка на отчёт

Состояние: закрыт в границах описанной базовой кучи. Запись от 9 ноября 2026 года; исходные проверки и их ограничения сохранены ниже, свежая QEMU-приёмка добавлена отдельным разделом.

Изменение

  • Общий распределитель GSL расширен с 504 страниц до всей разреженной области из 262 136 страниц. Виртуальная ёмкость — 1 073 709 056 байт; после 16-байтового заголовка начального блока полезный предел равен 1 073 709 040 байтам.
  • Перед первым обращением heap вызывает syscall 48 для явного резервирования всего окна; при отказе он не пишет по незарезервированному адресу и может повторить запрос позднее. Тот же предел установлен в проверке syscall 44 и в поле ёмкости снимка V/C/R. Приложение не выбирает физические кадры: физические страницы создаются лениво по page fault ядра.
  • Проверка heap резервирует 1 ГиБ виртуального диапазона Windows и фиксирует только начальные страницы, чтобы крупный диапазон теста не превращался в 1 ГиБ физического commit.

Проверки

  • python tests/kernel/test_user_heap.py — PASS: GSL-код распределителя, выравнивание, разбиение/слияние, повторное использование, отказ за границей, двойное и чужое освобождение.
  • Проверен остаток в 16 байт: он присоединяется к выданному блоку, V учитывает фактически занятый размер, после освобождения V возвращается к нулю.
  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS: граница V syscall 44, предел V/C/R, давление PMM, повторное размещение и MEM-11 верхняя таблица PTE.
  • python tests/integration/test_kernel_observer.py — 9 PASS; python tests/kernel/test_memory_fault_classifier.py — 1 PASS.
  • Свежая сборка python tools/host/build.py --out work/mem13-heap1g --platform-case память — PASS. EFI SHA-256 0bfe40d5e57b92e7152b5252d8a2d1aa776314e6cc93721b4ea8f1c842e1bb0b; образ SHA-256 c03d2eeab366af6fe093b36ad2d0e473235cc2baa3428b540b3687b723de2ffe.

Граница приёмки

QEMU отсутствует в активной среде. Поэтому не подтверждены фактическое обращение приложения к последней странице heap, обработка CPL3 fault на ней и сохранение/возврат данных через эту границу. Нативный тест распределителя не подменяет такую приёмку. MEM-13 остаётся открытым; MEM-11 также ожидает гостевой QMP-снимок верхнего PTE.

Освобождение блока пока только меняет состояние heap и V-учёт: пустые физические страницы не возвращаются, несколько потоков не синхронизируются.

В текущей схеме heap резервирует весь доступный 1-ГиБ диапазон компонента. Отдельные системные резервы виртуальных адресов в этом же компоненте не смогут занять его часть; разделение heap и других VA-областей остаётся следующим архитектурным ограничением.

Дополнение от 9 ноября 2026 года — гостевая приёмка MEM-13

  • Исправлено совпадение номера режима heap со сценарием shell-live: heap получил отдельный режим 18, не требующий загрузочного манифеста.
  • Исправлен ожидаемый баланс физических страниц: каждый компонент оставляет материализованную страницу heap отображённой после освобождения блока, хотя V-учёт возвращается к нулю. Поэтому завершение двух компонентов возвращает 22 кадра: 10 стартовых и одну затронутую страницу heap на компонент.
  • Сборка: python tools/host/build.py --out work/mem17-cpl3-heap-final --platform-case куча — PASS.
  • Гостевая приёмка: python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/mem17-cpl3-heap-final --timeout 60 --ram 128 — PASS на q35/TCG, 128 МиБ, 1 CPU.
  • Два независимых CPL3-компонента через обычный GSL heap выделили 24 байта, записали и прочитали значение, освободили блок, повторно получили тот же адрес и снова освободили блок. Каждый получил пять шагов исполнения; ошибки пользователя, faults, capability, IPC-запросы, device lease и ссылки на объекты после завершения равны нулю.
  • Снимок syscall 45 для каждого компонента подтвердил V=0, C=0, R не менее 10 страниц, R_bytes = R × 4096, ёмкость виртуального окна 1 073 709 040 байт и flags=7. QEMU/host-приёмка подтвердила возврат 22 физических кадров.
  • Хеш образа: 3ac1a47055041316209c48164b410d5247e29f754e69e90e13c71ffa2cfdb2ba. Полный отчёт: boot-report.json.

MEM-13 закрыт только для базового однопоточного GSL heap и указанного сценария. Не заявляются возврат пустых страниц heap распределителю физических кадров, независимые пользовательские резервы внутри heap-окна, синхронизация heap между потоками или гарантия работы при полном использовании 1 ГиБ физической RAM.

Дополнение от 9 ноября 2026 года — гостевая приёмка MEM-14

Heap-профиль дополнен проверкой syscall 45 до освобождения выделенного блока. Запрошенные 24 байта выравниваются распределителем до 32 байт; каждый из двух CPL3-компонентов проверяет V=32 и C=0 при живом блоке, R больше 10 и R_bytes = R × 4096. После повторного выделения/освобождения итоговый снимок подтверждает V=0, C=0 и корректный R.

  • Native-проверка GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS (1 интегрированный тест; включает предел и отказ V, полномочия снимка и очистку).
  • Сборка python tools/host/build.py --out work/mem14-live-accounting --platform-case куча — PASS.
  • QEMU python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/mem14-live-accounting --timeout 60 --ram 128 — PASS, q35/TCG, 128 МиБ, 1 CPU. Два компонента достигли progress=5; возвращено 22 страницы, faults=0, остаточных capability/IPC/device/object ресурсов нет.
  • SHA-256 образа 8803dfbedebc85ab7593226cd26e1f6d199101bb87b25d3994236b8016414964; проверенные байты сохранены в platform-0-page-5.bin, итог — boot-report.json.

MEM-14 закрыт в этих границах. V — диагностический самоотчёт компонента и не служит защитной квотой; C пока не резервирует физическую память и равен нулю. MEM-15 и MEM-16 остаются открыты до гостевой проверки.

Этап 068 — MEM-11: расширение разреженного окна виртуальной памяти

Прямая ссылка на отчёт

Состояние: в работе. Запись от 9 ноября 2026 года.

Что изменено

  • Метаданные карты отображений увеличены до 16 КиБ на компонент. В них раздельно хранятся физические кадры, ключи виртуальных страниц, указатели на таблицы PTE и интервалы явного резерва.
  • Динамическое окно расширено с 504 страниц (2 МиБ) до 262 136 страниц (около 1 ГиБ) на компонент. Физические кадры и дополнительные таблицы выделяются по мере обращения; один системный вызов резерва не заполняет весь объём физической памятью.
  • Наблюдатель QMP и его fixtures переведены на разреженные ключи страниц и новую запись таблиц. Проверяются PTE, освобождённые чистые страницы и интервалы резерва.
  • Реализованы поиск, освобождение и повторное использование страниц внутри интервалов. Освобождённая чистая страница сохраняет виртуальный адрес, а backing frame возвращается PMM.

Проверка

  • Свежая сборка python tools/host/build.py --out work/mem11-sparse --platform-case память — PASS. EFI SHA-256 38448379517112953066bed8d39b2c0edf5445e0ddf65d14cc62041c78f2c84b; образ SHA-256 ffe9b0792c7b722f593fb6d992e409af2921d269722a61db1066c32f0cc554c7.
  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS. Сценарий подтвердил автоматический путь исчерпания PMM → возврат до четырёх чистых страниц → одна повторная попытка. Прежний 0xC0000005 исчез после разделения первой попытки материализации и отдельного действия возврата/повтора.
  • Тот же нативный сценарий проверил последний адрес окна 0x83ffff000: ядро создало таблицу PTE №511 по требованию, установило её запись №511 с кадром для нужного виртуального ключа, а освобождение удалило PTE и ключ. Проверка также учла, что свободный слот карты кадров не обязан совпадать с номером виртуальной страницы.
  • python tests/integration/test_kernel_observer.py — 9 PASS; QMP-наблюдатель и проверки его сверки с разреженной картой проходят.
  • QEMU недоступен в PATH и рабочей копии; реальный гостевой запуск и QMP-снимок верхней страницы не выполнены.

Следующий шаг и границы

Нативные ошибки давления и повторного отображения устранены и адресно проверены. MEM-11 остаётся в работе до одной гостевой проверки нового верхнего диапазона с дополнительной таблицей PTE и фактической работы demand-fault в QEMU. Успешная сборка EFI и нативное исполнение GSL не заменяют эту проверку.

Новый предел относится к виртуальному адресу каждого компонента, а не к физически выделенным страницам или доступной RAM. Контроль надёжности и поведения при реальном физическом давлении остаётся открытым.

Этап 067 — MEM-11: явный резерв виртуальных областей

Прямая ссылка на отчёт

Состояние: в работе. Запись от 9 ноября 2026 года.

Реализовано

  • Системный вызов 48 находит первый подходящий непрерывный диапазон из 1–504 виртуальных страниц и помечает его в карте компонента. Резервирование само по себе не обращается к PMM и не создаёт таблиц отображения.
  • Системный вызов 49 снимает диапазон только при совпадении адресов и отсутствии физических страниц и PTE в его пределах. Запросы за границами, конфликтующие или частично неверные отвергаются без снятия части резерва.
  • При переходе в явный режим будущие обычные выделения используют свободные зарезервированные адреса. Ленивое размещение разрешено только внутри резерва. Освобождение кадра не отбирает зарезервированный адрес у приложения.
  • В последние 64 байта карты на компонент помещены 504 бита резерва и признак явного режима. QMP-наблюдатель сообщает количество страниц и объединяет соседние страницы в диапазоны; Dev Shell показывает резерв отдельно от отображённых страниц.

Проверка

  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — один выбранный сценарий PASS. Он проверяет резерв всех 504 страниц без изменения числа свободных кадров, отсутствие свободного адреса, снятие и повтор резерва последней страницы, запрет снять занятый диапазон, отказ page fault вне резерва и возврат освобождённой страницы в тот же зарезервированный виртуальный адрес с нулевым содержимым.
  • python tests/integration/test_kernel_observer.py — 9 PASS, включая раздельный вывод резервов и реальных отображений.
  • python -m py_compile tools/host/kernel_observer.py tools/host/dev_shell.py — PASS.
  • Свежая сборка профиля памяти work/mem11-regions — PASS; fingerprint — PASS. EFI SHA-256 32e0f0bfc429ba30fa34c4b7b87822da319da468c85e53b01602a6179ab0e1e9; образ SHA-256 3858bb47754b942d7c699b8dbdd6897ff99fa9cd2af622bfd8ea34a15d88b18e.

Оставшаяся граница

Текущая таблица страниц и виртуальное окно всё ещё ограничивают динамическую область 504 страницами (2 МиБ) на компонент. Реализовано резервирование внутри этого окна; расширяемые области за его пределами и новая структура таблиц страниц не реализованы. В текущем окружении QEMU недоступен, поэтому не выполнена приёмка syscall 48/49, фактического отсутствующего отображения, его CPL3 fault и наблюдения живого гостя. MEM-11 остаётся открытым; текущий результат не меняет статусы MEM-10, MEM-12 и MEM-15/16.

Этап 066 — MEM-10: сверка карты памяти с таблицами процесса

Прямая ссылка на отчёт

Состояние: закрыт 9 ноября 2026 года. Первоначальный аудит и реализация описаны ниже; фактическая QMP-приёмка добавлена в конце отчёта.

Аудит текущей раскладки

По исходникам GSL виртуальная область CPL3 начинается с 0x800000000. PTE 0 отображает код, PTE 1 — данные, PTE 2–3 оставлены неотображёнными как защитный промежуток, PTE 4–7 отданы четырём страницам стека. Динамические страницы используют PTE 8–511: 504 страницы по 4096 байт, верхний адрес — 0x8001ff000. Страница физически выделяется при первом обращении только внутри динамического окна. Резерв виртуального адреса и гарантия физического обеспечения отдельно не учитываются; лимит страниц находится в записи ресурса компонента.

До этого этапа host-наблюдатель строил таблицу отображений по записи ядра и карте физических кадров владельца, но не сверял её с аппаратными PTE. Поэтому он мог показать ожидаемое отображение, не обнаружив, что таблица процесса содержит другой кадр или лишнюю запись.

Изменение

Наблюдатель теперь снимает из гостевой физической памяти страницу таблиц процесса, указанную в записи компонента. Для отображённых фиксированных страниц он сверяет физический кадр и биты Present/User/Write/NX с картой ядра. Проверяет, что защитные PTE 2–3 пусты, отсутствующие фиксированные страницы не отображены, а каждый динамический PTE 8–511 соответствует карте владельца, включая пустые, отозванные и находящиеся за high-water записи. Расхождения добавляются в общий список проблем, который уже отображает Dev Shell. Для каждого компонента выводится состояние: PTE сверены, найдено расхождение или снимок таблицы не получен.

Проверка и границы

  • python tests/integration/test_kernel_observer.py — 8 PASS. Fixture подтверждает совпадение таблицы с картой и обнаружение намеренно изменённого кадра и отображения динамической записи за high-water.
  • python -m py_compile tools/host/kernel_observer.py tools/host/dev_shell.py — PASS.
  • Свежая сборка профиля память в work/mem10-pte-observer и проверка fingerprint — PASS. EFI SHA-256 9677e9c9eca3cb22c59f45009e6ab5ec88142730189703eee5548d124ca18a72, образ SHA-256 203435e5c7c0224d474dd870d8656660ba3d79ea3ce591ac487582091474a1aa.
  • QEMU в текущем окружении отсутствует. Чтение физической страницы таблиц через QMP и сравнение на реальном гостевом снимке не проверены, поэтому MEM-10 остаётся открыт.

Итоговая адресная приёмка 9 ноября 2026 года

Сценарий был расширен до 520 последовательных страниц на компонент и отдельного доступа к последней странице окна. Это нужно, чтобы наблюдение проверяло более 514 одновременно отображённых динамических страниц, а не только высокий виртуальный high-water.

  • Свежая сборка work/mem10-live-pte-observer, SHA-256 образа 2f552fffd0936c2c1f6e306553c35c7d01c8db20e5d6e6e355eff1b8435c0a3a.
  • python tools/host/test_live_pte_observer.py --qemu <QEMU 11.1.0> --build work/mem10-live-pte-observer --timeout 90 --ram 128 — PASS. Реальный снимок живого компонента ID 65537: high-water 262146, 521 динамическое отображение; прочитаны таблицы 0, 1 и 511; проверены адреса 0x800008000, 0x800200000, 0x83ffff000; page_table_verified=true, список замечаний пуст.
  • Обычный test_boot.py того же fingerprint — PASS: три компонента завершились, возвращено 1 593 страницы, 0 faults и 0 остаточных capability, IPC-запросов, device lease и object reference.
  • Снимки: mem10-live-snapshot.json, boot-report.json.

Граница: проверено чтение и независимое сравнение конкретных таблиц на QEMU q35/TCG, 128 МиБ и одном CPU. Это не доказывает аппаратную совместимость на физическом компьютере, работу при всех 262 136 динамических отображениях либо полную регрессию ядра.

Этап 065 — предварительная проверка возможностей процессора

Прямая ссылка на отчёт

Состояние: частично принят, обновлён 10 ноября 2026 года. Штатная загрузка и все диагностические ветви получили исполняемые проверки QEMU. Для BOOT-05-01 и BOOT-05-03 проверена ветвь загрузчика с тестовой подменой результата CPU; настоящий процессор без CPUID или long mode на x64 UEFI не испытывался.

Реализация

До настройки GOP и чтения загрузочной карты UEFI-переход проверяет:

  • доступность инструкции CPUID;
  • базовый CPUID leaf 1 и признаки MSR и PAE;
  • расширенный CPUID leaf и признак long mode;
  • поддержку NX.

При несовместимости загрузчик пишет один из диагностических типов BOOT-05-01 (CPUID), BOOT-05-02 (MSR/PAE), BOOT-05-03 (long mode), BOOT-05-04 (NX) и останавливает CPU до вызова ядра. При успехе пишет BOOT-05: CPU features verified. Ожидания штатной последовательности обновлены в qemu_acceptance.py и test_boot.py.

Для проверки двух ветвей, которые нельзя вызвать отключением возможностей в модели x64 UEFI QEMU, добавлен отдельный ключ сборщика --cpu-probe cpuid|long-mode. Он задаёт тестовую компиляцию загрузчика, принудительно возвращающую нужный отказ из проверки CPU. Значение по умолчанию выключено; обычный образ собирается с GUSEVA_CPU_PROBE=0. Этот механизм испытывает сообщение, ранний отказ и остановку CPU, но не симулирует реальный процессор без соответствующей возможности.

Проверки

  • Свежая сборка python -X utf8 tools/host/build.py --out work/boot05-nx-current --platform-case workers — PASS. Образ SHA-256 c34ccbbba836c369f63bea085055884d1e334a0d37bfb2d8e098e921352fffa4.
  • Штатная загрузка: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS. В журнале соблюдён порядок BOOT: UEFI entered → BOOT-05: CPU features verified → GOP → ExitBootServices → KERNEL: ready; контрольный сценарий дошёл до штатной остановки.
  • -cpu qemu64,-nx: PASS для отказной ветви. Выведен BOOT-05-04, отсутствуют GOP и KERNEL: ready. Журнал · отчёт.
  • -cpu qemu64,-msr и -cpu qemu64,-pae: оба профиля выдали BOOT-05-02 после входа в UEFI и до GOP/ядра. Результаты профилей.
  • -cpu qemu64,-lm: x64-прошивка не передала управление EFI-модулю: отсутствует даже BOOT: UEFI entered. -cpu qemu64,-cpuid отклонён самим QEMU как неизвестный параметр CPU. Поэтому эти результаты не засчитываются как проверка ID 03/01.
  • Тестовый образ --cpu-probe cpuid: QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS для кода BOOT-05-01; загрузчик вошёл в UEFI, вывел диагноз до GOP, не запускал ядро и остановил виртуальный CPU. SHA-256 образа 03d65a152680e78f0eb1fc6ef0774c08b3b6ea1ae757f74902c386d3634dfb5b. Сводка · журнал · отчёт сборки.
  • Тестовый образ --cpu-probe long-mode: тот же профиль QEMU — PASS для кода BOOT-05-03; тестовая сборка очистила именно LM-бит в ответе CPUID, обычная проверка выявила его отсутствие и загрузчик остановил CPU. SHA-256 образа 24af635187137575248f72284c794d089af30ec3a76b407b297d2972c0a078c3. Сводка · журнал · отчёт сборки.
  • После добавления макроса собран обычный shell-live без пробы (cpu_probe: null); проверка QEMU подтвердила BOOT-05: CPU features verified, продолжение загрузки и отклик мыши. SHA-256 образа 13a266717cd14b297c044e763c95ee89523acba7672e055ca5b7602f1c618d0a. Отчёт.

Граница приёмки

BOOT-05 остаётся частично принятым: все четыре диагностических обработчика и остановка до ядра проверены; BOOT-05-01 и BOOT-05-03 — через явную тестовую подмену результата, а не на физическом CPU без возможностей. Тестовый режим не входит в обычную сборку. Дальнейшее закрытие требует отдельной аппаратной платформы/эмулятора, способных запустить x64 EFI при отсутствии этих признаков; обычный QEMU x64 UEFI такую проверку не предоставляет.

Этап 064 — измеряемая реакция на нехватку физических страниц

Прямая ссылка на отчёт

Состояние: закрыт 9 ноября 2026 года для ограниченной политики и двух описанных QEMU-сценариев. Первоначальная запись ниже отражает состояние до гостевой проверки.

Реализация

  • При отказе PMM в обычном выделении и при demand fault ядро отмечает событие нехватки физического кадра. Отказ квоты не запускает политику давления.
  • Для вызывающего компонента выполняется один ограниченный проход по механизму MEM-15: максимум четыре чистые нулевые страницы. Затем ядро делает не более одной попытки получить кадр повторно.
  • При исчерпании после повтора обычное выделение возвращает свой отказ, а неразмещаемая demand page возвращает классификатору стабильный код 6205. Ожидания без верхней границы нет.
  • Новые поля процесса +240/+248 считают соответственно события нехватки кадров и страницы, возвращённые проходами давления. Syscall 47 возвращает версию снимка, ID цели и эти счётчики; разрешены только собственное состояние или полномочие inspect_memory.
  • Наблюдатель ядра и Dev Shell показывают счётчики как диагностику. Автоматический выбор чужого владельца, отзыв отображений, swap, сжатие и завершение приложений не добавлены.

Проверки

  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS. Нативный сценарий исчерпывает PMM отдельно для syscall-выделения и demand fault; проверяет один повторный успех, счётчики 1/4 и 2/8, восстановление страницы нулями, метки зарезервированных адресов и очистку счётчиков при завершении.
  • python -m unittest tests.compiler.test_compiler — 12 тестов PASS.
  • python tests/integration/test_kernel_observer.py — 6 тестов PASS.
  • Свежая сборка python tools/host/build.py --platform-case память --out work/mem16-pressure — PASS. EFI SHA-256: 7bd91d95ad86043a22ce42b7dee0b22ea024c258bcafd2759e168c1af86b08ce; образ SHA-256: 1205980f1a98a766bc3447c1c1c2f9d2ec5e234778ffc49a4ddaa916f090571b.

Первоначальная граница приёмки

На момент первой записи QEMU не был найден, поэтому сценарии оставались без гостевого подтверждения. MEM-15 закрыт отдельной гостевой приёмкой этапа 063; MEM-16 проверен ниже на свежих образах.

Дополнение от 9 ноября 2026 года — QEMU-приёмка MEM-16

QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU. Для доказательства обеих веток исчерпания созданы отдельные профили на общем CPL3 драйвере памяти. В обоих сначала записаны 520 страниц и проверена чистая страница по MEM-15. Приложение продолжает выделять и изменять кадры до фактического отказа PMM; каждая попытка ограничена одним проходом возврата собственных чистых страниц (не более четырёх) и одним повтором.

Обычное выделение — syscall 35

  • python tools/host/build.py --out work/mem16-pressure-allocation --platform-case давление-памяти-выделение — сборка PASS.
  • python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/mem16-pressure-allocation --timeout 90 --ram 128 — PASS.
  • Компонент 65537 успешно выделил 17 551 страницу, затем получил IPC_EMPTY после неудачного единственного повтора. Syscall 47 подтвердил 2 события нехватки и возврат 1 своей чистой страницы; ошибка приложения равна 0.
  • Все три компонента завершились штатно; возвращено 19 144 физических страниц, faults=0, остаточных capability/IPC/device/object ссылок нет.
  • EFI SHA-256 82043937207a1a86e1ce0ccd9da60bbf4b6b3a039b33cda70332d30e6e662207; образ SHA-256 c2f9129dd8a68ac054b9a1c9d10523b2d148481f4279cf93b54071e376ff0656. См. boot-report.json и platform-report.json.

Материализация demand fault

  • python tools/host/build.py --out work/mem16-pressure-fault --platform-case давление-памяти-ошибка — сборка PASS.
  • python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/mem16-pressure-fault --timeout 90 --ram 128 — PASS.
  • При исчерпании тот же компонент коснулся зарезервированного, но незаполненного VA 35433472000. Одна попытка demand materialization и один ограниченный повтор завершились стабильным диагностическим ID 6205 (vector 14, error 6). Журнал ядра независимо зафиксировал 3 события давления и 1 возвращённую чистую страницу.
  • Fault ограничен компонентом 65537; два соседних компонента завершили работу, всего возвращено 19 144 физических страницы, capability/IPC/device/object остатки равны нулю.
  • EFI SHA-256 204c3754a03ef3bfceeb1112d3773d32289bbde6e9fae98813f471739d11a856; образ SHA-256 5b4d44eb510c9c3dcbbe0541e5e2d156aaf6c55ab183173add7e1611fb9e2563. См. boot-report.json и platform-report.json.

Граница

MEM-16 закрыт в этих однопроцессорных сценариях. Восстановление ограничено собственными чистыми страницами текущего компонента; чужие страницы не выбираются. IPC-согласование на отзыв чужих отображений, сохранение изменённых страниц в backing store, swap, сжатие, многопоточная конкуренция и полная K8-регрессия не проверялись и не входят в эту приёмку.

Этап 063 — возврат нетронутых динамических страниц

Прямая ссылка на отчёт

Состояние: закрыт 9 ноября 2026 года для описанной политики и проверенных путей. Дата записи: 9 ноября 2026 года.

Реализация

  • Добавлен syscall 46: компонент может вернуть страницы собственного динамического диапазона; обладатель manage_resources может запросить возврат для неактивного компонента.
  • Вызов ограничен бюджетом от 1 до 16 страниц. Для каждой записи ядро сверяет PTE с физическим кадром из карты компонента.
  • Возвращаются только кадры, которые PMM предварительно обнулил и у которых PTE не имеет аппаратного dirty-бита. Изменённые страницы остаются доступны.
  • При успешном возврате очищается PTE, уменьшается компонентный учёт, а кадр возвращается PMM. Карта сохраняет метку UINT64_MAX, чтобы закрепить старый виртуальный адрес за прежним объектом и не допустить его выдачу новому блоку.
  • Повторный fault на таком адресе повторно материализует обнулённый кадр. Явный release снимает метку без возврата несуществующего кадра; reap очищает её без двойного освобождения; снимок не выдаёт её за резидентное отображение.
  • Для собственного адресного пространства syscall перезагружает CR3 после изменений. Для неактивного целевого пространства отложенная очистка TLB зависит от последующей загрузки его CR3 планировщиком на текущем однопроцессорном профиле.
  • Добавлен режим компилятора --native-test, который подменяет привилегированную активацию paging заглушкой только в нативной диагностической сборке. Обычный EFI-код сохраняет машинную инструкцию перезагрузки CR3. Вывод диагностического порта в этом режиме также заглушён; явный эффект устройства остаётся.

Проверки

  • GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS. Проверены запрет вызова без нужного полномочия, предел бюджета, сохранение изменённой страницы, возврат двух чистых страниц, отсутствие их адресов в снимке резидентных страниц, отказ повторно выдать сохранённый виртуальный адрес, повторная нулевая материализация, явное снятие метки и очистка при завершении.
  • python -m unittest tests.compiler.test_compiler — 12 тестов PASS. Проверено, что обычный кодогенератор содержит машинную операцию CR3, а --native-test её подавляет.
  • python tests/integration/test_kernel_observer.py — 6 тестов PASS.
  • python tests/kernel/test_user_heap.py — 1 тест PASS.
  • Вывод платформенного сценария теперь сообщает выбранные размеры состава и фактическое число IPC-обменов, чтобы однокомпонентный запуск не выдавался за матрицу.
  • Свежая сборка python tools/host/build.py --platform-case память --out work\\mem15-final — PASS. EFI SHA-256: f15e86b5bb719d137992e77b5a4412036c03e886b09ec87a05fd28ef54b14b38; образ SHA-256: 8b38d8fd6844ca57a19262c65a92a4b07172f4e48d6c971b8549a51c755ec298.

Граница приёмки

Нативный тест проверяет логику GSL и сохранение счётчиков, но не имитирует аппаратные dirty-биты, TLB или CPL3. Историческая часть этой записи оставлена как была: на тот момент QEMU не был доступен.

Дополнение от 9 ноября 2026 года — CPL3/QEMU-приёмка MEM-15

Свежий профиль памяти расширен целевым действием компонента 65537: после записи 520 динамических страниц он только читает ещё одну нулевую страницу, запрашивает syscall 46 с бюджетом 1, затем повторно читает тот же VA и проверяет ноль. Отдельно перепроверяется значение 12345 в изменённой странице.

  • python tools/host/build.py --out work/mem15-clean-page-guest --platform-case память — PASS.
  • python tools/host/test_boot.py --qemu <QEMU 11.1.0> --build work/mem15-clean-page-guest --timeout 90 --ram 128 — PASS: три CPL3-компонента завершены; возвращено 1 594 страниц; faults=0; остаточных capability/IPC/device/object ресурсов нет.
  • python tools/host/test_live_pte_observer.py --qemu <QEMU 11.1.0> --build work/mem15-clean-page-guest --timeout 90 --ram 128 — PASS. На снимке живого компонента 65537 PTE повторно материализованной страницы присутствует и имеет dirty=0; отображено 522 динамических страницы, таблицы 0/1/511 прошли независимую сверку с картой ядра.
  • SHA-256 образа 80a0341b4647d17fbdc2dec7547c6b9b5f5c53b831d93b5fb454cef67771a8fe; boot-report.json, mem10-live-snapshot.json, live-pte-table-0-1.bin.

MEM-15 закрыт для собственного пространства CPL3-компонента и указанной конфигурации. Native-сценарий дополнительно покрывает полномочия manage_resources, бюджет, явный release и очистку маркеров. Не заявляются возврат изменённых страниц, swap/сжатие, многоядерный TLB shootdown или гостевой OOM recovery — последнее остаётся MEM-16.

Этап 062 — учёт живого heap V

Прямая ссылка на отчёт

Состояние: в работе. Дата записи: 9 ноября 2026 года.

Реализация

  • Новый src/apps/учёт_памяти.gsl предоставляет GSL-обёртку syscall 44.
  • Общий src/apps/распределитель_памяти.gsl уведомляет ядро перед выдачей или освобождением блока. Отказ ядра отменяет операцию распределителя.
  • Ядро хранит текущие полезные байты живого heap в свободном поле записи компонента +232, проверяет выравнивание/лимит, запрещает underflow и обнуляет счётчик до повторного использования слота.
  • Syscall 45 возвращает владельцу или полномочному инспектору снимок из восьми 64-битных слов: версия, ID компонента, V, C, R в страницах, R в байтах, ёмкость heap и признаки достоверности.
  • kernel_observer.py показывает V отдельно от ёмкости виртуального окна и числа отображённых динамических страниц. C явно помечается неподдерживаемым.
  • V не является защитным лимитом: CPL3-компонент может напрямую менять только свой счётчик syscall 44 и намеренно исказить диагностику. Сейчас это наблюдение использования штатного распределителя, а не учёт всех виртуальных объектов.

Проверка

Команда:

$env:GUSEVA_PLATFORM_TEST_COUNTS='1'
python tests/kernel/test_platform.py

Результат: PASS, одно-компонентный сценарий платформы. Проверены увеличение V, отказ при превышении предела, чтение снимка полномочным инспектором, отказ в просмотре чужого компонента без полномочия, отказ освободить больше учтённого, корректное уменьшение V и очистка значения после завершения. Тестовая компиляция использует --native-test: она подавляет аппаратный диагностический вывод в порт, который не разрешён обычному Windows-процессу. Функциональный код ядра не меняется этим флагом.

Свежая сборка профиля память после изменений прошла командой python tools/host/build.py --platform-case память --out work\mem14-final: EFI SHA-256 5e0e60d9afbed76ec9fcdc2e4e12d64dd6c70965d9351f3ffe5ffa65221b5adb; образ SHA-256 d0ef2d547799fdb06e194544b0ddf15c2bf5dae257ab71d58584842b9f5c00c2.

Ограничения и критерии закрытия

  • Полная матрица состава компонентов 1/3/7/32 и цикл из 1500 обменов не запускались; выполнен один компонентный вариант.
  • В этой среде нет QEMU; гостевая проверка CPL3 не выполнена.
  • V пока означает только полезные байты блоков общего heap, а не весь резерв виртуальных адресов и не обязательство физически обеспечить эти байты.
  • C не реализован и выдаётся как 0 с признаком «не поддерживается».
  • Требуется проверить на свежем образе: приложение действительно вызывает обёртку при всех путях успешного выделения/освобождения; снимок соответствует состоянию живого heap; смерть компонента очищает отображения и кадры без двойного счёта общих страниц.

Поэтому MEM-14 остаётся открытым. Старые QEMU PASS не подтверждают этот код.

Уточнение V при расширении heap — 9 ноября 2026 года

При переносе общего heap на окно 1 ГиБ найдено расхождение: если остаток блока меньше минимального заголовка, allocator присоединял его к выдаваемому блоку, но счётчик V учитывал только запрошенные байты. GSL-код теперь учитывает реальный размер занятого блока. python tests/kernel/test_user_heap.py — PASS: поглощённые 16 байт входят в V и полностью снимаются после освобождения. Свежая сборка с этим кодом: work/mem13-heap1g, EFI SHA-256 0bfe40d5e57b92e7152b5252d8a2d1aa776314e6cc93721b4ea8f1c842e1bb0b, образ SHA-256 c03d2eeab366af6fe093b36ad2d0e473235cc2baa3428b540b3687b723de2ffe. Гостевой снимок heap остаётся непринятым без QEMU.

Этап MEM-12 — диагностируемое ленивое размещение

Прямая ссылка на отчёт

Состояние: в работе. Запись от 9 ноября 2026 года.

Изменение

Обработчик диспетчер_материализовать_нулевую_страницу возвращает 0 только после успешного учёта квоты, получения физического кадра и установки отображения. При отказе возвращается один из стабильных ID:

ID Причина
6201 неподдерживаемый тип/права страничной ошибки
6202 адрес вне разрешённой динамической области
6203 запись карты или таблицы уже занята
6204 квота компонента отклонила выделение
6205 физический менеджер не выдал кадр
6206 идентичность компонента не разрешилась

Ядро сохраняет ID, исходный код ошибки процессора и fault-адрес в полях 208, 216 и 224 записи компонента. Обычные нестраничные отказы компонента получают ID 6200. Коды описывают причину события, а не уникальный экземпляр.

Приёмка

Свежие сборки профилей память и fault прошли после выделения чистого классификатора причин. EFI SHA-256 профиля памяти: 7809f56ba917c2c241eff39dca0e710e45cb2f6634e099821115289cf1dff988; образ: 569e1d917b30a32e2b11f073c8a8c5d932c1629519c7cfd767221927b2f49620. EFI SHA-256 профиля fault: 6e74f03eb5a41b344072d73551b5b90e3dd95ceac90a0720324199fc9bdf8a3f; образ: 4ac21a6370fe0c0be04d1eee5dc45ee5799a330ccfba192b97777170134153d6. Новый точечный тест tests/kernel/test_memory_fault_classifier.py исполнил GSL-классификатор и подтвердил результаты 0, 6201, 6202 и 6206. QEMU-приёмка не стартовала: qemu-system-x86_64.exe отсутствует в текущем worktree, work/tools/qemu/, tools/qemu/ и PATH. Результаты QEMU для предыдущих сборок остаются историческими и не подтверждают эту версию.

При сборке fault обнаружено и устранено лишнее действие сборщика: он компилировал полный platform_device.gsl, хотя политика профиля не запускает драйвер. После изменения сборщик переиспользует ограниченный пакет рабочего компонента только в профилях без устройства. Профили с устройством продолжают собирать и запускать собственный драйвер.

Для закрытия MEM-12 необходимо собрать свежий профиль памяти и проверить:

  1. допустимая отсутствующая пользовательская страница получает нулевой результат размещения, отображается и сохраняет данные после возврата в CPL3;
  2. готовый сценарий --platform-case fault завершает нарушивший компонент и проверяет ID 6202, пользовательский error code 4 и адрес 4096; дополнительный вариант должен проверить ID 6201 для отказа по правам;
  3. конфликт отображения не выделяет повторный кадр и фиксирует ID 6203;
  4. отдельные варианты должны проверить отказ квоты и исчерпание физического менеджера: ID 6204 и 6205 без утечки временного учёта;
  5. соседние компоненты продолжают исполнение, а диагностическая запись содержит владельца, ID причины, исходный код ошибки и виртуальный адрес.

На следующем этапе кодирования:

  • корректность всех перечисленных отказных переходов на свежем образе;
  • сохранность незатронутых записей, освобождение временно зарезервированного ресурса и отсутствие утечки кадра;
  • CPL3-вывод fault-записи в свежей QEMU-сборке.

Доработка наблюдаемости — 9 ноября 2026 года

Host-наблюдатель теперь декодирует поля +208/+216/+224, расшифровывает ID через каталог КАТАЛОГ_ДИАГНОСТИКИ.md и сохраняет их для компонента с тем же поколением даже после закрытия слота. Dev Shell показывает тип ошибки, русское описание, вектор, аппаратный код и адрес. Точечная проверка fixture подтверждает декодирование живой и завершённой записи, но это не доказывает, что текущая гостевая сборка действительно создала такой fault. Текущая гостевая проверка всё ещё ожидает QEMU.

Запись fault ядром и сохранение после завершения — 9 ноября 2026 года

Добавлено действие GSL диспетчер_записать_диагностику_ошибки: оно сохраняет тип события, вектор, код ошибки CPU, fault-адрес и RIP в запись компонента; журнал получает общий префикс KERNEL-FAULT. platform_fault использует это действие перед завершением компонента. Адресная нативная проверка исполняет сам GSL writer и сверяет все поля как до, так и после p_end/p_reap, подтверждая сохранность записи для того же поколения.

Проверка: GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py — PASS; свежая сборка профиля память в work/mem12-diagnostic-writer — PASS. EFI SHA-256 9677e9c9eca3cb22c59f45009e6ab5ec88142730189703eee5548d124ca18a72, образ SHA-256 203435e5c7c0224d474dd870d8656660ba3d79ea3ce591ac487582091474a1aa. QEMU недоступен: фактический CPL3 fault и гостевое отображение записи ещё не подтверждены; MEM-12 остаётся открытым.

Адресная проверка отказных ID — 9 ноября 2026 года

Интегрированный нативный сценарий платформы теперь вызывает GSL-материализатор и проверяет ID 6203 при занятом отображении, 6204 при отказе квоты без изменения учёта, 6205 при исчерпании кадров без утечки временного учёта и 6206 для устаревшего поколения. tests/kernel/test_memory_fault_classifier.py подтверждает допустимую страницу в начале и в конце разреженного окна, ID 6201 при запрещённом типе обращения, ID 6202 на точной верхней границе 0x840000000 и приоритет отказа адреса, а также ID 6206 для неразрешённого слота. Проверки GUSEVA_PLATFORM_TEST_COUNTS=1 python tests/kernel/test_platform.py и python tests/kernel/test_memory_fault_classifier.py проходят. Свежая сборка python tools/host/build.py --out work/mem12-current --platform-case fault — PASS, EFI SHA-256 eb602a16c35161a138a5c749f30950238fb72619abfd97b0f30e98b0d7de0e67, образ SHA-256 15c1a5d98ba94ae51cc4e0dda8133e76bbef62880ffcb5eabd371c4fb762590a.

Граница остаётся прежней: без QEMU не подтверждены настоящий CPL3 fault, завершение только нарушившего компонента, продолжение соседнего компонента и появление записи из свежего гостевого образа. Поэтому MEM-12 не закрыт.

Этап 49 — граница пользовательского отображения страниц

Прямая ссылка на отчёт

Дата: 6 ноября 2026 года
Статус: принят целевым сценарием QEMU память.

Что изменено

  • Публичный syscall 35 принимает явный адрес только внутри динамического 1-ГиБ окна, на границах страниц. Запрос 0 для автоматического выбора остаётся допустимым.
  • Внутренний распределитель сохраняет отдельный привилегированный путь загрузчика. Загрузчик отображает код, данные и стеки до начала пользовательских вызовов; фильтровать эти адреса внутри общего распределителя было нельзя.
  • Резервирование, снятие резерва, освобождение и материализация отсутствующей страницы ограничены динамической областью. Максимальный резерв не включает фиксированный префикс.
  • CPL3-проверка отвергает попытку выделить или освободить низкую страницу загрузчика.
  • После освобождения разреженной страницы тест обращается к ней снова: обработчик page fault выделяет новый кадр, проверяются запись и чтение значения, затем новый кадр штатно освобождается.

Приёмка

Сборка: python tools/host/build.py --platform-case память --out work/b05-fixed-boundaries
QEMU: python tools/host/qemu_acceptance.py --build work/b05-fixed-boundaries --timeout 90
Результат: PASS, образ b675cd4d84dd3c70c777d29d42023a4f6a6511e1cb4a359d6519bbd264385fd4.

Сценарий также сохранил проверки 8193 динамических отображений, обратного индекса, уплотнения карты, десяти виртуальных резервов и очистки компонента. Счётчик фатальных ошибок компонентов — 0. Проверка первого обращения подтверждена содержимым памяти и успешным освобождением повторно созданной страницы.

Что остаётся в MEM-10

Отдельно нужны отрицательные сценарии page fault: обращение к фиксированному префиксу, guard-странице, чужой области, попытка исполнения из NX-страницы и отказ по квоте при материализации. Также нужно проверить верхнюю границу окна и резервы предельного размера. Они не входят в эту приёмку.

Этап 48 — прямой обратный индекс отображений

Прямая ссылка на отчёт

Статус: QEMU-приёмка пройдена; освобождение страницы больше не просматривает всю карту компонента.

Реализация

  • Для каждого виртуального номера страницы создаётся обратная запись со смещением на плотную запись отображения. Нулевое значение означает, что страница не отображена; ненулевое хранит map_slot + 1.
  • Обратный индекс разбит на 512 страниц метаданных по 512 виртуальных страниц. Каталог компонента теперь 12360 байт: 1024 указателя основной карты, 8 указателей bitmap, 512 указателей обратного индекса и корень списка резервов. Для 32 слотов статический каталог занимает 395520 байт.
  • syscall 36 сначала вычисляет страницу по виртуальному адресу и читает её запись напрямую. При уплотнении плотной карты ядро обновляет обратный индекс перемещённой записи; при освобождении очищает старое значение.
  • Наблюдатель собирает разреженные страницы всех трёх типов метаданных. Индексированные страницы обратного поиска доступны в диагностическом архиве вместе с основными отображениями.

Проверка

Сборка: python tools/host/build.py --platform-case память --out work/b05-reservations. QEMU: python tools/host/qemu_acceptance.py --build work/b05-reservations --timeout 90 — PASS, QEMU 11.1, q35, TCG, 128 МиБ. Точечная проверка наблюдателя: python -m unittest discover -s tests/integration -p test_kernel_observer.py — 7/7.

EFI-образ — 867328 байт, SHA-256 3dc503cb4a008919ed05d8b8e0c35c1537c71f5d628db8377a8b507a64512594.

QEMU одновременно проверил 8193 динамические страницы в CPL3, затем освободил не последнюю запись, проверил освобождение перемещённой последней записи после уплотнения, выделил тот же виртуальный адрес снова и освободил его повторно. Также прошли старые проверки разреженного отображения за 2 МиБ, десяти резервов, квоты 24 страницы, поколения ID и очистки компонента. Результат: 24870 возвращённых физических страниц, faults=0, активных компонентов, capabilities, запросов и ссылок после завершения нет.

Обратный индекс добавляет до 512 страниц на компонент (2 МиБ) при использовании всего 1-ГиБ окна. Индексные страницы выделяются по мере размещения адресов; физическая память и квоты ограничивают фактический размер. Следующие пункты MEM-10/MEM-11 — полный аудит page fault и растущие виртуальные области.

Этап 47 — расширение карты отображений компонента

Прямая ссылка на отчёт

Статус: QEMU-приёмка пройдена; структурный потолок старой карты снят.

Изменения

  • Каталог для 32 компонентов увеличен с 328 до 8264 байт на компонент. В нём помещаются 1024 указателя на страницы метаданных (по 256 записей отображения на страницу) и 8 указателей bitmap для 1-ГиБ пользовательского окна.
  • Максимум учёта отображений вырос с 8192 до 262144 записей на компонент. Bitmap перенесён в отдельный диапазон индексов метаданных; его страницы выделяются только при фактическом использовании.
  • Квота страниц может достигать структурной границы 262144. Фактическое выделение по-прежнему ограничено доступными физическими кадрами и политикой квот.
  • Наблюдатель хранит только реально выделенные страницы метаданных и выдаёт их как индексированный снимок, не создавая плотный буфер размером 1 ГиБ.
  • Сценарий CPL3 перемещён после проверок резервов, чтобы живые страницы стресс-теста не меняли ожидаемое поведение поиска свободного виртуального диапазона. Он оставляет очистку оставшихся кадров завершению компонента.

Приёмка

Команды:

python tools/host/build.py --platform-case память --out work/b05-reservations
python tools/host/qemu_acceptance.py --build work/b05-reservations --timeout 90
python -m unittest discover -s tests/integration -p test_kernel_observer.py

Результат: сборка успешна; QEMU 11.1, q35, TCG, 128 МиБ — PASS; тест наблюдателя — 7/7. Образ EFI — 866816 байт, SHA-256 08958f345068f50b53ad7f8834b3ded345e4bdbbda2e126ae9f796715e237661.

  • Два CPL3-компонента одновременно удерживали по 8193 динамические страницы; компонент поколения 2 повторил тот же сценарий после повторного использования слота. Проверены непрерывность диапазона, запись/чтение последней страницы, дополнительный уровень таблиц страниц и возврат всех ресурсов после завершения.
  • ID сменился 65537 → 131073; обращение к старому ID отклонено как IPC_STALE.
  • Отдельный компонент при квоте 24 страницы создал 14 резервов и получил ожидаемый отказ; список очищен.
  • QEMU сообщил 24816 освобождённых физических страниц, 0 faults и отсутствие оставшихся компонентов, запросов, возможностей и ссылок объектов.
  • Разреженный снимок проверяется по данным гостя; его индекс записи 8999 покрыт тестом наблюдателя.

Границы

262144 — максимум записей карты в виртуальном окне 1 ГиБ одного компонента, не «безлимитная память» и не физическая гарантия. Страница отображения занимает 16 байт; полная таблица метаданных потребовала бы до 4 МиБ на компонент, плюс до 32 КиБ bitmap, однако эти страницы выделяются по мере роста. Освобождение одной страницы пока линейно ищет её запись в таблице; быстрый обратный индекс остаётся отдельной задачей. MEM-10 ещё требует аудита полного пути page fault, MEM-11 — динамического расширения самих виртуальных областей.

Этап 46 — растущий список виртуальных резервов

Прямая ссылка на отчёт

Статус: принятая граница B-05: рост, квотный отказ, очистка и повторное использование слота проверены на QEMU.

Реализация

  • Два фиксированных поля резервов заменены односвязным списком. На каждый диапазон выделяется отдельная страница-дескриптор, которая учитывается в квоте владельца.
  • Добавление, поиск занятого диапазона и снятие обходят список; снятие отклоняется при отображённых страницах.
  • При завершении компонента ядро освобождает все дескрипторы и очищает корень списка. Наблюдатель следует каталогу и показывает диапазоны компонента.
  • Обычное выделение обходит зарезервированные адреса; явное выделение разрешает отображение внутри собственного резерва.
  • Syscall 45 для устаревшего ID теперь возвращает IPC_STALE, а не ошибку лимита.

Приёмка

Сборка python tools/host/build.py --platform-case память --out work/b05-reservations успешна: EFI-образ 866816 байт. Целевая команда python tools/host/qemu_acceptance.py --build work/b05-reservations --timeout 30 завершилась PASS на QEMU 11.1, q35, 128 МиБ; SHA-256 образа be9c32bbdcab8d875db15f18c91c897e0288f35d792dfc4596dfd6155ed543fc.

  • Три CPL3-компонента одновременно создали по десять разнесённых резервов; проверены размещение страниц во втором и десятом, отказ снять занятые диапазоны, освобождение и снятие всех резервов.
  • У третьего компонента квота страниц была снижена до 24: он создал 14 дескрипторов, получил ожидаемый отказ IPC_LIMIT на следующем резерве и снял все созданные диапазоны.
  • После завершения первый слот был повторно использован: ID сменился с 65537 на 131073, старый ID отвергнут как IPC_STALE, тест повторно прошёл на новом экземпляре.
  • Всего возвращено 153 страницы, списки резервов очищены, faults=0. Независимая проверка также сверила лимит, число успешных резервов и физический учёт.

Оставшиеся пределы памяти

Карта отображений всё ещё ограничена 8192 записями на компонент, адресное окно — 1 ГиБ. Они не объявляются безлимитными: аудит текущей структуры и расширяемых виртуальных областей ведётся отдельно в MEM-10/MEM-11 чек-листа. Дальнейшее расширение должно опираться на фактические расходы метаданных и физический пул.

Этап 45 — ранняя проверка возможностей CPU

Прямая ссылка на отчёт

Статус: принят для текущей конфигурации x86-64/QEMU.
Пункт плана: BOOT-05.

Что реализовано

До обращения к остальным службам UEFI загрузочный мост проверяет наличие обязательных возможностей процессора:

  • MSR — нужен для настройки EFER;
  • PAE и long mode — нужны таблицам страниц x86-64;
  • SSE2 — базовая возможность целевой x86-64 ABI;
  • NX — нужен для страниц данных без права исполнения.

При отсутствии обязательной возможности мост выводит причину через диагностический порт и останавливается до передачи управления ядру. При успешной проверке мост устанавливает EFER.NXE, сохраняя прочие биты регистра. Для каждой причины предусмотрена отдельная строка отказа.

Приёмка

Команда:

python tools/host/check_cpu_preflight.py --build work/boot05-final

Результат: PASS.

  • qemu64: получены сообщения успешной проверки, ядро достигло KERNEL: ready; QEMU показал EFER=0000000000000d00, бит NXE установлен.
  • qemu64,-nx: мост вывел BOOT: CPU REJECTED: NX unavailable; ни ExitBootServices, ни вход в ядро не произошли.

Обычная полная приёмка отдельных сценариев компонентов в этот результат не включена. Проверен только контракт BOOT-05 и вход поддерживаемого CPU в ядро. BOOT-06 остаётся открытым: другие прошивки и физическое оборудование не проверялись.

Этап 44 — критичность узлов загрузки и политика отказов

Прямая ссылка на отчёт

Дата: 6 ноября 2026 года
Статус: принят в проверенной границе INIT-05.

Что добавлено

  • BOOT.MAN переведён на версию 2; записи теперь содержат поле критичности.
  • Для интерактивных пакетов ядро сверяет критичность с доверенным каталогом наряду с образом, правами, привязкой и READY-кодом.
  • Общие записи автомата загрузки расширены до 32 байт: ID, зависимости, состояние и критичность.
  • Необязательный отказ блокирует только потомков. Независимые компоненты продолжают запускаться.
  • Заблокированный обязательный узел поднимает общий статус критического отказа.
  • Рабочее состояние менеджера BOOT.MAN хранится отдельно от неизменяемых полей манифеста.

Проверка

Целевые QEMU-прогоны на 128 МиБ, x86-64/q35, один CPU:

  • порядок-загрузки — PASS: цикл, повторное завершение, необязательный отказ, независимая ветвь, блокирование потомка, критический отказ, READY-запросы и очистка ресурсов. Завершено три компонента, освобождено 39 страниц; таблицы прав, запросов и ссылок очищены. Отчёт, сводка компонентов.
  • Интерактивный рабочий стол — PASS: порядок пакетов [1,3,4,2], проверка привязки/READY/цикла/критичности, доставка мышиного события, передача управления, кадр 1280×800. Отчёт.
  • Необязательная мышь без READY — PASS: система продолжила работу без мышиного ввода и передала управление рабочему столу; кадр 1280×800. Отчёт.

Граница

INIT-05 закрыт для текущего встроенного набора загрузки. Общая безопасность ядра и защита системных файлов не заявляются завершёнными: отдельные задачи SAFE-08 и SAFE-09 добавлены в чек-лист.

Этап 43 — завершение передачи управления рабочему столу

Прямая ссылка на отчёт

Что исправлено

В диагностическом снимке было видно, что запрос IPC с сообщением 702 пережил дедлайн: отправитель лишь ставил передачу управления в очередь, а затем переходил в сон. При тайм-ауте ядро формировало ответ об ошибке для отправителя, но отправитель его не считывал, поэтому запись оставалась занятой. Одновременно 702 записывался в общее поле страницы приложения и неверно отображался как ошибка.

Диспетчер готовности теперь после отправки ждёт ответ рабочего стола до заданного срока. И подтверждение, и завершение по тайм-ауту считываются через тот же IPC endpoint; ядро освобождает запись после получения результата. Результат передачи хранится в отдельном диагностическом наборе полей страницы компонента (632–688), а наблюдатель показывает его как startup_handoff. Поле ошибки приложения больше не используется для сообщения 702.

Окно наблюдения также показывает отдельную строку «Передача управления рабочему столу» с состоянием и значением ответа.

Проверка

Собран сценарий рабочий-стол и выполнена QEMU-приёмка. Она теперь ждёт, пока ядро выведет ЗАГРУЗКА: IPC передачи управления рабочему столу освобождён, и не засчитывает сценарий без этого маркера. Результат: PASS; маркер освобождения запроса получен, экран 1280×800 отображён, событие мыши доставлено.

Отчёт: work/fail08-handoff/interactive-report.json.

Границы

Сценарий подтверждает освобождение запроса при штатном старте рабочего стола. Тайм-аут передачи в отдельном отрицательном сценарии пока не инъецируется. Сейчас сообщение 702 — специальный код внутренней передачи управления; формат пользовательского протокола сообщений ещё не стандартизован.

Этап 42 — полномочия остановки и поколения ID

Прямая ссылка на отчёт

Статус: проверено в QEMU.

Реализация

  • В syscall 31 отдельное право stop_service по-прежнему требуется для остановки другого компонента; завершение себя разрешено.
  • Если право есть, но ID уже не разрешается в действующий компонент, syscall 31 возвращает IPC_STALE. Для вызывающего без права ответ остаётся IPC_DENIED, чтобы не раскрывать состояние чужих ID.
  • Добавлен сценарий сборки --platform-case проверка-остановки: проверочный компонент без права получает отказ через диспетчер syscall; supervisor останавливает компонент, запускает новый экземпляр в повторно используемом слоте, проверяет отказ старого ID и отдельно останавливает новый экземпляр по его ID.
  • Общие проверки CPL3-нагрузки уточнены: оценка расхода сравнивается с квотой компонента, адрес динамической страницы — с действительным диапазоном, буфер syscall чтения ресурсов передаётся в доступную память компонента.

Проверка

QEMU acceptance: PASS. Проверка подтвердила 3 создания компонентов при двух занятых слотах, завершение и повторное использование слота, отсутствие активных компонентов и утечек ссылок после теста.

Отказ непривилегированного компонента проверяется внутренним вызовом того же p_syscall с ID этого компонента и целевым ID supervisor. Это проверяет таблицу полномочий и диспетчер syscall, но не заменяет отдельную CPL3-проверку передачи управления через int 0x80.

Найденная отдельная проблема передачи управления

В переданном 6 ноября диагностическом снимке supervisor записал 702 в поле, которое наблюдатель называет application_error; по коду это ID сообщения передачи управления рабочему столу. В таблице IPC при этом оставался запрос caller=65537, receiver=65540, message=702, state=4, deadline=103 на отметке ticks=2401. Следующий отдельный пункт FAIL-08 требует обработать ответ/тайм-аут и убрать завершённый запрос из таблицы, а также показывать этот этап отдельно от ошибки приложения.

Этап 41 — откат графа рабочего стола при отказе READY

Прямая ссылка на отчёт

Статус: реализован; штатная загрузка и отказной откат проверены в QEMU.

Механизм

Для управления службами введено отдельное полномочие stop_service (бит 256). Оно не совпадает с start_service: диспетчер готовности может остановить дочерние службы, но не получает от этого права запускать новые пакеты. Политика компонентов и ядро принимают маски полномочий до 512.

Если READY не получен или сообщение готовности некорректно, диспетчер вызывает новый kernel syscall 48. Ядро через уже разрешённое display_output рисует встроенный экран отказа, который остаётся доступен без оболочки и композитора. Затем диспетчер останавливает оболочку, композитор и мышь в обратном порядке зависимостей через syscall 31.

Общий p_end завершает компоненты, отзывает их capability-дескрипторы, отменяет IPC-запросы и снимает device leases. Планировщик запускает p_reap, возвращает частные страницы и освобождает слоты. После очистки ядро проверяет, что из стартового графа остался только supervisor, и пишет диагностические строки о возврате страниц.

Проверки

  • Штатная сборка: QEMU PASS, пакеты созданы 1, 3, 4, 2, READY подтверждён, мышиное событие доставлено, экран 1280×800. Отчёт.
  • Отказ READY мыши: QEMU PASS, на экране показана диагностика, все три графических компонента завершены, остался supervisor, возвращено 36 страниц. Отчёт, снимок экрана.
  • В текущем каталоге stop_service выдан только диспетчеру. Отдельный отрицательный QEMU-сценарий для попытки остановки от непривилегированной службы и старого ID оставлен на FAIL-07.

Граница

Откат пока применяется к четырём пакетам интерактивной загрузки и ошибкам READY. Для отказов при создании компонента, исчерпания ресурсов, циклического манифеста и необязательных служб требуется общая таблица критичности и политика потомков. Автоматический перезапуск службы и восстановление сохранённого пользовательского состояния не входят в этот этап.

Этап 40 — бюджеты пакетов рабочего стола

Прямая ссылка на отчёт

Статус: реализован для четырёх встроенных пакетов; штатный и отказной запуск проверены в QEMU.

Что теперь делает ядро

Таблица доверенных пакетов расширена до записи с ресурсными пределами. После создания каждого компонента ядро читает пределы только из этой таблицы и устанавливает их через p_limit, используя полномочие supervisor. Значения из BOOT.MAN не принимаются как лимиты. Если ядро не может применить хотя бы один предел, загрузка останавливается с диагностикой.

Поля лимитов соответствуют существующим видам учёта ядра: физические страницы, capability-дескрипторы, незавершённые IPC-запросы, потоки и выданные ресурсы устройств. Пятое поле — именно счётчик выдачи ресурсов устройств; это не CPU-квота. CPU пока только учитывается по тикам.

Пакет Страницы Дескрипторы IPC-запросы Потоки Ресурсы устройств
Диспетчер готовности 512 32 32 1 32
Рабочий стол 512 16 32 1 32
Драйвер мыши 128 8 32 1 32
Композитор 384 16 32 1 32

Это стартовые бюджеты для текущей сборки рабочего стола. Верхняя граница страниц в общем runtime сейчас 8192; значения в таблице намеренно ниже и задаются отдельно на пакет.

Проверки

  • Нормальная сборка в каноническом каталоге Dev Shell и QEMU acceptance — PASS.
  • Порядок создания по зависимостям — 1, 3, 4, 2.
  • READY и передача мышиного события рабочему столу — PASS, кадр 1280×800.
  • Отказной вариант, где мышь не подтверждает READY, — PASS: загрузчик ограниченно ждёт и показывает экран отказа.
  • На первом прогоне меньшие лимиты запросов блокировали завершение READY. Предел IPC поднят до 32 и перепроверен в штатном QEMU-сценарии. Это зафиксировало полезный результат: лимиты проверяются на реальной связке служб, а не только по синтетическим значениям.
  • Машиночитаемые результаты: штатная загрузка, отказ READY.

Граница

Бюджеты пока жёстко заданы ядром для четырёх встроенных пакетов. Нет автоматической оценки запроса, CPU-квоты, гарантированного резерва или внешнего каталога приложений. Откат всего стартового графа при отказе READY добавлен на следующем этапе.

Этап 39 — доверенный каталог пакетов загрузки

Прямая ссылка на отчёт

Статус: реализован; штатный и отказной пути проверены в QEMU.

Ядро формирует таблицу доверенных пакетов отдельно от пользовательского BOOT.MAN. Для каждой записи в ней находятся ID, разрешённая привязка, READY-код, исходные полномочия, адрес и размер образа, а также роль компонента. Манифест выбирает граф зависимостей и порядок создания. По его ID ядро ищет запись каталога; само содержимое манифеста не может заменить исполняемый образ или выдать полномочия.

До создания компонентов ядро копирует манифест во временную область и выполняет две негативные проверки: меняет привязку пакета и READY-код. Проверка каталога должна отвергнуть каждую копию. QEMU принимает загрузку только при наличии обоих диагностических подтверждений.

Проверки:

  • Сборка рабочий-стол в каталоге DevShell и QEMU acceptance — PASS: четыре компонента созданы в порядке 1, 3, 4, 2, мышь READY и событие мыши получены, кадр 1280×800.
  • Отказная сборка без READY мыши — PASS: ограниченное ожидание и уведомление на экране.
  • QEMU отверг подмену привязки и READY-кода в тестовых копиях BOOT.MAN.

Граница: доверенный каталог пока заполняется четырьмя встроенными компонентами графической среды. Пакеты с диска, проверка их подписи, динамические полномочия и пользовательская установка не реализованы. Расширение каталога требует добавлять явное решение ядра о доверии и правах, а не принимать эти сведения из манифеста.

Этап 38 — READY-настройки из манифеста и безопасный разбор заголовка

Прямая ссылка на отчёт

Статус: реализован; интерактивный запуск и граф зависимостей проверены в QEMU.

После проверки соответствия пакетов доверенным ID и привязкам ядро передаёт READY-коды из BOOT.MAN службам и диспетчеру готовности. Диспетчер проверяет, что корректный код пришёл от соответствующего экземпляра. Сами значения пока ограничены известными ролями рабочего стола: запись манифеста не может выдать компоненту новое полномочие.

Валидатор сначала проверяет, что буфер содержит полный заголовок и не превышает 4096 байт, и только потом читает поля. Приёмочный режим проверяет усечённый заголовок, неверную версию и длину, цикл зависимостей и повторный ID. Независимая проверка графа скорректирована под фактический расход 13 страниц на экземпляр; тесты адресного пространства не применяются к этой отдельной нагрузке.

Проверки:

  • python tools/host/build.py --platform-case порядок-загрузки --out work/boot-manifest-validation
  • python tools/host/qemu_acceptance.py --build work/boot-manifest-validation --timeout 30 — PASS; проверки графа, повреждённых и усечённого манифестов, очистки служб и ресурсов пройдены.
  • Сборка оболочки в build/host/windows-x86_64/debug/qemu-x86_64/dev-shell и QEMU acceptance — PASS: порядок пакетов 1, 3, 4, 2, READY мыши и событие мыши подтверждены, кадр 1280×800.
  • Сборка с намеренно пропущенным READY мыши и QEMU acceptance — PASS: ограниченный тайм-аут и уведомление об отказе подтверждены.

Граница: набор пакетов, соответствие ролей, полномочия и ресурсы остаются доверенной политикой ядра. Манифест задаёт зависимости и проверяемые настройки запуска внутри этого набора; универсального каталога приложений и правовой модели для сторонних пакетов пока нет.

Этап 37 — интерактивный запуск из BOOT.MAN

Прямая ссылка на отчёт

Статус: реализован; штатный и отказной сценарии проверяются QEMU.

Имя сценария сборки shell-live удалено. Интерактивный режим теперь называется «рабочий-стол» и получает граф четырёх компонентов из BOOT.MAN. Записи намеренно расположены не по порядку зависимостей. Ядро выбирает следующий пакет только после создания его зависимостей, поэтому проверочный граф приводит к порядку: диспетчер, драйвер мыши, композитор, рабочий стол.

До создания компонентов ядро проверяет число записей и сверяет ID каждого пакета с разрешённой привязкой и ожидаемым кодом READY. Это не позволяет подменить пакет другим типом полномочий. Проверенные значения READY передаются пакетам и CPL3-диспетчеру, который принимает их только от соответствующей идентичности. Права, доступ к PS/2 и IRQ по-прежнему назначает доверенная политика ядра; поля полномочий в манифесте не дают их расширить. Дополнительная проверка границ заголовка описана в этапе 38.

Проверки:

  • python tools/host/build.py --platform-case рабочий-стол --out work/boot-manifest-desktop — сборка с четырьмя записями BOOT.MAN.
  • python tools/host/qemu_acceptance.py --build work/boot-manifest-desktop --timeout 30 — PASS: граф принят, зависимости соблюдены, READY мыши получен, кадр рабочего стола 1280×800.
  • python tools/host/build.py --platform-case рабочий-стол --тест-таймаута-ready --out work/boot-manifest-desktop-fault — тестовый драйвер не сообщает READY.
  • python tools/host/qemu_acceptance.py --build work/boot-manifest-desktop-fault --timeout 30 — PASS: отсутствие READY обнаружено, ожидание ограничено, диагностическая плашка проверена на кадре.

Граница: BOOT.MAN управляет зависимостями и порядком только для встроенного набора рабочего стола. Он пока не выбирает произвольные пакеты с диска и не назначает новые полномочия, порты или IRQ.

Этап 36 — ограниченное ожидание готовности служб

Прямая ссылка на отчёт

Историческая запись до этапа 37: команда сборки shell-live больше не поддерживается. Текущий эквивалентный сценарий — --platform-case рабочий-стол; актуальные проверки и загрузку из BOOT.MAN см. в этапе 37.

Статус: реализован; штатный и отказной сценарии проверены в QEMU.

Диспетчер готовности проверяет отправителя и роль каждой службы, подтверждает READY одноразовым IPC-ответом и ограничивает ожидание четырьмя последовательными интервалами по 100 системных тиков. При истечении лимита он сохраняет код 703 и число тайм-аутов в собственных данных, после чего отправляет рабочему столу уведомление «СЛУЖБА НЕ ГОТОВА». Рабочий стол показывает его поверх экрана.

Проверки:

  • python tools/host/build.py --platform-case shell-live --out work/internal-ready-timeout — сборка прошла.
  • python tools/host/qemu_acceptance.py --build work/internal-ready-timeout --timeout 30 — PASS: штатная готовность, экран 1280×800 и ответ мыши.
  • python tools/host/build.py --platform-case shell-live --тест-таймаута-ready --out work/internal-ready-timeout-fault — тестовая сборка намеренно подавляет READY мыши.
  • python tools/host/qemu_acceptance.py --build work/internal-ready-timeout-fault --timeout 30 — PASS: READY мыши отсутствует, тайм-аут обнаружен, диагностическая плашка подтверждена по пикселю внутри неё.

Проверка ограничена стендовой конфигурацией shell-live. Она не делает запуск интерактивных служб управляемым через BOOT.MAN; граф запуска пока создаётся политикой платформы.

Этап 35 — первый рабочий стол Guseva OS

Прямая ссылка на отчёт

Статус: реализован; сборка и интерактивная приёмка QEMU — PASS.

После экрана загрузки появляется отдельная CPL3-программа рабочего стола. Она рисует светлую рабочую область, фирменный знак и панель запуска через IPC-композитор. Кнопка «ПУСК» открывает панель настроек; переключатель меняет светлую и тёмную темы, кнопка «ЗАКРЫТЬ» и щелчок вне панели закрывают её.

Диспетчер готовности подтверждает запуск оболочки и мыши. После обоих подтверждений он отправляет рабочему столу IPC-событие передачи экрана, и тот перерисовывает сцену поверх экрана загрузки. Большая заливка фона разбита на полосы: ядро ограничивает площадь одной операции вывода 500 000 пикселями.

Проверка:

  • python tools/host/build.py --platform-case shell-live --out work/desktop-v1 — сборка прошла.
  • python tools/host/qemu_acceptance.py --build work/desktop-v1 --timeout 45 — PASS: MOUSE:READY, MOUSE:DONE, кадр 1280×800.
  • Снимок приёмки: screen.png.

QEMU-приёмка подаёт событие мыши в рабочую область, но автоматический сценарий пока не нажимает кнопку «ПУСК» и не переключает тему. Эти обработчики реализованы в приложении, отдельная автоматизация проверки конкретных пунктов меню остаётся следующей проверкой.

Граница этапа: композитор по-прежнему предоставляет одну поверхность. Каталога приложений и независимых окон пока нет; панель запуска сейчас содержит настройки рабочего стола.

Этап B-04.4 — агрегированная телеметрия рабочего стола

Прямая ссылка на отчёт

Статус: реализовано, проверено на живом QEMU-сценарии shell-live.

Что добавлено

  • Ядро предоставляет системный снимок через вызов 47: версия ABI, такты, свободные/общие физические страницы, занятые страницы, число компонентов, счётчики системных вызовов/сбоев/завершений, события и подтверждения IRQ, нарушения, регионы PMM, фокус и незавершённые IPC-запросы.
  • Снимок содержит только агрегаты. Он не выдаёт адреса, карты страниц или содержимое памяти компонентов.
  • Для чтения введено отдельное полномочие read_system_stats (бит 128). Оно отделено от inspect_memory (бит 32), чтобы рабочий стол не получал право просмотра карт чужой памяти.
  • Политика запуска, валидатор манифеста и реестр полномочий принимают новый бит; остальные полномочия сохраняют прежние значения.
  • Системный вызов подготовлен как интерфейс для отдельного приложения мониторинга. Главная поверхность рабочего стола не должна превращаться в панель диагностики; потребитель снимка будет подключён после реализации независимых поверхностей и окон.
  • В первоначальном прототипе рабочего стола снимок кратко отображался на главной поверхности и был проверен QEMU. Это представление удалено; интерфейс ядра и раздельные полномочия сохранены.

Проверка

  • Первоначальная проверка: сборка и shell-live QEMU — PASS, 1280×800, MOUSE:READY, MOUSE:DONE; прототип выводил значения снимка на экран.
  • Текущий shell-live больше не запрашивает телеметрию из главного рабочего стола. Для приёмки интерфейса нужен отдельный сервис/приложение с выданным read_system_stats.

Граница

Снимок ядра — только read-only агрегированный интерфейс, а не полный просмотрщик. Он ещё не подключён к отдельному гостевому окну: для этого нужны независимые поверхности, диспетчер окон и приложение мониторинга. Число физических страниц зависит от карты памяти и конфигурации виртуальной машины.

Этап B-04.3 — многостраничный код CPL3-компонентов

Прямая ссылка на отчёт

Статус: QEMU PASS на двух страницах кода. Изменён общий путь p_spawn; одностраничный путь старых приложений сохранён.

Реализация

  • Максимальный размер машинного кода пакета увеличен с 4096 байт до 1 МиБ. Проверки формата пакета по-прежнему требуют корректный entry point, размер данных и общую длину.
  • Код компонента размещается в отдельном виртуальном окне: первая RX-страница создаётся при запуске, дополнительные страницы отображаются ядром как RX и учитываются общей картой отображений.
  • Страница данных остаётся RW/NX. Между данными и стеком сохранены три защитные страницы; стек занимает четыре страницы. Автоматические выделения памяти обходят зарезервированное окно загрузчика.
  • Старые одностраничные сервисы используют прежний адресный диапазон и отдельную проверку совместимости. Общие IPC-вызовы сверяют буферы по актуальной странице данных.
  • В build.py добавлен параметр --многостраничный-код-тест: он дополняет тестовый пакет безопасными x86 NOP до двух кодовых страниц.

Проверка

  • Сборка: python tools/host/build.py --platform-case shell-live --многостраничный-код-тест --out work/shell-live-multipage.
  • Пакет рабочего стола: 8192 байта кода, 4096 байт данных; QEMU запустил его и выполнил полноценный интерактивный путь.
  • Приёмка: python tools/host/qemu_acceptance.py --build work/shell-live-multipage --timeout 45 — PASS. Зафиксированы MOUSE:READY, MOUSE:DONE, кадр 1280×800 и отсутствие исключения ядра.
  • При первой проверке обнаружился неверный нижний предел первой дополнительной RX-страницы; после исправления адресного диапазона повторная сборка и QEMU-приёмка прошли.

Граница

Проверены две страницы кода. Ёмкость 1 МиБ не проверялась целиком; отказ при исчерпании кадров, освобождение дополнительных RX-страниц после завершения, счётчик этих страниц в наблюдателе и загрузка пакетов из BOOT.MAN остаются следующими задачами. Интерфейс оболочки в этом этапе не менялся.

Этап B-04.2 — интерактивная оболочка через композитор

Прямая ссылка на отчёт

Статус: QEMU PASS. Композитор включён в интерактивную конфигурацию shell-live; Dev Shell и QEMU оставлены запущенными.

Что сделано

  • В shell-live запускаются четыре компонента: supervisor, рабочий стол, драйвер мыши и CPL3-композитор.
  • Только композитор получает display_output. Рабочий стол отправляет ему команды прямоугольников и глифов через IPC; kernel screen path сохраняет финальный кадр вместо повторной заставки.
  • Композитор проверяет поколенческий ID отправителя и геометрию прямоугольников. Для глифов окончательную проверку координат и параметров выполняет ограниченный системный вызов вывода.
  • Рабочий стол оформлен в светлой палитре и рисует русские подписи «Рабочий стол», «Компоненты», «Память», «Устройства» через IPC-глифы. Подписи передаются одной последовательностью глифов, чтобы использовать страницу кода пакета рационально.
  • Удалена дублирующая строка готовности диспетчера: готовность оболочки и мыши подтверждается отдельными IPC-сообщениями, а экран рисует сам рабочий стол.

Приёмка

  • Сборка: python tools/host/build.py --platform-case shell-live --out work/shell-live-compositor.
  • QEMU: python tools/host/qemu_acceptance.py --build work/shell-live-compositor --timeout 30 — PASS.
  • QEMU сообщил MOUSE:READY и MOUSE:DONE; событие указателя прошло путь драйвер → IPC → оболочка. Экран 1280×800; CPU остаётся в интерактивном цикле.
  • Скриншот: screen.png. Отчёты: interactive-report.json, build-report.json.
  • Стандартная сборка Dev Shell обновлена в build/host/windows-x86_64/debug/qemu-x86_64/dev-shell; Dev Shell запущен с этим образом. Старый QEMU-процесс держал тот же образ и был остановлен перед успешным перезапуском.

Граница этапа

  • Упаковщик и CPL3-загрузчик по-прежнему допускают одну страницу кода на компонент. Рабочий стол занял 4072 из 4096 байт; композитор — 3904 байта. В этой сборке строка монитора ресурсов и динамические числовые значения ещё не выведены в гостевой экран.
  • Проверена одна рабочая поверхность оболочки. Буферы независимых окон, фокус нескольких приложений, восстановление композитора после отказа и обновляемые данные рабочего стола остаются следующими задачами.

Этап B-04.1 — композитор и контракт сцены

Прямая ссылка на отчёт

Статус: QEMU PASS. Это первый проверяемый композиторный путь Guseva OS, а не завершение всего B-04.

Что сделано

  • Добавлена CPL3-служба-композитор. Она принимает команды прямоугольников и глифов через IPC, проверяет поколенческий ID отправителя, метод и границы, затем сама вызывает ограниченный вывод в GOP.
  • Добавлено отдельное CPL3-приложение-производитель сцены. Оно передаёт шесть прямоугольников оформления и девять глифов заголовка Guseva OS, получая ответ на каждую команду.
  • Producer отправляет один заведомо неверный прямоугольник. Композитор отвечает IPC_BAD_MESSAGE, не прекращает работу и принимает следующие команды.
  • display_output выдан только композитору. Прямая попытка рисования от приложения-производителя возвращает отказ.
  • После остановки компонентов ядро сохраняет кадр, нарисованный композитором; QEMU снимает экран и проверяет цвета фона, панели и акцента при 1280×800.
  • Хостовый отчёт проверяет права, завершение двух компонентов, 16 ответов IPC, отклонение неверной команды, итоговые пиксели текста и панели, отсутствие ошибок и очистку страниц, capability и запросов.

Приёмка

Команда: python tools/host/build.py --platform-case композитор --out work/compositor-next, затем python tools/host/qemu_acceptance.py --build work/compositor-next --timeout 20.

Результат: PASS, QEMU 11.1, q35/TCG, 128 МиБ, один CPU; 2 компонента завершены, 6 прямоугольников и 9 глифов отрисованы, 1 неверная команда отклонена без остановки producer, 0 faults, возвращены 20 страниц, capability/IPC-запросы очищены. Проверен отказ прямого вывода у producer. SHA-256 образа: c595ff50d15a27fb8cca05b3dcfa7d1a730ac4cf91f638a155296f71f2d4f6bb.

Экран: screen.png. Машинный результат: platform-report.json, boot-report.json.

Граница этапа

Это пока проверочный статический producer, а не интерактивный рабочий стол. Поверхности окон с буферами и вводом мыши ещё не подключены. Восстановление композитора при отказе и переподключение приложений остаются следующим шагом B-04.

Этап 10.8 — ёмкость учёта и резерв адресов

Прямая ссылка на отчёт

Результат: QEMU PASS. Ёмкость карты отображений увеличена с 4096 до 8192 записей на компонент. Добавлено резервирование виртуального диапазона без выделения физических страниц.

Изменения

  • Каталог метаданных расширен до 40 указателей на слот: до 32 страниц пар адрес/кадр и 8 страниц занятости для виртуального окна 1 ГиБ. Хранение остаётся физически динамическим и оплачивается квотой компонента.
  • Syscall 45: first — число страниц, second — желаемый адрес либо 0 для автоматического выбора; возвращает начало резерва. Резерв не выделяет кадры RAM.
  • Syscall 46: first — начало резерва. Ядро снимает его, только если ни одна страница в диапазоне не отображена.
  • Обычное выделение ищет адрес вне активных резервов. Выделение по точному адресу допускается внутри своего резерва; отображение и физический кадр появляются только после этого вызова.
  • Сейчас компонент может иметь два резервных диапазона. Их границы хранятся вместе с записью процесса и очищаются при его завершении/повторном использовании слота.
  • Наблюдатель читает увеличенный каталог и страницы метаданных; декодер отображает учёт до 8192 записей.

Проверка

QEMU 11.1, q35, 128 МиБ: PASS. Три CPL3-компонента одновременно обработали по 5000 страниц, превысив прежний предел. Проверены запись/чтение верхней страницы, освобождение всех 5000 отображений, разреженный адрес 0x800200000, резерв 5000 страниц, автоматическое выделение за его границей, отображение внутри резерва, отказ снять занятый резерв и успешное снятие после освобождения страницы. 0 faults, при завершении возвращены 96 удерживаемых страниц трёх компонентов.

Проверки наблюдателя: 6/6. Хеш EFI 4b923f490d70f3bceb4385cdaa04c8478efa724ae0f7192297760b98811710a3, образа ab5aae851a45420f2d26302902e3ab96919a86443a9aa21e560fdb805133ec69.

Текущие границы

  • 8192 записей на компонент, окно адресов 1 ГиБ и два резерва на компонент остаются явными конечными пределами этой реализации.
  • Полностью масштабируемый каталог и список резервов, окна для всех пользовательских задач и отказоустойчивость при исчерпании PMM/квоты остаются следующим этапом.
  • Зарезервированный диапазон не является обещанием RAM; приложение должно отдельно отображать страницы и обрабатывать отказ физического выделения.

Этап 10.7 — динамические метаданные отображений

Прямая ссылка на отчёт

Результат: QEMU PASS. Статические таблицы карт по 96 КиБ на каждый из 32 слотов (3 МиБ суммарно) заменены PMM-страницами, которые выделяются только при появлении записей и возвращаются при завершении компонента.

Реализация

  • В ядре хранится компактный каталог: 24 физических указателя на слот, 6144 байта на 32 слота. Первые 16 указателей относятся к таблицам до 4096 пар «виртуальный адрес — физический кадр», следующие 8 — к карте занятости виртуальных страниц.
  • Таблица пар и битовая карта размещаются отдельными физическими страницами. Они выделяются из PMM при необходимости, очищаются перед использованием и учитываются в квоте и счётчиках компонента.
  • Удаление отдельного отображения очищает бит и уплотняет таблицу пар. Страницы метаданных сохраняются как кэш до завершения компонента, чтобы не churn-ить PMM при повторном выделении.
  • Завершение освобождает страницы данных, таблицы страниц и все занятые страницы каталога метаданных. Тест проверил три завершившихся компонента и возврат 84 страниц.
  • Наблюдатель читает каталог и адресуемые физические страницы метаданных, восстанавливает упакованную карту для существующего декодера, сохраняет оба вида снимка в диагностическом экспорте.

Проверка

QEMU 11.1, q35, 128 МиБ: PASS. Три CPL3-компонента выделили, записали/прочитали и освободили по 4096 динамических страниц, проверили 9 областей каталога и разреженный адрес 0x800200000. 0 faults; тест отдельно проверил возврат динамических страниц при работе и 84 оставшихся страниц (исходные страницы, таблицы и метаданные) при завершении компонентов. Хеш EFI caaa9d24b810f8530acba120a4953d13928838d2f4fda64a0f213ea56aaf7f53, образа b3dcdce8a10bce0cfc16fc4a8f90f94971a958c242b74669fd4bc0253943313.

Проверки наблюдателя: 6/6, включая обход физического каталога метаданных. Команды воспроизведения находятся в верхней записи журнала изменений.

Границы

  • Ёмкость карты ограничена 4096 динамическими отображениями на компонент. Меняется цена хранения метаданных, а не предел числа записей.
  • Карта присутствия покрывает 262144 виртуальных страниц, то есть 1 ГиБ диапазона; физическая память, квоты и адресные диапазоны остаются ограниченными.
  • После освобождения всех отображений метаданные остаются кэшированными до завершения компонента.
  • Ядро пока не предоставляет отдельное API резервирования виртуального диапазона или заявленного обязательства физической памяти.

Этап 10.6 — ёмкость карты виртуальных страниц

Прямая ссылка на отчёт

Результат: QEMU PASS. Карта учёта компонента расширена с 504 до 4096 динамических отображений. Поиск свободного виртуального адреса использует отдельную карту присутствия, а не сравнивает каждый кандидат со всеми записями.

Что сделано

  • Для каждого компонента выделено 4096 записей пар «виртуальный адрес — физический кадр» и карта занятости для 262144 виртуальных страниц в диапазоне 1 ГиБ.
  • Курсор адресов движется к следующей свободной странице; освобождение сбрасывает бит присутствия и возвращает курсор к освобождённому адресу, если он расположен раньше.
  • Удалённая запись карты заменяется последней записью, поэтому освобождения из середины не оставляют потерянные слоты.
  • Диагностический сборщик читает увеличенную карту и показывает фактические виртуальные адреса, в том числе разреженные.
  • Квота компонента допускает 8192 учтённых страницы. Это потолок политики текущей платформы; фактическое выделение всё ещё ограничено физическим пулом, правами и доступностью кадров таблиц.

Проверка

python tools/host/build.py --platform-case память --out TEMP/qemu-memory-scaled
python tools/host/qemu_acceptance.py --build TEMP/qemu-memory-scaled --timeout 50
python tests/integration/test_kernel_observer.py

QEMU 11.1, q35, 128 МиБ: PASS, три CPL3-компонента, каждый выделил, записал/прочитал и освободил 4096 страниц, пересёк девять областей каталога страниц, затем проверил разреженный адрес 0x800200000. 0 faults, таблицы страниц и кадры возвращены, после завершения освобождены 33 исходные страницы. Наблюдатель: 5 тестов прошли. Хеши: EFI 1ac33414651edef97b27c5e0bbc19cd1fe42883b87cb65c0b925bd672dfbf469, образ 009a6b368c7d5ffdf49d72c7f231b916c718310e3860c8b910cef00600b6a61c.

Отчёты: QEMU, платформа.

Граница результата

Карта всё ещё имеет конечный размер и статически занимает 96 КиБ на слот компонента (3 МиБ на 32 слота). Следующий шаг B-05 — выделять метаданные по мере роста таблицы отображений либо выбрать другое компактное представление; затем предоставить приложению явное резервирование виртуальных областей, показать резерв/обязательство/физические кадры в среде наблюдения и проверить OOM, повторное использование слотов и отказы.

Этап 10.5 — разреженные отображения за пределами первой таблицы страниц

Прямая ссылка на отчёт

Результат: QEMU PASS. Проверка расширяет адресные отображения компонента в новую область каталога страниц. Она не снимает общий предел числа одновременно учтённых динамических отображений.

Что сделано

  • Учёт динамического отображения хранит пару «виртуальный адрес — физический кадр»; размер карты увеличен до 504 записей на компонент.
  • При запросе адреса из следующей области каталога ядро выделяет таблицу страниц по требованию, включает её в квоту и возвращает кадр при освобождении последнего отображения этой области.
  • Очистка завершённого компонента проходит по динамической карте и дополнительно освобождает оставшиеся таблицы страниц.
  • Счётчики выделения/возврата учитывают и кадры данных, и динамически созданные таблицы. Квота платформы поднята с 514 до 515 страниц: это покрывает 11 исходных страниц компонента и все 504 динамических отображения.
  • Системная карта и диагностический сборщик читают расширенный буфер учёта.

Проверка

python tools/host/build.py --platform-case память --out TEMP/qemu-memory-extended
python tools/host/qemu_acceptance.py --build TEMP/qemu-memory-extended --timeout 50

QEMU 11.1, q35, 128 МиБ: PASS, три CPL3-компонента, 0 faults. Каждый выделил 504 динамические страницы, проверил запись/чтение PTE 511 и освободил все страницы. Затем каждый отобразил страницу по 0x800200000, проверил её содержимое и освободил; дополнительная таблица была возвращена. При завершении возвращены все 33 исходные страницы, capabilities/IPC/device leases и ссылки очищены. Хеши: EFI fcdd08c78323a144ac70b77c17b65fd4f4267899fef34d64ca9c30e247cdc5ae, образ диска 576222298dbd79c9f84697665d1c143339e14784d317b5e35ee1dc7dbcf858ee.

Отчёты и артефакты проверки: QEMU, платформа.

Граница результата

Разреженное отображение за первым 2-МиБ окном работает, но количество записей карты по-прежнему ограничено 504 на компонент. Это не безлимитная память и не автоматический резерв виртуальных областей. Следующий этап должен масштабировать учёт отображений и формат программы вместе с наблюдателем, лимитами и реальными приложениями; затем проверить исчерпание адресного пространства, физического пула и квоты.

Этап 10.4 — проверка верхней границы памяти компонента

Прямая ссылка на отчёт

Дата: 5 ноября 2026 года
Статус: проверено в QEMU на трёх CPL3-компонентах; таблица страниц остаётся одноуровневой.

Реализовано

  • Проверочный компонент отдельно настраивает квоту 514 страниц: 10 страниц загрузки и 504 динамические страницы.
  • Перед проверкой пользовательской кучи компонент системными вызовами ядра выделяет последовательно весь диапазон PTE 8–511.
  • Каждое выделение активирует адресное пространство компонента. CPL3 записывает и читает контрольное значение в последней странице по адресу 0x8001FF000.
  • Компонент освобождает все 504 страницы в обратном порядке, затем проверяет пользовательскую кучу. Сохранённые результаты проверяются хостом после завершения.
  • Отказ QEMU-приёмки теперь включает счётчики ошибок, нарушений и диагностику адресов проверки памяти.

Приёмка

  • python tools/host/build.py --platform-case память --out TEMP/qemu-memory-boundary — сборка PASS.
  • python tools/host/qemu_acceptance.py --build TEMP/qemu-memory-boundary --timeout 40 — QEMU PASS.
  • Три компонента проверили по 504 страницы каждый; верхний PTE 511 доступен из CPL3, ошибки защиты — 0, после каждого компонента освобождено по 11 закреплённых страниц, утечки динамических страниц нет.
  • SHA-256 образа: 9aedd98b8e46c5d8c1466f8f0d723db0830a6d73238a0a5ad7297f608edf37e6.

Границы

Проверен текущий диапазон 2 МиБ с одной таблицей страниц. Многоуровневые таблицы, адресное пространство больше 2 МиБ, поверхности приложений в этом диапазоне и продолжение снимка памяти через несколько страниц остаются отдельной работой.

Этап 10.3 — манифест служб с загрузочного тома

Прямая ссылка на отчёт

Дата: 5 ноября 2026 года
Статус: QEMU PASS. UEFI читает отдельный \EFI\BOOT\BOOT.MAN с FAT16-раздела до ExitBootServices; ядро проверяет содержимое и передаёт проверенный список CPL3-диспетчеру.

Реализация

  • FAT16-образ содержит BOOTX64.EFI и отдельный BOOT.MAN. Сборка больше не встраивает манифест в EFI-код.
  • UEFI получает том через LoadedImage и SimpleFileSystem, открывает файл и читает его в ограниченный буфер внутри EFI-образа. Размер ограничен 32–4096 байт; все операции с Boot Services завершаются до ExitBootServices.
  • ABI-мост передаёт ядру адрес буфера и фактическую длину. Обычная загрузка передаёт нулевую длину.
  • Ядро проверяет magic, версию, количество и точную длину записей, пакеты и права по каталогу, уникальность ID/привязок/псевдонимов и ацикличность зависимостей.
  • CPL3-диспетчер повторно обходит граф до готовности всех записей: запускает только узлы с READY-зависимостями, не привязывает запуск к порядку строк и останавливает запуск при отказе.
  • Проверочная сборка намеренно ставит зависимый пакет первым в файле. QEMU подтверждает, что пакет 2 получает READY раньше пакета 3, несмотря на обратный порядок записей.

Приёмка

  • python tools/host/build.py --platform-case порядок-загрузки --out work/startup-graph-runtime — PASS.
  • python tools/host/qemu_acceptance.py --build work/startup-graph-runtime --timeout 30 — PASS.
  • Журнал QEMU подтверждает порядок: BOOT: manifest loaded → настройка GDT/IDT/TSS → ExitBootServices OK → ядро.
  • QEMU-сценарий проверил неверную версию, неверную длину, цикл, повторный ID, два READY-обмена, завершение трёх компонентов и освобождение 30 страниц; живых capabilities, запросов, leases и ссылок не осталось.
  • Последний образ с обратным порядком записей: b08e6a70051b1ac170637a0a7cc5fa77424ee3dbd67420654c323818adaf0972.

Границы

Проверены FAT16 и QEMU/EDK II, одна тестовая конфигурация с двумя службами. Диспетчер ограничен 32 записями маской зависимостей, но проверена только конфигурация с двумя узлами, а каталог сейчас содержит три тестовых пакета. Ядро пока не имеет общего файлового менеджера: файл загружает UEFI-мост. Не реализованы каталог пакетов с диска, критичность, лимиты ресурсов и политика перезапусков. Штатные драйверы и оболочка пока не запускаются из этого графа.

Отчёты: QEMU, платформа, манифест.

Этап 10.1 — зависимости запуска двух CPL3-служб

Прямая ссылка на отчёт

Дата: 5 ноября 2026 года
Статус: проверен в QEMU для двух служб и одной зависимости; произвольный системный манифест ещё не подключён.

Реализовано

  • CPL3-диспетчер читает две записи: пакет, зависимости, состояние, привязку и ожидаемую READY-метку.
  • Каталог содержит отдельные GUP-пакеты служб; запуск разрешён только в пределах каталога и полномочия start_service.
  • Привязки компонентов уникальны. Каждая запущенная служба получает выданное ядром право отправить READY только своему родителю.
  • Вторая служба запускается только при состоянии первой «готово». Надзиратель проверяет полный ID отправителя, код READY и ответ по IPC.

Приёмка

  • python tools/host/build.py --platform-case порядок-загрузки --out work/startup-order — PASS.
  • python tools/host/qemu_acceptance.py --build work/startup-order --timeout 20 — PASS.
  • Проверено: 3 компонента, 2 подтверждённых READY-обмена, состояние обеих служб «готово», 30 страниц освобождены, ошибки, права, запросы и ссылки очищены.
  • SHA-256 образа: 05e103d835ae728eb0d139724b038468bb47de783a53c9af20044eab93412c1d.

Ограничения и следующий шаг

Список и каталог пакетов заданы только проверочным QEMU-сценарием; цикл рассчитан на две записи. Формат и чтение системного манифеста с загрузочного тома, проверка версий/прав/лимитов, произвольный топологический обход, политика критичных служб и перевод штатной загрузки на граф пока не реализованы.

Отчёты: загрузка QEMU, сводка платформы.

Этап B-03 — маршрутизация ввода по фокусу компонентов

Прямая ссылка на отчёт

Дата: 4 ноября 2026 года
Статус: завершён 4 ноября 2026 года в границах маршрутизации указателя и клавиатуры между двумя CPL3-приложениями. Глобальный композитор и восстановление служб в эту приёмку не входят.

Реализовано

  • Полномочие manage_input_focus отделено от полномочий памяти и управления службами.
  • Syscall 38 назначает/сбрасывает фокус, syscall 39 возвращает текущий ID. Разрешённый компонент задаётся по полному ID с поколением; устаревшая или завершённая идентичность не принимается.
  • При завершении компонента, на котором стоит фокус, ядро очищает фокус и увеличивает счётчик переходов.
  • Dev Shell показывает активный ID фокуса и количество смен для наблюдения за состоянием ядра.
  • Проверка QEMU workers покрывает уполномоченное назначение, отказ компонентам без права и автоматическую очистку при завершении выбранного компонента.

Проверки основания фокуса

  • python tests/kernel/test_platform.py — PASS.
  • python tests/kernel/test_components.py — PASS.
  • python tests/integration/test_kernel_observer.py — PASS.
  • python -m py_compile tools/host/kernel_observer.py tools/host/dev_shell.py — PASS.

Реализация маршрута

  • Один CPL3 PS/2 controller владеет общими портами i8042 и IRQ12/IRQ1, поэтому два драйвера не спорят за один контроллер. После указательных пакетов он передаёт клавиатурные make/break события той же службе input-router.
  • Для мыши router сначала передаёт событие менеджеру окон и дожидается его ответа; менеджер выбирает окно по координатам и назначает фокус через syscall 38. Для клавиатуры router сохраняет тип события и читает текущий фокус через syscall 39.
  • Router читает ID фокуса syscall 39 и использует capability только выбранного приложения. Другие приложения не получают событие.
  • Router читает поколенческий ID фокуса и использует capability только выбранного приложения. Два клиента и router работают в CPL3 с раздельными адресными пространствами. Оконный менеджер рисует две ограниченные тестовые панели; это ещё не глобальный композитор.
  • При завершении приложение удаляется из таблицы, его фокус очищается, capability и запросы освобождаются.

Приёмка

python tools/host/build.py --platform-case focus-routing --out build/focus-routing-router и python tools/host/test_boot.py --build build/focus-routing-router — QEMU PASS. Проверка подтверждает 6 компонентов, 4 пакета от мыши, 12/12 IRQ acknowledgement, по два клика приложениям (последние координаты x=600 и x=700), затем make/break scan code 30 только второму приложению; всего 14/14 подтверждений IRQ, 4 перехода фокуса, очистку фокуса и нулевые ошибки/утечки capabilities, IPC-запросов, device leases и object references. Снимок и отчёты: build/focus-routing-router/screen.png, build/focus-routing-router/platform-report.json, build/focus-keyboard/screen.png, build/focus-keyboard/platform-report.json. Оба сценария проходят.

Следующее

Для полноценного этапа 9 требуются глобальный композитор нескольких поверхностей и восстановление службы отображения после контролируемого сбоя.

Этап 9.2 — указатель и видимый курсор оболочки

Прямая ссылка на отчёт

Дата: 4 ноября 2026 года
Статус: подэтап проверен; этап 9 продолжается

Результат

Изолированная GSL-оболочка продолжает получать события PS/2-указателя через IPC, обрабатывает нажатие и отпускание кнопки и показывает результат на своей проверяемой поверхности. Добавлен простой чёрно-белый программный курсор с контуром. Он рисуется поверх оболочки после получения события, только когда указатель находится внутри поверхности 32×16, масштабированной в 8 раз. Пиксели по-прежнему формирует приложение CPL3; физический GOP ему не доступен.

Проверка

  • Сборка стандартной конфигурации shell-input: PASS.
  • Свежая загрузка в QEMU 11.1.0, q35/TCG, 128 МиБ: PASS.
  • QEMU передал движение, нажатие и отпускание; независимый checker подтвердил один обработанный клик и курсор в ожидаемой точке поверхности.
  • Снимок экрана проверил фон, рамку, заголовок, кнопку, белую часть курсора и чёрный контур.
  • Проверка компонента подтвердила CPL3, явное право display_output, два события оболочки, шесть IRQ/подтверждений мышиного драйвера, возврат 30 страниц и очистку временных объектов и полномочий.
  • Полный локальный прогон с Clang и Rust: 29 тестов компилятора, 38 тестов ядра и 6 интеграционных — PASS без пропусков. Для нативных тестов компилятора исправлены устаревшие пути к примеру и исходникам ядра после переноса дерева.

SHA-256 образа: 5e8b1b5af13e11271adee519071d9960eca7819e2cc6246f2b89a1555fe6fbef.

Граница результата

Курсор сейчас рисуется только на поверхности оболочки; за её пределами он скрыт. Нет фокуса окон, второго пользовательского приложения и отдельной службы отображения с восстановлением. Следующий шаг — два изолированных приложения и явная передача фокуса, чтобы ввод получало только активное окно.

Этап 9.1 — статическая графическая оболочка

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Дата: 4 ноября 2026 года
Статус: подэтап проверен; этап 9 продолжается

Результат

Стандартная сборка загружает простую графическую оболочку как отдельный CPL3-компонент, написанный на GSL. Компонент строит пиксельную поверхность 32×16 в формате RGB24-in-u32 и выводит её с масштабом 8: на экране видны фон, окно, заголовок GUSEVA и кнопка OPEN.

Доступ к дисплею не следует из роли или номера компонента: загрузочная политика выдаёт оболочке только право display_output. Ядро проверяет это право, формат, размеры, буфер, масштаб, координаты и переполнение при выводе прямоугольника. Проверки подтвердили отказ при отсутствии полномочия, при недопустимом масштабе и некорректной геометрии.

Проверка

  • Компилятор GSL: 29 тестов — PASS.
  • Ядро: 38 тестов — PASS.
  • Стандартная сборка и свежая загрузка QEMU 11.1.0, q35/TCG, 128 МиБ, один CPU: PASS.
  • QEMU checker сверил экранные пиксели окна, заголовка и кнопки; отдельный отчёт компонента показывает CPL3, полномочие вывода, успешный commit и отказ недопустимого масштаба.
  • Компонент завершился без fault; все 10 принадлежащих ему страниц возвращены. После завершения нет активных capabilities, requests, device leases или object references.
  • Регрессионный QEMU сценарий поверхности этапа 8 повторно прошёл после изменения вывода.

SHA-256 штатного образа: ca23e1644db9a55fec9cc694a617fee07a111bedfd514c181860487a2418a713. Машинные результаты сохранены в STAGE9_VALIDATION.json и каталоге сборки.

Граница результата

Кнопка пока является нарисованным элементом, а не интерактивным контролом. Нет курсора, фокуса, второго приложения, отдельного композитора с проверкой восстановления или отображения показателей ресурсов. Поэтому завершён только подэтап 9.1, а не весь этап 9 и не разработка ядра целиком.

Следующий ограниченный шаг: передать указательные события от PS/2-драйвера в CPL3-приложение оболочки, ограничить координаты областью окна и проверить нажатие/отпускание кнопки, включая выход указателя за границы. Затем добавить курсор/фокус и отдельное второе приложение.

Отчёт этапа 8 — ввод и графический вывод для изолированных приложений

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Дата: 4 ноября 2026 года. Статус: функциональный минимум завершён (P0-020).

Что реализовано

Клавиатурный драйвер и драйвер PS/2-указателя находятся в отдельных компактных CPL3-программах на GSL. Они получают только выданные device leases и IRQ handles; IRQ подтверждает ядро после проверки владельца. Клавиатура передаёт make/break события через FIFO ёмкостью 16 с политикой drop-oldest и счётчиком потерь. Указатель разбирает трёхбайтовые пакеты, ограничивает координаты 1280×800 и отслеживает состояние кнопок.

Для отображения добавлены GSL-эффект screen_pixel и syscall 32. CPL3-приложение формирует дескриптор и пиксельный буфер в своей частной странице; ядро проверяет указатель, длину, формат, stride и целевой прямоугольник до переноса пикселей в GOP. Формат буфера — RGB24 в u32-словах, stride задан в пикселях. Приложение не получает прямой доступ к физическому framebuffer.

Сценарий поверхности рисует цветной прямоугольник и фон, затем пытается commit за правой/нижней границей. QEMU-снимок проверяет цвета и координаты, а приложение подтверждает отказ на некорректный прямоугольник. Завершение возвращает все страницы и отзывает полномочия.

Проверки

  • Компилятор GSL: 29 тестов, все прошли, включая нативную проверку границ screen_pixel и запрет эффекта для пользовательских actions.
  • Ядро: 35 тестов, все прошли с локальным toolchain; нативные проверки планировщика, IPC, ресурсов, объектов и устройств выполнены.
  • Четыре свежие загрузки QEMU 11.1.0 (q35/TCG, 1 CPU, 128 МиБ): keyboard, keyboard-overflow, mouse, surface. Их SHA-256, метрики и отчёты checker сохранены в STAGE8_VALIDATION.json.
  • Все сценарии вернули по 10 частных страниц; после выхода нет живых capabilities, requests, device leases или object references. QEMU подтвердил стабильный HLT.
  • Стандартная сборка пересобрана; test_boot.py прошёл. run.py принял свежий build report и запустил viewer без ошибки устаревшей сборки.

Ограничения

Драйверы проверены на виртуальных PS/2-устройствах QEMU. Полный USB/HID, ускорение GPU, общая разделяемая поверхность, планирование CPU-квот и гарантированные резервы не входят в этот этап. Поверхность сейчас фиксированного размера 32×16; приложение делает commit через syscall ядра, отдельный compositor ещё не реализован.

QMP-события клавиатуры и мыши инжектировались в QEMU и прошли через драйверы. Интерактивную передачу именно из окна Tk-viewer отдельно не подтвердили: системный UI-инвентарь этой сессии не предоставил его окно для ввода. Длительный P1 soak и отдельную стадию повторных загрузок пропустили по решению пользователя.

Следующий этап

Первая графическая оболочка: служба отображения, фон, курсор, одно окно и кнопка; затем фокус и запуск двух приложений. Этот этап использует проверенный ввод и surface ABI, не переносит драйверы в ядро.

P0-019 — завершение этапа 7.1

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Дата проверки: 2026-11-04. Статус: принято для P0.

Результат

Убрана зависимость активного пути ядра от трёх демонстрационных процессов. Обычная команда сборки подключает общий ограниченный runtime компонентов CPL3. У компонента есть идентификатор с поколением и состояние жизненного цикла. Selector планировщика, загрузчик и обработка syscall используют общий реестр экземпляров. IPC, полномочия, счётчики и очистка объектов привязаны к полной идентичности компонента.

Управляющие действия требуют явно выданного start_service; имя, слот и номер программы не создают право. Устройства представлены ограниченными leases для port I/O, MMIO и IRQ. Обработчик подтверждает событие; завершение владельца отзывает lease, а старый handle не работает после повторного использования слота.

Проверочный RTC-драйвер с протоколом устройства находится в CPL3-приложении GSL. Это демонстрирует отделение политики устройства от ядра; универсальная внешняя загрузка произвольных драйверов пока не заявляется.

Критерии завершения и доказательства

  • Компилятор GSL: 29/29 тестов.
  • Ядро: 35/35 тестов. Нативная проверка общей модели прошла составы 1/3/7/32, 1500 IPC-обменов, балансы владения, квоты, старые ID, конфликты устройств и подтверждение/отзыв/повторную выдачу IRQ.
  • Совместимость прежнего поведения: 33/33 сценария QEMU пересобраны и прошли.
  • Новый runtime: 8/8 сценариев QEMU прошли с независимым захватом состояния: 3, 7 и 32 компонента; fault; IRQ; revoke/reuse IRQ; spawn; terminate.
  • На максимальном составе возвращены 320 страниц; по завершении нет живых capability, запросов, leases или object references. На предельном составе отказ 33-го компонента проверен явно.
  • Свежая штатная сборка в outputs/guseva-kernel/build прошла test_boot.py. run.py открыл QEMU viewer.

Машинные результаты и SHA-256 всех образов — в PLATFORM_VALIDATION.json; по одному журналу на сценарий — в artifacts/archive/work-history/platform-validation/.

Воспроизведение

Из PowerShell в корне проекта загрузить локальный Clang в текущую сессию, затем запустить:

. ./tools/host/use-laptop-toolchain.ps1
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python artifacts/archive/work-history/validate_platform.py
python outputs/guseva-kernel/build.py
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Если штатная сборка не существует или её исходники изменились, сначала снова выполните python outputs/guseva-kernel/build.py: run.py намеренно отклоняет отсутствующий или устаревший образ.

Зафиксированные ограничения P0

Один CPU; до 32 одновременно учитываемых компонентов; один целочисленный контекст исполнения на компонент; фиксированные ограниченные таблицы, пакеты и квоты. Нет пользовательского heap, shared memory, CPU reservations и гарантированных резервов. Произвольный динамический набор процессов не заявляется: действует проверяемая граница в 32 слота. Длительная нагрузка и приёмка платформы P1 остаются будущей отдельной работой и не блокируют завершение этапа 7.1.

Следующий этап

Этап 8 — ввод и графический вывод для изолированных приложений. Первый ограниченный результат: CPL3-драйвер клавиатуры и приложение, показывающее события и переполнение очереди. Этот отчёт закрывает этап 7.1; новые работы не добавляются в него задним числом.

P0-018 — этап 7.1: время жизни объектов IPC

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

3 ноября 2026 года. Продолжение P0-017. Переход проверен; этап 7.1 целиком остаётся открытым.

Что изменено

Прежние поколения дескрипторов и билетов защищали повторную выдачу самого объекта IPC. Теперь добавлена независимая проверка экземпляра компонента: одинаковый номер исполнителя после перезапуска не означает прежнего владельца.

  • Точка приёма хранит ID своего экземпляра.
  • Дескриптор хранит ID держателя и ID владельца целевой точки. Проверяются оба, поколение дескриптора, открытое состояние точки, её ID, эпоха отзыва и права. Даже повторное открытие точки с прежней эпохой не восстанавливает право на другой экземпляр.
  • Запрос хранит ID вызывающего и принимающего экземпляров. Проверки выполняются при доставке, ответе и опросе сроков/состояния, а не только при отправке.
  • Ожидание приёма и сон хранят ID владельца. Завершение ожидания принимает ожидаемый ID явно и сверяет его с текущим экземпляром и записью ожидания до изменения кадра. Старое завершение не снимает новое ожидание.
  • Перезапуск диагностической службы явно связывает новую точку и корневой дескриптор с новым ID. Остановка и освобождение дескриптора очищают соответствующие привязки.

Отсутствие реестра или нулевой ID не дают неявного разрешения. ABI сообщений пользовательских программ остаётся v1; версия защищённого состояния IPC повышена до 2, поскольку изменился внутренний формат.

Доставка и возврат

Если исходный вызывающий экземпляр завершён, опрос удаляет оставшийся запрос/результат и его очередь. Если завершён исходный получатель ещё не завершённого запроса, работающему исходному вызывающему возвращается PEER_CLOSED. Уже подготовленный ответ или ошибка остаются доступны исходному живому вызывающему после завершения службы; новому вызывающему они не доставляются.

Прямая доставка также проверяет идентичность до записи в пользовательский буфер. Устаревшая запись удаляется с результатом STALE. Отложенное пробуждение со старым ID не изменяет кадр и состояние нового владельца.

Учёт живых дескрипторов и запросов сопоставляет ID, поэтому старый объект не начисляется новому владельцу прежнего номера исполнения. Пока оба исходных участника работают, кредит запроса учитывается у обоих до получения результата. После завершения одного участника оставшийся результат занимает место в общем ограниченном пуле и учитывается у живого исходного участника; он не переносится на новый экземпляр. Это не новый универсальный менеджер ресурсов: лимиты и накопительная статистика прежней службы ещё привязаны к загрузочному адаптеру.

Размещение

Использованы ранее свободные поля прежней защищённой страницы состояния; новых страниц под метаданные IPC не выделено.

Объект Поле ID
Точка приёма +40
Запрос +88 вызывающий, +96 получатель
Ожидание +40
Дескриптор таблица держателей с 3744, таблица целей с 3808; по восемь u64

При очистке ID точек, ожиданий и обе таблицы дескрипторов должны быть нулевыми. ipc_check.py и supervisor_check.py независимо проверяют это по захвату памяти QEMU, дополнительно к прежней проверке отсутствия запросов, прав и частных страниц.

Проверки

Фактический итог: 58 автоматических тестов без пропусков (26 компилятора и 32 ядра), все 33 заново собранных сценария QEMU — PASS. Включены 64/128 МиБ, исчерпание памяти, варианты supervisor, IPC, пользовательские нарушения и аварии ядра. Актуальным проверяющим кодом повторно сверена очистка ID всех 15 захватов с IPC.

Сводка — IPC_IDENTITY_VALIDATION.json; журналы — validation-ipc-identity (включая 33 журнала QEMU), рабочие журналы — artifacts/archive/work-history/ipc-identity-validation. Архив — artifacts/archive/project-zips/guseva-os-ipc-identity-018.zip; QEMU в него не входит. При упаковке проверяются свежесть всех сборок, хеши образов, результаты загрузок и очистка реестров.

Обычная сборка: EFI 174080 байт, загруженный образ 1040384 байт. При 128 МиБ пул содержит 19684 страницы, после очистки 19683 свободны и одна контрольная занята. Рост образа изменил число доступных страниц относительно P0-017; это сверено заново, а не принято за утечку. Экран остаётся STAGE 7.

Нативные проверки выполняют фактически сгенерированный GSL. Сохранены 500 обменов прежнего контракта. Добавлены все четыре фазы запроса с заменой любого участника; доставка до опроса очистки; отказ старому билету ответа; отсутствие записи в новые пользовательские данные/кадры; повторное открытие точки с той же эпохой; старый приём, сон, тайм-аут, пробуждение и явное завершение; сохранение нового ожидания при старом завершении; сверка начислений и освобождения; 100 последовательных остановок, смен поколений, новых корневых прав и ограниченных grant.

Часть проверок намеренно заменяет экземпляр без штатной очистки IPC, сохраняя старые объекты: это проверка независимой защиты последней границы доставки. Это не разрешённый путь пользовательского перезапуска. Штатный загрузочный адаптер сначала останавливает IPC, затем завершает экземпляр и возвращает страницы.

Проверка захвата дополнена порчей ID точек, ожиданий, обеих таблиц прав и версии состояния. Старые исторические отчёты относятся к предыдущему формату и не перезаписываются как новые результаты.

. ./tools/host/use-laptop-toolchain.ps1
python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python artifacts/archive/work-history/validate_ipc_identity.py

Что остаётся

IPC всё ещё использует две точки, четыре запроса, четыре дескриптора на участника и прежний машинный доступ к буферам. Адресация syscall grant и поле sender пока сохраняют публичный псевдоним; внутри защита времени жизни опирается на ID экземпляра. Аудит сохраняет прежний формат с псевдонимом, отдельной истории ID в нём пока нет. Инициализация IPC и выдача корневых прав — доверенные загрузочные операции, не пользовательские syscall.

Следующий переход — общие таблицы объектов IPC и ресурсных адресатов для произвольного состава компонентов в пределах ёмкости, затем обобщение машинного исполнителя. Общий протокол удержания всех объектов до освобождения записи экземпляра ещё не завершён: сейчас lifecycle отдельно контролирует страницы, IPC очищается адаптером и защищает доставку проверками ID. Механизмы портов/MMIO, доставки/подтверждения IRQ и отзыва устройств не реализованы. Защита IPC не объявляется защитой ещё отсутствующих аппаратных уведомлений. Этап 8 не начат.

Перед изменениями сохранён artifacts/archive/baselines/ipc-identity-baseline-017.zip. Журнал проекта — CHANGELOG.

P0-017 — этап 7.1: общий выбор готового компонента

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

3 ноября 2026 года. Продолжение P0-016; этап 7.1 целиком остаётся открытым.

Изменение

В component_scheduler.gsl реализован обход общей таблицы экземпляров. Выбор принимает предыдущий ID с поколением и возвращает ID работающего готового экземпляра либо ноль. Алгоритм не знает имён программ, публичных псевдонимов, ролей или адресов демонстрационных контекстов. Вместимость — 32 записи. При неизменном составе готовых компонентов используется круговой обход; гарантия справедливости при произвольном непрерывном изменении состава этим шагом не установлена.

Запись экземпляра хранит состояние исполнения по смещению +56 (отключён, готов, ожидает) и указатель сохранённого контекста по +72. Изменение допускается только по текущему ID работающего экземпляра. Завершение сразу очищает оба поля. Новый владелец записи не наследует готовность и контекст; старый ID не может изменить его состояние.

Прежние проверки пользовательского кадра, очистка flags, пределы RIP/RSP, диагностический watchdog в 1000 тиков и выбор idle/контрольного кадра вынесены в prototype_execution.gsl. Адаптер сначала проверяет кадры, затем публикует полный снимок готовности: завершение одного участника может разбудить другого через IPC. process_select подключает этот адаптер к общему выбору. Проверки вызывающего syscall и выборочный учёт CPU используют наличие работающего экземпляра вместо списка номеров программ.

Проверки

Фактический итог: 57 автоматических тестов без пропусков (26 компилятора и 31 ядра), 33 заново собранных сценария QEMU — PASS. Пройдены 64/128 МиБ, исчерпание памяти, варианты восстановления службы, IPC, пользовательские нарушения и аварии ядра. Сводка — SCHEDULER_VALIDATION.json; журналы тестов — validation-scheduler, журналы загрузок — artifacts/archive/work-history/scheduler-validation. При упаковке повторно проверяются актуальность исходников, хеши образов и захваты реестра всех неаварийных сценариев.

Обычная сборка: EFI 170496 байт, загруженный образ 1036288 байт. Пул при 128 МиБ: 19685 страниц, после очистки 19684 свободны и одна контрольная занята. Экран остаётся STAGE 7. Архив результата — artifacts/archive/project-zips/guseva-os-scheduler-017.zip; QEMU в него не входит.

Новая нативная проверка исполняет скомпилированный GSL: составы из 1, 3, 7 и 32 экземпляров с произвольными привязками и псевдонимами; восемь полных кругов каждого стабильного состава; 2000 вариантов готовности в сравнении с независимой Python-моделью; ожидание и пробуждение; запрет публикации запускающегося экземпляра; отсутствие выбора без контекста; завершение, повторное использование и отклонение старого ID без изменения новой записи.

Полное повторение на ноутбуке:

. ./tools/host/use-laptop-toolchain.ps1
python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python artifacts/archive/work-history/validate_scheduler.py

Граница результата

Обобщён именно выбор пользовательского экземпляра. Машинный исполнитель по-прежнему использует фиксированные layout и три демонстрационные программы; исполнение 32 произвольных CPL3-программ в QEMU не заявляется. Статический диагностический планировщик пяти потоков ядра этапа 3 этим шагом не заменён.

IPC, адресаты ресурсных операций и загрузочная политика ещё содержат прежние привязки. Следующие подпункты 7.1 — перенос IPC, прав и ресурсов на общую идентичность, устранение ограничений исполнителя и проверка отложенной доставки старому поколению. Затем нужны ограниченные механизмы устройств, доставка/подтверждение IRQ и отзыв доступа. Драйвер клавиатуры и этап 8 пока не реализованы. CPU-квот, heap и гарантированных резервов нет.

История и сохранение

Создан корневой CHANGELOG с восстановленной историей этапов и отдельными архитектурными уточнениями. Обязательное обновление журнала закреплено в корневом AGENTS.md и правилах проекта. Старые результаты сохраняются как исторические, текущие указываются отдельно. Перед изменением сохранена копия предыдущего архива artifacts/archive/baselines/scheduler-baseline-lifecycle-016.zip.

Этап 7.1: таблица экземпляров и жизненный цикл

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Продолжение границы компонентов. Реализован первый подпункт этапа 7.1 — общая таблица экземпляров с поколениями и подключением к загрузке/очистке. Этап 7.1 целиком ещё не завершён: планировщик и IPC сохраняют ограничения адаптера.

Таблица

Логика написана на GSL в lifecycle.gsl. Таблица занимает ранее свободную часть защищённой страницы реестра; отдельного выделения памяти для неё не понадобилось. Вместимость — 32 записи. Общие функции таблицы принимают произвольные допустимые привязки и идентификаторы; роль или номер supervisor в алгоритм выделения не зашиты. Вместимость таблицы не означает, что прежний исполнитель уже умеет запускать 32 программы.

Стартовая декларация и экземпляр разделены:

  • Декларация задаёт доверенную конфигурацию загрузки: привязку, публичный псевдоним и начальные допуски.
  • Экземпляр получает собственный ID с поколением, состояние, текущие управляющие допуски и счётчик принадлежащих ему страниц.
  • Одна декларация сама по себе больше не даёт активных управляющих полномочий. Они действуют только у работающего экземпляра.

Формат ID: generation * 65536 + slot + 1. Низкие 16 бит содержат номер записи плюс один; старшие 48 — поколение. Нулевой ID недействителен. Система выдаёт ID в пределах одного запуска ядра; сохранение их между перезагрузками не поддерживается.

Переходы

Состояние Действие
Свободен Можно выделить запись; данные и допуски прежнего владельца очищены
Запускается Запись занята, страницы могут выделяться; ID ещё не разрешается как работающий, управляющие права не действуют
Работает Загрузка завершена, ID разрешается, действуют явно назначенные допуски
Завершается ID уже не разрешается, управляющие допуски сняты; ещё принадлежащие экземпляру страницы препятствуют освобождению записи
Свободен следующего поколения Страницы освобождены, запись очищена, поколение увеличено
Выведен из использования Последнее представимое поколение завершено; запись больше не выдаётся

При заполнении таблицы выделение отклоняется с нулевым ID, увеличивается отдельный счётчик отказов. Повторная привязка занятого исполнителя или занятого публичного псевдонима также отклоняется. Повторный commit и повторное освобождение недопустимы. Поколение не оборачивается к единице.

component_init теперь одноразовый: повторная инициализация действующего реестра отклоняется, поэтому она не может обнулить поколения. Нативные тесты смены стартовой политики моделируют отдельную загрузку в доверенной фикстуре, а не разрешённую операцию пользовательской программы.

Подключение к реальным процессам

process_create после предварительных проверок занимает запись экземпляра и отмечает каждую полученную страницу. Только после успешной загрузки запись становится работающей. Частичная неудачная загрузка проходит завершение, возврат страниц и освобождение записи. Поколение такого несостоявшегося экземпляра также расходуется.

Повторная попытка создания в занятой записи не освобождает страницы уже работающей программы. Эта защита добавлена отдельно и проверена нативно.

При штатном завершении, fault или отклонённом возвратном кадре снимаются управляющие допуски и прекращает разрешаться ID. Физические страницы продолжают числиться за экземпляром до фактического process_release. После успешного возврата всех страниц запись очищается, а поколение увеличивается. Повторный запуск диагностической службы проходит этот же путь.

Общее выделение нового экземпляра принимает допуски явно и не копирует их из старой записи. Прежний загрузочный адаптер при предусмотренном восстановлении той же службы явно применяет её стартовую декларацию заново. Это не общий spawn произвольной программы; перед ним ещё нужно убрать привязки пакетов, ресурсов и исполнения к демонстрационной конфигурации.

Диагностика идентичности

Syscall 19 возвращает ID текущего работающего экземпляра. Клиент, служба и supervisor сохраняют полученное значение в собственной странице данных для независимого захвата. Syscall 2 пока сохраняет прежний публичный псевдоним для совместимости тестового протокола; этот псевдоним не является правом или ID с поколением.

В обычном QEMU-сценарии первый экземпляр службы получает ID 65539, второй — 131075. Низкие биты одинаковы, поколение увеличено. Наблюдаемые текущие ID клиента/службы/supervisor — 65537, 131075, 65538. Это результат текущего порядка загрузки, не фиксированные значения ABI.

После завершения обычной проверки четыре экземпляра выделены и освобождены, занятых записей нет. Сохраняются прежние 40 выдач и освобождений частных страниц; пик памяти и лимиты этапа 7 продолжают проверяться.

Что пока не закрыто

  • Планировщик ещё использует фиксированные исполняемые записи, а не обходит общую таблицу.
  • IPC, ресурсные адресаты и специальный протокол supervisor ещё не полностью переведены на ID экземпляров. Проверка ID уже отклоняет старое поколение, но это само по себе не доказывает запрет доставки всех отложенных сообщений новому владельцу. Этот критерий остаётся обязательным для следующих подпунктов 7.1.
  • Уведомлений устройств, подтверждения IRQ, прав на порты/MMIO и отдельного драйвера пока нет. Защита от старого прерывания должна быть реализована вместе с их временем жизни.
  • Условие освобождения записи в текущем подключении проверяет частные страницы; общий учёт сообщений, объектов прав и IRQ должен стать частью этого же протокола при их переносе на общую идентичность. Прежняя очистка IPC сохраняется отдельно.

Проверки

Фактический итог: 56 автоматических тестов без пропусков (26 компилятора и 30 ядра), 33 заново собранных и успешно проверенных сценария QEMU. Пройдены обычные загрузки 64/128 МиБ, исчерпание PMM, варианты supervisor, все прежние IPC, пользовательские отказы и аварии ядра. При упаковке все неаварийные захваты реестра повторно проверены актуальным независимым проверяющим кодом.

Обычная сборка: EFI 167936 байт, загруженный образ 1036288 байт, дисковый контейнер 17825792 байта. При 128 МиБ RAM пул содержит 19685 страниц: после очистки 19684 свободны, одна занята прежней контрольной страницей. Экран остаётся STAGE 7, поскольку ввода этапа 8 пока нет. Эти значения относятся к данной сборке и прошивке, не к требованиям будущей ОС.

Нативная проверка исполняет именно сгенерированный GSL-код: заполнение 32 записей, определённый отказ следующей выдачи, 2000 повторных использований, отклонение накопленных старых ID, отсутствие наследования допусков, запрет освобождения с принадлежащими страницами, незавершённая загрузка, двойные переходы и граница последнего поколения. Проверены атомарный отказ повреждённой стартовой декларации и запрет повторной инициализации.

Нативные проверки загрузчика дополнены сверкой отката и счётчиков экземпляров при исчерпании PMM, а также отказом повторной загрузки в занятый процесс без изменения его страниц или идентичности.

component_check.py независимо читает реестр из памяти QEMU: проверяет отсутствие живых допусков/страниц после очистки, поколения, последние освобождённые ID и соответствие счётчиков сумме переходов поколений. Дополнительно сопоставляет ID, полученные CPL3, с текущими записями и архивом первого экземпляра службы. Результат — build/component-report.json.

Команды повторения:

. ./tools/host/use-laptop-toolchain.ps1
python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python artifacts/archive/work-history/validate_lifecycle.py

Сводка полной регрессии — LIFECYCLE_VALIDATION.json; журналы — validation-lifecycle и artifacts/archive/work-history/lifecycle-validation. Следующий подпункт — планировщик по общей таблице, затем перенос IPC/прав/ресурсов на идентичность экземпляра.

Этап 7.1: граница ядра и компонентов, первый переход

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Пользователь явно подтвердил дополнительный этап 7.1 «Общая модель компонентов» перед этапом 8. Этот отчёт описывает первый переход; этап 7.1 ещё не завершён. Клавиатура, указатель и пользовательская поверхность пока не подключены. Актуальные порядок и критерии приёмки — в разделе 7.1 KERNEL_ROADMAP.md.

Исправление направления

Пользователь подтвердил: ядро — независимое основание конструктора, к которому подключаются компоненты. Конкретный протокол клавиатуры не должен становиться частью ядра. Незавершённая PS/2-ветка исключена из активных исходников и сборки; исходники и экспериментальный образ сохранены в artifacts/archive/work-history/deferred-keyboard, дополнительная копия — artifacts/archive/baselines/unfinished-keyboard-stage8.zip. Компилятор возвращён к GSL 0.0.12; новый port_read8 из прерванной ветки не оставлен как действующий интерфейс.

Рабочая версия этапа 7 сохранена в artifacts/archive/project-zips/guseva-os-stage7-014.zip и artifacts/archive/baselines/stage8-baseline-stage7.zip.

Что изменено в работающем коде

Добавлен components.gsl: общий ограниченный реестр стартовых идентификаторов и управляющих полномочий. Он не содержит имён приложений, номеров «особого supervisor» или протокола устройства. Поддерживает от 1 до 32 записей и произвольные допустимые идентификаторы/привязки. Это вместимость таблицы, не обещание запуска 32 процессов нынешним планировщиком.

Полномочия задаются отдельно от механизмов — в prototype/stage7-components.json. component_policy.py проверяет и кодирует декларацию, сборка помещает её в read-only секцию EFI. Ядро независимо проверяет формат и копирует её в защищённую страницу. Число записей, уникальность ID и привязок, допустимая маска прав, длины, версия и резервные поля проверяются до изменения реестра. Отклонённая декларация не меняет уже установленное состояние.

Управление лимитами ресурсов, запуск предусмотренной службы и чтение ресурса пакета теперь проверяют выданное полномочие, а не получают его автоматически из слота 4 или 1. Отсутствующий реестр не даёт управляющих прав. Копия token и самостоятельно названный PID не создают полномочие. Для ресурсного API соответствие публичного ID и внутренней записи берётся из реестра. Syscall идентификации также читает декларацию.

Права стартовой политики:

Маска Полномочие
1 Управление ресурсными лимитами
2 Запуск службы через прежний ограниченный протокол
4 Чтение предусмотренного ресурса пакета
8 Чтение событий прежнего supervisor-протокола; его получатель пока фиксирован адаптером

Это стартовые управляющие допуски, не универсальный формат всех будущих capabilities. IPC-дескрипторы с поколениями продолжают существовать отдельно. Делегирование, отзыв этих стартовых допусков и повторное использование привязок динамическими процессами ещё не реализованы. Перед динамическим spawn обязательны явное время жизни полномочия и защита поколениями от наследования прав новым процессом в старом слоте.

Честная граница текущей реализации

Номер больше не создаёт управляющее право сам по себе, но существующий исполнитель ещё ограничен демонстрацией этапов 6–7. prototype_layout.gsl выделяет известные адреса записей и отображение слотов. Проверка адаптера разрешает старому runtime только три предусмотренные привязки 0, 1 и 4 и отклоняет другую конфигурацию до запуска.

Поэтому произвольное число компонентов, замена любого драйвера без пересборки и общая подключаемость ещё не достигнуты. Объявлять их работающими на основании одного реестра нельзя.

Найденные зависимости:

Место Оставшаяся привязка Что нужно обобщить
kernel.gsl Выбор среди двух процессов или трёх в supervisor-режиме; отдельные controller/idle Таблица исполняемых контекстов, обход готовых записей, выделение и поколения слотов
ipc.gsl Два endpoint, четыре request, таблицы прав по четырём слотам на участника Независимые объекты endpoint и таблицы дескрипторов каждого компонента; хранение ограничено общими ресурсными бюджетами
supervisor.gsl Один пакет службы, фиксированные получатели подключения/событий, демонстрационный запуск Отдельная политика сборки и восстановления; общий управляемый жизненный цикл
resources.gsl Три записи, 10 начальных страниц и один поток; storage через прежний control Привязка счётчиков и лимитов к записи компонента и жизненному циклу объектов
app_build.py, GUP1/GUSEVAP1 Три конкретных приложения, один кодовый блок и фиксированный каталог Каталог компонентов и независимые пакеты с описанными интерфейсами
kernel.gsl, supervisor.gsl Демонстрационные проверки и экран встроены в загрузочную последовательность Отдельная проверочная конфигурация поверх механизмов

Последовательность до возвращения к клавиатуре

  1. Сделано в этом переходе: отдельная стартовая декларация ID/полномочий, общий проверяемый реестр, отсутствие неявного управляющего права из номера процесса, удаление PS/2 из активного ядра.
  2. Обобщить таблицу компонентов и планировщик: ID с поколением, независимые записи, общий выбор готовой задачи и очистка. Число объектов зависит от ёмкости и лимитов, а не от имён или ролей.
  3. Обобщить IPC и таблицы прав на этой идентичности; заменить специальный управляющий протокол общими объектами жизненного цикла. Разделить пакет теста и механизм загрузки.
  4. Предоставить драйверу ограниченное право на диапазон портов/MMIO и доставку аппаратных прерываний через общий интерфейс ядра. Определить подтверждение обработки прерываний и отзыв доступа при завершении. Проверить отказ вне диапазона, чужой дескриптор, отзыв и смерть владельца. Отложенные сообщения и прерывания старого владельца не должны попадать новому компоненту в том же слоте; возврат ресурсов сверяется независимо. Протокол конкретного устройства в этом интерфейсе не описывается.
  5. Написать отдельный драйвер клавиатуры на GSL в CPL3 и подключить его к общей очереди событий. После этого продолжать этап 8.

Это рабочая последовательность реализации подтверждённого направления. Формат будущих объектов устройств, семантика отзыва и окончательный ABI здесь не выдаются за уже согласованные или реализованные решения.

Проверки перехода

Фактически прошли 54 автоматических теста без пропусков: 26 компилятора и 28 ядра. Заново собраны и успешно проверены все 33 сценария QEMU. Сохранены обычные загрузки 64/128 МиБ, полное исчерпание PMM, варианты supervisor, IPC, пользовательские отказы и аварии ядра. Сводка — COMPONENTS_VALIDATION.json.

Обычная сборка: EFI 159744 байта, загруженный образ 1028096 байт, дисковый контейнер 17825792 байта. При 128 МиБ RAM в пуле PMM 19687 страниц, после очистки свободны 19686 и одна занята прежней контрольной страницей. Это наблюдения данной сборки. Экран остаётся STAGE 7, поскольку ввода и графической поверхности этапа 8 ещё нет.

Нативный код GSL проверен с таблицами на 1, 3, 7 и 32 записи, произвольными ID и привязками. Повреждённые/повторные записи и неподдерживаемые права отклоняются атомарно. Отдельно проверяется отсутствие прав у привычного слота 4 без гранта.

Нативные проверки существующих механизмов меняют декларацию: управление ресурсами переносится в слот 0, публичные ID меняются на 1001/2002/3003. Новый получатель может менять лимит, прежний управляющий получает DENIED, запрос своего учёта возвращает новый ID. Аналогично проверены перенос допуска к запуску службы и чтению ресурса пакета, а также отказ прежним получателям. Назначение управляющего права другому компоненту не означает, что прежний демонстрационный протокол событий уже стал динамическим.

component_check.py независимо сверяет декларацию и защищённую таблицу, реально извлечённые из QEMU. Проверка включена во все обычные сценарии, где запускаются процессы, включая прежние legacy/user-fault режимы. Проверки W^X, supervisor-only отображений, очистки, ресурсов, перезапуска и IPC сохраняются.

Команды из корня проекта:

. ./tools/host/use-laptop-toolchain.ps1
python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python artifacts/archive/work-history/validate_components.py

Фактические результаты полной регрессии сохраняются в COMPONENTS_VALIDATION.json, журналы — validation-components и artifacts/archive/work-history/components-validation. Исторические STAGE7_VALIDATION.json и отчёт этапа 7 относятся к сохранённой предыдущей сборке.

Этап 7: учёт и ограничения ресурсов статических компонентов

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

3 ноября 2026 года. GSL 0.0.12; новых конструкций языка не потребовалось.

Воспроизведение этапа 6 на ноутбуке

Перед изменениями выполнена новая сборка, все 26 тестов компилятора и 20 тестов ядра прошли без пропусков. Загрузочный тест QEMU дал PASS. Tkinter-viewer запускался и был автоматически закрыт после семи секунд; снимок STAGE 6 просмотрен. Все 33 сценария на этом шаге не запускались.

Окружение: Python 3.13.15, Clang 17.0.0 из установленного Unity, rustc 1.97.1 как источник rust-lld, локальный QEMU 11.1.0. Clang добавлялся только в PATH процесса. Исходная версия и новые результаты сохранены в artifacts/archive/baselines/laptop-stage6-baseline.zip, SHA-256 253723de9c0d4d424fa99a8d040dda27e93e71a2dd5dcb2209a241fea203930a. Перенесённый архив artifacts/archive/project-zips/guseva-os-stage6-013.zip не изменялся.

Реализованная граница

Учёт и действительные лимиты применяются к трём фиксированным компонентам режима supervisor. Прежние IPC и user-fault режимы сохраняют собственные фиксированные ограничения и служат регрессией. Универсального менеджера динамических процессов, пользовательского heap и динамического создания потоков пока нет.

Политика написана на GSL в resources.gsl. Данные защищены аппаратными supervisor-only отображениями: 1024 байта ранее свободной области control, начиная с control+2048. Указатель находится в state+1480. Формат версии 1, три записи по 128 байт начиная с 64. Записи принадлежат логическому компоненту и сохраняются между воплощениями службы.

Ресурс Учёт и применение лимита
Частная память Число физических страниц в принадлежащем процессу списке; начальная загрузка требует 10 страниц. Предел проверяется до выделения. Пик, суммарная выдача и освобождение учитываются отдельно
Потоки Сейчас один поток исполнения на статический процесс. Лимит 0 запрещает запуск, 1 разрешает; создания второго потока API не предоставляет
Права Активные IPC-дескрипторы получателя; отдельный управляющий объект supervisor считается одним правом, пока supervisor жив. Grant проверяет бюджет получателя до изменения таблицы
Сообщения Каждый живой request вместе с резервом результата занимает единицу у обоих участников. Отправка проверяет оба бюджета. Получение запроса и отправка ответа не освобождают резерв; сбор результата или очистка освобождают
CPU Число принятых IRQ0, пришедшихся на текущий компонент. Счётчик накапливается при перезапуске; это выборочные тики примерно по 10 мс, не точное время и не CPU-квота

Пределы текущей конфигурации: 10 страниц, четыре IPC-права, два request-кредита, один поток на компонент. Supervisor может устанавливать значения от нуля до этих потолков. Нельзя установить лимит ниже текущего расхода. Клиент в проверке получает более строгие лимиты: два права и один request.

Обычный компонент не может менять свой лимит или читать чужой учёт. Доступ к управлению привязан к вызывающему supervisor в защищённом слоте 4; число PID или скопированный token не создаёт полномочие. Сейчас это тот же фиксированный принцип авторизации, что на этапе 6, а не общая система делегируемых объектов управления ресурсами.

Память и служебные расходы

Десять страниц процесса включают четыре страницы таблиц, код, данные и четыре страницы пользовательского стека: 40960 байт. Учитывается физическая память, а не длина полезного кода. Неудачная частичная загрузка возвращает все выданные страницы; эти выдачи и освобождения остаются в накопительных счётчиках.

Статические стеки входа в ядро, таблицы IPC, управляющие записи, диагностический архив первого воплощения, read-only пакет и карта PMM принадлежат образу ядра. Они входят в loaded_image_bytes, но не прибавляются к частным страницам процесса. Динамического выделения этих объектов пока нет. Структура учёта использует свободное место уже существующего control и не требует отдельного выделения страниц.

Пользовательской общей памяти нет. Встроенный read-only пакет относится к образу ядра, приватные копии кода и данных — к соответствующему процессу. Общий учёт разделяемых пользовательских страниц, гарантированные резервы и CPU-квоты остаются отдельными задачами.

ABI

Syscall Аргументы Результат
17 PID (0 = вызывающий), адрес собственного буфера, ровно 128 байт 128 либо ошибка; свой учёт доступен компоненту, чужой — только supervisor
18 PID (0 = вызывающий), ресурс 1..4, новый лимит 0 либо ошибка; только supervisor

Ресурсы: 1 — страницы, 2 — права, 3 — request-кредиты, 4 — потоки. Буфер syscall 17 содержит 16 little-endian u64: версия, PID, пары «расход, лимит» для четырёх ресурсов, CPU samples, общее число отказов, пик страниц, выданные страницы, освобождённые страницы, отказы по памяти. Полная разбивка отказов находится в защищённой записи и независимом resource-report.json.

Неавторизованный доступ возвращает SERVICE_DENIED, неверный ресурс/значение — IPC_BAD_MESSAGE, неверный буфер — IPC_BAD_POINTER. Исчерпание бюджета выдачи права, сообщения или запуска службы возвращает IPC_LIMIT. Недостаток физических страниц остаётся SERVICE_UNAVAILABLE. Лимит памяти не приводит к автоматическому завершению компонента.

Запуск нового воплощения проверяет его начальный бюджет до архивирования или освобождения старого. Отказ не расходует эпоху и бюджет успешных запусков. Частные страницы завершившегося процесса остаются учтёнными до фактического process_release, даже если поток уже не выполняется.

Проверки

Фактически прошли 49 автоматических тестов без пропусков: 26 компилятора и 23 ядра. Заново собраны и успешно загружены все 33 сценария QEMU, включая обычные 64/128 МиБ, полное исчерпание PMM с 64/128 МиБ, варианты supervisor, все восемь вариантов IPC, одиннадцать user-проверок и семь аварий ядра. Сводка — STAGE7_VALIDATION.json, журналы — validation-stage7 и artifacts/archive/work-history/stage7-validation.

Обычная сборка: EFI 155136 байт, загруженный образ 1019904 байта, дисковый контейнер 17825792 байта. При 128 МиБ RAM пул PMM содержит 19689 страниц, после проверки 19688 свободны и одна занята прежней контрольной страницей. Это измерения данной сборки и прошивки, не требования будущей ОС. Viewer STAGE 7 также запускался; снимок просмотрен.

Обычный сценарий дополнен проверками из CPL3:

  1. Supervisor устанавливает службе девять страниц: запуск возвращает IPC_LIMIT без выдачи страниц. После восстановления лимита проверяет запрет запуска при нулевом лимите потоков и затем запускает службу.
  2. Клиенту запрещено повысить свой лимит и прочитать чужой учёт. Создание третьего права при лимите два отклоняется.
  3. При лимите один новый запрос отклоняется, пока первый запрос или его результат занимает кредит. Обычный обмен после получения результата продолжается.
  4. Сохраняются сбой службы, новое воплощение, явное переподключение и очистка этапа 6.

Новый нативный тест исполняет сгенерированный GSL-код: авторизация, все четыре бюджета, переполнение размера запроса, отказ посередине выделения страниц и откат, запрет уменьшения ниже расхода, оба участника IPC и сохранение резерва после ответа, успешное продолжение после освобождения, очистка.

resource_check.py независимо сверяет захваченный control с состоянием процессов, счётчиками IRQ каждого воплощения, пользовательскими снимками syscall 17 и общим числом освобождённых страниц. Негативные тесты повреждают указатель, версию, лимит, CPU, выдачи/освобождения, отказы, права, сообщения и пользовательский снимок; такие снимки отклоняются.

Ожидаемый итог обычного сценария: 40 страниц выдано и освобождено, пик по 10 на компонент, четыре отказа по ресурсам (два у клиента, два у службы), нет живых прав, requests и потоков после очистки. CPU samples могут быть нулевыми у короткой программы: это допустимое следствие выборочного учёта.

Команды повторения и фактические результаты полной регрессии — в README и STAGE7_VALIDATION.json. Снимок STAGE 7 показывает пик страниц службы, число отказов и выборочные тики CPU. После самопроверки CPU останавливается. Следующий этап плана — ввод и вывод для первой графики.

Этап 6 Supervisor, пакет программ и восстановление службы

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Завершён 3 ноября 2026 года для QEMU q35/TCG, одного x86-64 CPU. Проверены 64/128 МиБ RAM. Версия компилятора остаётся GSL 0.0.12: для этого этапа понадобились новые действия и протоколы на GSL, без новых конструкций синтаксиса.

Работающий сценарий

В CPL3 запускаются три программы с отдельными CR3: клиент PID 1, диагностическая служба PID 2 и supervisor PID 3. Supervisor принимает решения о запуске и повторном запуске. Ядро проверяет его управляющее право, поколение службы, допустимый пакет, паузу и лимит. Автоматического перезапуска внутри планировщика нет.

Обычная сборка выполняет следующую проверку:

  1. Из read-only пакета загружаются клиент и supervisor. Клиенту пока не выдано право отправки службе.
  2. Supervisor запускает диагностическую службу из того же пакета. Клиент явно запрашивает подключение и получает право первого поколения.
  3. Служба читает разрешённый ресурс пакета и отвечает на IPC-запрос. Затем по отдельной проверочной операции намеренно выполняет запрещённый переход к адресу 0.
  4. Ядро изолирует #PF 14/error 20 в службе. Клиент получает PEER_CLOSED, supervisor — отдельное уведомление с причиной и поколением. Клиент и supervisor сохраняют свои адресные пространства.
  5. Немедленный повторный запуск отклоняется с BACKOFF. После пяти тиков supervisor запускает новый экземпляр. Старые десять страниц службы освобождаются до выделения новых.
  6. Новая служба получает очищенную память и новую эпоху точки приёма. Клиент запрашивает подключение к поколению 2. Старый дескриптор отклоняется, новый отвечает на свежий запрос.
  7. Клиент отдельно запрашивает штатное завершение службы. Supervisor получает уведомление о завершении; затем программы заканчивают самопроверку, ресурсы очищаются.

Сбойный запрос автоматически не воспроизводится. Supervisor не переносит повреждённое состояние службы в новый экземпляр. Служба проверяет нулевой начальный маркер в своей странице данных и заново читает ресурс. Это проверка восстановления одной статeless диагностической службы, не произвольного драйвера или файловой системы.

Полномочие и протокол управления

Supervisor — пользовательская программа apps/supervisor.gsl. Его управляющий объект привязан к защищённой записи процесса. Числовой token сам по себе не даёт права: запрос от клиента или службы с тем же token отклоняется. Пример запрета проверяется из обеих программ.

Внутренние слоты ядра: 0 — клиент, 1 — служба, 2 — контроллер проверки, 3 — idle, 4 — supervisor. Пользовательский PID supervisor равен 3. У него отдельный стек входа в ядро и собственные страницы; всего теперь 28 guard pages стеков ядра.

Syscall Операция Ограничения
13 Запустить пакет службы: token, package ID, ожидаемая эпоха Только supervisor, только пакет 2, совпадение эпохи, допустимое состояние, пауза и лимит
14 Подключение: service ID, 64-байтный buffer, ожидание Только клиент; ожидается поколение новее указанного в buffer
15 Уведомление: token, buffer, ожидание Только supervisor; очередь из восьми событий
16 Прочитать ресурс: ID, buffer, доступная длина Ресурс 4 разрешён службе и supervisor, клиенту запрещён

Syscall 3 со стороны supervisor выполняет ограниченный сон в его собственной записи ожидания. IPC клиента и службы продолжает использовать контракты этапа 5. У supervisor пока нет третьей IPC-точки: управляющие уведомления идут отдельным ограниченным протоколом ядра.

Запись подключения сообщает эпоху, новый локальный дескриптор клиента, PID службы и ID пакета. Запись события содержит тип exit/fault, ID службы, эпоху, состояние, vector/error, адрес fault и номер события. Ожидания ограничены ста тиками и используют idle/HLT, когда готовых программ нет.

Ошибки управления: DENIED=−40, LIMIT=−41, BACKOFF=−42, UNAVAILABLE=−43, BAD_PACKAGE=−44 в представлении u64. Неверная эпоха возвращает STALE; попытка запуска уже работающего экземпляра — FULL/занято. Указатели проверяются по собственной странице данных вызывающего процесса.

Разрешены два успешных запуска службы за проверочный runtime, включая первый. Неверные права и пакет не расходуют этот лимит. Перед повторным запуском выдерживается пять принятых тиков. После второго сбоя дальнейший запуск отклоняется с LIMIT, ожидающий клиент получает определённый отказ. Это ограничитель текущей конфигурации, не готовая общая политика восстановления.

Read-only пакет GUSEVAP1

Пакет bundle.gub встроен в RO/NX-секцию образа. Он содержит три программы GUP1 и один ресурс. Загрузка и проверка выполняются на GSL в supervisor.gsl; Python только собирает пакет на машине разработки.

Заголовок: восемь little-endian u64 — magic GUSEVAP1, версия 1, размер заголовка 64, четыре записи, размер каталога 256, начало данных 320, общий размер, флаги 0. Запись каталога занимает 64 байта: ID, тип, смещение, длина, FNV-1a-64, маска роли, флаги 0 и резерв 0.

ID Объект Разрешённая роль
1 Клиент GUP1 Клиент
2 Диагностическая служба GUP1 Служба
3 Supervisor GUP1 Supervisor
4 Ресурс GUSEVA16, 8 байт Служба и supervisor

Проверяются версия, размеры, ID, типы, разрешённые роли, отсутствие пересечений и лишних данных, границы, выравнивание и checksum каждого объекта. Программы дополнительно проходят GUP1-проверку. Общий пакет ограничен 64 КиБ. Полномочия определяет политика ядра; изменение роли в каталоге не создаёт новое право.

В обычной сборке пакет занимает 18744 байта. FNV здесь обнаруживает повреждение; он не является подписью и не аутентифицирует издателя. Доверие к встроенному пакету следует из доверия к загруженному EFI-образу. Secure Boot, обновления пакетов и внешние хранилища пока не реализованы.

Программа и ресурс загружаются по каталогу пакета, а не через Windows loader в гостевой ОС. ELF/PE user.exe на хосте остаётся промежуточным результатом сборки. Пользовательского API записи в пакет нет; аппаратные права RO/NX проверяются вместе со всеми секциями ядра.

Память, поколения и очистка

На программу по-прежнему выдаётся десять страниц: четыре таблицы, код, данные и четыре страницы стека. В максимуме одновременно работают три такие программы — тридцать страниц. При одном восстановлении суммарно выделены и освобождены сорок страниц: клиент 10, supervisor 10, два экземпляра службы по 10.

Старый CR3 службы уже не активен, когда supervisor вызывает повторный запуск. Очистка выполняется на CR3 supervisor, после чего GSL-загрузчик создаёт новый экземпляр. Физические адреса могут использоваться повторно; идентичность службы задаётся эпохой и правами, а не адресом страницы.

Таблицы прав IPC и поколения tickets не обнуляются при восстановлении. Старый SEND-дескриптор клиента освобождается, его слот получает новое поколение. В обычном прогоне старое значение 65794 заменяется на 131330; после замены старое возвращает STALE. Повторное подключение выполняется только по запросу клиента.

Для диагностики перед освобождением сохраняются запись и страницы первого экземпляра в защищённый буфер 40 КиБ внутри образа. Это позволяет независимо проверить права, старое содержимое и владение страницами, даже если allocator повторно выдал те же адреса. Буфер недоступен пользовательским программам. Нулевой начальный маркер нового экземпляра проверяется самой службой и нативным тестом загрузчика.

После проверки отсутствуют живые IPC-права, requests и ожидания, очередь supervisor пуста, все выдававшиеся страницы возвращены PMM. Остаётся одна прежняя контрольная страница менеджера памяти. Снимок первого экземпляра — фиксированная диагностическая память ядра, не динамическая утечка.

Проверки

Прошли 46 автоматических тестов: 26 компилятора и 20 инфраструктуры ядра. Новый нативный тест исполняет GSL-код проверки пакета, авторизации, эпохи, backoff и лимита, очистки, загрузки свежей памяти и подключения. Повреждённые заголовки, checksum, роли, перекрывающиеся записи и некорректная программа отклоняются. Сохранены прежние 2000 операций PMM, 500 состояний планирования и 500 IPC-обменов.

Прошли 33 сценария QEMU: обычные 64/128 МиБ, полное исчерпание/восстановление PMM с 64/128 МиБ, три дополнительных сценария supervisor, восемь IPC-вариантов, одиннадцать прежних пользовательских проверок и семь аварий ядра.

Supervisor-вариант Запусков / повторных Результат
recover, обычная сборка 2 / 1 Первый экземпляр fault, явное подключение к новому, штатное завершение
exit-recover 2 / 1 Первый экземпляр штатно завершается без ответа; новый обслуживает клиента
restart-limit 2 / 1 Два fault, третьего запуска нет, клиент получает LIMIT
no-fault 1 / 0 Три программы завершаются штатно без восстановления

supervisor_check.py независимо декодирует фактически загруженный пакет, все три текущих адресных пространства и сохранённый первый экземпляр. Проверяются реальные кадры CPL3, неизменность кода, допустимые изменения данных, маркеры очищенной памяти, ресурс из пакета, поколения, события и причина fault, пауза, подсчёт syscall/IRQ всех воплощений и очистка. Намеренно испорченные снимки не проходят проверку.

Сохраняются W^X, CR0.WP, EFER.NXE, TSS/IST, блокировка FP/SIMD, отсутствие пользовательского доступа к ядру и всех лишних отображений. PMM отдельно сверяется с картой UEFI и полной битовой картой после очистки. Подтверждены исходный CR3 контроллера, IF=0 и замаскированный PIC.

В обычной сборке: три программы, четыре объекта пакета, два запуска службы, один повторный запуск, два подключения, один намеренный fault, 45 syscall и 40 освобождённых страниц. На backoff приходится пять idle-тиков. При 128 МиБ PMM содержит 19691 страницу, при 64 МиБ — 3307; после проверки занята одна контрольная страница.

Размер EFI — 146944 байта, загруженного образа — 1011712, дискового образа — 17825792. Это размеры текущего прототипа, не оценка готовой ОС.

Доказательства: build/supervisor-report.json, supervisor-state.bin, embedded-bundle.gub, first-service-pages.bin, снимки трёх процессов и таблиц, memory-report.json, protection-report.json и boot-report.json. Сводка всех прогонов — STAGE6_VALIDATION.json. Старые отчёты описывают соответствующие архивные версии.

Повторение

python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Отдельный вариант:

python outputs/guseva-kernel/build.py --supervisor-case restart-limit
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-supervisor-restart-limit

Прежний обычный IPC-прогон теперь вызывается явно: --ipc-case exchange, папка build-ipc-exchange. Пользовательские и аппаратные аварийные варианты сохраняют прежние аргументы.

После сборки окно нужно закрыть и открыть заново. Экран STAGE 6 показывает результаты проверки; затем CPU намеренно останавливается. Supervisor пока не остаётся постоянной фоновой службой после завершения демонстрации.

Границы

Три фиксированные целочисленные программы, одна восстанавливаемая stateless-служба, один read-only пакет с фиксированным каталогом, ограниченный управляющий объект. Нет общего spawn, службы имён, файловой системы с записью, state transfer, восстановления произвольного драйвера, обновлений и пользовательских квот. Следующий этап — учёт и ограничения ресурсов компонентов.

Восстановление служб имеет известные аналоги, например reincarnation server MINIX. Здесь реализованы собственные действия GSL и явный протокол смены поколения с ограниченным повторным запуском; абсолютная новизна механизма не утверждается.

Этап 5 IPC и права на обращения

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Завершён 3 ноября 2026 года для QEMU q35/TCG, одного x86-64 CPU и фиксированной пары процессов. GSL 0.0.12. Развиваем продуктовое направление Guseva OS: понятные полномочия, сроки и ограниченная стоимость обращений. Следующий этап — supervisor, первые службы и загрузка приложений.

Контракт вместо неограниченного накопления

ipc.gsl реализует обмен между клиентом и отдельной программой-службой в CPL3. У них разные CR3 и физические страницы. Данные передаются копированием через ядро; общей пользовательской памяти нет. Отправитель определяется ядром, поле отправителя из заявки не принимается.

Запрос имеет срок и резерв на завершение. При приёме ядро учитывает место, которое потребуется для ответа или ошибки. Другие запросы не могут занять этот резерв. У каждой точки приёма две ячейки, всего четыре записи запросов. Переполнение возвращает FULL без дополнительного выделения памяти. Прямое обращение к собственной точке приёма сейчас запрещено; взаимодействие двух программ проверяется отдельно от локального вызова.

Каждое принятое обращение завершается ответом, уведомлением об истечении, отзыве или исчезновении получателя либо освобождается при завершении самого клиента. Уведомление не требует нового свободного слота сверх зарезервированного. Непрочитанные завершения удерживают кредит, ограничивая следующие обращения.

Тайм-аут определяется принятыми тиками PIT. Максимальный срок нового запроса — 100 тиков вперёд; срок включает получение результата клиентом. Максимальное отдельное ожидание приёма — 100 тиков. Истёкший ответ не принимается. Это не гарантия физического реального времени: пропущенные/задержанные IRQ и нагрузка хоста влияют на время.

Конверт v1

Размер строго 64 байта, восемь little-endian u64:

Смещение Поле
0 Ненулевой ID, уникальный среди незавершённых запросов клиента
8 Номер операции 1–255
16 Одно значение u64
24 Абсолютный срок в тиках этого запуска процессов
32 Подтверждённый отправитель, заполняет ядро
40 Одноразовое право ответа, заполняет ядро
48 Вид доставки: 0 запрос, 1 ответ, 2 завершение с ошибкой
56 Резерв, ноль

При отправке поля 32–56 должны быть нулевыми. Это не 64 байта произвольного payload: полезное значение текущей версии — одно u64. ID, операция и срок ответа берутся из исходного контракта. Ответ не может продлить срок. Формат остаётся рабочим и будет расширяться вместе со службами.

Ожидание приёма блокирует поток. Когда обе программы ждут, планировщик выбирает supervisor-idle с HLT. При получении сообщения или наступлении срока ядро обновляет сохранённый результат syscall и возвращает поток в готовое состояние. Выделен дополнительный защищённый стек idle; теперь проверяются 26 guard pages стеков ядра.

Права и поколения

На процесс выделены четыре записи capability. Дескриптор содержит поколение, тег владельца и номер локального слота. Полномочие существует только при совпадении с защищённой записью ядра. Дескрипторы не являются секретными случайными числами: защита обеспечивается проверкой владельца, записи, поколения, эпохи и разрешённого действия.

Права: SEND=1, RECEIVE=2, GRANT=4, REVOKE=8, CLOSE=16. Стартовый grant разрешает клиенту только отправку службе. Права не выдаются из строки имени или объявления machine/user в GSL.

GRANT устанавливает отдельную запись получателю. Выдаваемые права должны быть подмножеством исходных. Другому процессу пока можно передавать только SEND; приём и управление точкой остаются у владельца. Полученный числовой дескриптор передаётся в сообщении после установки ядром: одна передача числа полномочия не создаёт.

Освобождение дескриптора меняет поколение. При максимальном 48-битном поколении слот выводится из использования вместо переполнения. Отзыв повышает эпоху точки, сохраняет корневое право владельца и завершает связанные незаконченные контракты с REVOKED. Чужие старые права становятся недействительными. Отозванный или закрытый дескриптор можно освободить, чтобы вернуть локальный слот.

Ответ разрешён только тому процессу, которому доставлен запрос, по отдельному одноразовому ticket. Ticket использует другой диапазон тегов, поэтому его нельзя применить как capability. После ответа, отмены или получения завершения старое право ответа не принимается. Обёртывание поколений также исключено.

Закрытие точки и завершение процесса удаляют принадлежащие ему запросы и права, освобождают ожидания и уведомляют оставшихся клиентов. Штатное завершение и пользовательский fault используют одну процедуру очистки IPC. Отдельный CLOSE сейчас отключает IPC-сторону процесса целиком, включая её локальные дескрипторы.

Syscall

Сохраняется INT 0x80: RAX — номер/результат, RCX/RDX/R8 — аргументы. Все пользовательские конверты проверяются по своей странице данных до копирования. Таблицы прав и запросов пользователю не отображены.

Номер Аргументы Результат
3 Длительность 0–100 0: yield при 0, ограниченный сон при >0 в IPC-режиме
6 send-cap, buffer, 64 0 либо ошибка
7 receive-cap, buffer, ожидание 0–100 64 либо ошибка; при 0 без сообщения — EMPTY
8 reply-ticket, buffer, 64 0 либо ошибка
9 grant-cap, PID получателя, права Новый локальный дескриптор получателя либо ошибка
10 Собственный дескриптор Освободить, результат 0
11 Право REVOKE своей точки Отозвать выданные права, результат 0
12 Право CLOSE своей точки Закрыть IPC-сторону, результат 0

Именованные результаты определены в ipc_abi.gsl: BAD_HANDLE, DENIED, FULL, EMPTY, TIMEOUT, PEER_CLOSED, REVOKED, STALE, BAD_MESSAGE, LIMIT, DUPLICATE. Их значения — u64-представления −16…−26; неверный указатель сохраняет прежний EFAULT=−1. Завершение контракта с ошибкой доставляется конвертом с flags=2 и значением причины. Прямой тайм-аут пустого receive возвращает TIMEOUT как результат syscall.

Диагностика и очистка

В защищённом состоянии хранятся счётчики и кольцо из шестнадцати событий: тик, инициатор, операция, результат, ID и объект. Полезное значение сообщения в журнал не копируется. Старые записи перезаписываются; это диагностическое кольцо, не долговечный журнал. ipc-report.json показывает ошибки по именам. Пользовательского API чтения глобального журнала пока нет.

Размещение внутри 4096 байт состояния: процессы с байта 256, списки страниц с 1024, заголовок IPC с 1536, две точки с 1664, восемь прав с 1792, четыре запроса с 2112, два ожидания с 2560, кольцо с 2688. Счётчики кольца — 3712/3720. Эти структуры не требуют динамических страниц под каждый обмен.

После обеих программ подтверждены пустые очереди, отсутствие активных прав, tickets и ожиданий, освобождение 20 страниц процессов и исходное состояние PMM. Истечение срока отзывает право ответа, но не откатывает уже выполненные действия службы. Повторное применение ID после полного завершения допустимо; гарантии «ровно один бизнес-эффект» эта версия не предоставляет.

Проверки

Прошли 43 автоматических теста: 26 компилятора и 17 инфраструктуры ядра. Машинный код GSL выполнил 500 обменов с проверкой каждого состояния: вместимость и резерв ответов, FIFO, подтверждённый отправитель, одноразовые ответы, неверные аргументы, ослабление прав, отзыв, старые дескрипторы, истечение, исчезновение получателя и вывод слота из использования на максимальном поколении. Отказы не меняют полномочия и очереди; ограниченные счётчики и журнал фиксируют причину. Сохранены 2000 операций PMM и 500 наборов round-robin.

Прошли 29 сценариев QEMU: обычные загрузки с 64/128 МиБ, полное исчерпание/восстановление PMM с 64/128 МиБ, семь отдельных IPC-вариантов, одиннадцать прежних пользовательских проверок и семь аварий ядра.

IPC-вариант Запросов / ответов Что проверено
exchange, обычная сборка 2 / 1 Ответ, затем уведомление о завершении службы
full 2 / 2 FIFO, дубликат ID, отказ третьей заявке; 10 idle-тиков
timeout 1 / 0 Завершение по сроку, старый ticket; 8 idle-тиков
rights 3 / 3 Явный grant в обратную сторону, ослабление, отзыв
peer-exit 0 / 0 Получатель завершился до отправки
peer-fault 2 / 1 Fault службы, клиент получает PEER_CLOSED и завершает работу
revoke 1 / 0 Отзыв во время ожидания, отказ позднему ответу
receive-timeout 0 / 0 Оба ждут пустую очередь; два тайм-аута и 4 idle-тика

ipc_check.py независимо проверяет снимок IPC, итоговые счётчики, очистку прав/запросов, кольцо и кадр idle. process_check.py сохраняет полную проверку разных CR3, всех частных таблиц, RX/NX, supervisor-only ядра, кода и начальных данных с разрешёнными изменениями, кадров CPL3 и очистки. Намеренно испорченные снимки отклоняются. Сохранены CR0.WP, EFER.NXE, блокировка FP/SIMD, TSS/IST и обход всех guard pages.

В обычной сборке: SYSTEM CALLS: 25, CONTAINED FAULTS: 0, IPC REQUESTS: 2, IPC REPLIES: 1. Одно закрытие контракта по завершению службы — ожидаемый результат, отражённый в ipc-report.json. Прежняя намеренная ошибка приложения теперь доступна отдельным --user-fault kernel-read.

При 128 МиБ PMM содержит 19717 страниц, при 64 МиБ — 3333; после проверки одна прежняя контрольная страница занята. EFI — 111104 байта, загруженный образ — 905216, диск — 17825792. Числа меняются при росте исходников и другой прошивке.

Развитие GSL

0.0.12 добавляет типизированные скалярные constant NAME: u64 = literal;. Константы не присваиваются и не затеняются. Введены явные повторяемые --prelude PATH для совместной компиляции ABI и реализации; ошибка отображается на исходный файл и строку. Скрытых импортов нет. --opt-size включает Oz для малых пользовательских программ, сохраняя запрет red zone и FP/SIMD. Проверены типы, дубликаты, границы и сохранение выходного файла при ошибке.

Это ещё не полноценная модульная система и не статическая проверка прав типами GSL. Права и сроки проверяет ядро; представление дескриптора в языке пока u64.

Повторение

python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Отдельный вариант:

python outputs/guseva-kernel/build.py --ipc-case timeout
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-ipc-timeout

Низкоуровневые проверки этапа 4:

python outputs/guseva-kernel/build.py --user-fault kernel-read
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-user-kernel-read

Доказательства: build/ipc-report.json, process-state.bin, process-idle-context.bin, process-report.json, снимки таблиц/страниц и boot-report.json. Сводка — STAGE5_VALIDATION.json, журналы тестов — validation-stage5. Папки build в старых отчётах относились к соответствующей версии; предыдущие архивы сохранены.

Границы

Один CPU, два статических процесса с одним потоком и по одной точке приёма. Нет общей памяти, динамических endpoint/spawn, службы имён, автоматического переподключения и перезапуска, приоритетов IPC, долговечного журнала или общего ресурсного менеджера. Дескрипторы действуют внутри этого запуска пары; восстановление связи после создания новой службы потребует отдельного протокола поколений.

Предполагается доставка тиков и корректность ядра; это проверка фиксированных сценариев, а не доказательство безопасности всех программ. После самопроверки CPU останавливается. Следующий этап создаст основу supervisor и служб поверх работающего IPC.

Этап 4 Пользовательские процессы и системные вызовы

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Завершён 3 ноября 2026 года для QEMU q35/TCG, одного x86-64 CPU и 64/128 МиБ RAM. GSL 0.0.11. Реализована ограниченная платформа двух целочисленных процессов с собственными CR3. Следующий этап — IPC и права на обращения; он пока не начинался.

Что теперь работает

Две программы на GSL запускаются в CPL3. У каждой собственные таблицы страниц, физические страницы кода, данных и стека. Они используют одинаковые виртуальные адреса и разные физические страницы. Код доступен пользователю как RX, данные и стек — RW/NX. Младшие 4 ГиБ с ядром остаются supervisor-only во всех адресных пространствах. Переключение процесса меняет CR3 и TSS.RSP0.

Область процесса Виртуальный адрес Размер
Код RX 0x800000000 4 КиБ
Данные RW/NX 0x800001000 4 КиБ
Стек RW/NX 0x800004000–0x800008000 16 КиБ

Остальные страницы пользовательского окна не отображены, в том числе границы стека. Для входов в ядро выделены отдельные статические стеки по 16 КиБ с двумя guard pages. Общее число guard pages стеков ядра выросло до 24; отсутствующие страницы пользовательского окна проверяются отдельно.

PIT/PIC вытесняет пользовательский код. Возврат в пользовательский режим идёт через проверенный кадр IRETQ. Неподходящие RIP/RSP завершают процесс до возврата; CS/SS установлены явно, IOPL/NT/VM/AC/TF не наследуются, IF включён. Поэтому повреждённый пользовательский стек не превращается в исключение ядра на IRETQ.

Пока поддерживается только целочисленный код. CR0.TS/MP блокируют FP/SIMD, OSXSAVE выключен. Попытка SSE-инструкции проверена отдельно и завершается #NM только у нарушившего процесса. Сохранение FP/SIMD-состояния между процессами ещё не реализовано.

Собственный формат программы GUP1

app_build.py компилирует apps/demo.gsl через GSL/Clang, линкует freestanding-программу, извлекает код и создаёт два пакета .gup с разными начальными данными. В гостевой системе нет Python, C-runtime или Windows-загрузчика: ядро читает GUP1 на GSL. PE-файл user.exe служит только промежуточным результатом на машине разработки и не запускается на хосте.

Заголовок GUP1 — восемь little-endian u64: magic GSLAPP01, версия 1, размер заголовка 64, размер кода, смещение входа, размер начальных данных, общий размер, флаги 0. Затем идут код и начальные данные. Код — 1–4096 байт с выравниванием размера на 8, данные — до 4096 байт с тем же выравниванием, вход должен попадать в код. Максимальный пакет — 8256 байт. Неподдержанные версии, флаги и противоречивые размеры отклоняются до выделения страниц.

На процесс выдаётся десять физических страниц: четыре таблицы, код, данные и четыре страницы стека. Список принадлежности хранится в защищённой записи процесса. При частичном отказе выделения список откатывается. После завершения этой демонстрационной пары контроллер освобождает оба списка; проверяется возврат всех 20 страниц и исходное состояние PMM. Это отложенная очистка после возврата в контроллер, не общий механизм немедленного удаления произвольного процесса.

Пакеты пока встроены в образ ядра и проверяются по этому доверенному диапазону. Чтения программ с диска, модулей, динамической линковки, подписей и обновлений формата ещё нет.

GSL 0.0.11

Добавлен контекст user;:

action user_main {
    user;
    output unit;
    invoke identity: u64 = system_call(2, 0, 0, 0);
    invoke exited: u64 = system_call(4, 0, 0, 0);
    produce done;
}

Компиляция требует --allow-user и явной цели x86-64. Привилегированные эффекты ядра, stop и прямые вызовы между user/machine-контекстами запрещены. Доступны ограниченные чтение/запись, чистые вычисления, явный system_call и вызов пользовательского кода по адресу. При числовом нарушении границ чтения/записи пользовательский helper вызывает UD2, а не портовый вывод и CLI/HLT. Возвращаться из входной функции вместо exit пока не следует: начальный пользовательский стек не содержит обычного вызывающего приложения.

Ограничения компилятора не заменяют аппаратную изоляцию: специально подготовленные двоичные пробы с HLT, INT, SSE, нулевым доступом и испорченным RSP проходят тот же загрузчик и проверяют аппаратные и возвратные границы.

Минимальный ABI вызовов

Вход — INT 0x80, единственный пользовательский interrupt gate с DPL3. Номер в RAX, аргументы в RCX/RDX/R8, результат в RAX. Значения записей ядра и физические адреса в качестве пользовательских указателей не принимаются. RFLAGS очищается по описанной политике; интерфейс пока внутренний и изменяемый.

Номер Операция Результат
1 Вывод буфера своей страницы данных, до 128 байт Число байт
2 Идентификатор текущего процесса 1 или 2
3 Уступить CPU 0
4 Завершиться с указанным кодом Процесс больше не запускается
5 Тики пользовательского проверочного запуска Текущий счётчик

Ошибки представлены u64: UINT64_MAX — EFAULT, UINT64_MAX−1 — неизвестный вызов, UINT64_MAX−2 — слишком большой буфер. Сейчас copy допускает только собственную страницу данных, не стек и не код. Проверяются начало, конец, переполнение и длина до чтения. Нулевая длина допустима при адресе внутри страницы или точно на её конце. Вывод выполняется через физическую supervisor-копию этой страницы.

Это не постоянные часы системы: счётчик запуска процессов начинается отдельно после самопроверки потоков ядра. Общий интерфейс времени будет развиваться. Пользовательский запуск ограничен 1000 принятыми тиками, чтобы проверочная программа не удерживала демонстрацию бесконечно; это не готовая система квот.

Проверка отказов

В обычной сборке процесс 1 намеренно читает страницу ядра. Получается user page fault 14 с кодом 5. Ядро помечает только этот процесс завершённым по ошибке и запускает оставшийся. Процесс 2 достигает 10 000 000 шагов в своей странице данных, проходит проверки syscall и завершается с кодом 0. При записи fault его прогресс ещё меньше конечного; независимая проверка подтверждает продолжение после отказа первого процесса.

Проба процесса 1 Ожидаемый результат
Чтение ядра #PF 14, error 5
Чтение физической страницы другого процесса через низкий адрес #PF 14, error 5
Запись в ядро #PF 14, error 7
Запись в собственный RX-код #PF 14, error 7
Исполнение собственной NX-страницы данных #PF 14, error 21
HLT #GP 13, error 0
Чтение нулевого адреса #PF 14, error 4
INT 0x30 в закрытый gate ядра #GP 13, error 386
SSE-инструкция #NM 7, error 0
Неканонический RSP перед syscall Отказ проверки возврата, причина 256

256 — внутреннее обозначение недопустимого кадра, не номер аппаратного исключения. Во всех пробах вторая программа завершилась с корректными данными, CR3 контроллера восстановлен, выданные страницы освобождены. Отдельный вариант none подтвердил нормальное завершение обеих программ.

Обычный экран показывает USER PROCESSES: 2, SYSTEM CALLS: 14, CONTAINED FAULTS: 1. Последняя строка означает успешно обработанную намеренную проверку. В варианте без нарушения — 16 вызовов и 0 faults. Счётчик аппаратных пользовательских IRQ зависит от времени исполнения и нагрузки хоста; во всех проверках IRQ были, каждому соответствует EOI.

Независимые доказательства

Прошли 36 автоматических тестов: 22 компилятора и 14 инфраструктуры ядра. Добавлены негативные проверки user-контекста и вызовов; нативное исполнение GSL-проверок диапазона и формата, частичного отказа выделения, построения и очистки процесса. Сохранены 2000 операций PMM и 500 состояний round-robin. Привилегированные и пользовательские INT-пути не исполняются на хосте.

Прошёл 21 сценарий QEMU: обычные загрузки 64/128 МиБ, полное исчерпание и восстановление PMM с 64/128 МиБ, семь прежних аварий ядра и десять отдельных пользовательских вариантов — девять дополнительных отказов и нормальное завершение пары. В обычных и стрессовых загрузках также проходит самопроверка пяти потоков этапа 3.

process_check.py независимо сверяет снимок защищённых записей, все 20 выданных страниц, четыре уровня частных таблиц, отсутствующие отображения, RX/NX и supervisor-only границы. Проверяются целостность кода, все начальные данные с разрешёнными изменениями, результаты вызовов, реальные кадры CPL3, fault RIP/CR2/error, завершение второго процесса и очистка. Эталонные пакеты сравниваются с фактически встроенными в память QEMU. Проверки намеренно повреждённых снимков отклоняют алиасы, пользовательский доступ к ядру, writable-код, утечки страниц и неверные кадры.

PMM отдельно сверяется с захваченной картой UEFI и полной битовой картой после очистки. Сохранены RX/NX ядра, CR0.WP, EFER.NXE, TSS/IST, отсутствие RWX/алиасов и все 24 guard pages. После завершения подтверждены исходный CR3, IF=0 и замаскированный PIC.

При 128 МиБ PMM содержит 19731 страницу, при 64 МиБ — 3347; в конце одна прежняя контрольная страница занята, остальные свободны. Рост статических стеков, кода и встроенных пакетов объясняет уменьшение пула. В обычной сборке EFI занимает 78336 байт, загруженный образ — 847872, образ диска — 17825792.

Основные файлы: process-report.json, process-state.bin, process-bridge.bin, process-context-0/1.bin, process-0/1-page-0…9.bin, embedded-app-0/1.gup, user-segments.bin, pmm-report.json, boot-report.json и screen.png внутри нужной папки build. Сводка всех сценариев — STAGE4_VALIDATION.json.

Повторение

python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Для отдельного отказа, например NX:

python outputs/guseva-kernel/build.py --user-fault nx
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-user-nx

Доступны kernel-read (обычная сборка), foreign-read, kernel-write, code-write, nx, privileged, null, interrupt, simd, stack, none. Варианты создаются отдельно и не заменяют обычную сборку. После пересборки окно просмотра нужно закрыть и открыть заново.

Границы этапа

Два статических процесса по одному целочисленному потоку, фиксированный виртуальный layout и встроенные пакеты; общего spawn/exec, heap, динамических библиотек, IPC, прав на службы и пользовательского ввода нет. Самопроверка потоков ядра и запуск процессов — последовательные фазы; это ещё не единый планировщик приложений и служб. Учёт списков страниц не заменяет будущие квоты и capability-модель.

Исключения CPL3 изолируются в проверенных сценариях; ошибка самого ядра остаётся фатальной. Это не утверждение безопасности для произвольного оборудования или всех возможных программ. После самопроверки CPU намеренно останавливается. Оконной оболочки ещё нет.

Аппаратные границы сверены с Intel SDM. Loader, выбор процесса, syscall и очистка написаны в GSL; Assembly выполняет только переходы привилегий, работу с регистрами и передачу управления.

Этап 3 Время, прерывания и потоки ядра

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Завершён 3 ноября 2026 года для фиксированной конфигурации QEMU q35/TCG, одного x86-64 CPU и 64/128 МиБ RAM. GSL 0.0.10. Следующий этап — пользовательские процессы и системные вызовы; он пока не начинался.

Работающий результат

Подключены PIT channel 0 и PIC. Таймер настроен в mode 2 с делителем 11932, номинально около 100 Гц. PIC переназначен на векторы 32–47; разрешён только IRQ0. Каждое принятое прерывание получает EOI. После проверки контроллер маскируется, IF выключен. Другие устройства и APIC пока не подключены.

Планировщик GSL ведёт пять записей потоков: idle, вычисляющий поток, ожидающий поток, отправитель событий и контроллер загрузки. Состояния — готов, ожидает, завершён. Политика round-robin среди готовых рабочих потоков, квант — один принятый тик таймера. Ожидающие и завершённые потоки пропускаются. Idle выбирается, когда рабочих готовых потоков нет, и выполняет STI; HLT вместо активного ожидания.

Все потоки работают в режиме ядра и общем адресном пространстве. Четыре дополнительных стека по 16 КиБ имеют нижние и верхние guard pages. Контроллер использует исходный стек ядра. Всего стало 20 guard pages. Стеки заранее зарезервированы в образе и не освобождаются при завершении демонстрационного потока.

Доступны относительный сон, ожидание одного из восьми событий с тайм-аутом, отправка события, завершение, уступка CPU и необязательный срок отмены потока. Результат ожидания: 0 — событие, 1 — тайм-аут, 2 — неверный номер события. Сроки насыщаются на максимальном u64 вместо переполнения. Нулевая длительность сна уступает CPU; нулевой тайм-аут проверяет уже сохранённое событие и сразу возвращает результат.

Событие будит одного ожидающего. Если ожидающего нет, событие сохраняется в битовой маске до последующего ожидания. Повторные отправки одного события объединяются: это сигнал, не очередь сообщений. Обработка запроса и изменение состояния выполняются с выключенными прерываниями через interrupt gate. Поэтому между проверкой события и переходом в ожидание нет промежутка с разрешённым IRQ. Системного IPC эта модель не заменяет.

GSL и машинный модуль

Очередность, статусы, сроки, события, выбор следующего потока и программа проверки написаны в kernel.gsl. Новые привилегированные эффекты:

  • thread_request(command, value, timeout) — software interrupt 0x30, параметры u64 в RCX/RDX/R8;
  • cpu_idle() — STI; HLT;
  • enter_threads(entry, state) — вызов доверенного стартового модуля по переданному адресу.

Эти эффекты разрешены только в machine-действиях и требуют разрешения компиляции машинного кода. Это внутренний интерфейс доверенного ядра, не пользовательский syscall ABI.

boot/thread_codegen.py создаёт начальные кадры, сохраняет 15 целочисленных регистров, передаёт управление GSL-планировщику и восстанавливает выбранный контекст через IRETQ. Кадр содержит также RIP, CS, RFLAGS, RSP и SS. Начальный RSP учитывает 32 байта shadow space ABI Windows x64. IRQ0 и software interrupt используют текущий стек потока, IST=0; аварийные исключения сохраняют отдельные IST. GSL компилируется с запретом red zone и SIMD-регистров.

FP/SIMD-контекст пока не сохраняется: текущие потоки должны быть целочисленными и компилироваться с -mgeneral-regs-only. Прерывания выключены на время планировщика. PMM не стал реентерабельным: обращения к нему требуют исключения IRQ; демонстрационные потоки его не вызывают. Подготовка памяти выполняется до включения таймера.

Проверка поведения

Вычисляющий поток бесконечно увеличивает счётчик, без добровольного yield. Другой поток ждёт событие, затем заранее отправленный сигнал и затем тайм-аут 7 тиков. Отправитель спит 5 тиков, отправляет сигналы и завершается. Контроллер задаёт вычисляющему потоку срок отмены 40 тиков и спит до тика 80. После завершения рабочих потоков запускается idle. На тике 80 контроллер возвращается, отключает IRQ и сохраняет результат.

В обычных загрузках с 64 и 128 МиБ получены одинаковые результаты:

Показатель Результат
Принято IRQ0 / отправлено EOI 80 / 80
Смен текущего потока 17
Software requests 9
Тиков вычисляющего потока / idle 40 / 40
Пробуждений по ожидаемому событию / тайм-ауту 1 / 1
Измеренная длительность ожидаемого тайм-аута 7 тиков
Guard pages / записываемых исполняемых страниц 20 / 0

Ожидающий поток завершает проверку до отмены вычисляющего потока: это проверяет вытеснение, а не работу задач только после его остановки. Заранее отправленное событие потребляется без ожидания. Снимок PIC показывает все линии замаскированными и отсутствие IRQ в обслуживании после завершения.

От начала до конца теста наблюдалось около 0,8 секунды времени хоста. Измерение сделано по появлению строк журнала с опросом раз в 0,1 секунды; оно не является точной калибровкой часов. Тики считают принятые IRQ, а не гарантированное физическое время при задержанных прерываниях. Гарантий реального времени нет.

Прошли 29 автоматических тестов: 18 компилятора и 11 инфраструктуры ядра. Машинный код GSL проверен нативно: сон, события, сохранённый сигнал, граница тайм-аута, неверный номер, нулевое ожидание, завершение, отмена, насыщение срока и 500 наборов состояний round-robin. Нативный тест вызывает только software-request ветвь планировщика с подготовленным кадром; аппаратный IRQ проверяется в QEMU. Сохранён тест менеджера памяти с 2000 операциями.

Прошли 11 сценариев QEMU: 64/128 МиБ обычные, 64/128 МиБ с полным исчерпанием и восстановлением PMM, семь аварийных UD2/null/stack/code/NX/guard/overflow. В четырёх успешных обычных/стрессовых загрузках также проходит тест потоков. Аварийные образы останавливаются в ожидаемом обработчике до запуска потоков.

test_boot.py захватывает состояние планировщика, таблицу стеков и четыре сохранённых контекста. scheduler_check.py независимо сверяет счётчики, состояния, прогресс, результат ожидания, кадры IRETQ, попадание RIP в исполняемые секции и границы защищённых стеков. Тесты намеренно повреждают снимки, чтобы проверить отказ проверяющего модуля. Сохранены полный обход таблиц страниц, RX/NX, CR0.WP, EFER.NXE, TSS/IST и отсутствие алиасов.

Файлы доказательств: build/scheduler-report.json, scheduler-state.bin, thread-layout.bin, thread-context-0.bin…thread-context-3.bin, pic.log, boot-report.json и screen.png. Состояние занимает 4096 байт; пять записей по 64 байта начинаются с байта 128. Заголовок и рабочие метки теста находятся в первых 128 байтах.

В текущем образе ядра 765952 байта, EFI-файл 49152 байта, образ диска 17825792 байта. При 128 МиБ PMM управляет 19751 страницей, при 64 МиБ — 3367; после проверки одна страница остаётся занятой. Уменьшение пула относительно этапа 2 связано с ростом образа и новыми зарезервированными стеками.

Повторение

python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Окно нужно закрыть и открыть заново после сборки. Экран показывает STAGE 3, TIMER TICKS: 80 и THREADS TESTED: 5. После проверки CPU намеренно останавливается: это текущий загрузочный тест, ещё не интерактивная ОС.

Границы

Пять статических потоков, один CPU, общий CR3, доверенный целочисленный код ядра. Нет пользовательской изоляции, динамического создания потоков и очистки их ресурсов, FP/SIMD, heap, системных вызовов и IPC. Исключение рабочего потока пока останавливает всё ядро. Для пользовательских приложений эти ограничения должны устраняться на следующих этапах.

Аппаратные соглашения сверены с Intel SDM Volume 3A, реализацией PIT QEMU, его частотой и PIC QEMU. Планировщик и исходники языка реализованы в этом проекте.

Этап 2 Менеджер физических страниц

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Завершён 3 ноября 2026 года для x86-64, UEFI, QEMU q35/TCG, одного CPU. Компилятор GSL 0.0.9. Политика выделения и освобождения написана в kernel.gsl; Assembly передаёт адрес статического хранилища. Этап 3 пока не начинался.

Что работает

Менеджер принимает несколько непересекающихся областей EfiConventionalMemory из уже проверенной карты. Сохраняет список областей, подсказки для следующего поиска, битовую карту занятых страниц и счётчики. Выделение выдаёт страницу 4096 байт, полностью очищенную перед возвратом. Исчерпание возвращает адрес 0. Освобождение возвращает 0 при успехе, 1 для невыровненного или не принадлежащего пулу адреса, 2 для уже свободной страницы. Отклонённое освобождение не изменяет состояние.

Поиск идёт по областям в порядке карты, внутри области — от сохранённой подсказки. Освобождение опускает подсказку при необходимости, поэтому страницы используются повторно. Пересекающиеся, пустые, невыровненные и недопустимые области не добавляются. Размер записи области — 24 байта: начало, конец, подсказка. Максимум 3276 записей соответствует вместимости буфера карты UEFI с минимальным шагом 40 байт.

Метаданные занимают фиксированные 256 КиБ внутри исключённого из пула образа ядра: заголовок 64 байта, список областей, резерв выравнивания, битовая карта 128 КиБ с байта 131072. Один бит соответствует физической странице ниже 4 ГиБ. Фиксированная ёмкость позволяет запустить менеджер без предварительного динамического выделения памяти. Это рабочее решение раннего ядра.

Две стартовые проверочные страницы и страницы активных таблиц закреплены до создания менеджера: их диапазон исключается из соответствующей области. В текущих загрузках закреплено 11 страниц: 2 проверочные и 9 таблиц. Образ ядра, метаданные, framebuffer, стеки и guard pages не выдаются. Loader/BootServices/Runtime/ACPI/MMIO пока не возвращаются в пул. Адреса от 4 ГиБ отложены: текущие таблицы отображают только младшие 4 ГиБ.

Аварийная диагностика использует заранее размещённые panic/IST-стеки и вывод через порт, без обращения к распределителю. Эти стеки остаются зарезервированными внутри образа. Отдельного динамического аварийного пула пока нет.

Расширение GSL

Явное выражение последовательности invoke page: u64 = pmm_allocate(state); вызывает пользовательское machine-действие и создаёт неизменяемое локальное значение. perform pmm_reset(state); вызывает machine-действие с результатом unit. Обычные выражения по-прежнему не вызывают machine-действия. Проверяются тип результата, входы, привилегированный контекст и отсутствие рекурсии. Форма синтаксиса остаётся экспериментальной.

Алгоритм менеджера не спрятан в генераторе C. Компилятор обеспечивает обычный вызов действия и прежние примитивы чтения/записи.

Проверки

Прошли 25 автоматических тестов: 17 компилятора и 8 инфраструктуры ядра. Среди них — исполнение машинного кода менеджера в отдельном процессе Windows на выделенном низком диапазоне памяти: 2000 операций с фиксированным seed, несколько областей с промежутком, переход через границу слова битовой карты, исчерпание, повторная выдача с очисткой, неверные и двойные освобождения. После операций проверяются счётчики, подсказки и каждый бит. Отклонённые операции сравниваются с полным предыдущим состоянием.

Прошли 11 сценариев QEMU: обычные загрузки с 64/128 МиБ, полное исчерпание и восстановление пула с 64/128 МиБ, семь прежних аварийных сценариев UD2/null/stack/code/NX/guard/overflow. Проверки RX/NX, CR0.WP, EFER.NXE, TSS/IST, 12 guard pages и отсутствия RWX/алиасов сохранены.

В каждой загрузке небольшой двухобластный пул проверяет отказ при исчерпании, повторную выдачу, очистку, неверное и двойное освобождение. Отдельные стрессовые образы выдают все страницы реального пула, проверяют отказ следующего выделения и освобождают каждую страницу. После этого остаётся одна контрольная занятая страница для независимой проверки постоянного состояния.

RAM Областей менеджера Страниц пула Свободно после проверки Занято Полный цикл
128 МиБ 10 19780 19779 1 19780 страниц
64 МиБ 9 3396 3395 1 3396 страниц

В обычной загрузке 128 МиБ карта содержит 19791 страницу-кандидат: 11 закреплённых + 19780 страниц менеджера. Внутри менеджера 19779 свободных + 1 занятая = 19780. Это не вся физическая память: прочие типы UEFI и образ ядра консервативно исключены. Числа могут изменяться при росте образа или изменении прошивки.

test_boot.py независимо захватывает через QMP карту UEFI, 256 КиБ состояния и содержимое занятой страницы. pmm_check.py сверяет точный список областей с картой, исключение закреплённого диапазона, подсказки, счётчики, каждый бит и очистку страницы. Тесты намеренно портят снимки, чтобы проверить отказ проверяющего модуля. Доказательства лежат в build/pmm-state.bin, pmm-report.json, pmm-live-page.bin и boot-report.json; полные циклы — в build-memory-test и build-memory-test-64.

Повторение

Из корня проекта:

python outputs/guseva-kernel/build.py
python -m unittest discover -s outputs/gsl-compiler -v
python -m unittest discover -s outputs/guseva-kernel -v
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/build.py --memory-test
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-memory-test --timeout 60
python outputs/guseva-kernel/run.py

Для отдельной проверки 64 МиБ собрать с --memory-test --out outputs/guseva-kernel/build-memory-test-64, затем передать тесту --build outputs/guseva-kernel/build-memory-test-64 --ram 64 --timeout 60. Стрессовые и аварийные сборки не заменяют обычную.

Границы этапа

Владелец всех выдаваемых страниц сейчас — ядро. Отказ для чужого адреса означает адрес вне разрешённых областей менеджера; идентификаторов процессов и прав владельцев ещё нет. Интерфейс с физическими адресами предназначен только доверенному коду ядра. Состояние также доверенное и не передаётся приложению. Очистка выполняется при каждой выдаче, в том числе повторной.

Работа последовательная, прерывания выключены; синхронизация для потоков и нескольких CPU ещё не реализована. Нет heap, пользовательских адресных пространств и автоматической очистки ресурсов процесса. Исключения пока завершают ядро. Следующий этап плана — время, прерывания и потоки.

Этап 1 Защита памяти ядра

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Статус: завершён для фиксированной конфигурации QEMU q35/TCG, один x86-64 CPU. Компилятор GSL 0.0.8, проверка 3 ноября 2026 года. Этап 2 — выделение и освобождение памяти — в этом шаге не начинался.

Изменения

kernel.gsl читает собственные заголовки PE и определяет права по секциям. Код .text отображается RX, константы и заголовки — R/NX, данные и стеки — RW/NX. Одновременно записываемые и исполняемые секции отклоняются. Остальной стартовый диапазон ниже 4 ГиБ остаётся RW/NX. Пользовательский доступ не разрешён.

Крупные страницы вокруг образа ядра заменены страницами 4 КиБ. У остальных областей сохранены крупные страницы, с запретом исполнения. CR0.WP включён для запрета записи в RO-страницы даже из режима ядра; EFER.NXE включён для аппаратного запрета исполнения. Начальный примитив проверяет поддержку NX. Глобальные старые трансляции очищаются при переключении CR3.

У шести стеков — основного, panic и четырёх IST — добавлены нижняя и верхняя страницы без отображения. Всего двенадцать guard pages. Стековые вершины находятся у границы верхней guard page, а записи стека направлены в доступную область ниже неё. Буферы, таблицы, guard pages и сами стеки остаются зарезервированы внутри PE-образа.

Правила и создание таблиц реализованы на GSL. Машинные примитивы выполняют только необходимые процессорные операции. Для чтения заголовков добавлены fetch u8/u16, явное widen_u64 и логическое shr_u64. Сдвиг на 64 и более определён как ноль, без неопределённого поведения промежуточного C. Неявные преобразования типов не вводились.

Независимая проверка

protection_check.py обходит захваченное из QEMU дерево таблиц целиком. Он сравнивает права с секциями исходного EFI-файла, проверяет соответствие виртуальных и физических адресов, отсутствие повторного использования таблиц, отсутствие высоких алиасов и точное расположение всех отсутствующих страниц: нулевой и двенадцати guard pages. Автоматически установленные процессором Accessed/Dirty учитываются отдельно.

В текущей сборке найдено 6 исполняемых страниц 4 КиБ и 0 одновременно записываемых исполняемых страниц. Код не имеет альтернативного записываемого отображения в активном адресном пространстве. Подтверждены CR0.WP и EFER.NXE, размеры и размещение TSS/IST, а также работоспособность panic после включения защиты.

Тесты проверяющего модуля намеренно портят модель таблиц: открывают запись в код и константы, исполнение данных, доступ к guard и нулю, добавляют высокий алиас и крупную страницу, обходящую права. Все такие варианты отклоняются.

Аппаратные аварийные проверки

Вид Операция Результат
ud UD2 Вектор 6, код 0, IST4
null Чтение адреса 0 Page fault 14, код 0, CR2=0
stack RSP=0, затем UD2 Вектор 6; аппаратный вход на IST4, прежний RSP=0
code Запись в первую страницу .text Page fault 14, код 3, CR2 указывает на код
nx Попытка исполнить выделенную страницу данных Page fault 14, код 17, RIP/CR2 указывают на данные
guard Чтение нижней guard page основного стека Page fault 14, код 0, CR2 указывает на guard
overflow Push пересекает нижнюю границу основного стека Page fault 14, код 2, вход на IST3

Все семь сценариев прошли: обработчик на GSL вывел диагностику и остановил CPU, процесс QEMU остался работающим. Проверяются точный код ошибки, адрес и диапазон аппаратного IST-кадра. Обычный и аварийные образы имеют разные папки и хеши.

Прошли 15 тестов компилятора и 5 тестов инфраструктуры ядра. Обычная загрузка с полной проверкой прав прошла с 64 и 128 МиБ RAM. Итого — 20 unit/integration-проверок плюс 9 сценариев загрузки QEMU (2 обычных и 7 аварийных).

Размеры и учёт

В обоих обычных запусках выдано 11 страниц: две проверочные и девять под таблицы. Дополнительные таблицы нужны для двух блоков по 2 МиБ, пересекаемых текущим образом. Число таблиц вычисляется во время загрузки и может изменяться с размещением образа.

RAM Областей Исходных страниц-кандидатов Выдано
64 МиБ 98 3473 11
128 МиБ 100 19857 11

EFI-файл занимает 28672 байта, загруженный PE-образ — 376832 байта. Счётчик candidate pages показывает исходный запас до выделения страниц. Ни размер PE-образа, ни диапазон отображения 4 ГиБ не равны полному расходу RAM или размеру установленной базы ОС.

Как повторить

Обычная сборка, тест и просмотр:

python outputs/guseva-kernel/build.py
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Пример проверки запрета исполнения данных:

python outputs/guseva-kernel/build.py --fault-test --fault-kind nx
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-fault-nx --expect-exception 14

Для code, guard и overflow также ожидается вектор 14. Для ud и stack — 6. По умолчанию --fault-test означает ud и папку build-fault; остальные виды используют build-fault-ИМЯ.

Результаты находятся в boot-report.json и protection-report.json соответствующей папки. Первый содержит также фактический кадр исключения. Исходники и параметры сборки связываются хешами. Снимок обычного экрана содержит строку GSL KERNEL P0 - STAGE 1.

Границы результата

Проверена защита страниц в текущем адресном пространстве ядра. Всё ещё выполняется доверенный привилегированный код; защиты от намеренной перенастройки таблиц самим ядром и изоляции пользовательских процессов здесь нет. Исключения фатальные, восстановления задач нет. Кэширование MMIO, широкая поддержка аппаратуры, многопроцессорность и освобождение страниц остаются последующими задачами.

Следующий этап по плану — менеджер памяти с постоянным состоянием, несколькими областями, выделением и освобождением страниц и определённым поведением при исчерпании.

Справочники для форматов и аппаратных механизмов: PE/COFF Microsoft и Intel SDM.

Guseva OS Собственные таблицы памяти и стеки исключений

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Этап с компилятором GSL 0.0.7. Реализовано и проверено 3 ноября 2026 года в QEMU q35/TCG.

TSS и IST

В GDT добавлен 16-байтовый дескриптор 64-битной TSS, загруженный через LTR с селектором 0x18. TSS содержит RSP0 и четыре отдельных стека IST по 16 КиБ. I/O map offset равен 104, то есть лежит за лимитом TSS 103. Данные TSS, стеки и таблицы находятся внутри исключённого из распределения образа ядра.

Событие IST
Double fault, вектор 8 1
NMI, вектор 2 2
Page fault, вектор 14 3
Остальные входы, включая invalid opcode 4

Процессор переключает стек до записи кадра исключения. После этого вход на Assembly передаёт номер, код ошибки, RIP, CR2, адрес входного кадра и прежний RSP в kernel_panic на GSL. Диагностика выполняется на отдельном программном panic-стеке. Повторный вход при уже активной панике приводит к остановке.

Это фатальные обработчики, без возврата и восстановления приложений. Guard pages вокруг стеков и полноценная защита от всех повторных аппаратных ошибок ещё не реализованы. Реальные DF и NMI пока не вызывались в тестах; проверены их записи IDT и стеки TSS.

Таблицы страниц на GSL

Начальный распределитель выдаёт девять страниц: две для теста памяти и семь под таблицы — PML4, PDPT, четыре каталога и таблицу младших 2 МиБ. Все записи таблиц создаёт kernel.gsl через store_u64. Машинный примитив activate_paging переключает CR3 и сбрасывает в том числе прежние глобальные трансляции через PGE.

Начальный диапазон — адреса ниже 4 ГиБ с одинаковыми виртуальными и физическими адресами. Большая часть диапазона использует страницы по 2 МиБ; младшие 2 МиБ — по 4 КиБ. Запись для адресов 0…4095 отсутствует, поэтому чтение по нулевому указателю вызывает page fault. Диапазон отображения не означает наличие 4 ГиБ RAM: доступная физическая память по-прежнему определяется картой UEFI.

Все отображённые страницы пока имеют широкие права supervisor read/write/execute. Отдельных адресных пространств процессов, W^X, NX для данных и полной политики кэширования MMIO пока нет. Образ ядра и framebuffer должны целиком помещаться в начальном диапазоне; LA57 и PCID в начальном примитиве не поддерживаются. Это переход от таблиц прошивки к своим таблицам, не завершённая защита памяти.

В проверенной конфигурации корень находится по адресу 0x102000, таблицы занимают семь последовательных страниц, курсор распределителя — 0x109000. Исходный счётчик candidate pages включает запас до выдачи всех девяти страниц.

Проверки реального исполнения

Проверка независимо читает через QMP карту памяти, GDT, TSS, IDT и все семь таблиц страниц. Сверяет TR, CR3, busy-дескриптор TSS, I/O map offset, размеры и непересечение IST-стеков, все 256 шлюзов IDT и все записи таблиц страниц. Изменяемые процессором биты Accessed/Dirty учитываются отдельно. Первые две тестовые страницы остаются обнулёнными.

Три отдельные аварийные сборки прошли:

Сборка Проверенный результат
ud UD2 → вектор 6, вход через IST4
null Чтение адреса 0 → вектор 14, код 0, CR2=0, вход через IST3
stack RSP принудительно равен 0, затем UD2 → вектор 6 через IST4; кадр сохраняет прежний RSP=0

Во всех случаях обработчик вывел диагностику и остановил CPU без перезагрузки виртуальной машины. Тест stack подтверждает работоспособность конкретного входа при RSP=0, а не восстановление после произвольного повреждения памяти.

Прошли 14 тестов компилятора и 3 проверки состояния сборки. Обычная загрузка прошла с 64 и 128 МиБ RAM; три аварийных сценария — с 128 МиБ.

RAM Областей Исходных страниц-кандидатов Выдано
64 МиБ 98 3488 9
128 МиБ 100 19872 9

Размер EFI текущей сборки — 22016 байтов, загруженного PE-образа — 315392 байта. Это не полный объём потребляемой RAM и не размер установленной базы.

Команды

Обычный запуск:

python outputs/guseva-kernel/build.py
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Проверка нулевой страницы:

python outputs/guseva-kernel/build.py --fault-test --fault-kind null
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-fault-null --expect-exception 14

Проверка стека:

python outputs/guseva-kernel/build.py --fault-test --fault-kind stack
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-fault-stack --expect-exception 6

Обычный UD2 по-прежнему собирается с --fault-test без указания вида; результат находится в build-fault. Каждая папка содержит собственные образ, хеши и boot-report.json. Аварийные образы не заменяют обычную сборку.

Новые машинные эффекты GSL: activate_paging(root: u64), fault_null() и invalid_stack(). Все требуют machine; последние два предназначены для намеренных тестов в QEMU. В пользовательском процессе Windows они не исполняются. Начальная модель TSS и paging опирается на Intel SDM.

Следующий этап — права страниц для кода и данных и guard pages стеков, затем расширение распределителя и подготовка изоляции процессов. Рабочие примитивы этого этапа не утверждают окончательный синтаксис языка.

Guseva OS Исключения и первые физические страницы

Прямая ссылка на отчёт

Историческая запись: команды и пути сборки ниже показывают состояние на дату этапа. Для текущего размещения исходников, тестов и актуальных команд используйте PROJECT_STRUCTURE.md.

Этап с компилятором GSL 0.0.6. Реализовано и проверено 3 ноября 2026 года в QEMU q35/TCG, один CPU.

Исключения

После ExitBootServices стартовый модуль устанавливает собственную GDT с 64-битным сегментом кода и IDT на 256 записей. Генератор boot/exception_codegen.py создаёт минимальные машинные точки входа. Они нормализуют наличие кода ошибки, сохраняют номер вектора и RIP, считывают CR2 и вызывают kernel_panic на GSL на отдельном стеке 16 КиБ.

kernel_panic выводит значения в журнал и останавливает CPU. Возврат из исключения и восстановление процесса пока не предусмотрены. IRQ выключены; TSS/IST, независимые таблицы страниц и защита от повторного исключения в самом обработчике пока отсутствуют. Переключение на отдельный стек происходит программно после входа в обработчик, поэтому повреждение входного стека не считается решённой задачей. CR2 имеет диагностическое значение адреса именно для page fault; для других исключений он может содержать старое значение.

Тестовый образ выполняет UD2 только по специальному режиму запуска. Реальное исключение № 6 дошло до GSL, код ошибки был нулевым, RIP принадлежал образу ядра, CPU остановился без перезагрузки. Это проверка пути invalid opcode, не подтверждение корректности всех видов аппаратных исключений.

Первый распределитель

Политика и состояние распределения находятся в kernel.gsl. Из уже проверенной карты выбирается первая подходящая область EfiConventionalMemory с минимум двумя страницами и концом не выше 4 ГиБ. Сохраняются прежние исключения: низкая память, Runtime, образ со стеком и картой, framebuffer, другие типы UEFI.

page_after — чистое действие GSL, которое проверяет выравнивание, ненулевой курсор, границу области и переполнение. При успехе возвращает следующий курсор, при исчерпании или неверных параметрах — 0; исходный курсор меняет вызывающий код только после успешной проверки. Страница выдаётся по прежнему адресу курсора, размер — 4096 байтов.

В текущем сценарии выданы страницы 0x100000 и 0x101000, курсор продвинулся до 0x102000. Обе страницы обнулены, в начало первой и конец второй записаны разные контрольные значения, данные прочитаны и проверены, затем контрольные байты снова обнулены. Тест QEMU независимо прочитал 8192 байта и подтвердил нулевое содержимое, расположение в допустимой области и отсутствие пересечения с ядром и framebuffer.

Это начальный линейный распределитель одной области, а не общий сервис памяти. Освобождения, перехода между областями, многопоточности, динамической передачи состояния другим компонентам и изоляции процессов пока нет. Счётчик candidate pages показывает исходный запас до выдачи двух страниц, а не число оставшихся свободных страниц. Работа пока зависит от отображений памяти, подготовленных прошивкой и проверенных в QEMU.

Изменения GSL

perform store_u64(base, size, offset, value); разрешён только в machine-действии. Все четыре параметра — u64. Перед записью проверяются числовые границы области и переполнение, затем записываются восемь байтов little-endian. При неверном диапазоне — фатальная диагностика MEMORY: bounds failure. Проверка не доказывает наличие отображения памяти или право доступа; это доверенный низкоуровневой примитив.

perform invalid_opcode(); генерирует UD2 и служит только для проверки обработчика. Требует machine, аргументов нет.

Повторение проверок

Обычная сборка и запуск:

python outputs/guseva-kernel/build.py
python outputs/guseva-kernel/test_boot.py
python outputs/guseva-kernel/run.py

Отдельный намеренно аварийный образ, не заменяющий обычную сборку:

python outputs/guseva-kernel/build.py --fault-test
python outputs/guseva-kernel/test_boot.py --build outputs/guseva-kernel/build-fault --expect-exception 6

Для аварийного образа PASS означает, что ожидаемое исключение было корректно доставлено и зафиксировано. Обычный run.py отклоняет такой образ. Все новые артефакты проверки сохраняются внутри соответствующей папки build или build-fault.

Проверки дополнительно сохраняют idt.bin и allocated-pages.bin. По регистрам CPU подтверждены адреса GDT/IDT внутри образа, лимиты 23 и 4095. Все 256 шлюзов IDT указывают внутрь ядра, имеют selector 8, DPL 0, тип interrupt gate и IST 0.

Прошли 13 тестов компилятора и 3 проверки состояния сборки. В машинном коде Windows отдельно проверены границы store_u64 без исполнения привилегированных ветвей и page_after, включая исчерпание и неправильное выравнивание. Обычная загрузка с выделением страниц проверена с 64 и 128 МиБ RAM; UD2 — с 128 МиБ.

RAM Областей Исходных страниц-кандидатов Выдано
64 МиБ 98 3504 2
128 МиБ 100 19888 2

Числа относятся к текущему образу и прошивке. Размер EFI — 19456 байтов, размер загруженного PE-образа — 249856 байтов. Это не размер базовой установки и не полное потребление памяти ОС.

Форматы машинных таблиц и исключений основаны на Intel Software Developer Manuals. Следующий этап — TSS/IST и усиление аварийного пути, затем собственные таблицы страниц и расширение распределителя.

Окно просмотра

run.py теперь использует обычное окно Tk с кадрами, прочитанными из QEMU через QMP. Это реальный экран виртуальной машины с обновлением примерно два раза в секунду. Мышь и клавиатура в гостевую систему не передаются и не захватываются. Прямой ввод потребуется отдельно, когда в ядре появятся драйверы. Закрытие окна останавливает запущенный им процесс QEMU.

Этап HUP-02 — приёмка пакета в гостевой ОС

Прямая ссылка на отчёт

Дата: 9 ноября 2026 года
Результат: PASS в ограниченном QEMU-профиле.
Связанный этап: обновление компонентов без перезапуска.

Что проверялось

Проверить, что собранный пакет GUP1 можно передать в CPL3-компонент гостевой ОС по выделенному тестовому каналу COM1, вернуть отправленные байты и проверить внешний фрейм и структуру пакета. Полученные байты не исполняются.

Реализация

  • В src/kernel/core/platform_acceptance.gsl тестовый профиль выдаёт приёмнику только нужные полномочия COM1 и диагностического порта. Общие port/IRQ/MMIO leases этому компоненту не выдаются.
  • src/drivers/приёмник_пакета_uart.gsl ограниченно принимает один фрейм, проверяет заголовок, версию, длину, флаги и GUP1, а принятые данные возвращает отправителю.
  • tools/host/qemu_acceptance.py передаёт фрейм через локальный TCP-мост к COM1 QEMU и сверяет каждое возвращённое восьмибайтовое слово.
  • tools/host/platform_check.py проверяет независимые счётчики: у CPL3-компонента 13 выделенных и 13 освобождённых страниц (10 стартовых и 3 временных); агрегат физического возврата при p_reap равен 10. Также проверяются очистка компонентов, capabilities, IPC, device leases и ссылок.

Приёмка

Сборка:

python tools/host/build.py --platform-case приём-пакета --out work/hup-02-uart

QEMU:

python tools/host/qemu_acceptance.py --qemu <путь-к-qemu-system-x86_64.exe> --build work/hup-02-uart --timeout 45 --ram 128

Результат QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU:

  • result: PASS.
  • package_bytes: 7 328.
  • frame_bytes: 7 360; echoed_bytes: 7 360.
  • Гостевая проверка: заголовок GUP1 и FNV-1a-64.
  • В журнале гостя: UART:READY, UART:GUP1:PASS, затем штатный KERNEL: halt.
  • Один компонент; fault = 0; остаточные capabilities, IPC-запросы, device leases и object references = 0.
  • Страницы компонента выделено/освобождено = 13/13; агрегат p_reap = 10.
  • SHA-256 EFI: 0dc9816149fa2338719823bf2263857d76ad21e778dde0d63403748ee65b769b.
  • SHA-256 образа: aef6d731c7605961530f5a2503fa147e6e8b26697328b4956f41bc9de1ba71ed.

Машинные данные сохранены в work/hup-02-uart/: live-package-transfer.json, boot-report.json, platform-report.json, platform-state.bin и boot.log.

Границы результата

Это отдельная загрузка профиля для проверки гостевого приёмника. Тест не передаёт пакет в уже работающую интерактивную Dev Shell, не запускает полученные байты и не выполняет горячую замену компонента. FNV-1a-64 обнаруживает случайное повреждение, но не удостоверяет отправителя и не выдаёт право исполнения. Для живого обновления ещё требуются подключение Dev Shell, защищённый IPC-объект, проверка полномочий supervisor, запуск нового поколения, READY, смена маршрута и корректное завершение старого поколения.

Дополнительная приёмка GUP1 v3 — 10 ноября 2026 года

После исходной проверки v1 транспортный фрейм и гостевой буфер расширены для v2/v3. CPL3-приёмник резервирует 11 последовательных виртуальных страниц через syscall 48, получает их через syscall 35, после проверки освобождает через syscall 36 и снимает резерв syscall 49.

  • Свежая сборка: work/comp05-uart-v3b, профиль приём-пакета.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • GUP1 v3: 15 552 байта; кадр: 15 584 байта; возвращено без изменений 15 584 байта; UART:GUP1:PASS.
  • Счётчик CPL3-приёмника: выделено/освобождено 21/21 (10 стартовых и 11 буферных страниц); faults 0; остаточные IPC, capabilities, device leases и object references — 0.
  • SHA-256 образа: c78e0eb19049feadf8b92d37d70f0152206eec75ce51d9258bb32ae405194162.

Проверена одна конфигурация v3 размером 15 552 байта. Буферный предел — 41 024 байта; максимальный кадр — 41 056 байт. Полученный пакет только проверен и возвращён: исполнение, подключение к интерактивной Dev Shell и горячая замена не реализованы.

Дополнительная приёмка GUP1 v2 — 10 ноября 2026 года

  • Свежая сборка: work/comp05-uart-v2, профиль приём-пакета-v2.
  • QEMU 11.1.0, q35/TCG, 128 МиБ, 1 CPU — PASS.
  • GUP1 v2 размером 8 264 байта передан через COM1/TCP; кадр 8 296 байт полностью возвращён без изменений, гость выдал UART:GUP1:PASS.
  • Полученный пакет не запускался. SHA-256 образа: eb787be21434920b69e7fe4b710754d7ec020dd56fc3ba9ec9585ebe223dfeac.