Глава 1. Архитектура WSL

Для получения максимальной выгоды от Подсистемы Windows для Linux полезно разобраться с лежащей в её основе архитектурой и её историей. Если вы планируете врубиться в WSL или просто развернуть её в своём предприятии, всё это необходимо знать. В этой главе мы рассмотрим архитектуру WSL 1 и WSL 2, как мы тут оказались, а затем погрузимся в некоторые новейшие функциональные возможности платформы WSL.

Сопоставление WSL1 с WSL2

WSL 1 создаёт среду Linux в Windows применяя уровень трансляции исполняемого кода Linux. WSL 2 делает это при помощи легковесной платформы виртуализации на основе Hyper-V. Обе они уникальны и предоставляют обворожительные подходы для получения взаимодействия Linux и Windows.

Драйверы ядра

При включении WSL в Windows 10, Windows 10 загружает два драйвера ядра NT (Рисунок 1-1). Этими драйверами выступают Lxss.sys, некий драйвер заглушки, загружаемый в самом начале процесса запуска и LxCore.sys, полный драйвер WSL, который загружается позднее в процессе запуска.

 

Рисунок 1-1


Схема архитектуры WSL1

Пико процессы

Приложения Linux в WSL выполняются в пико процессах, виртуальных пространствах с малым весом, создаваемыми в пространстве пользователя Windows. LxCore.sys действует в качестве пико поставщика, имитирующего некую среду Linux в этом виртуальном пространстве изнутри пико процессов WSL. LxCore.sys к тому же выполняет трансляцию системных вызовов в WSL1, которая более подробно обсуждается далее.

Запускаемые в пико процессах приложения Linux полностью не осведомлены о том, что они выполняются в Windows. Технология пико процессов теоретически может применяться аналогично для имитации среды любой операционной системы. Аналогичная технология пико процессов применяется Microsoft чтобы позволять Windows 10 IoT запускать наследуемые приложения Windows CE и применялась, наоборот, для портации сервера Microsoft SQL в Linux.

Диспетчер Lxss

LxssManager (Диспетчер Lxss) это служба Windows (Рисунок 1-2) которая обслуживает в качестве брокера LxCore.sys. Некий вызов NT для запуска исполняемого кода Linux маршрутизируется LxssManager в LxCore.sys. LxssManager к тому же выполняет мониторинг состояния пользователя WSL и обеспечивает гладкую установку и деинсталляцию дистрибутивов WSL (Рисунок 1-2).

 

Рисунок 1-2


Свойства службы LxssManager

Трансляция системных вызовов в WSL1

LxCore.sys обязан транслировать системные вызовы Linux из приложений Linux в системные вызовы NT. Системные вызовы это запросы нижнего уровня, осуществляемые скомпилированным исполняемым кодом в ядро некой операционной системы для выполнения таких задач, как распределение памяти, открытие файлов и считывание с устройств.

Для считывания создаваемых неким простым приложением системных вызовов, установите в Ununtu под WSL strace:


$ sudo apt install strace -y
		

Затем запустите простое приложение через strace, выдавая отслеживаемый вывод получаемых системных вызовов в файл с названием output.txt:


$ strace -o output.txt echo 'hello world'
		

Затем вы можете прочесть полученный вывод strace при помощи cat:


$ cat output.txt
		

И вы сможете обнаружить системные вызовы Linux, выполняемые простым echo "hello world" (Рисунок 1-3).

 

Рисунок 1-3


Системные вызовы, выполняемые командой echo ‘hello world’

Эти системные вызовы вовлечены в выполнение запускаемого кода, открытии файлов, выделении памяти и написании вывода в вашей консоли.

И ядро Linux, и ядро Windows NT, оба были созданы в ранние 1990е. Linux был создан Линусом Торвальдом в 1991, вдохновлённым MINIX, исследовательской операционной системой, которая сома по себе была воодушевлена Unix из Bell Labs. Ядро Windows NT было разработано командой Microsoft под руководством Дэвида Н. Катлера, чья базовая подготовка в Digital Equipment Corporation на операционной системе VMS значительно повлияла на проектирование NT. Как и Linux, NT изначально разрабатывался как совместимый со стандартами POSIX. Как и Linux, NT также обладал отличающимися режимами исполнения, режимом привилегированного ядра и режимом непривилегированного пользователя. Несмотря на очень различающиеся реализации, ядра NT и Linux подвергались воздействию одних и тех же теорий операционных систем и тенденций в ранние и средние 1990е.

Вопреки различиям в их реализации, благодаря их общей приверженности в некоторых ситуациях имеют место прямые трансляции системных вызовов Linux в NT. При работе исполняемого кода Linux в пико процессах и наличии системных вызовов Linux в NT в соотношении 1 к 1, они могут передаваться напрямую через LxCore.sys в имеющееся ядро NT (Рисунок 1-4).

 

Рисунок 1-4


Диаграмма обработки системных вызовов в WSL1

При отсутствии соответствия 1 к 1 системных вызовов Linux в NT, однако когда аналогичный системный вызов NT имеется для некого системного вызова Linux, LxCore будет транслировать такой системный вызов Linux в некий системный вызов NTпреобразуя или перерабатывая такой системный вызов Linux в некий системный вызов NT.

В прочих ситуациях, когда не существует эквивалентного системного вызова для Linux, LxCore обязан обрабатывать такой системный вызов самостоятельно. Он обрабатывается в реализации стерильной комнаты API ядра Linux и не содержит никакого кода ядра Linux.

Не все возможные системные вызовы Linux реализованы в WSL1 и некоторые из большинства невразумительных системных вызовов и вовсе не могут быть реализованными. WSL1 достигает близкой к 90% двоичной совместимости в Linux при помощи своего уровня трансляции. Для ранних разработок WSL1 для удостоверения совместимости Linux использовался проект тестирования Linux/

WSL2

WSL2 это разительно отличающийся по своей архитектуре от WSL1 подход. Применяя преимущества ядра Linux и обладающего малым весом контейнера Hyper-V, WSL2 разрешает многие из тех проблем, с которыми сталкиваются пользователи в WSL1, такими как несовместимость системных вызовов.

Hyper-V

WSL2 призван решать проблему полной поддержки системных вызовов для всех возможных системных вызовов Linux через реализацию истинного ядра Linux в некой обладающей малым весом платформе виртуализации, собранной в Hyper-V (Рисунок 1-5).

 

Рисунок 1-5


Диаграмма архитектуры WSL2

Hyper-V это естественная технология виртуализации, встраиваемая в само ядро Windows NT, эквивалентная естественной реализации виртуализации, такой как KVM в Linux или Hypervisor.Framework в macOS.

Hyper-V является гипервизором 1 типа, что означает, что он запускается на уровне самого ядра NT. Сторонние гипервизоры, такие как VirtualBox и VMware, выступают гипервизорами 2 типа, которые загружают драйверы уровня ядра, но в основном реализуются в пространстве пользователя.

Именно по этой причине Hyper-V и сторонние гипервизоры вступают в клинч. Вы не можете запускать VirtualBox и WSL2 в одной и той же установке Windows.

Платформа Виртуальной машины

WSL2 применяет вычислительную службу хоста Windows (WHCS, Windows Host Compute Service), некий собираемый на Hyper-V API и выставляемый через включение платформы виртуальных машин в Windows 10.

WSL2 определяет среду Linux с малым весом через некую последовательность вызовов API к своей Службе вычислений хоста (Host Compute Service), включая подключение виртуальных файловых систем и виртуальных сетевых адаптеров.

В противоположность WSL1, где системные вызовы на открытие файлов или открытие сетевых портов в WSL1 обрабатываются непосредственно самим ядром NT, вызовы на открытие файлов или сетевых портов в WSL2 обрабатываются ядром Linux, которое затем взаимодействует с виртуальными устройствами Hyper-V.

Вызовы на открытие файлов в WSL2 напрямую отсылаются в соответствующее ядро Linux, которое взаимодействует с некой виртуальной файловой системой, эмулируемому Hyper-V. Такая виртуальная файловая система это некий образ жёсткого диска, монтируемого как некое виртуальное блочное устройство, поверх которого хранится соответствующая файловая система. Это предоставляет бо́льшую производительность и меньшие накладные расходы, нежели эмуляция физического устройства IDE, SATA или NVMe.

Вызовы на открытие некого сетевого порта в WSL2 напрямую отправляются в ядро Linux, которое взаимодействует с неким эмулируемым Hyper-V виртуальным сетевым адаптером.

Вы можете просмотреть свои виртуальные файловые системы и сетевые адаптеры в WSL2 запустив


$ lshw
		

Соответствующие драйверы устройств для таких виртуальных файловых систем и устройств Hyper-V были включены в восходящий поток ядра Linux начиная с 2009 года. Вот некий образец виртуального сетевого адаптера:


    *-network:0
       description: Ethernet interface
       physical id: 1
       logical name: eth0
       serial: 00:10:4d:eb:01:ab
       size: 10Gbit/s
       capabilities: ethernet physical
       configuration: autonegotiation=off broadcast=yes driver=hv_netvsc duplex=full firmware=N/A ip=172.24.18.219 link=yes multicast=yes speed=10Gbit/s
		

Ядро WSL2

Само ядро Linux в WSL2 это слегка видоизменённое ядро Linux для запуска в соответствующей среде на основе Hyper-V. Его исходный код сделан доступным под GPL 2/0 в https://github.com/microsoft/WSL2-Linux-Kernel. Обновления для этого ядра Linux в WSL2 предоставляются в обновлениях Windows (Рисунок 1-6).

 

Рисунок 1-6


Снимок экрана Windows Update в настройках Windows 10

Некоторым пользователям всё ещё требуется вручную устанавливать своё ядро WSL2 (Рисунок 1-7) из некого установщика при обновлении с предыдущей версии Windows 10, выгружая его с https://aka.ms/wsl2kernel. Также доступна версия ядра WSL2 для устройств ARM64.

 

Рисунок 1-7


Снимок экрана установщика ядра подсистемы Windows для Linux 2

Сборка вашего собственного ядра для WSL2 подробно описывается в Главе 8, Следуем далее с WSL2.

Сопоставление WSL1 с WSL2

Доступность

WSL1 в настоящее время доступен в большинстве версий Windows 10, включая Windows Server 2019. WSL1 является единственным вашим выбором в Windows 10 с 1709 по 1809.

WSL2 доступен в Windows 10 с обновления 10 мая 2019, известного как версия 1903 с применением последних обновлений, специфично собравших 18362.1049 и выше. Если вы работает с этой версией Windows 10 или более высокой, я настоятельно рекомендую вам попробовать WSL2.

WSL2 первоначально была запущена 10 мая 2020 в обновлении Windows 10 версии 2004, однако позднее в 2020м получило ретроподдержку Windows 10 версии 1903 10 мая 2019.

Зачем вам выбирать WSL1

WSL1 обладает меньшими накладными системными расходами, нежели WSL2. Она может оказаться наилучшим выбором для машины с меньшими системными ресурсами, например, Surface Go, в которых потребление электричества имеет преимущество над производительностью.

WSL1 также обладает упрощённой сетевой средой по сравнению с WSL2. WSL1 просто приспосабливает имеющуюся конфигурацию сетевой среды ваших машин хостинга Windows, в то время как WSL2 обязана реализовывать сетевую среду NAT целиком внутри своей виртуальной среды, что может усложнять некоторые рабочие нагрузки.

[Замечание]Замечание

NAT это сокращение от Network address translation. Всякий дистрибутив WSL2 обладает своим собственным адресом IP, который доступен с того устройства Windows, в котором он доступен. Windows транслирует исходящие подключения на предмет того как они поступают из своего устройства Windows.

WSL1 обладает совместимостью с большим числом приложений Linux. Когда вы ограничены WSL1, вам не следует пугаться. Она всё ещё допустима для некоторых пользователей. Тем не менее, обратите внимание на то, что она не ожидает получения новых функциональных возможностей.

Зачем вам выбирать WSL2

Если ваши приложения, такие как Docker или Microk8s нуждаются в ней, вам следует выбирать WSL2. WSL2 более производительна нежели WSL1, причём со значительным множителем. Если вы желает максимизировать производительность WSL, тогда WSL2 это прорыв для вашего рабочего потока.

WSL2 обладает более сложной настройкой сетевой среды по сравнению с WSL1. WSL2 реализует некую сетевую среду NAT целиком внутри своей виртуальной среды. Для соединения со службами WSL2 из прочих устройств требуются дополнительные шаги, нечто, что необходимо держать на уме при планировании своего развёртывания WSL или при миграции с WSL1 в WSL2.

WSL2 к тому же позволяет вам компилировать и запускать ваше собственное ядро Linux когда вам требуются функциональные возможности, которые по умолчанию не предоставляются ядром WSL2 Microsoft.

Будущее WSL

В 2020 году было заявлено о новых архитектурных изменениях в WSL2. Главным из них выступает поддержка вычислительных задач для GPU, которые ускоряются при помощи DirectX, Direct3D, and DirectML. Поддержка для OpenGL, OpenCL и Vulkan ожидается позднее. Такие новые вычислительные функциональные возможности GPU потребовали обновления ядра WSL2 и того, как устройства GPU обрабатываются в WSL2. Это знаменует собой следующее важное архитектурное развитие с момента появления WSL2.

Вычисления GPU

Windows 10 собирается с поддержкой вычислений GPU, которая была выпущена в Insider Dev Channel в июне 2020 и ожидается в качестве функциональной возможности в выпуске Windows 10 в 2021.

Такая новая функциональность вычислений GPU основывается на паравиртуализации GPU в среде WSL2. Ускорение GPU сделает возможным целую новую категорию движимых GPU рабочих нагрузок вычислений, искусственного интеллекта, машинного обучения и статистического анализа в WSL.

Детали настройки ускоряемых GPU рабочих потоков приводятся в Главе 10, Применение WSL для корпоративной разработки.

/dev/dxgkrnl

Паравиртулизируемое GPU вооружается новым устройством ядра Linux. Новое устройство ядра Linux, /dev/dxgkrnl, предоставляет некую последовательность вызовов устройства, которые аналогичны тому, что предоставляет DirectX ядру Windows NT через WDDM (Windows Display Driver Model). Это позволяет API и написанным драйверам работать с WDDM для его запуска внутри WSL.

/dev/dxgkrnl подключается извне среды WSL через соответствующую шину ВМ Hyper-V (Рисунок 1-8) при помощи протокола паравиртуализации WDDM. /dev/dxgkrnl затем взаимодействует поверх шины ВМ напрямую с dxgkrnl, компонентом DirectX в самом ядре NT,который передаёт запросы в драйвер режима ядра GPU и в конечном счёте в само GPU.

 

Рисунок 1-8


Диаграмма реализации DirectX в WSL2

Само ядро NT воспринимает процессы GPU в WSL и Windows равными и будет между ними динамически выделять доступные ресурсы GPU. /dev/dxgkrnl это проходной драйвер, аналогичный до некоторой степени драйверам графического ускорения в прочих виртуальных платформах, таких как VirtualBox.

В /dev/dxgkrnl в настоящее время поддерживаются лишь вычисления GPU и построение изображений за экраном; нет возможностей отображения. Ознакомьтесь с приводимым ниже относительно дополнительной и официальной поддержки, поступающей со стороны WSL2.

/dev/dxgkrnl не содержит DirectX, однако он является открытым исходным кодом, доступным через https://github.com/microsoft/WSL2-Linux-Kernel/tree/linux-msft-wsl-4.19.y/drivers/gpu/dxgkrnl. Microsoft инициировал данный процесс для этого драйвера как отправляемый в "восходящий поток" сопровождения ядра Linux.

Вычисления GPU в настоящее время требуют по крайней мере сборки 20150 Windows 10 и осведомлённого о WSL драйвера для Windows от вашего производителя набора микросхем GPU. Бета драйверы для наборов микросхем GPU nVidia доступны через программу разработчиков nVidia. В конечном счёте эти драйверы будут выпущены через обновление Windows.

Direct3D 12

Direct3D является частью DirectX. Direct3D это API реального времени для построения трёхмерной графики в приложениях и играх. Это расширение WDDM для Linux позволяет Microsoft портировать свой API Direct3D 12 в Linux. Полная библиотека Direct3D скомпилирована под Linux из исходного кода для библиотеки Windows Direct3D. В настоящее время Direct3D может применяться лишь для построения изображений вне экрана; следите за последующими сведениями официальной поддержки GUI, поставляемой для WSL2.

DirectML

DirectML это часть DirectX. DirectML выступает API нижнего уровня для машинного обучения, который должен быть знаком искушённым в DirectX разработчикам. DirectML поддерживается всем совместимым с DirectX оборудованием. В отличии от CUDA, которому требуется GPU nVidia, DirectML работает в GPU Intel и AMD. Совместно с портацией DirectML в WSL, Microsoft также выпустила предварительный обзор TensorFlow с DirectML в его основе. Microsoft работает с сообществом TensorFlow над восходящим потоком основы своего DirectML.

OpenGL и OpenCL

Большинство графических построений в Linux применяет API OpenGL и OpenCL с открытым исходным кодом. Microsoft совместно с Collabora работал над предоставлением уровней соответствия для OpenGL и OpenCL поверх DirectX через библиотеку с открытым исходным кодом Mesa (Рисунок 1-9). Это позволит приложениям OpenGL и OpenCL бесшовно ускоряться DirectX при исполнении в WSL. Эта работа не завершена и будет поступать в обновлениях в библиотеку Mesa в будущем. После того как подобные Ubuntu дистрибутивы обновятся на новые библиотеки Mesa, трёхмерное ускорение для OpenGL и OpenCL будет автоматическим. Microsoft высказался о том, что они всё ещё изучают как лучше поддерживать Vulkan в WSL.

 

Рисунок 1-9


Диаграмма реализации OpenGL и OpenCL в WSL2

CUDA nVidia

CUDA выступает кроссплатформным API параллельной обработки, созданного nVidia. Microsoft работал с nVidia над построением версии CUDA для Linux, которая нацелена на уровень WDDM через драйвер /dev/dxgkrnl (Рисунок 1-10). Это предоставляет ускорение CUDA таким приложениям как TensorFlow в WSL и контейнерам Docker, запущенным со средой времени исполнения nVidia.

 

Рисунок 1-10


Диаграмма реализации CUDA в WSL2

Библиотеки

Те библиотеки, которые требуются для доступа к расширенным функциональным возможностям GPU в WSL накладываются в файловую систему WSL в /usr/lib/wsl/lib для дистрибутивов на основе glibc. Не требуются никакие особенные для Linux драйверы. Такие дистрибутивы как Alpine, которые применяют musl libc вместо glibc, в настоящее время не поддерживаются.

Библиотека Direct3D (libd3d12), DirectML (libdirectml), CUDA (libcuda), а также связанный с нею портированный в Linux драйвер, DxCore (libdxcore) не являются открытым исходным кодом.

Поддержка GUI

В сборке 2020 Microsoft также анонсировал, что в WSL2 будет поставляться официальная поддержка GUI. Как подробнее описывается в Главе 7, Персонализация WSL при помощи основанного на Windows X сервера, такого как VcXsrv или X410, сегодня можно запускать некое приложение с графическим интерфейсом в WSL1 и WSL2. Дополнительные подробности относительно официального сопровождения GUI под WSL2 поступят в 2021 году.

Мы знаем, что в предстоящей поддержке графического интерфейса будет применяться компоновщик Wayland на основе Weston, а также будет включена поддержка PulseAudio. Компоновщик Microsoft будет пересылать необработанные элементы поверх RDP своему клиенту RDP, встроенному в Windows (Рисунок 1-11). Собственно графическая визуализация происходит в Windows. Все визуально отображаемые элементы графического интерфейса Linux, включая окна приложений, прорисовываются Windows при помощи графического процессора вашего компьютера. Windows также будет прослушивать ввод с клавиатуры и мыши для передачи обратно в Linux.

 

Рисунок 1-11


Схема поддержки приложения Wayland в WSL2

Основанный на Weston компоновщик Microsoft будет поддерживать Xwayland, уровень совместимости для приложений Linux с графическим интерфейсом, собираемом под библиотеки Xorg (Рисунок 1-12). Wayland содержит некий Xserver, который пользуется устройствами ввода Wayland и переправляет вывод на поверхности Wayland.

 

Рисунок 1-12


Схема поддержки приложения Xorg в WSL2

На момент написания этих строк Microsoft применял канал RAIL (Remote Application Integrated Locally, Интегрированного локально удалённого приложения) своего RDP (Remote Desktop Protocol) для отправки графических данных из Linux в Windows. Microsoft намерен предложить некое расширение RDP с названием VAIL (Virtual Application Integrated Locally, Интегрированного локально виртуального приложения), который в настоящее время используется только между клиентами Windows (Рисунок 1-13).

 

Рисунок 1-13


Схема RDP поверх VAIL

Когда VAIL достигнет вверх стандарт RDP, тогда, вместо применения канала RAIL для отправки графических данных, буфер видео кадра можно копировать непосредственно из Linux в Windows. Это впечатляющим образом улучшит производительность графического интерфейса аналогично технологии Intel GVT-g. Также могут иметься и прочие приложения для взаимодействия удалённых и виртуальных рабочих столов между Windows и Linux. Microsoft заявила, что их компоновщик Wayland, разработки во FreeRDP и расширение RDP будут обладать открытым исходным кодом.

Microsoft также анонсировал что в WSL2 совместно с поддержкой графического интерфейса будет выполняться поддержка аудио, предоставляемая минимальным уровнем PulseAudio, запускаемом в специальном прицепном контейнере, который требуется сокету домена UNIX для монтирования взаимодействия с вашим дистрибутивом WSL2.

Стремление к применению настоящего ядра Linux с открытым исходным кодом при продвижении вверх открытых протоколов представляет собой впечатляющий сдвиг для Microsoft. Разобравшись с архитектурой WSL1, и тем как их части работают вместе, мы можем начинать осознавать в своих последующих главах как применять эти части для удовольствия и извлечения прибыли.