10 puntos por GN⁺ 21 일 전 | 3 comentarios | Compartir por WhatsApp
  • Se completó un proyecto de port para ejecutar Mac OS X 10.0 (Cheetah) de forma nativa usando el hardware basado en PowerPC de la Wii
  • Se modificó el kernel Darwin/XNU para adaptarlo a la Wii y se escribieron desde cero el bootloader, el device tree y los drivers, logrando arrancar incluso el entorno GUI
  • Se implementaron drivers personalizados de IOKit con soporte para tarjeta SD, framebuffer y dispositivos de entrada USB, consiguiendo un sistema completamente funcional
  • Se reflejaron características propias de la Wii, como la corrección de conflictos en la configuración BAT, la creación de una capa de drivers para el SoC Hollywood y un framebuffer con conversión RGB→YUV
  • Tras más de 10 años de intentos, se logró el arranque completo y la operación de Mac OS X en la Wii, demostrando el valor de asumir proyectos que parecen imposibles

Resumen del proyecto para ejecutar Mac OS X en Wii

  • Se llevó a cabo un proyecto de port para ejecutar Mac OS X 10.0 (Cheetah) de forma nativa en Nintendo Wii
  • La Wii ya había tenido ports de sistemas como Linux, NetBSD y Windows NT, y ahora se suma Mac OS X
  • Aprovechando el hardware basado en PowerPC de la Wii, se ejecutó el kernel Darwin/XNU y se escribieron directamente los drivers y el bootloader necesarios
  • Como resultado, se logró el arranque completo de Mac OS X hasta su entorno gráfico en la Wii, con soporte incluso para teclado y mouse

Investigación de viabilidad

  • El CPU PowerPC 750CL de la Wii es sucesor del PowerPC 750CXe usado en la G3 iMac/iBook, por lo que no había problemas de compatibilidad de CPU
  • Los 88 MB de RAM de la Wii (MEM1 24 MB + MEM2 64 MB) son menos que el requisito oficial (128 MB), pero pruebas con QEMU confirmaron que podía arrancar incluso con 64 MB
  • El hardware soportado incluye USB Gecko (depuración serial), tarjeta SD, controlador de interrupciones, salida de video por framebuffer y puertos USB
  • Si se adaptaba a la Wii el núcleo open source de Mac OS X, Darwin (kernel XNU, IOKit), también era posible hacer funcionar la capa gráfica superior
  • La Wii permite la ejecución de código propio mediante Homebrew Channel y BootMii, lo que la hace adecuada para experimentar con ports

Enfoque del port

  • Se eligió entre tres estrategias de arranque:
    1. Portar Open Firmware
    2. Portar BootX
    3. Escribir directamente un bootloader personalizado
  • Se escribió un nuevo bootloader específico para Wii que realiza la inicialización de hardware, la carga del kernel, la creación del device tree y la transferencia de control al kernel
  • Una vez que el kernel arranca, el código del bootloader deja de ser necesario, y el trabajo posterior se centra en parches al kernel y desarrollo de drivers

Escritura del bootloader

  • Se implementaron la inicialización de la Wii y funciones para tarjeta SD, framebuffer y depuración USB basándose en código de ejemplo de ppcskel
  • El kernel XNU en formato Mach-O se carga en memoria y se ejecuta saltando a su entry point especificado
  • Para verificar si el kernel estaba entrando en ejecución, se insertó un parche de parpadeo de LED para rastrear esa etapa
  • Al rastrear en reversa la ruta de ejecución del kernel, se confirmó que ocurría una excepción 300 en la etapa device_tree.c → se identificó la necesidad de pasar un device tree
  • Creación y entrega del device tree

    • Se construyó un árbol mínimo hardcodeado basado en la estructura fija del hardware de la Wii (/cpus, /memory)
    • Se incluyó un puntero al device tree en la estructura boot_args para pasarlo al kernel
    • Después de eso, el kernel reconoció correctamente el árbol y continuó el arranque

Parches al kernel

  • La configuración de BAT (Block Address Translation) en XNU entraba en conflicto con el mapa de memoria de la Wii, por lo que fue necesario modificar el código fuente del kernel
  • Se montó un entorno de compilación del kernel dentro de un guest de Mac OS X Cheetah (QEMU)
  • Gracias a la corrección de BAT y al agregado de redirección de salida de consola hacia USB Gecko, fue posible depurar
  • Después, se inicializaron correctamente la memoria virtual, IOKit y el subsistema BSD
  • En el log de arranque apareció el mensaje “Still waiting for root device” → se confirmó la necesidad de un driver para la tarjeta SD

Escritura de drivers

  • Comprender la estructura de IOKit

    • IOKit es un framework de extensiones de kernel basado en C++ que representa las capas de hardware mediante una estructura de driver-nub
    • Ejemplo: IOPCIBridgeIOPCIDeviceSomeEthernetCardIOEthernetInterface
    • Como la Wii usa una estructura SoC (Hollywood) y no un bus PCI, hizo falta un driver personalizado que reemplazara a IOPCIFamily
  • Driver de Hollywood

    • Se escribió el driver NintendoWiiHollywood, que hace match con el nodo “hollywood” del device tree
    • Se creó y registró el nub NintendoWiiHollywoodDevice para representar el hardware subordinado
    • Gracias a esto, pudieron conectarse drivers de dispositivos inferiores, como el de la tarjeta SD
  • Driver de tarjeta SD

    • Se implementó el acceso a la tarjeta SD de la Wii heredando de IOBlockStorageDevice
    • La comunicación con la tarjeta SD se realiza usando los comandos IPC de MINI (coprocesador Starlet): IPC_SDMMC_SIZE, READ, WRITE
    • Para resolver problemas con memoria cacheada, se usó un buffer de memoria no cacheada
    • Se generó con éxito un nub IOMedia, permitiendo el reconocimiento del sistema de archivos raíz y el arranque completo
    • En el log de arranque se confirmó BSD root: disk0s4
  • Driver de framebuffer

    • Heredando de IOFramebuffer, se asignó como framebuffer la región MEM1 de la Wii (0x01700000)
    • Para permitir la transición entre la consola de texto inicial y la GUI, isConsoleDevice() devuelve true
    • Como el hardware de video de la Wii usa formato YUV, se implementó un framebuffer doble para conversión RGB→YUV
    • Mediante un loop de conversión se realizó la conversión de color a 60 Hz → se logró salida GUI con colores correctos
  • Soporte de entrada USB

    • Se intentó usar AppleUSBOHCI para manejar el controlador USB 1.1 OHCI de la Wii
    • Problema 1: no había código fuente de IOUSBFamily, así que no se podía depurar
    • Problema 2: existía una dependencia de IOPCIDevice, por lo que se escribió un NintendoWiiHollywoodPCIDevice falso para la Wii
    • Problema 3: había una incompatibilidad de endianess (la Wii usa reversed-little-endian), por lo que fue necesario eliminar el byte swap por software
    • Tras conseguir por IRC el código fuente de IOUSBFamily para Mac OS X Cheetah, se pudo modificar y compilar con éxito
    • Como resultado, funcionaron el teclado y el mouse USB, y la Wii pasó a comportarse como un sistema Mac OS X completo

Mejoras al bootloader y al kernel

  • Mejoras al bootloader

    • Se añadieron búsqueda de particiones en la tarjeta SD y menú de arranque, además de implementar el parseo de Apple Partition Map (APM)
    • El bootloader carga extensiones de kernel (kext) y las registra en el nodo /chosen/memory-map
    • Gracias a esto, se puede arrancar usando una imagen de instalación de Mac OS X sin modificar
  • Simplificación del kernel

    • Se minimizaron los cambios específicos para Wii en el kernel:
    • corrección de la configuración BAT
    • reconocimiento de direcciones de I/O basado en el nodo “hollywood”
    • corrección de coherencia de caché del framebuffer
    • separar los drivers fuera del kernel mejoró la eficiencia de compilación y la mantenibilidad

Cierre

  • Se completó, después de más de 10 años, un proyecto concebido originalmente en la universidad en 2013
  • El desafío estuvo inspirado por un caso de port de Windows NT a Wii
  • Como resultado final, se logró el arranque completo de Mac OS X 10.0 y el manejo de su GUI en la Wii
  • Se enfatiza la lección de que “los proyectos que parecen imposibles son precisamente los que vale la pena intentar”

3 comentarios

 
ffdd270 21 일 전

Qué texto tan bueno, y qué gran autor....

 
jjpark78 21 일 전

Dicen que entre los fans, los más fans son los gringos...

 
GN⁺ 21 일 전
Opiniones en Hacker News
  • Este proyecto fue un trabajo realmente asombroso. El texto en sí también fue muy atrapante y me mantuvo enganchado hasta el final
    En particular, me impresionó la parte de “WindowServer se quejaba, y para resolverlo hubo que escribir directamente un controlador de framebuffer”
    Me sorprendió ver que la capa de abstracción I/O Kit de MacOS realmente cumple su función. Mis aplausos para los desarrolladores de NeXT

    • Yo sentí algo parecido. Como era mi primera vez escribiendo un controlador, la curva de aprendizaje fue empinada, pero al ver el sistema cobrar vida empecé a entender el enfoque de IOKit
      No me resulta fácil compararlo porque no tengo experiencia desarrollando controladores en otras plataformas, pero estructuralmente me pareció bastante atractivo
    • Tengo entendido que IOKit fue creado desde cero específicamente para OS X, y que en la época de NeXT usaban otro modelo llamado DriverKit
      Hace tiempo incluso hubo desarrolladores de NetBSD que lograron ejecutar PPC Darwin sobre una capa de compatibilidad Mach/IOKit y levantar hasta Xquartz. Es interesante que NetBSD tradujera las llamadas de IOKit
    • También tiene bastantes similitudes con la pila de Linux, así que estoy pensando revisar el proyecto Linux on Wii para comparar cómo resolvieron el tema del framebuffer
      Todavía me cuesta creer que se puedan ejecutar tantos sistemas operativos sobre una Wii
    • Parece probable que la experiencia acumulada desde la época de OPENSTEP, apuntando a múltiples arquitecturas y sistemas operativos, haya ayudado con este tipo de abstracción
    • Coincido con eso de que “es sorprendente lo bien abstraído que está MacOS”
      En realidad, la diferencia entre una buena abstracción y una mala suele depender de qué tan bien esté explicada
  • La ingeniería en sí ya es impresionante, pero lo que de verdad me impactó es que el autor estaba desarrollando en clase económica

    • A mí ya me cuesta usar bien una laptop en clase económica, así que no puedo creer que además haya conectado una Wii para depurar
    • Hace tiempo Apple hizo un anuncio sobre editar en un avión (enlace de YouTube)
    • La persona del asiento de al lado probablemente solo estaba mirando su celular pensando “¿y eso qué es?”. Yo no habría aguantado la curiosidad y seguro preguntaba
    • Por las fotos, parecía a veces un bus y a veces un avión. En cualquier caso, desarrollar cargando una Wii mientras se trasladaba es prueba de una concentración y dedicación enormes
      (Luego vi un poco más y sí: la primera foto era en un bus, la segunda en un avión)
    • Me sorprende que alguien pueda meterse de lleno en un proyecto tan complejo mientras viaja. Volví a mirar las fotos y también podría ser tren o bus. Sea como sea, es un flex impresionante
  • Como autor del port de NetBSD para Wii y Wii U, quiero felicitar sinceramente este proyecto
    Tengo muchas ganas de ver qué problemas fueron apareciendo y cómo los resolvieron

    • Tu port fue una gran inspiración. Gracias por haber aportado tanto en este campo
  • Antes yo también era un fanático hardcore de Mac, e incluso llegué a hacer por ingeniería inversa algunas “apps de iOS” no oficiales de los primeros tiempos
    Pero este proyecto supera todo eso. Ya de por sí ejecutar MacOS en una Wii es increíble, pero además el texto está muy bien elaborado y es muy interesante

    • Gracias por tus palabras :)
  • No sabía hasta ahora que la Wii solo tiene 88 MB de RAM. Menos mal que los juegos no eran a base de electrones

    • Es un dato histórico curioso: Windows Vista salió en Norteamérica el mismo mes en que se lanzó la Wii
      El requisito mínimo de Vista era 512 MB, pero la mayoría de las PC tenían menos memoria que eso
      Hoy ver que 8 GB van quedando atrás y 16 GB se vuelven el estándar demuestra cuánto ha cambiado el mundo
    • Me da risa saber que el menú de configuración de la Wii estaba hecho como una página web HTML. Ni las consolas de 2006 pudieron escapar del dominio de la web
  • Antes de empezar el proyecto, quise comprobar si esto siquiera era posible, y en un comentario de Reddit de 2021 alguien decía que tenía “0% de probabilidad
    Ver eso más bien me motivó. Así que empecé analizando el hardware de la Wii. Fue realmente gracioso

    • Parte del valor de estos proyectos está en dejar inmortalizadas para siempre esas afirmaciones de “eso es totalmente imposible”
      Hay gente que da por hecho que algo “casi imposible” nunca va a ocurrir y se convence de que eso los vuelve escépticos rigurosos
    • Esto me recordó un viejo chiste sobre Linux. En vez de preguntar “¿cómo se hace X en Linux?”, bastaba decir “X es imposible en Linux” para que apareciera alguien y te mostrara cómo hacerlo
    • A mí me pasó algo parecido al ver en la documentación de MacroPad de Adafruit la frase “no se puede agregar BLE ni WiFi”
      Pensé “¿ah, sí?” y reconfiguré el puerto UART para conectarle un ESP32
    • También estuvo divertida la escena de depuración de “todo está de color magenta”
    • Mucha gente que comenta en internet confunde el cinismo con la agudeza de esa forma
      El problema es que ni siquiera reconocen la idea de un cinismo ignorante
  • Estar sentado en clase económica de un avión depurando un kernel panic en una Wii implica un nivel de concentración que ni me imagino
    A la mayoría ya le cuesta terminar un solo libro en un vuelo

  • Fue un proyecto realmente genial. Me hizo recordar la época dorada del desarrollo de bajo nivel
    Antes era fácil inicializar VGA y dibujar píxeles, y chips como el 6502 también eran mucho más accesibles
    Pero hoy los sistemas se han vuelto tan complejos que la barrera de entrada subió muchísimo
    Y encima la IA, fingiendo simplificar el desarrollo, en realidad está reduciendo todavía más la accesibilidad

  • Yo también estoy intentando algo parecido: portar Mac OS 9 a Wii U
    Ver este proyecto me dejó totalmente impresionado, y cada vez que pienso “esto es imposible”, me devuelve el ánimo

    • Está buenísimo. Mac OS 9 además es código cerrado, así que debe ser un desafío todavía más difícil
    • No tener el código fuente de XNU o Darwin es una desventaja, pero herramientas como el código filtrado de System 7.1, Ghidra o MCP podrían compensarlo. Mucha suerte
  • El texto estuvo muy bueno, pero insertar el video .mov con una etiqueta <video> trae problemas de compatibilidad entre navegadores
    No se reproduce ni en Chrome ni en Firefox

    • Si no funciona en Chrome ni en Firefox, en la práctica hay que asumir que no funciona en casi ningún navegador
    • ¡Gracias! Ya lo corregí