Привет, Хабр! Мое плотное знакомство с консолями Nintendo началось с Wii U. Так уж получилось, что лучшей серией слешеров я считаю Bayonetta. А поскольку вторая часть вышла как эксклюзив для Wii U, мне пришлось приобрести приставку. Потом заодно познакомился с The Legend of Zelda — и понеслось. Примерно то же самое случилось и с выходом Bayonetta 3 — обзавелся Nintendo Switch. Что самое интересное, у меня никогда не было обычной Wii.

Волей случая мне в руки попался замечательный экземпляр, но на него я решил посмотреть с точки зрения железа. Внутри меня ждал любопытный конфиг из PowerPC процессора IBM Broadway + SoC производства ATI, который отвечает за графику, а также устройств ввода-вывода.


В первую очередь меня интересовал запуск сторонних операционных систем. Из-за скромных технических характеристик список ограничивается довольно старыми версиями Linux, MacOS 9 (не нативно) и даже Windows NT (через эмуляцию). 

Все это я разумеется захотел попробовать, но наткнулся на информацию из Reddit, что на устройство можно поставить вполне себе актуальную версию NetBSD и она даже будет неплохо работать. Это было максимально интересно, поскольку у Wii скромные характеристики процессора и мало оперативной памяти, всего 88 MB. Да и раньше я, к своему стыду, с этой ОС никогда дела не имел. Решено: ставлю.

Намеренно не буду здесь расписывать методы получения Homebrew на приставке. Уточню лишь, что они прекрасно работают и сейчас, когда все официальные сервисы уже давно выключены. Результатом будет появление одноименного канала в главном меню. Он позволяет запускать любые сторонние образы с USB-флешек или SD-карт. В моем случае это была скоростная SD-карта размером 16 GB. Собственно, это и будет дисковым накопителем для запуска.

Что такое NetBSD

Представьте себе трех братьев-близнецов. Они могут быть очень похожи внешне, но обладать абсолютно разными чертами характера. Речь, разумеется, о FreeBSD, OpenBSD и NetBSD. Все они весьма достойно трудятся на серверах и в сетевых устройствах, ставя рекорды по аптайму и защищенности. Но тем не менее у каждого свои причуды, поведение и требования.

Самый современный — FreeBSD. Тут прокачанный сетевой стек, отказоустойчивая файловая система ZFS и встроенный механизм контейнеризации Jails, разработанный задолго до этого вашего Docker. Именно эту ОС выбирают для крупных проектов вроде Netflix CDN, и она чудесно справляется с ролью повседневного рабочего инструмента, сочетая надежность и производительность.

Кредо OpenBSD — консерватизм и безопасность. Эта ОС словно монах в монастыре вудуистов из Cyberpunk 2077. Разработчики и мейнтейнеры стараются поддерживать систему в кристально чистом и хорошо задокументированном состоянии. Все, что вызывает малейшее сомнение, незамедлительно выкидывается. Каждая строка кода тут перепроверена по много раз, а удобство и производительность стоит где-то вдалеке, утирая слезы исходниками.

А вот NetBSD не стал кидаться в крайности, оставаясь универсальным инструментом и соблюдая баланс между безопасностью и внедрением новых технологий. Тем не менее у него появилось интересное хобби — он поддерживает множество диковинных и устаревших архитектур. Неважно, на чем вы его запускаете, — эта система одинаково будет работать как на VAX, так и на каком-нибудь MIPS64. Именно эта особенность позволяет запустить NetBSD на Nintendo Wii.

Необычный CPU

Процессор Nintendo Wii (источник)
Процессор Nintendo Wii (источник)

В самом начале я уже раскрыл карты — сердцем японской консоли служит кастомный CPU IBM Broadway, специально разработанный для этой цели. Инженеры IBM взяли за основу RISC-процессор PowerPC 750CL и довели его до почти идеального баланса между производительностью, тепловыделением и ценой.

Такой выбор не был чем-то необычным. IBM в то время активно разрабатывала процессоры для игровых консолей. Sony Playstation 3 базировался на Cell, Xbox 360 на Xenon, а GameCube на Gekko. Все это сильно модифицированные про��ессоры на PowerPC, что давало ряд серьезных преимуществ. Прежде всего это чистая архитектура: инструкции делают ровно то, что написано в документации и почти без побочных эффектов.

Немаловажную роль играет и прозрачная модель памяти. Разработчики четко понимают, когда данные видимы, как функционирует кеш, а правила упорядочивания памяти (memory ordering) не превращаются в запутанное дело для Эркюля Пуаро. Такая предсказуемость позволяла на полную катушку использовать программную оптимизацию игр, выжимая из железа все, что можно.

Работает Broadway на частоте 729 МГц, что вдвое быстрее, чем Gekko, имеет кеши L1/L2 объемом 64 и 256 КБ соответственно. Разница в архитектуре была минимальной, что обеспечило обратную совместимость и позволило запускать игры GameCube на Wii нативно, без эмуляции. При этом было достигнуто 20%-е снижение энергопотребления по сравнению с предшественником.

Установка NetBSD

Если на вашей консоли уже поселился the homebrew channel, то никаких сложностей с установкой системы не предвидится. Официальный образ NetBSD 10.1 доступен для свободного скачивания по этой ссылке. Если же хочется совсем свежего, то daily-образы системы также собираются для Wii.

Скачанный образ можно напрямую записать на SD-карту при помощи Raspberry Pi Imager или Balena Etcher. Единственное, о чем стоит помнить: сама консоль не поддерживает карты объемом больше 32 ГБ. Именно SD будет дисковым накопителем для NetBSD, и от скорости ее работы зависит общая производительность системы.

После того как вы вставите SD-карту в консоль, в Homebrew появится пункт, позволяющий запустить NetBSD:

В процессе первого запуска ОС проверит дисковый накопитель и расширит файловую систему до полного размера. Работает почти такой же механизм, как и для Raspberry Pi:

Сразу после запуска понадобится доступ к интернету. Однако собственной сетевой карты у Wii нет, а беспроводная сеть из под NetBSD недоступна. Так что можно будет воспользоваться внешним сетевым адаптером, подключив его по USB. Подойдет стандартный RVL-015 (используемый для Wii / Wii U / Switch) или любой сторонний, лишь бы драйверы на него присутствовали в ядре. У меня это USB-сетевая карта с Aliexpress на чипе AX88772A. В системе определяется следующим образом:

wii# dmesg | grep -i ether
[     2.089987] axe0: ASIX Electronics (0x0b95) AX88772A USB 2.0 10/100 Ethernet adapter (0x772a), rev 2.00/0.01, addr 2
[     2.579992] axe0: Ethernet address 00:00:00:00:00:0c

Каких-либо дополнительных танцев не потребовалось — система подхватила IP-адрес и DNS-серверы от роутера:

wii# ifconfig axe0
axe0: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        ec_capabilities=0x1<VLAN_MTU>
        ec_enabled=0
        address: 00:00:00:00:00:0c
        media: Ethernet autoselect (100baseTX full-duplex)
        status: active
        inet6 fe80::aded:931e:4d21:3a54%axe0/64 flags 0 scopeid 0x1
        inet 192.168.88.59/24 broadcast 192.168.88.255 flags 0

SSH тут включен по умолчанию, однако для безопасности директива PermitRootLogin выставлена в дефолтное значение no. Так что вооружаемся vi и меняем ее на yes

wii# vi /etc/ssh/sshd_config

…
PermitRootLogin yes
…

Сохраняемся и выходим командой :wq. После перезагрузки можно без проблем залогиниться в системе под рутом по SSH (не безопасно, но для примера пойдет). Далее самое главное — надо понять, как ставить софт. 

Проще всего установить утилиту pkgin и через нее накатывать предварительно скомпилированные бинарники. С одной стороны, это звучит как отличный план, но есть некоторые проблемы. В current-версии pkgsrc этой утилиты уже нет. Архива на ftp.netbsd.org мне найти не удалось. Потратив некоторое время на поиски, обнаружил искомый архив на сервере Университета Гамбурга. 

Скачиваем:

wii# ftp -4 
https://mirror.sobukus.de/object/d2/52/d25250747d773797e9823b4245ef7238-82215026-1719429029/pkgsrc-2024Q2.tar.gz

Распаковываем его в /usr:

wii# tar xvzf pkgsrc-2024Q2.tar.gz -C /usr

У меня tar упал с [1] Segmentation fault (core dumped) tar xvzf pkgsrc-2024Q2.tar.gz -C /usr. Причина в библиотеке libarchive, которая пыталась считать большой .tar.gz через mmap(). VM-подсистема NetBSD на такой архитектуре не смогла корректно отобразить этот mmap, в результате чего пользовательский процесс поймал ошибку доступа к памяти (DSI trap). 

Решение банально: отключить mmap у libarchive. Да, тупо, но работает, заставляя считывать файл через read():

wii# env LIBARCHIVE_MMAP=0 tar xvzf pkgsrc-2024Q2.tar.gz -C /usr

Минимально настраиваем окружение:

wii# export PATH=/usr/pkg/bin:/usr/pkg/sbin:$PATH

Переходим в директорию с исходниками pkgin:

wii# cd /usr/pkgsrc/pkgtools/pkgin

Выполняем сборку:

wii# make install

Обновляем список актуальных пакетов:

wii# pkgin update

Теперь все готово к тому, чтобы ставить софт в стиле apt install [package_name].

Установка веб-сервера

Вспоминаем, что железо у нас достаточно слабое, а оперативной памяти, откровенно говоря, мало (64 МБ GDDR3 SRAM + 24 МБ 1T-SRAM):

wii# dmesg | grep -i mem
[     1.000000] total memory = 90112 KB
[     1.000000] avail memory = 67632 KB

Так что обычный Apache2 тут точно не будет чувствовать себя комфортно. Вместо него можно поставить lighttpd — легковесный веб-сервер, созданный Яном Кнешке (Jan Kneschke). Вдобавок установим утилиту bsdfetch, которая будет отображать информацию о системе:

wii# pkgin install lighttpd bsdfetch

Копируем дефолтный пример конфига, делая его рабочим:

wii# cp -fv /usr/pkg/share/examples/rc.d/lighttpd /etc/rc.d

Добавляем в автозагрузку:

wii# echo 'lighttpd=YES' >> /etc/rc.conf

Раскомментируем строку server.document-root в /usr/pkg/etc/lighttpd/lighttpd.conf. По умолчанию она имеет значение /var/www/html.

Запускаем веб-сервер:

wii# /etc/rc.d/lighttpd start

Упс, получили ошибку 403. А все потому, что по дефолту каталога, который играет роль document-root, не было и создавался он из под root. Так что передаем его в собственность пользователя lighttpd:

wii# chown -R lighttpd:lighttpd /var/www/html/

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

wii# cp /usr/pkg/etc/lighttpd/lighttpd.conf /usr/pkg/etc/lighttpd/lighttpd.conf.bak

Удаляем оригинал:

wii# rm /usr/pkg/etc/lighttpd/lighttpd.conf

И создаем новый конфиг, который сразу же включает обработку CGI-скриптов:

wii# cat > /usr/pkg/etc/lighttpd/lighttpd.conf << 'EOF'
server.port = 80
server.document-root = "/var/www/html"

server.username = "lighttpd"
server.groupname = "lighttpd"

server.modules = (
    "mod_indexfile",
    "mod_cgi"
)

index-file.names = ( "index.cgi", "index.html" )

cgi.assign = (
    ".cgi" => "/bin/sh"
)
EOF

Создаем index.cgi в директории /var/www/html со следующим содержимым:

#!/bin/sh

echo "Content-Type: text/html"
echo ""

ACTION=""
if [ -n "$QUERY_STRING" ]; then
    ACTION=$(echo "$QUERY_STRING" | sed 's/.*action=\([^&]*\).*/\1/')
fi

cat <<EOF
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Wii NetBSD Control Panel</title>
  <style>
    body {
      font-family: monospace;
      background: #111;
      color: #0f0;
      padding: 10px;
    }
    h1 { margin-top: 0; }
    button {
      padding: 6px 12px;
      margin: 5px 0;
      background: #222;
      color: #0f0;
      border: 1px solid #0f0;
      cursor: pointer;
    }
    pre {
      background: #000;
      padding: 10px;
      border: 1px solid #0f0;
      overflow-x: auto;
    }
  </style>
</head>
<body>

<h1>Wii NetBSD</h1>

<h2>System info</h2>
<pre>
EOF

if command -v bsdfetch >/dev/null 2>&1; then
    bsdfetch
else
    echo "bsdfetch not found"
fi

cat <<EOF
</pre>

<form method="get">
  <button name="action" value="ifconfig">Show ifconfig</button>
</form>
EOF

if [ "$ACTION" = "ifconfig" ]; then
    echo "<h2>Network</h2>"
    echo "<pre>"
    /sbin/ifconfig
    echo "</pre>"
fi

cat <<EOF
</body>
</html>
EOF

Делаем файл исполняемым:

chmod +x /var/www/html/index.cgi

На всякий случай перезапускаем веб-сервер:

wii# /etc/rc.d/lighttpd restart

Вот и готов простейший вариант веб-панели, куда можно прикрутить много чего интересного:

Заключение

Nintendo Wii — прекрасная игровая консоль и достойный образец компьютера на редкой архитектуре. Благодаря ей я наконец-то смог добраться до NetBSD, знакомство с которой откладывал уже давно. Оказалось, что она гораздо дружелюбнее OpenBSD и очень даже пригодна, чтобы использовать ее для некоторых задач, особенно связанных с ретрокомпьютерами.

В будущем планирую попробовать ее работу на ПК с VLIW-процессором Transmeta Crusoe и посмотреть, как она себя поведет. Установленную же версию на Wii продолжу использовать для каких-нибудь хоббийных нужд. Например, на ней вполне возможно развернуть BBS-станцию или превратить ее в небольшое уютное Wiki. Работает она тихо, потребляет мало и отлично впишется в любой интерьер.

Накидывайте свои идеи, что можно сделать на базе такой железки, в комментариях.