天天看点

Windows Linux子系统

原文链接:https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/

  我们最近宣布了Windows平台上的Ubuntu上的Bash,它使本机Linux ELF64二进制文件可以通过Windows Linux子系统(WSL)在Windows上运行。该子系统是由Microsoft Windows内核团队创建的,并引起了很多兴奋。我们被问到的最常见问题之一是这种方法与传统虚拟机有何不同。在系列博客文章的第一篇中,我们将概述WSL,它将回答该问题和其他常见问题。在以后的文章中,我们将深入介绍所介绍的组成部分。代表Deepu Thomas发表。

  

  Windows子系统的历史自成立以来,Microsoft Windows NT旨在允许Win32之类的环境子系统向应用程序提供程序化接口,而无需与内核内部的实现细节联系在一起。这使得NT内核在其初始版本中支持POSIX,OS / 2和Win32子系统。

  

  早期的子系统被实现为用户模式模块,这些模块根据提供给该子系统应用程序的API发出适当的NT系统调用。所有应用程序都是PE / COFF可执行文件,是一组用于实现子系统API的库和服务,以及用于执行NT系统调用的NTDLL。当启动用户模式应用程序时,加载程序会基于可执行标头调用正确的子系统来满足应用程序依赖性。

  

  子系统的更高版本替换了POSIX层,以提供基于Unix的应用程序(SUA)的子系统。它由满足以下要求的用户模式组件组成:

  1、进程和信号管理

  2、终端管理

  3、系统服务请求和进程间通信

  

  SUA的主要作用是鼓励应用程序移植到Windows而无需大量重写。这是通过使用NT构造实现POSIX用户模式API来实现的。鉴于这些组件是在用户模式下构造的,因此对于内核模式系统调用(如fork())很难具有语义和性能奇偶性。由于此模型依赖于需要重新编译程序的需求,因此需要持续进行功能移植并且是维护负担。

  

  随着时间的流逝,这些最初的子系统被淘汰了。但是,由于Windows NT内核是为允许新的子系统环境而设计的,因此我们能够使用在该领域进行的最初投资并扩大它们来开发Linux的Windows子系统。

  

  Windows Linux子系统

  

  适用于Linux的Windows子系统WSL是使本机Linux ELF64二进制文件能够在Windows上运行的组件的集合。它包含用户模式和内核模式组件。它主要包括:

  1、处理Linux实例生命周期的用户模式会话管理器服务

  2、Pico提供程序驱动程序(lxss.sys,lxcore.sys)通过转换Linux syscalls托管未修改的用户模式Linux的

  3、Pico进程来模拟Linux内核(例如/ bin / bash)

  用户模式Linux二进制文件和Windows内核组件之间的空间就是神奇的地方。 通过在Pico进程中放置未修改的Linux二进制文件,我们使Linux系统调用可以定向到Windows内核。 lxss.sys和lxcore.sys驱动程序将Linux系统调用转换为NT API,并模拟Linux内核。

Windows Linux子系统

LXSS Manager服务

LXSS Manager服务是Linux子系统驱动程序的代理,也是Bash.exe调用Linux二进制文件的方式。 该服务还用于安装和卸载周围的同步,一次仅允许一个进程执行这些操作,并在操作挂起时阻止启动Linux二进制文件。

特定用户启动的所有Linux进程都进入Linux实例。 该实例是一个数据结构,可跟踪所有LX进程,线程和运行时状态。 NT进程第一次请求启动Linux二进制文件时,将创建一个实例。

最后一个NT客户端关闭后,Linux实例将终止。 这包括在实例内部启动的所有进程,包括守护程序(例如git凭据缓存)。

Pico进程

作为Project Drawbridge的一部分,Windows内核引入了Pico进程和Pico驱动程序的概念。 Pico进程是OS进程,不存在与诸如Win32 Process Environment Block(PEB)之类的子系统相关的OS服务的陷阱。 此外,对于Pico进程,系统调用和用户模式异常将分派给配对的驱动程序。

Pico进程和驱动程序为Linux子系统提供了基础,该Windows子系统通过将可执行的ELF二进制文件加载到Pico进程的地址空间中并在与Linux兼容的syscall层上执行来运行本机未修改的Linux二进制文件。

系统调用

WSL通过虚拟化Windows NT内核之上的Linux内核接口来执行未修改的Linux ELF64二进制文件。它公开的内核接口之一是系统调用(syscalls)。 syscall是内核提供的一项服务,可以从用户模式下调用。 Linux内核和Windows NT内核都向用户模式公开了数百个syscall,但是它们具有不同的语义,通常不直接兼容。例如,Linux内核包括fork,open和kill之类的东西,而Windows NT内核具有类似的NtCreateProcess,NtOpenFile和NtTerminateProcess。

Windows Linux子系统包括内核模式驱动程序(lxss.sys和lxcore.sys),这些驱动程序负责与Windows NT内核协同处理Linux系统调用请求。驱动程序不包含Linux内核中的代码,而是Linux兼容内核接口的无尘室实现。在本机Linux上,当从用户模式可执行文件进行syscall时,它由Linux内核处理。在WSL上,当从同一可执行文件进行系统调用时,Windows NT内核会将请求转发到lxcore.sys。在可能的情况下,lxcore.sys会将Linux syscall转换为等效的Windows NT调用,这又会导致繁重的工作。如果没有合理的映射,则Windows内核模式驱动程序必须直接为请求提供服务。

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

文件系统

WSL中的文件系统支持旨在满足两个目标。

提供支持Linux文件系统的完整保真度的环境

允许与Windows中的驱动器和文件互操作

适用于Linux的Windows子系统提供了类似于真实Linux内核的虚拟文件系统支持。两个文件系统用于提供对用户系统上文件的访问:VolF和DriveF。

VolFs

VolFs是一个文件系统,它完全支持Linux文件系统功能,其中包括:

可以通过诸如chmod和chroot之类的操作来修改Linux权限

指向其他文件的符号链接

Windows文件名中通常不包含字符的文件名

区分大小写

包含Linux系统,应用程序文件(/ etc,/ bin,/ usr等)和用户Linux主目录的目录均使用VolF。

不支持Windows应用程序与VolF中的文件之间的互操作性。

驱动器

DriveFs是用于与Windows互操作的文件系统。它要求所有文件名均为合法的Windows文件名,使用Windows安全性,并且不支持Linux文件系统的所有功能。文件区分大小写,用户不能创建名称仅按大小写不同的文件。

使用DriveF将所有固定的Windows卷安装在/ mnt / c,/ mnt / d等下。用户可以在这里访问所有Windows文件。这使用户可以使用自己喜欢的Windows编辑器(例如Visual Studio Code)来编辑文件,并同时使用WSL在Bash中使用开源工具来操作它们。

继续阅读