Cómo funciona Wine 101
(werat.dev)- 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
syscallsse implementan en el OS, no dentro del ejecutable o la biblioteca - Las
syscallsque ofrece el OS son la API del OS- Linux:
read,write,open,brk,getpid,.. - Windows:
NtReadFile,NtCreateProcess,NtCreateMutant,..
- Linux:
- 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%rsiy la cantidad de bytes a leer en%rdx - Pero en Windows no existe una función
read()en el kernel
- En Linux, al llamar a
- Si ejecutamos código que imprime el mismo "Hello World!" en Linux y en Windows:
- Linux llama a
putsdelibc.so, mientras que Windows llama aprintfdeucrtbase.dll - En Linux moderno, lo habitual es enlazarlo estáticamente, incluir la implementación de
putsdentro del binario y quelibc.sono se use en tiempo de ejecución
- Linux llama a
- 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.dllpara no comunicarse directamente con el kernel
- Las aplicaciones normales siempre dependen de
Runtime translation of Syscalls
- ¿Qué pasa si interceptamos una
syscall?
Si intervenimos cuando la aplicación llama aNtWriteFile(), luego llamamos awrite()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) yntdll.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.soy 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
syscallsy, técnicamente, no hay manera de impedir que las aplicaciones llamen asyscallsdirectamente
(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
Más allá del contenido, la calidad del resumen es realmente impresionante. Gracias.
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”).
Me alegra que desde
wine5.0KakaoTalk 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..
Sabía lo básico más o menos, pero me sorprende que expliquen Wine con tanto detalle... jaja
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)
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,
win32era la API multiplataforma más popular y exitosa.Pero ahora es la era de Electron/Wasm;;
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.
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).
Sí. Tal como dices... creo que sin darme cuenta lo limité a máquinas de la familia x86.
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..
222