
Привет, Хабр! Мое плотное знакомство с консолями 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

В самом начале я уже раскрыл карты — сердцем японской консоли служит кастомный 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 0SSH тут включен по умолчанию, однако для безопасности директива 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. Работает она тихо, потребляет мало и отлично впишется в любой интерьер.
Накидывайте свои идеи, что можно сделать на базе такой железки, в комментариях.