wsl

Windows Subsystem for Linux o como Windows 10 ejecuta nativamente software para GNU/Linux

Windows 10 es capaz de ejecutar nativamente binarios ELF de Linux sin modificaciones ni emulación ni virtualización. ¿Quieres ver cómo? ¡Hagamos un repaso completo empezando por los subsistemas del kernel de Windows NT!

7 min de lectura
Windows Subsystem for Linux o como Windows 10 ejecuta nativamente software para GNU/Linux

Windows 10 es compatible con Linux, sin virtualización ni emulación, o en otras palabras: ejecuta binarios ELF sin modificaciones. Aunque esta poderosa característica no es nueva, la verdad es que lleva un tiempo sorprendiéndome mucho lo relativamente poco conocida que es, por lo que he considerado dedicarle una publicación para hablar de ella.

Empecemos por, ¿cómo es posible esto?

Los subsistemas del kernel de Windows NT

Aunque Windows NT haya desaparecido como nombre de producto y sistema operativo, su tecnología sigue muy presente; y es que a día de hoy el kernel que tenemos en Windows 10 es una evolución de la línea y familia de Windows NT.

A diferencia de Windows 9x, que tenía severas penalizaciones para mantener la compatibilidad con DOS y Win16, NT establecía un diseño robusto y potente libre de obligaciones para mantener compatiblidades: kernel híbrido, preemtivo, portable (x86, x64, ARM, Itanium, Alpha, MIPS y PowerPC) y con distintos subsistemas.

El ambicioso objetivo de los subsistemas del kernel de Windows NT era darle la capacidad de ejecutar nativamente aplicaciones de otros sistemas operativos sin modificación alguna. Así pues, Windows NT salió al mercado con 3 subsistemas:

  • Win32. Ejecuta aplicaciones Windows de 32 y 64 bits. Es el que utilizan las aplicaciones nativas para Windows. Si se ejecuta en arquitectura x86, este subsistema también puede correr aplicaciones Win16 y DOS a través de la NT Virtual Dos Machine. A día de hoy se mantiene intacto en con Windows 10.
  • OS/2. Ejecuta aplicaciones 16 bits en modo texto para OS/2 1.x y mediante un addon también las de entorno gráfico. La última versión de Windows en soportar este subsistema fue Windows 2000.
  • POSIX. Ejecuta aplicaciones escritas para el estandar POSIX.1. Este subsistema evolucionó de la mano de Interix en lo que sería conocido durante muchos años como los Windows Services for UNIX, que finalmente han sido descatalogas en favor del Windows Subsystem for Linux que este artículo nos ocupa.

La siguiente imagen del genial artículo de arquitectura del kernel de NT en Wikipedia muestra una visión simplicada de alto nivel sobre la arquitectura del kernel:
wsl4

Windows Subsystem for Linux

Que el kernel de Windows NT estuviera preparado para ejecutar software de otros sistemas operativos sentaba una muy buena base para materializar la compatibilidad Linux, pero Microsoft ha trabajado muchísimo hasta llegar a este punto.

Para conocer en detalle cómo son los internals de la implementación de este subsistema recomiendo las publicaciones de Microsoft y Jessie Frazelle. Por otro lado Microsoft dispone de un blog oficial de WSL, que... bueno, no actualizan mucha frecuencia y un repositorio de Github -este sí, con mucha actividad- destinado a informar de problemas encontrados en el subsistema.

Una vez hecho el recorrido por la historia hasta llegar aquí, ¡vamos a ver lo insultántemente fácil que es poner a punto nuestro Windows 10 para ser compatible con Linux!

Requerimientos

Son muy sencillos: Windows 10 1607 x64, recomendando servidor encarecidamente la versión 1709 como mínimo y a ser posible la más actual, 1803 en el momento de escribir estas líneas. El motivo es que el subsistema ha estado recibiendo sustanciales mejoras con cada nueva versión de Windows 10.

Más allá de que necesitemos arquitectura Intel de 64 bits, el subsistema se puede instalar en cualquiera de las ediciones de Windows 10, a excepción de la S.

Instalación

La instalación se lleva a cabo en dos pasos muy sencillos:

  1. Debemos activar la característica de Windows Subsystem for Linux. Tal y como podemos ver aquí:
    wsl5
  2. Abrimos la Microsoft Store y una simple búsqueda de la palabra linux nos arrojará resultados de las distribuciones que tenemos disponibles para instalar.
    wsl6
  3. Pulsamos Get u Obtener y comienza la descarga e instalación de la distribución. Se nos creará un icono en el menú de inicio.

Una gran noticia aquí es que no estamos limitados a seleccionar una sola distribución. El subsistema nos permite ejecutar al mismo tiempo instancias de múltiples distros, por ejemplo: openSUSE y Debian al mismo tiempo.

Arracando bash

Bourne Again Shell, bash para los amigos se ha convertido en la shell de facto para sistemas UNIX, si bien hay muchísimas opciones adicionales. Esta es la shell por defecto que tenendremos cuando hagamos clic desde el menú de inicio en el icono de la distribución que acabamos de instalar.

wsl7

E instantáneamente tenemos nuestra shell con el subsistema ejecutándose.

wsl8

A partir de aquí podemos operar tal y como lo haríamos con Linux y ejecutar binarios ELF sin hacer ninguna modificación. Como comenté al principio del artículo, es ejecución nativa sin emulación. Así que podemos hacer un:

$ sudo apt update && sudo apt install mc

Y así en la siguiente captura podemos ver cómo se ejecuta el Midnight Commander.

wsl9

Parece que en la consola todo está a pedir de boca, sin embargo, si ejecutamos una aplicación gráfica...

$ sudo apt install vim-gtk3
$ gvim

Nos encontraremos con el siguiente error:

wsl12

Evidentemente nos hace falta un servidor de X Window.

X Window System

El X Window System, comúnmente conocido como las X han sido durante más de 30 años el sistema de ventanas por defecto de los sistemas operativos UNIX y derivados. Provee un potente framework cliente-servidor con transparencia de red para dibujar y mover ventanas así como gestionar dispositivos de entrada como el teclado y el ratón.

Cabe destacar que las X no gestionan la interfaz de usuario, motivo por el cual nos encontramos una abrumadora cantidad de gestores de ventanas para X, cada uno de los cuales puede cambiar radicalmente la experiencia con el sistema operativo. Por ello no dejaba de ser frecuente encontrar gestores que imitaban otros sistemas operativos, como Window Maker, que simula la apariencia de NeXTSTEP o el anciano fvwm95. Actualmente existen potentes gestores de ventanas como KWin.

La arquitectura cliente-servidor de las X se define siempre desde la perspectiva de la aplicación, lo cual quiere decir:

  • Un servidor X es el software que provee los servicios necesarios para mostrar una aplicación al usuario e interactuar con el teclado y/o ratón.
  • Un cliente X es el software que se ejecuta utilizando los servicios que el servidor X provee. Por tanto, en nuestro ejemplo anterior gvim es un cliente X.

Servidores X para Windows

Las X son multiplataforma y existen implementaciones para casi todos los sistemas operativos y arquitecturas conocidas: prácticamente cualquier UNIX, macOS, incluso AmigaOS y... evidentemtente Windows; sin embargo, WSL no viene con ninguno integrado, por lo que tendremos que instalar uno.

Hay multitud de elecciones de servidores X para Windows, por citar unos pocos:

Particularmente soy bastante fan de Xming, que aunque no es gratuito, el precio es una donación de 10 GBP; bastante asequible. He podido ver que las versiones recientes de Xming ejecutan cargas de trabajo pesadas (como ejecutar Firefox) mejor que VcXsrv, que no deja de ser una buena opción.

Una vez tengamos instalado y ejecutándose cualquiera de ellos, veremos un pequeño icono en la zona de reloj de la barra de tareas.

wsl13

Importante el tooltip que nos aparece al pasar el ratón por encima, donde se nos indica el número de display que estamos sirviendo.

El gestor de ventanas

Antes comentaba que las X no se preocupan por la interfaz de usuario y que tenemos que elegir un gestor de ventanas para poder ejecutar nuestras aplicaciones gráficas de Linux. En nuestro caso... ¡ya tenemos un gestor de ventanas estupendo llamado Windows!

Efectivamente vamos a aprovechar el propio Windows 10 como nuestro gestor de ventanas, así que nada que hacer aquí.

Ejecutando aplicaciones gráficas en WSL

Volvemos a abrir nuestra ventana de bash, pero esta ocasión antes de ejecutar nuestra aplicación necesitamos decirle al sistema la pantalla a la que se debe enviar nuestra aplicación gráfica. Esto se hace mediante la variable $DISPLAY, que veíamos antes pasando el cursor del ratón por el icono del servidor X.

Así que hacemos:

$ export DISPLAY=:0.0
$ gvim

¡Tadá! Tenemos aplicación gráfica de Linux ejecutándose nativamente en nuestro Windows 10. Fíjaos en el detalle de como incluso el icono del gvim aparece en la barra de tareas como cualquier otra aplicación de Windows.

wsl14

Con esto ya tenemos el poder de trabajar bajo un mismo sistema operativo con aplicaciones de Windows o de Linux de forma nativa. Adjunto otro par de capturas de pantalla muy significativas.

Aplicaciones de Windows y Linux ejecutándose nativamente en el mismo sistema operativo.
wsl10-1

Una curiosa comparación: la versión de Windows de Firefox a la izquierda y la versión Linux de Firefox a la derecha. Se pueden apreciar diferencias sutiles en la interfaz de usuario y como el renderizado de fuentes es mejor en la versión Windows. La calidad del renderizado de fuentes en Linux es muy dependiente del servidor X utilizado.

wsl11

Y aunque hasta aquí es todo, no podía cerrar el artículo sin hacer una nota especial sobre un tema...

LCOW: Linux Containers on Windows

Seguro que a los usuarios de Docker se les ha encendido la bombilla con todo este tema. ¿Puedo instalar mi entorno de desarrollo basado en Docker CE bajo Windows sin necesidad de Hyper-V y la máquina virtual mobyLinux? ¿Podría utilizar WSL? ¡La respuesta es sí! Pero se trata de una capacidad experimental, así que recomiendo hacer pruebas y juguetear con ella pero no utilizarla en escenarios productivos.

wsllcow

Si tenemos WSL instalado y configurado y las experimental features del demonio de Docker habilitadas podemos ejecutar contenedores Linux sobre WSL sin abandonar el modo Windows Containers. Para ellos hay que agregar --platform=linuxa la línea de comandos. Por ejemplo:

C:\> docker run --name linux-mysql --platform=linux -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7

Este es un tema del que podremos hablar con más detalle en otra ocasión.

Happy Linuxing... ¡desde Windows!