34 puntos por xguru 2022-10-25 | 11 comentarios | Compartir por WhatsApp
  • Wine es una capa de compatibilidad que permite ejecutar programas de Windows en sistemas operativos compatibles con POSIX (Linux, macOS, BSD)
    • El Steam Deck de Valve también usa una solución basada en Wine

WINE = Wine Is Not an Emulator

  • El enfoque de emulación es lento y, de hecho, Linux/macOS pueden ejecutar binarios de Windows de forma nativa (con un poco de ayuda)
  • Explicación detallada, usando un depurador, de cómo funcionan los binarios de Linux/Windows

Hello, Wine!

  • Básicamente, Wine es un "Dynamic Loader" para ejecutables de Windows
  • Es un binario nativo de Linux y sabe cómo procesar EXE o DLL
  • Wine carga el ejecutable de Windows en memoria, lo parsea para identificar dependencias y luego salta al código que debe ejecutar
  • Solo con eso ya es posible ejecutar binarios de Windows, pero hay excepciones

System Calls

  • Las llamadas al sistema, conocidas como syscalls, son lo que complica a Wine
  • Las syscalls se implementan en el OS, no dentro del ejecutable o la biblioteca
  • Las syscalls que ofrece el OS son la API del OS
    • Linux: read, write, open, brk, getpid,..
    • Windows: NtReadFile, NtCreateProcess, NtCreateMutant,..
  • Las llamadas al sistema son distintas de una llamada de función normal en el código. Por ejemplo, abrir un archivo debe procesarse en el kernel porque hay que rastrear el File Descriptor
  • Por eso, el código de la aplicación necesita una forma de "interrumpir" por sí mismo y ceder el control al kernel ("Context Switch")
  • El conjunto de funciones que ofrece el OS y la forma de invocarlas varían según el sistema operativo
    • En Linux, al llamar a read() hay que poner el file descriptor en el registro %rdi, el puntero al buffer en %rsi y la cantidad de bytes a leer en %rdx
    • Pero en Windows no existe una función read() en el kernel
  • Si ejecutamos código que imprime el mismo "Hello World!" en Linux y en Windows:
    • Linux llama a puts de libc.so, mientras que Windows llama a printf de ucrtbase.dll
    • En Linux moderno, lo habitual es enlazarlo estáticamente, incluir la implementación de puts dentro del binario y que libc.so no se use en tiempo de ejecución
  • En Windows, al menos hasta hace poco, "solo el malware usaba llamadas al sistema directamente"
    • Las aplicaciones normales siempre dependen de kernel32.dll/kernelbase.dll/ntdll.dll para no comunicarse directamente con el kernel

Runtime translation of Syscalls

  • ¿Qué pasa si interceptamos una syscall?
    Si intervenimos cuando la aplicación llama a NtWriteFile(), luego llamamos a write() y devolvemos el resultado en el formato que espera el binario.
  • Sería posible si se ofreciera una versión personalizada de ucrtbase.dll, pero eso trae problemas complejos
  • En su lugar, se modifica ntdll.dll, que está entre el binario y el kernel
  • Las versiones recientes de Wine están compuestas por ntdll.dll (binario PE) y ntdll.so (binario ELF)
    • La DLL es una capa delgada que simplemente redirige la llamada hacia el lado ELF
    • El ELF tiene una función especial llamada __wine_syscall_dispatcher, que hace la magia de convertir la pila actual de Windows a Linux, o viceversa
  • Ese syscall dispatcher es el puente que conecta el mundo de Windows con el mundo de Linux
    • Maneja la calling convention, reserva espacio en la pila, mueve registros y realiza tareas similares
    • Cuando la ejecución llega a ntdll.so y pasa al binario de Linux, ya podemos usar toda la API de Linux

¿Eso es todo?

  • Suena muy fácil, pero...
    • La API de Windows es enorme, está mal documentada, tiene bugs conocidos y desconocidos, y hay que preservarlos tal cual. La mayor parte del código de Wine es la implementación de varias DLL de Windows
    • Hay varias formas de invocar syscalls y, técnicamente, no hay manera de impedir que las aplicaciones llamen a syscalls directamente
      (Recuerden que los juegos de Windows hacen todo tipo de locuras)
      El kernel de Linux tiene un mecanismo especial para manejar esto y, por supuesto, eso añade más complejidad
    • El tema de 32bit vs 64bit también es un sinsentido. Hay muchísimos juegos de 32 bits, y no van a volver a lanzarlos en 64 bits. Como Wine soporta ambos, eso también añade complejidad
    • Ni siquiera se ha mencionado wine-server. Es un proceso separado que crea Wine y que mantiene el "estado" del kernel (file descriptors, mutexes, etc.)
    • ¿Quieres ejecutar juegos? Entonces hay que manejar DirectX, PulseAudio, dispositivos de entrada y mucho más, así que el trabajo es enorme
  • Wine lleva mucho tiempo en desarrollo y ha recorrido un largo camino. Hoy en día puede ejecutar sin problemas juegos modernos como Cyberpunk 2077 o Elden Ring
    Incluso, a veces, Wine puede rendir mejor que Windows

11 comentarios

 
roxie 2022-10-29

Más allá del contenido, la calidad del resumen es realmente impresionante. Gracias.

 
minho2da 2022-10-25

Estoy usando yes24 y Kyobo Book Centre, que ofrecen servicios de lectura por suscripción.

Después de cambiar el entorno de mi PC de casa a Ubuntu, intenté ejecutar YES24 y Kyobo Book Centre con Wine.

Pensé que quizá no funcionarían porque ambos usan DRM por separado, pero YES24, que tengo entendido está hecho con Qt, funcionó bien, mientras que el EBOOK de Kyobo Book Centre no se ejecutó. (La UI sí se inicia, el DRM no)

Sé que ambos tienen DRM aplicado, así que me puse a pensar qué diferencia hacía que uno funcionara y el otro no, pero al ver el texto de arriba siento que más o menos ya lo entiendo (el meme de “lo entendí perfectamente más o menos”).

 
bbulbum 2022-10-25

Me alegra que desde wine5.0 KakaoTalk se ejecute sin ninguna configuración. (Aparte de que no es que quiera usar KakaoTalk..)
Hay algunos problemas con la visualización de ciertas pantallas, pero funciones como enviar imágenes por el portapapeles funcionan de manera fluida.
Parece que Wine en general está enfocado en ejecutar juegos, pero está bueno que también haga correr bien varias apps.
Incluso cuando se habla de adoptar Linux en instituciones públicas, que ni siquiera se les ocurra una versión de KakaoTalk para Linux es algo... bastante malo..
La versión para Mac sí la sacaron rapidísimo..

 
bbulbum 2022-10-25

Sabía lo básico más o menos, pero me sorprende que expliquen Wine con tanto detalle... jaja

 
kayws426 2022-10-25

Dado que Wine suele ejecutar bastante bien los programas de Windows, ¿también sería posible la idea de crear una app multiplataforma usando Wine? (solo en escritorio)

 
ganadist 2022-10-26

Tengo entendido que hace muchísimo tiempo incluso se lanzó una versión de HWP de Hancom para Linux porteada sobre la base de Wine. (R4 incluía una capa aparte de biblioteca de compatibilidad win32, y ya no recuerdo bien si fue R5 o 2002 cuando se usó Wine).
Por eso, en algún momento también corría la broma de que gracias a Wine, win32 era la API multiplataforma más popular y exitosa.
Pero ahora es la era de Electron/Wasm;;

 
jinseokim 2022-10-25

Es una historia un poco distinta, pero si piensan hacerlo de esa manera, dado que la licencia de Wine es LGPL, dependiendo de cómo escriban el código, puede que tengan que publicar parte o la totalidad del código fuente.

 
kunggom 2022-10-25

Como también se explica en el texto original, la razón por la que Wine no es un emulador es que utiliza las instrucciones de CPU tal cual. Eso significa que, en esencia, el software que puede ejecutarse con Wine es software para Windows que funciona en CPU x86 o x86-64.

Ahora que Apple ya migró toda la línea Mac a la arquitectura ARM, y que Microsoft también está lanzando kits de desarrollo basados en ARM, me parece que ya es un poco forzado llamar “soporte multiplataforma” a software que solo funciona en CPU basadas en x86(-64).

 
kayws426 2022-10-27

Sí. Tal como dices... creo que sin darme cuenta lo limité a máquinas de la familia x86.

 
jjpark78 2022-10-25

Con electron o Tauri, si hubiera que crear algo multiplataforma desde cero, parece que no sería una buena opción. Si hay alguna restricción especial por la que no se puedan usar tecnologías basadas en navegador web, tal vez sería mejor usar una biblioteca como Qt, que ofrece buen soporte para compilación cruzada..

 
iceflower01 2022-10-25

222