通常要装 Linux 系统,我们会通过虚拟机或系统启动盘安装,不过最近发现 Windows 系统提供了 WSL 的解决方式,可以直接在 Windows 系统上运行 Linux 的操作,比较方便简单且无需繁琐的切换,本文简单介绍一下。

1、WSL 介绍

WSL(Windows Subsystem for Linux),是在 Windows 10 以上系统能够原生运行 Linux 二进制文件(ELF 格式) 的兼容层。

WSL 提供了一个由微软开发的 Linux 兼容的内核接口,然后可以在其上运行 GNU 用户空间,例如 Ubuntu、openSUSE、Debian、Kali Linux。这样的用户空间可能包含 Bash shell 和命令语言,可以使用本机 GNU/Linux 命令行工具 sed、awk 等,编程语言解释器(Ruby、Python 等),甚至是图形应用程序。—— wiki

根据官方教程,安装完 WSL 之后,可以直接从 Microsoft Store 下载安装使用需要的 Linux 系统。比较好的体验是还可以通过 VSCode 打开 Linux 里的文件来做编辑。

遇到的一些麻烦,主要都是网络相关的配置,不过这些就逐个来解决就好了。

2、WSL 原理

Microsoft Windows NT(New Technology) 是微软设计的操作系统核心,自诞生以来,就被设计允许 Win32 等环境子系统向应用程序提供编程接口,而无需与内核内部的实现细节相关联。这使得 NT 内核在其初始版本中能够支持 POSIX、OS/2 和 Win32 子系统。早期的子系统被实现为用户模式模块,这些模块根据向该子系统的应用程序提供的 API 发出适当的 NT 系统调用。

2.1、系统调用

在用户模式中,将 Linux 二进制文件放置到 Pico 进程当中,来使 Linux 的系统调用可以被定向到 Windows 内核当中,lxss.sys 和 lxcore.sys 驱动程序会将 Linux 系统调用转换为 NT API 并模拟 Linux 内核。

LXSS 管理器服务是 Linux 子系统驱动程序的代理,也是 Bash.exe 调用 Linux 二进制文件的方式。特定用户启动的所有 Linux 进程都会进入 Linux 实例。该实例是一个跟踪所有 LX 进程、线程和运行时状态的数据结构。当 NT 进程第一次请求启动 Linux 二进制文件时,就会创建一个实例。一旦最后一个 NT 客户端关闭,Linux 实例就会终止。

Pico 进程是轻量级、安全的隔离容器。它从操作系统的进程地址空间构建,但移除了所有的操作系统传统的服务。Pico 进程和驱动程序为 WSL 提供了基础支持,可以加载 Linux 二进制文件,并在 Linux 兼容的系统调用层运行。

在 WSL 上,当从同一可执行文件进行系统调用时,Windows NT 内核会将请求转发到 lxcore.sys(遵循 Linux 的调用约定,检查 rax 寄存器以确定是哪个系统调用号)。在可能的情况下,lxcore.sys 将 Linux 系统调用转换为等效的 Windows NT 调用,从而完成繁重的工作。如果没有合理的映射,Windows 内核模式驱动程序必须直接服务该请求。

例如,Linux fork() 系统调用没有针对 Windows 的直接等效调用映射。当对 WSL 进行 fork 系统调用时,lxcore.sys 会执行一些初始工作来准备复制进程。然后,它调用内部 Windows NT 内核 API 以使用正确的语义创建进程,并完成新进程的附加数据复制。

2.2、文件系统

而 WSL 上的文件系统,是将所有的系统资源(文件、线程、共享内存、计时器等) 都归为对象来进行管理。所有文件操作的请求最终都会通过 NT 内核中的对象管理器,该对象管理器将请求通过 I/O 管理器路由到正确的文件系统驱动程序。

WSL 必须提供 Linux 系统文件可以存在的地方,以及所需的所有功能,包括 Linux 权限、符号链接和其他特殊文件(例如 FIFOS);它必须提供对系统上 Windows 卷的访问(一般在 /mnt/ 下面可以找到);并且它必须提供特殊的文件系统,例如 ProcFs。为了实现这一点,WSL 有一个模仿 Linux 上的 VFS 的 VFS 组件。整体架构如下图所示。

3、WSL 1

WSL1 的设计没有硬件模拟/虚拟化(与 coLinux 等其他项目不同),WSL1 直接使用主机文件系统和硬件的某些部分。WSL1 无法运行所有 Linux 软件(如 32 位二进制文件)或在 WSL1 中未实现支持的特定 Linux 内核服务的软件。由于 WSL1 中没有“真正的” Linux 内核,因此无法运行内核模块(如设备驱动程序)。

4、WSL 2

WSL2 主要做了几个方面的优化:

  • file system performance。在文件处理 I/O 方面(git clone、cmake 等) 有着 2.5~20 倍速度上的优化。
  • full system call compatibility。解决了系统调用上的兼容性问题,官方说法是实现了 100% 的支持。
  • virtualization。提升了虚拟化的能力,它是集成而非独立的虚拟化容器,可以只在需要时运行。

当然并不是只有优势,由于使用了虚拟化的能力,WSL2 在交叉编译、内存消耗、网络桥接等方面,是比 WSL1 差一些的,可以按这篇文档的描述按需选用。

参考