Wie funktioniert Wine 101
(werat.dev)- Wine ist eine Kompatibilitätsschicht, die es ermöglicht, Windows-Programme auf POSIX-kompatiblen Betriebssystemen (Linux, macOS, BSD) auszuführen
- Auch Valves Steam Deck verwendet eine auf Wine basierende Lösung
WINE = Wine Is Not an Emulator
- Ein Emulator-Ansatz ist langsam, und tatsächlich können Linux/macOS Windows-Binärdateien nativ ausführen (wenn man ihnen ein wenig hilft)
- Ausführliche Erklärung, wie Linux-/Windows-Binärdateien mithilfe eines Debuggers funktionieren
Hello, Wine!
- Im Grunde ist Wine ein "Dynamic Loader" für Windows-Executable-Dateien
- Es ist eine native Linux-Binärdatei und weiß, wie EXE- oder DLL-Dateien verarbeitet werden müssen
- Wine lädt eine Windows-Executable-Datei in den Speicher, parst sie, ermittelt Abhängigkeiten und springt zu dem Code, der ausgeführt werden soll
- Allein damit lassen sich Windows-Binärdateien bereits ausführen, aber es gibt Ausnahmen
System Calls
- Systemaufrufe, sogenannte syscalls, machen Wine kompliziert
- syscalls werden vom Betriebssystem implementiert und befinden sich nicht in der Executable-Datei oder Bibliothek selbst
- Die vom Betriebssystem bereitgestellten syscalls sind die OS-API
- Linux: read, write, open, brk, getpid,..
- Windows: NtReadFile, NtCreateProcess, NtCreateMutant,..
- Systemaufrufe unterscheiden sich von normalen Funktionsaufrufen im Code. Das Öffnen einer Datei muss zum Beispiel im Kernel verarbeitet werden, weil dabei File Descriptors nachverfolgt werden
- Deshalb braucht Anwendungscode eine Möglichkeit, sich selbst zu "unterbrechen" und die Kontrolle an den Kernel zu übergeben ("Context Switch")
- Die vom Betriebssystem bereitgestellte Funktionsmenge und die Aufrufweise unterscheiden sich je nach OS
- Unter Linux müssen bei einem Aufruf von read() der File Descriptor in Register
%rdi, der Buffer-Pointer in%rsiund die Anzahl der zu lesenden Bytes in%rdxgelegt werden - Unter Windows existiert eine read()-Funktion im Kernel jedoch nicht
- Unter Linux müssen bei einem Aufruf von read() der File Descriptor in Register
- Wenn man denselben Code zum Ausgeben von "Hello World!" unter Linux und Windows ausführt
- Linux ruft puts aus libc.so auf, Windows printf aus ucrtbase.dll
- Auf modernem Linux wird heute häufig statisch gelinkt, sodass die puts-Implementierung in die Binärdatei eingebettet ist und libc.so zur Laufzeit oft gar nicht verwendet wird
- Unter Windows galt zumindest bis vor Kurzem: "Nur Malware nutzte Systemaufrufe direkt"
- Normale Anwendungen hängen immer von kernel32.dll/kernelbase.dll/ntdll.dll ab, damit sie nicht direkt mit dem Kernel kommunizieren
Runtime-Übersetzung von Syscalls
- Was wäre, wenn man syscalls abfängt?
Wenn sich eine Anwendung in den Aufruf von NtWriteFile() einklinkt, dann write() aufruft und das Ergebnis in dem vom Binary gewünschten Format zurückgibt? - Das wäre möglich, wenn man eine angepasste Version von ucrtbase.dll bereitstellt, aber dabei entstehen komplizierte Probleme
- Stattdessen wird ntdll.dll angepasst, die zwischen Binärdatei und Kernel sitzt
- Neuere Versionen von Wine bestehen aus ntdll.dll (PE-Binärdatei) und ntdll.so (ELF-Binärdatei)
- Die DLL ist eine dünne Schicht, die Aufrufe lediglich an die ELF-Seite weiterleitet
- Die ELF-Datei besitzt eine spezielle Funktion namens __wine_syscall_dispatcher, die den aktuellen Stack auf magische Weise von Windows nach Linux oder umgekehrt umwandelt
- Dieser syscall dispatcher ist die Brücke zwischen der Windows-Welt und der Linux-Welt
- Er verarbeitet Calling Conventions, reserviert Stack-Speicher, verschiebt Register und Ähnliches
- Sobald die Ausführung in ntdll.so angekommen und in die Linux-Binärdatei gewechselt ist, können wir die gesamte Linux-API nutzen
Ist das alles?
- Klingt sehr einfach, aber...
- Die Windows-API ist riesig, schlecht dokumentiert, enthält bekannte und unbekannte Bugs, und diese müssen unverändert erhalten bleiben. Der Großteil von Wine ist die Implementierung verschiedenster Windows-DLLs
- Es gibt verschiedene Arten, syscalls aufzurufen, und technisch gibt es keine Möglichkeit, Anwendungen daran zu hindern, syscalls direkt aufzurufen
(Man sollte daran denken, dass Windows-Spiele jeden denkbaren Wahnsinn anstellen)
Der Linux-Kernel besitzt dafür einen speziellen Mechanismus, was die Komplexität natürlich noch erhöht - Auch das Thema 32 Bit vs. 64 Bit ist absurd. Es gibt unzählige 32-Bit-Spiele, und sie werden nicht noch einmal als 64-Bit-Version neu veröffentlicht. Wine unterstützt beides, was die Komplexität weiter erhöht
- wine-server wurde hier noch gar nicht erwähnt. Das ist ein separater Prozess, den Wine erzeugt und der den "Zustand" des Kernels (File Descriptors, Mutexe usw.) verwaltet
- Will man Spiele ausführen, müssen auch DirectX, PulseAudio, Eingabegeräte usw. behandelt werden, also gibt es enorm viel zu tun
- Wine wird seit langer Zeit entwickelt und hat einen weiten Weg zurückgelegt. Heute lassen sich aktuelle Spiele wie Cyberpunk 2077 oder Elden Ring problemlos ausführen
Manchmal liefert Wine sogar eine bessere Performance als Windows
11 Kommentare
Der Inhalt ist zwar auch gut, aber die Qualität der Zusammenfassung ist wirklich enorm. Vielen Dank.
Ich nutze yes24 und Kyobo Book Centre, die beide einen abonnierbaren Leseservice anbieten.
Nachdem ich die Umgebung meines Heim-PCs auf Ubuntu umgestellt hatte, habe ich versucht, YES24 und Kyobo Book Centre mit Wine auszuführen.
Da beide ein separates DRM verwenden, fragte ich mich, ob sie überhaupt laufen würden. Aber YES24, das meines Wissens mit Qt erstellt wurde, lief problemlos, während das E-Book von Kyobo Book Centre nicht startete. (UI startet, DRM startet nicht)
Soweit ich weiß, ist bei beiden DRM angewendet, und ich habe darüber nachgedacht, warum das eine läuft und das andere nicht. Aber nachdem ich den obigen Artikel gelesen habe, glaube ich, es jetzt grob zu verstehen (dieses Meme mit „Ich habe es vollkommen verstanden“, na ja, so ungefähr).
Ich freue mich, dass KakaoTalk seit
wine5.0ohne jede Konfiguration läuft. (Unabhängig davon, dass ich KakaoTalk nicht unbedingt nutzen möchte ..)Es gibt zwar ein paar Probleme bei der Darstellung, aber Funktionen wie das Senden von Bildern über die Zwischenablage funktionieren nahtlos.
Insgesamt scheint sich Wine vor allem auf das Ausführen von Spielen zu konzentrieren, aber es ist schön, dass auch verschiedene Apps gut laufen.
Selbst wenn über die Einführung von Linux in öffentlichen Einrichtungen gesprochen wird, scheint man nicht einmal an eine Linux-Version von KakaoTalk zu denken – das ist schon ziemlich enttäuschend ..
Eine Mac-Version haben sie dagegen im Handumdrehen herausgebracht ..
Ich kannte zwar grob, wie es funktioniert, aber es ist schon faszinierend, dass Wine hier so detailliert erklärt wird .. haha
Da Wine Windows-Programme im Großen und Ganzen gut ausführt, wäre dann nicht auch die Idee denkbar, mit Wine plattformübergreifende Apps zu entwickeln? (nur für Desktop)
Soweit ich weiß, wurde vor langer Zeit sogar Hancoms HWP auf Basis von Wine für Linux portiert und veröffentlicht. (Bei R4 gab es eine separate
win32-kompatible Bibliotheks-Schicht, und ich bin mir nicht mehr sicher, ob Wine bei R5 oder 2002 verwendet wurde.)Deshalb gab es eine Zeit lang auch den Spruch, dass
win32dank Wine die populärste und erfolgreichste Cross-Platform-API sei.Aber inzwischen ist die Zeit von Electron/Wasm;;
Etwas anderes, aber falls Sie das tun möchten: Da die Lizenz von Wine die LGPL ist, müssen Sie je nach Art und Weise, wie Sie den Code schreiben, möglicherweise Teile oder den gesamten Quellcode offenlegen.
Wie auch im Original erklärt wird, ist Wine kein Emulator, weil es die CPU-Befehle unverändert verwendet. Das bedeutet, dass Software, die mit Wine ausgeführt werden kann, grundsätzlich Windows-Software ist, die auf x86- oder x86-64-CPUs läuft.
Angesichts der aktuellen Lage, in der Apple den gesamten Mac auf die ARM-Architektur umgestellt hat und auch Microsoft ein ARM-basiertes Entwickler-Kit auf den Markt bringt, ist es wohl etwas gewagt, Software, die nur auf x86(-64)-basierten CPUs läuft, als „plattformübergreifend unterstützt“ zu bezeichnen.
Ja. Wie Sie sagen … offenbar habe ich es, ohne es zu merken, auf Maschinen der x86-Familie beschränkt.
Da es Electron oder Tauri gibt, scheint das keine gute Wahl zu sein, wenn man von Anfang an plattformübergreifend entwickeln muss.
Falls es keine besonderen Einschränkungen gibt, die den Einsatz von webbasierten Technologien ausschließen,
wäre vielleicht die Nutzung einer Bibliothek wie Qt, die Cross-Compiling gut unterstützt, die bessere Wahl..
222