Наблюдаем, как Windows XP разговаривает с железом: эмулятор x86 в одном HTML-файле

Ранее я уже рассказывал о своих проектах для изучения низкого уровня, выполненных в виде одного HTML-файла и работающих офлайн: дизассемблер (5 платформ), ассемблер с поддержкой HLA64 и эмулятор процессора с пошаговой отладкой.
Сегодня в копилку добавлен еще один проект: виртуальная машина, которая запускает настоящую Windows XP прямо в браузере. Как обычно, все в одном HTML-файле.

Но фишка не в этом. Эмуляторы Windows XP в браузере уже делали много раз, и никого этим не удивить. Здесь же мы сможем наблюдать, как Windows XP общается с железом: что передает железу и что железо отвечает операционной системе.
С чего все начиналось и при чем тут эффект Маккордак
На идею меня натолкнули в обсуждении статьи о вайбкодинге. А именно, автор комментария справедливо заметил, что мой эмулятор процессора уж очень простой, там есть только регистры, память и простые устройства. И привел в пример “Эмулятор БК 0010(01)”:
Эх, не видели Вы детальных эмуляторов многих архитектур, эх, не видели…
И я ранее даже не задумывался о написании таких сложных систем даже с помощью LLM-усилителей.
Тот же VirtualBox казался проектом, который смогут реализовать лишь самые крутые спецы, причем лишь объединившись в команду и получив хорошее финансирование.
И даже более простые проекты, как v86 от Фабиана Хеммера, пишут звезды, делают они их годами, причем, как правило, еще до написания имеют солидный опыт низкоуровневой разработки. А репозитории подобных проектов набирают десятки тысяч звезд на GitHub.
И мне показалось, что я нашел то, что искал. То есть проект, в который LLM-ка упрется и просто не сможет ничего сделать. Хотел посмотреть, как она будет “водить по кругу” (как ранее делали более старые версии), до какого предела сможет дойти. И решил не тратить много токенов, ведь был уверен, что результат будет отрицательный.
Первое удивление
Спустя минут сорок работы LLM-агента он отрапортовал, что все готово и даже любезно запустил вирт. машину в браузере.
Я был бы удивлен, если бы оно дошло хотя бы до загрузки BIOS.
Но оказалось, что уже первая версия запустила Windows XP, я увидел рабочий стол, двигалась мышка и даже, пусть не без труда, удалось запустить калькулятор, и он работал!
На второй итерации LLM-ка уже оптимизировала запуск, стало возможно запускать игры, добавился звук…
Первая итерация по стоимости получилась около доллара по подписке.
И долгожданный эффект Маккордак
После того как люди узнают, что компьютерная система сделала X, мы перестаем это X считать сложной задачей. К примеру, тот же оппонент высказался по поводу эмулятора Windows XP так – это всего лишь “большой массив и большой switch”:
А чему тут не верить? Как Вам ниже написали: большой массив для эмуляции памяти, большой switch для “что будет делать процессор, увидев вот это слово” (примерно так, хоть это и не эмулятор), и эмуляция (клавиатура, диски, монитор). Все, что нужно – это документация (на процессор и обвязку), усидчивость и время этим заниматься – а у LLM с этим проблем нет.
Но на самом деле, конечно, код несколько сложнее, чем “большой switch”. Но магией уже не кажется, ценность этого результата в наших глазах уже снижена, ведь это смог ИИ (как когда-то были обесценены интеллектуальные способности шахматных гроссмейстеров).
Придание смысла
Мои ожидания были разрушены, я хотел увидеть, как LLM-ка упрется в неразрешимую для нее задачу, как возникнет непреодолимый барьер чрезмерной сложности. Но не увидел, оно справилось. Причем работает не хуже тех, что делали люди.
Далее пришлось думать, что с этим делать, ведь это очередной аналог Windows XP в браузере, что было реализовано не единожды и, по сути, никакого практического смысла не имеет, разве что можно по-быстрому поностальгировать.
Идея уже была – нужно не просто запускать ОС, а наблюдать за системой. То есть видеть, как ОС общается с диском, какие ассемблерные инструкции (и на каком уровне) выполняет процессор, что получаем от клавиатуры и т.д.
Теперь детально, что получилось.
Панель Устройства
Это дерево эмулированного железа. У каждого устройства есть лампочка активности и живая цифра, которая обновляется дважды в секунду. Стоит пошевелить мышью, и в строке “Мышь PS/2” побегут прерывания. Стоит запустить программу, и диск вместо “тишина” начнет показывать байты в секунду.
Устройство | Что показывает панель |
|---|---|
Процессор | загрузка, % |
Память | страничных ошибок в секунду |
Чипсет | обращений к портам в секунду |
Шина PCI | обращений к конфигурации в секунду |
Контроллер прерываний | прерываний в секунду |
Системный таймер | частота тиков, Гц |
Часы и CMOS | прерываний в секунду |
Клавиатура PS/2 | прерываний в секунду |
Мышь PS/2 | прерываний в секунду |
Диск IDE | байт в секунду или “тишина” |
Видео Cirrus | запись в видеопамять, КБ/с |
Звук AC’97 | “играет” или “тишина” |
Системные порты | обращений в секунду |
Галочка рядом с устройством включает запись всех обращений. Щелчок открывает карточку.
Карточка устройства
Все карточки устроены одинаково: разобравшись с таймером, можно прочитать и карточку звуковой карты.
Сначала идет паспорт: что это за чип и зачем нужен, простыми словами. Потом то, как с устройством общается Windows: какие порты и какие области памяти для этого отведены.
Дальше самое интересное, путь прерывания от железа до кода:
устройство → линия IRQ → контроллер прерываний → вектор в IDT → обработчик в драйвере
Регистры устройства показаны вживую. У таймера это каналы, у звука микшер и буферы, а еще осциллограф того, что играет прямо сейчас.
И есть “вспышка”: короткая запись, от 0,1 до 5 секунд, в которую попадает все, что происходило с устройством. У диска туда попадают даже имена файлов, которые Windows читала и писала.
В конце карточки ждут вопросы для самопроверки.
Вкладки
Обзор: пульс машины
Плитки и графики за последнюю минуту: загрузка процессора, прерывания, системные вызовы, страничные ошибки, работа диска и видео. Видно, сколько времени процессор проводит в программах, сколько в ядре и сколько просто спит.

Тут же “диспетчер задач из железа”. Время каждого процесса считается без вопросов к Windows: процесс опознается по регистру CR3, где лежит адрес таблиц страниц.
Монитор: логический анализатор
Шкала времени за последние 4 секунды и журнал событий по устройствам, отмеченным галочками. Записи в журнале расшифрованы:
IRQ0 → вектор 0x30 – Прерывание: Таймер PIT
У каждого обращения к порту указан автор: процесс и функция. Журнал можно заморозить, чтобы спокойно прочитать.

Процессор
Видно, в каком режиме работает процессор и чем занят прямо сейчас, например “HLT – спит”. Регистры подсвечиваются при изменении, а флаги и управляющие регистры разобраны по битам.

Дизассемблер показывает следующие инструкции с привязкой к модулю:
hal.dll+0x772a ≈ HalProcessorIdle
Значок ≈ значит, что имя функции определено приблизительно. К инструкциям есть подсказки, привилегированные выделены красным.

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

Любой адрес можно перевести вручную и пройти по шагам весь путь от виртуального к физическому. Есть просмотр содержимого страницы и карта физической памяти: где RAM, где ROM, а где устройства.
Windows
Список процессов собран без помощи Windows: эмулятор сам находит и читает структуры ядра в физической памяти. Про каждый процесс известны PID, родитель, число потоков и время работы. Щелчок по процессу показывает загруженные DLL. Еще есть список драйверов и таблица системных вызовов.
Диск
Вкладка показывает загрузочные секторы и карту активности всего диска: где читали, где писали.

Кнопка “Построить карту файлов NTFS” заставляет эмулятор самому разобрать файловую систему и подписать каждый сектор именем файла. А вспышка “что Windows читает и пишет” покажет, какие файлы система трогала, пока шла запись.
Вывод. Или зачем все это нужно.
Запускать Windows XP в браузере и разглядывать прерывания на TypeScript – все равно что удалять гланды через задний проход. Зачем, ведь есть QEMU, почему не WinDbg?
Желание разобраться, как ОС работает с железом, возникает часто, а дальше начинается подготовка: поставить эмулятор, собрать образ, подключить отладчик, найти символы. Отдельная история, когда изучать хочется x86, а на столе ноутбук на ARM. Вечер уходит на настройку, и к моменту, когда все заработало, запал уже прошел.
Здесь подготовки нет. Достаточно открыть страницу и подставить образ диска: через пару минут на экране рабочий стол XP, а рядом прерывания, порты и таблицы страниц. Замены WinDbg из этого не выйдет, да и цель другая: дать посмотреть на живую систему снизу, пока интерес не остыл.
Попробовать и посмотреть код:
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.