⏱️ Reading time: 14 min

On October 18, 2026, developer Thomas Frohwein sent an experimental port to the openbsd-ports mailing list that brings Wine on Linux to OpenBSD as well. The technical detail that made it possible: emulating the %gs segment register in software, because OpenBSD doesn’t allow setting its base directly. With that obstacle solved, dozens of 64-bit Windows programs (from Notepad++ to the Witcher 3 remaster) now run on a system that for three decades had no interest whatsoever in Windows compatibility.

📑 En este artículo
  1. TL;DR
  2. What Is Wine?
  3. Why the OpenBSD Port Matters
  4. How Wine Works Under the Hood
  5. Code Examples and How to Get Started with Wine on Linux
  6. Real-World Use Cases
  7. Common Mistakes and Best Practices
  8. Wine on Linux Compared to Other Alternatives
  9. Going Deeper: The %gs Register Problem and WoW64
  10. Frequently Asked Questions
    1. Does Wine on Linux Need a Windows License?
    2. What’s the Difference Between Wine and Proton?
    3. Why Do Some Windows Programs Not Work with Wine?
    4. Is It Safe to Install an Unknown .exe with Wine?
    5. Do 32-Bit Games Run on the New Wine Port to OpenBSD?
    6. Is CrossOver the Same as Wine?
  11. References

That this happens right when most Windows software is already 64-bit is no coincidence.

TL;DR

  • Wine translates Windows API calls into native POSIX calls, without emulating the processor.
  • An experimental port adds Wine to OpenBSD as of October 18, 2026, emulating the %gs register.
  • WoW64 still doesn’t work in that port: only 64-bit Windows programs run, not 32-bit ones.
  • WINEARCH and WINEPREFIX let you have several simulated Windows versions on the same machine.
  • Valve’s Proton and CodeWeavers’ CrossOver use the same translation engine as Wine.

What Is Wine?

Wine is an open-source compatibility layer that translates Windows API calls into equivalent calls on the host operating system, without emulating the processor or using a virtual machine; it lets you run Wine on Linux, macOS, FreeBSD, and, as of October 2026, OpenBSD too.

The project started in 1993, before Windows 95 even existed, originally designed to run 16-bit Windows 3.1 applications on Linux. Since then it expanded to macOS, FreeBSD, NetBSD, and Solaris; OpenBSD was, until this announcement, one of the few major Unix systems without even an experimental port.

The name is a recursive acronym, Wine Is Not an Emulator. The distinction matters because emulators like QEMU or DOSBox interpret another processor’s instructions one by one, which costs performance. Wine, instead, lets the processor execute the Windows program’s native x86 code as is; it only replaces the system libraries that program calls (kernel32.dll, user32.dll, ntdll.dll) with its own versions that translate each function to its Linux, macOS, or BSD equivalent.

That’s why a Windows program runs under Wine at nearly the same speed as on real Windows: the CPU doesn’t have to translate anything, only the operating system calls change destination. The WineHQ project also maintains a public catalog, the AppDB, where the community rates thousands of programs on how well they work before anyone installs them.

Wine started in 1993, two years before Windows 95. Foto de Gabriel Heinzer en Unsplash

Why the OpenBSD Port Matters

OpenBSD is, within the Unix world, the system most distrustful of outside code: its team prioritizes code auditing and isolation over compatibility. That project receiving a Wine port confirms a real shift: most of the Windows software people still need is already 64-bit, not 32-bit.

Frohwein himself sums it up in the announcement: there’s a growing interest in Wine different from that of 5 or 10 years ago, precisely because much of Windows software moved to 64-bit in that time. That simplifies the work of a new port. There’s no need to solve WoW64 (the layer that lets 32-bit binaries run on a 64-bit Windows) for the port to already be useful with current software.

In practice, the team successfully tested dozens of 64-bit programs, documented with screenshots and live recordings. The most striking case is the The Witcher 3 remaster, released just a month before the announcement, which runs by adding vkd3d-proton to translate Direct3D 12 calls to Vulkan.

How Wine Works Under the Hood

A Windows executable (.exe) uses the PE (Portable Executable) format. Wine includes its own PE loader: a program that reads that format, allocates memory for each section, and resolves which DLL each imported function needs, just like the real Windows loader would.

The difference lies in what’s behind each DLL. Wine reimplements Windows system libraries, it doesn’t copy Microsoft’s, as .dll.so libraries: they share the name and the functions a real DLL exports, but the code running inside translates each call to its POSIX equivalent. CreateFileW ends up calling open(); VirtualAlloc ends up calling mmap().

sequenceDiagram
    participant App as Windows App (.exe)
    participant Wine as kernel32.dll.so (Wine)
    participant Kernel as System Kernel
    App->>Wine: CreateFileW("data.txt")
    Wine->>Kernel: open("data.txt", O_RDWR)
    Kernel-->>Wine: file descriptor
    Wine-->>App: Windows HANDLE
    Note over App,Kernel: the CPU executes the exe's x86 code without translating instructions

That rewriting can go two ways when the program needs a DLL that Wine doesn’t fully reimplement: use the builtin version (Wine’s own) or load the native Windows DLL if the user copied it by hand, configurable per process with the WINEDLLOVERRIDES variable. This flexibility explains why some games need the user to copy a specific DLL, for example from .NET or Visual C++, to work: Wine prioritizes its own implementation, but can step aside for the original one when needed.

Code Examples and How to Get Started with Wine on Linux

On Debian or Ubuntu, the package is called wine64, and you should enable the 32-bit repositories even if you only plan to run 64-bit programs, because some of Wine’s base libraries are still 32-bit. On macOS, brew install --cask wine-stable installs the build maintained by Homebrew.

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install wine64 wine32:i386
wine --version

That last command confirms the installation worked: it prints something like wine-9.0 (the exact number depends on the version packaged by your distribution).

wine notepad.exe

The first time any Wine command runs, the program creates its configuration folder (the “prefix”) before opening the window. The terminal shows a line like this:

wine: created the configuration directory '/home/user/.wine'

That ~/.wine directory is a full virtual C: drive: that’s where the simulated Windows registry lives, the “Program Files” and “Users” folders, and the configuration controlled by winecfg.

WINEDEBUG=+loaddll wine notepad.exe 2>&1 | head -3

This enables the loaddll debug channel, which prints every library Wine resolves before opening the window. A typical line looks like this:

trace:loaddll:load_native_dll Loaded L"C:\windows\system32\kernel32.dll" at 0x7bc00000: builtin

The final word, builtin, confirms that particular DLL was resolved by Wine and not a native Windows copy.

#include <windows.h>
#include <stdio.h>

int main(void) {
    printf("Uptime reported by Wine: %lu ms\n", GetTickCount());
    return 0;
}
winegcc -o uptime uptime.c
./uptime

The output changes each run because GetTickCount() returns the milliseconds since the prefix started, but the format is always the same, for example Uptime reported by Wine: 48213028 ms. What matters here is that ./uptime is a native ELF binary, not a .exe: winegcc linked it directly against Wine’s Win32 implementation, so it runs without going through wine. This is Winelib, the other way of using the project besides running already-compiled Windows binaries.

To check which Windows version a given prefix is reporting, just ask cmd.exe to identify itself:

wine cmd /c ver

The response depends on the configuration chosen in winecfg (“Applications” tab); by default, recent Wine versions identify as Windows 10, with output similar to Microsoft Windows [Version 10.0.19043]. If a program needs to identify as a different version, changing it there usually fixes “unsupported operating system” errors.

💡 Tip: if you only need one specific program and don’t know where to start, try winetricks: it automates installing common dependencies (.NET, Visual C++, fonts) that many Windows installers assume already exist.
CodeWeavers has funded much of Wine’s development since 1996. Foto de CDC en Unsplash

Real-World Use Cases

The most widespread use of Wine on Linux today is gaming: Proton, the fork Valve maintains, adds layers to Wine like DXVK and VKD3D, translators from Direct3D to Vulkan, and it’s the foundation of the Steam games that run on Steam Deck without being compiled for Linux.

In corporate environments, the usual path is CrossOver, CodeWeavers’ commercial product built on the same engine: companies migrating from Windows to Linux but relying on an accounting or design program with no native version keep using it there, with paid support and compatibility profiles already tested by the vendor.

The OpenBSD port adds a third, more niche case: security administrators and users who choose OpenBSD for its auditing model but need one specific Windows tool without spinning up a full virtual machine for it. The thread itself recommends trying Notepad++, a lightweight text editor, first before attempting anything heavier.

Common Mistakes and Best Practices

  • Treating Wine as a CPU emulator: this confusion leads to expecting full compatibility with any architecture; Wine only translates the Windows API on the same x86/x86-64 architecture as the host.
  • Mixing everything into a single prefix: installing dozens of different programs into the default ~/.wine makes one installer break another’s configuration. Creating a separate WINEPREFIX for each complex program avoids that clash.
  • Not checking the AppDB before installing: WineHQ’s catalog classifies thousands of programs by compatibility level (Platinum, Gold, Silver, Bronze, Garbage); skipping that check means discovering known issues the hard way.
  • Running unknown installers as the regular user: Wine doesn’t isolate file access for the installer it runs by default. The OpenBSD port announcement itself recommends creating a separate unprivileged user to test new software, while exploring whether unveil(2) can limit which files each Wine process can see.
  • Assuming WoW64 already works in any port: in the OpenBSD port, 32-bit software still doesn’t run. Before trying a .exe, it’s best to check with file whether it’s PE32 (32-bit) or PE32+ (64-bit).

Wine on Linux Compared to Other Alternatives

Compared to a full virtual machine, Wine on Linux shares the same kernel as the host system: there’s no second operating system booting underneath, which is why a program opens almost instantly and without reserving a fixed amount of RAM.

OptionWhen to Use ItAdvantageLimitation
WineRun one specific Windows program on Linux, macOS, or BSDFree, starts fast, no Windows licenseCompatibility depends on the program (see AppDB)
Proton (Valve)Play Steam titles on Linux or Steam DeckAdds DXVK/VKD3D and game-oriented patchesDesigned for games, not office suites
CrossOver (CodeWeavers)Commercial support for a specific app at a companyPreconfigured profiles and paid supportHas a license cost; the engine is still Wine
Virtual machine (VirtualBox, VMware)Full compatibility is needed or several interdependent appsRuns real Windows, no compatibility surprisesUses more RAM and CPU; requires a Windows license
QEMU with CPU emulationThe software is for a different architecture (for example, ARM on an x86 PC)The only option when the instruction set changesMuch slower: translates every instruction, not just the API

Going Deeper: The %gs Register Problem and WoW64

The blockage that for years held back a Wine port to OpenBSD had to do with how Windows stores each thread’s data on x86-64. Windows uses the %gs segment register to point to the TEB (Thread Environment Block, the memory block holding each thread’s own data); any code, including Wine’s, needs that register pointing to the right place to work.

On Linux, Wine sets the base of %gs with a system call specific to that kernel, arch_prctl(ARCH_SET_GS). OpenBSD doesn’t expose an equivalent way to set that base from user space, something discussed in the earlier openbsd-tech thread that the announcement itself mentions. Without that piece, Wine’s loader couldn’t start any program.

flowchart TD
    A["Code using gs:[offset]"] --> B{"Architecture supports set gsbase?"}
    B -->|"yes (Linux: arch_prctl)"| C["Real TEB via segment register"]
    B -->|"no (OpenBSD)"| D["Intercept instruction with gs prefix"]
    D --> E["Rewrite the access against a TEB emulated in memory"]
    C --> F["Windows program runs"]
    E --> F

The solution the port proposes, attributed to Andrii, avoids fighting the kernel. Instead of getting OpenBSD to set the %gs base at the hardware level, Wine emulates in software every instruction that uses the %gs prefix, rewriting that access against a copy of the TEB it keeps in memory. It’s an emulation limited to a single instruction type, very different from emulating the whole processor the way QEMU does: the rest of the program keeps running with native x86-64 instructions, without going through any interpreter.

Something similar happens on Linux with native threads: glibc uses the %fs register to locate each thread’s local data (TLS), the same principle as %gs on Windows, except it points to a different structure. That’s why, when a Windows program runs under Wine on Linux, the system ends up using two segment registers with different roles at the same time: %fs for Linux’s native threads and %gs, emulated or not, for the Windows TEB the program’s code needs.

The remaining limitation is WoW64, the Windows (and Wine) layer that lets 32-bit binaries run on top of a 64-bit environment by translating between both calling conventions. Since the port doesn’t implement it yet, any 32-bit .exe or .dll is, for now, a no-op: it doesn’t even start. Before trying a program, it’s best to check its architecture with file, since a PE32 (32-bit) behaves very differently from a PE32+ (64-bit).

⚠️ Heads up: the OpenBSD port is still a draft submitted for review (it ends with a simple “ok?” in the email), not an official package in the ports tree yet. Trying it today means compiling it from the patch attached to the thread, not installing it with pkg_add.

Your next step: install wine64 in a disposable VM or container, run wine notepad.exe, and watch with WINEDEBUG=+loaddll which DLL it resolves before opening the window.

📬 Get new articles by email

We only email about big articles (1-2 a month).

Frequently Asked Questions

Does Wine on Linux Need a Windows License?

No. Wine doesn’t copy or distribute Microsoft code: it reimplements the system DLL functions from scratch. The project’s own official FAQ clarifies that running a program with Wine doesn’t require any Windows license, though you should check the license of the program you want to run.

What’s the Difference Between Wine and Proton?

Proton is the fork Valve maintains for Steam: it builds on Wine’s same translation engine and adds DXVK and VKD3D to translate Direct3D to Vulkan, plus game-specific patches. Many of those improvements eventually make their way back to the original project.

Why Do Some Windows Programs Not Work with Wine?

Because compatibility depends on which API functions each program uses. Software with kernel-level anticheat, custom drivers, or aggressive copy protection tends to fail because those pieces expect a real Windows kernel. Before installing something, it helps to check its rating in WineHQ’s AppDB.

Is It Safe to Install an Unknown .exe with Wine?

Not by default: Wine doesn’t automatically isolate which files the installer it runs can touch. The recommendation from the OpenBSD port announcement itself, creating a dedicated unprivileged user to test new software, applies to any system where Wine is used.

Do 32-Bit Games Run on the New Wine Port to OpenBSD?

Not yet. The port lacks WoW64, the layer that translates between 32-bit and 64-bit binaries, so any 32-bit .exe is a no-op. Only software natively compiled for 64-bit Windows runs.

Is CrossOver the Same as Wine?

CrossOver uses the same engine as Wine underneath, but it’s a commercial CodeWeavers product with paid support, already-tested compatibility profiles, and, often, patches that haven’t yet made it into the free version of the project.

References

  • openbsd-ports mailing list: the original announcement of the Wine port to OpenBSD, October 18, 2026.
  • WineHQ: the official Wine project site, with documentation and the AppDB compatibility catalog.
  • Official Wine FAQ: the project’s frequently asked questions, including the section on security and malware.
  • vkd3d-proton: the layer that translates Direct3D 12 to Vulkan used to run the Witcher 3 remaster on the port.
  • Wine (software) on Wikipedia: the project’s history and general architecture, active since 1993.

📱 Enjoy this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.

Featured image: Foto de Rob Wingate en Unsplash

Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.

Leave a comment
Categories: Tech NewsTutorials

Andrés Morales

Developer and AI researcher. Writes about language models, frameworks, developer tooling, and open source releases. Covers ML papers, the tech startup ecosystem, and programming trends.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

You can include code inside <code>…</code> or, for several lines, <pre><code>…</code></pre>.

This site uses Akismet to reduce spam. Learn how your comment data is processed.