Comment fonctionne Wine 101
(werat.dev)- Wine est une couche de compatibilité qui permet d’exécuter des programmes Windows sur des OS compatibles POSIX (Linux, macOS, BSD)
- Le Steam Deck de Valve utilise lui aussi une solution basée sur Wine
WINE = Wine Is Not an Emulator
- L’approche par émulation est lente, et en réalité Linux/macOS peuvent exécuter nativement des binaires Windows (avec un petit coup de pouce)
- Explication détaillée, via un débogueur, de la façon dont les binaires Linux/Windows fonctionnent
Hello, Wine!
- Fondamentalement, Wine est un « chargeur dynamique » pour les exécutables Windows
- C’est un binaire Linux natif, qui sait comment traiter les EXE et les DLL
- Wine charge un exécutable Windows en mémoire, l’analyse pour identifier ses dépendances, puis saute vers le code à exécuter
- Rien qu’avec cela, il est déjà possible d’exécuter un binaire Windows, mais il y a une exception
System Calls
- Ce sont les appels système, appelés
syscalls, qui compliquent Wine - Les
syscallssont implémentés par l’OS, ils ne se trouvent ni dans l’exécutable ni dans une bibliothèque - Les
syscallsfournis par l’OS constituent l’API de l’OS- Linux : read, write, open, brk, getpid,..
- Windows : NtReadFile, NtCreateProcess, NtCreateMutant,..
- Un appel système est différent d’un appel de fonction ordinaire dans le code. Par exemple, l’ouverture d’un fichier doit être traitée par le noyau, car elle implique le suivi des descripteurs de fichier
- Le code applicatif a donc besoin d’un moyen de « s’interrompre » lui-même et de céder le contrôle au noyau (« context switch »)
- L’ensemble des fonctions fournies par l’OS et leur mode d’appel diffèrent selon l’OS
- Sous Linux, pour appeler la fonction
read(), il faut placer le descripteur de fichier dans le registre%rdi, le pointeur de tampon dans%rsiet le nombre d’octets à lire dans%rdx - Mais sous Windows, la fonction
read()n’existe pas dans le noyau
- Sous Linux, pour appeler la fonction
- Si l’on exécute sur Linux et Windows un code qui affiche le même « Hello World! »
- Linux appelle
putsdelibc.so, tandis que Windows appelleprintfdeucrtbase.dll - Sur Linux aujourd’hui, il est courant de faire un lien statique, donc l’implémentation de
putsest incluse dans le binaire etlibc.son’est généralement pas utilisée à l’exécution
- Linux appelle
- Sous Windows, du moins jusqu’à récemment, « seuls les malwares utilisaient directement les appels système »
- Les applications ordinaires dépendent toujours de
kernel32.dll/kernelbase.dll/ntdll.dllafin de ne pas communiquer directement avec le noyau
- Les applications ordinaires dépendent toujours de
Runtime translation of Syscalls
- Et si l’on interceptait les
syscalls?
Que se passerait-il si, lorsqu’une application appelleNtWriteFile(), on s’intercalait pour appelerwrite(), puis qu’on renvoyait le résultat dans le format attendu par le binaire ? - Ce serait possible en fournissant une version personnalisée de
ucrtbase.dll, mais cela soulèverait des problèmes complexes - À la place, on modifie
ntdll.dll, qui se trouve entre le binaire et le noyau - Les versions récentes de Wine se composent de
ntdll.dll(binaire PE) et dentdll.so(binaire ELF)- La DLL est une fine couche qui redirige simplement les appels vers la partie ELF
- La partie ELF possède une fonction spéciale appelée
__wine_syscall_dispatcher, qui fait la magie consistant à convertir la pile courante de Windows vers Linux, ou inversement
- Ce syscall dispatcher est le pont entre le monde Windows et le monde Linux
- Il gère la convention d’appel, alloue l’espace de pile, déplace les registres, etc.
- Une fois l’exécution arrivée dans
ntdll.sopuis passée au binaire Linux, on peut utiliser toutes les API Linux
C’est tout ?
- Cela semble très simple, mais…
- Les API Windows sont extrêmement nombreuses, mal documentées, avec des bugs connus et inconnus, et il faut les préserver telles quelles. La majeure partie du code de Wine est constituée des implémentations des différentes DLL Windows
- Il existe plusieurs façons d’invoquer les
syscalls, et techniquement il n’y a aucun moyen d’empêcher les applications d’appeler directement lessyscalls
(N’oubliez pas que les jeux Windows font toutes sortes de folies)
Le noyau Linux possède un mécanisme spécial pour gérer cela, ce qui augmente évidemment encore la complexité - Le problème du 32 bits contre le 64 bits est aussi absurde. Il existe d’innombrables jeux 32 bits, et ils ne seront jamais republiés en 64 bits. Wine prend en charge les deux, ce qui ajoute encore à la complexité
- On n’a même pas encore parlé de
wine-server. Il s’agit d’un processus séparé créé par Wine, qui maintient l’« état » du noyau (descripteurs de fichier, mutex, etc.) - Vous voulez exécuter un jeu ? Il faut alors gérer DirectX, PulseAudio, les périphériques d’entrée, etc., donc il y a énormément de travail
- Wine est développé depuis longtemps et a parcouru un long chemin. Aujourd’hui, il peut exécuter sans problème des jeux récents comme Cyberpunk 2077 ou Elden Ring
Il arrive même parfois que Wine offre de meilleures performances que Windows
11 commentaires
Au-delà du contenu lui-même, la qualité du résumé est vraiment impressionnante. Merci.
J’utilise yes24 et Kyobo Book Centre, qui proposent des services de lecture par abonnement.
Après avoir basculé l’environnement de mon PC personnel sur Ubuntu, j’ai essayé de lancer YES24 et Kyobo Book Centre avec Wine.
Les deux utilisent un DRM distinct, donc je me demandais s’ils allaient fonctionner, mais YES24, qui est apparemment développé avec QT, s’est bien lancé, alors que l’e-book de Kyobo Book Centre ne se lançait pas. (l’interface se lance, le DRM non)
Je savais que les deux appliquent un DRM, donc je me demandais d’où venait la différence entre ce qui fonctionne et ce qui ne fonctionne pas, mais en lisant l’article ci-dessus, j’ai l’impression de comprendre à peu près (le mème « j’ai parfaitement compris », en gros).
Depuis
wine5.0, KakaoTalk se lance sans aucune configuration, ce qui me réjouit. (Indépendamment du fait que je n’aie pas spécialement envie d’utiliser KakaoTalk...)Il y a quelques petits problèmes d’affichage, mais des fonctions comme l’envoi d’images via le presse-papiers marchent de manière fluide.
On dirait que Wine se concentre surtout sur l’exécution des jeux, mais c’est appréciable de voir qu’il fait aussi bien tourner diverses applications.
Même quand on parle d’adopter Linux dans les organismes publics, le fait qu’ils n’envisagent même pas une version Linux de KakaoTalk, c’est assez… franchement regrettable.
Ils ont pourtant sorti une version Mac en deux temps trois mouvements...
J’en connaissais les grandes lignes, mais c’est fascinant de voir Wine expliqué avec autant de détail… haha
En général, comme Wine exécute plutôt bien les programmes Windows, est-ce qu’on pourrait aussi imaginer créer des applications multiplateformes avec Wine ? (sur desktop uniquement)
Si je me souviens bien, il fut un temps où le HWP de Hancom avait aussi été porté pour Linux sur la base de Wine et commercialisé. (Pour R4, il y avait une couche de compatibilité win32 distincte, et je ne me rappelle plus très bien si c’est R5 ou 2002 qui utilisait Wine.)
C’est pourquoi, à une époque, on plaisantait en disant que grâce à Wine, win32 était l’API cross-platform la plus populaire et la plus réussie.
Mais maintenant, c’est l’ère d’Electron/WebAssembly ;;
C'est une histoire un peu différente, mais si vous voulez procéder ainsi, comme la licence de Wine est la LGPL, vous pourriez devoir publier une partie ou la totalité de votre code source, selon la manière dont vous l'écrivez.
Comme cela est également expliqué dans l’article d’origine, si Wine n’est pas un émulateur, c’est parce qu’il utilise directement les instructions du CPU. Cela signifie que les logiciels pouvant être exécutés avec Wine sont, fondamentalement, des logiciels Windows conçus pour fonctionner sur des processeurs x86 ou x86-64.
À l’heure où Apple a fait passer l’ensemble des Mac à l’architecture ARM et où Microsoft propose lui aussi un kit de développement basé sur ARM, il me semble un peu difficile de qualifier de « prise en charge multiplateforme » un logiciel qui ne fonctionne que sur des CPU basés sur x86(-64).
Oui. Comme vous le dites... j’ai l’impression m’être moi aussi, sans m’en rendre compte, limité aux machines de type x86.
Avec electron ou tauri, si l’on doit créer du cross-platform dès le départ, ça ne semble pas être un très bon choix.
S’il y a des contraintes particulières qui empêchent d’utiliser des technologies basées sur le navigateur web,
l’usage d’une bibliothèque comme Qt, qui prend bien en charge la cross-compilation, pourrait être préférable..
222