10.2 C
Москва
Четверг, 3 апреля, 2025

Энтузиаст рассказал, как запустил Go на PlayStation 2 — через TinyGo, ps2dev и боль — Tproger

Go запустили на PlayStation 2: энтузиаст адаптировал TinyGo и ps2dev для MIPS-процессора консоли и обошёл ограничения LLVM.

Разработчик под псевдонимом Ricardo опубликовал подробный отчёт о том, как ему удалось запустить Go-программу на PlayStation 2 — консоли 2000 года.

Он использовал компилятор TinyGo, SDK ps2dev и собственные костыли, чтобы адаптировать современный язык программирования под устаревшую архитектуру.

TinyGo, MIPS и странности платформы

PS2 построена на процессоре MIPS R5900 (архитектура MIPS-III с расширениями), который не поддерживается стандартной сборкой Go. Проблему частично решает TinyGo, который компилирует Go-код в LLVM IR.

Но даже с ним возникли сложности: ни LLVM, ни сам TinyGo не умеют работать с особенностями PS2 «из коробки». Пришлось вручную описывать платформу через ps2.json, определять baremetal-окружение, runtime и заглушки под прерывания.

Первые успехи: «Hello from Go»

Чтобы код TinyGo можно было линковать с библиотеками из ps2dev (а они скомпилированы под ABI N32), автору пришлось добиваться совместимости: целиться в MIPS-III, использовать hard-float, отключать abicalls и собирать IR с последующей ручной сборкой объектника через Clang с нужными флагами.

Читать также:
Microsoft остановит поддержку приложений «Календарь», «Люди» и «Почта Windows»

🔥 Минцифры с 31 мая введет для айтишников аттестацию на Госуслугахtproger.ru

После успешного линка и запуска в эмуляторе PCSX2 программа вывела строку и число на отладочный экран PS2.

Собственный main() и отладка

Дальше автор отказался от загрузчика на C и написал полноценный main() на Go, вручную выделяя память под кучу и завершая программу через exit() из ps2dev. Он добавил простую обёртку над scr_printf() — теперь можно печатать текст прямо из Go.

DDIVU и проклятие деления

Серьёзным багом стал сбой fmt.Sprintf: PS2 не поддерживает инструкцию DDIVU, которую LLVM генерирует при делении uint64.

Автор обошёл это, подключив функции __udivdi3, __divdi3 и прочие, а затем пропатчил компилятор TinyGo, чтобы он использовал их при делении int64 и uint64.

Что дальше

Демо работает. Go-код запускается напрямую, выводит текст и корректно делит числа.

Впереди — системные вызовы, inline-ассемблер, поддержка прерываний и, возможно, новая цель в LLVM для процессора r5900.

НОВОЕ НА САЙТЕ