1. 30

  2. 20

    WSL is not actually a subsystem in the classical NT sense. Mark R’s Windows Internals book has more detail, but the subsystem model was not ever intended to provide different syscall interfaces. In the *NIX world, libc may be shipped with the OS and maintained by the same people as the kernel (and, in *BSD, may depend on part of the kernel build) but it’s ‘just’ a userspace library. NT subsystems were somewhat like the combination of libc, CSU, and rtld on a *NIX system. Just as glibc and musl provide different loader functionality, different memory layouts, and different APIs, so do different Windows NT subsystems, though sitting on top of the same low-level NT kernel syscall interface.

    NT differs from *NIX in that most software never goes near the NT syscall interface, whereas most software calls thin C wrappers around the *NIX syscall interface directly (and may even issue syscall instructions in its own stubs, as the GNU OpenMP library does for futex calls on Linux). Both NT and Windows95 provided (almost) the same set of OS functions to Win32 applications, but had very different implementations. The POSIX subsystem provided a set of functions that looked like a *NIX libc but did not use a different syscall table. Whether you launched a Win32 or POSIX process on NT, the kernel did the same initial process setup, mapped the DLL for syscalls into your address space, and did some PE/COFF loading things.

    WSL, in contrast, provides an entirely different setup and system call path. This uses the picoprocess abstraction that was originally added to Windows for the Drawbridge library OS. A picoprocess starts with an almost empty address space and has a custom syscall table. Unfortunately, NT has only a single picoprocess handler and so the kernel can’t support two WSL-like things. This model is a lot closer to how FreeBSD’s Linux compat (and COMPAT32) layers work than the NT subsystem model. This is how WSL can efficiently implement things like fork: all of the process state (including the memory map) is controlled by the WSL layer and there’s no need for it to handle weird special cases resulting from Windows bits in the address space not understanding fork (as cygwin’s implementation does).

    1. 4

      more or less in agreement here, but felt much more comfortable recommending WSL2 to colleagues than WSL1 due to the reasons you mentioned

      WSL2 does have some nice integration, you can technically still call windows executables, and WSL2 should be able to pass STDIN and STDOUT around.

      For example: cat somefile.txt | clip.exe works great from within my Ubuntu 20.04 WSL2 instance

      1. 2

        WSL1 meant that the Windows 10 was the first version of Windows that lasted more than a few months on my work desktop. It was slow, and the integration was far from perfect, but given that I could get a usable terminal with all of my work in one place, it meant that I could use it for my work developing for linux, and for the other demands of my work, which was all windows based. It was much better than the Windows VM on linux solution that I had used prior to the introduction of WSL1.

        I haven’t used WSL2 but it really does seem like a step backwards, and I’m not sure that it’s a better solution than just running a Linux VM on windows, or vice-versa.

        1. 2

          There’s a whole spectrum of options between “use CMD” and “full Linux VM.” The most obvious one is cygwin, which provides a Linux like experience within Win32 and can be used for Windows system administration. MSYS is a lighter-weight form which is bundled with git. The article also doesn’t mention that WSL2 can pipe to Windows processes and can mount Windows file systems (via a redirector) so many scenarios really do work.

          Speaking as someone who’s in the same situation as the author (developing for Windows on Windows but having valued Linux shell capabilities) I’ve been building my own shell aiming to incorporate things I like on Linux into a native Windows form. This is closer to Windows than cygwin (uses Windows path separators, drive letters, etc) and can be seen at http://www.malsmith.net/yori/ .

          1. 1

            I was thinking recently, why didn’t MS implement NetBSD instead? They could have used the kernel headers directly (no need to comply with GPL), and the stark majority of the software that’s of interest for “Linux” developers runs on it as well.

            1. 4

              Because Linux has cachet, and BSDs don’t.

              1. 1

                It would be interesting to know whether NetBSD was approached for this.

                1. 1

                  WSL is ABI compatible with Linux. You download a distribution that Microsoft doesn’t directly author, such as Ubuntu, and run those exact same programs on a drop in replacement kernel. The issue with doing anything such as NetBSD is it implies software needs to be recompiled for the environment. That starts to offer an experience similar to cygwin, where somebody needs to manage a repository of ported packages and be continually submitting upstream patches to programs that make Linux specific assumptions. This is basically the experience on macOS. The hope of WSL was to go one better and provide compatibility without needing things to be explicitly ported to it.

                  1. 2

                    WSL is ABI compatible with Linux.

                    If you mean WSL1, then yes, but until it doesn’t. And the goalpost is moving with each new flag / syscall / ioctl / netlink option.

                    The issue with doing anything such as NetBSD is it implies software needs to be recompiled for the environment

                    Well, yes, but NetBSD has pkgsrc, and it’s not exactly a bare repository. And it runs on macOS too. Free work to profit off to!

                    EDIT: My point is that long-term WSL1 is unsustainable w/o Windows 10 Mobile using the same mechanism for Android compat. That ship has sailed, and so have the resources for re-impl of the linux ABI. WSL2 is the correct solution for Linux ABI compat.

                2. 1

                  I was pretty sure that you can run both types at the same time?

                  You aren’t constrained to only having one “flavour” at a time.