Contents
windows下的Linux子系统wsl
介绍
参考:https://baike.baidu.com/item/wsl/20359185
Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,其目标是使纯正的Ubuntu、Debian等映像能下载和解压到用户的本地计算机,并且映像内的工具和实用工具能在此子系统上原生运行。 [1-3]
如果使用Windows 10 2004以上,可以通过WSL 2来窗口化运行桌面应用,也不需要另外安装其他的X 服务器。
WSL提供了一个微软开发的Linux兼容内核接口(不包含Linux代码),来自Ubuntu的用户模式二进制文件在其上运行。 [4]
该子系统不能运行所有Linux软件,例如那些图形用户界面,以及那些需要未实现的Linux内核服务的软件。不过,这可以用在外部X服务器上运行的图形[X Window](https://baike.baidu.com/item/X Window)系统缓解。
历史
在设计之初,微软就允许类似于Win32这种子系统运行于Windows NT内核之上,它可以为上层应用提供编程接口,同时避免应用去实现内核里的一些调用细节。NT内核的设计在最开始就可以支持POSIX,OS/2和win32子系统。
早先的子系统是用户态模块的实现,它封装了NT系统的系统调用为应用程序提供编程接口。所有的应用程序都是PE/COFF(一些为子系统封装NT系统调用的库和服务)可执行的。当一个用户态的程序启动的时候,启动器就会基于可执行的头部去引用适当的子系统来满足应用程序的依赖。
后来版本的子系统替换掉了POSIX层,由用户态组件提供了Subsystem for Unix-based Applications (SUA),满足:
\1. 进程和信号管理
\2. 终端管理
\3. 系统服务请求和进程间通信
SUA的主要目的是为了鼓励应用程序移植到Windows上能尽量少的重写。这已经通过实现POSIX用户态API达到了。考虑到这些组件是用户态实现,很难跟内核态的系统调用(比如“fork()”)在语义上和效率上完全相对应。因为这种模式需要程序重新编译,它需要持续的功能移植,维护也是负担。
随着时间的演变,这些早先的子系统都退出历史舞台了。但是因为Windows NT内核的架构允许新的子系统环境,微软就基于这领域的原始积累进行扩展,在2016年发布Windows Subsystem for Linux。
wsl包含内容
Windows Subsystem for Linux
WSL是一些组件的集合,允许原生的Linux ELF64二进制文件跑在Windows上。它同时包括了用户态和内核态组件,主要包含以下部分:
\1. 用户态会话管理服务处理Linux实例的生命周期
\2. Pico provider drivers (lxss.sys, lxcore.sys)“翻译”系统调用,以模拟Linux内核
\3. Pico 进程管理原生的用户态Linux(比如/bin/bash)
奇迹就发生于用户态的Linux二进制文件和Windows内核组件之间。通过将未经修改的Linux二进制文件放置于Pico进程中,我们把Linux系统调用直接导入Windows内核中。lxss.sys, lxcore.sys驱动将Linux系统调用翻译为NT APIs,来模拟Linux内核。
pico进程
作为Project Drawbridge的一部分,Windows内核引入了Pico进程和Pico驱动的概念。Pico进程和驱动提供了Windows Subsystem for Linux的基础。可执行的ELF二进制文件被加载到Pico进程的地址空间,并在系统调用的Linux兼容层上执行。
系统调用
WSL基于Windows NT内核虚拟了Linux内核接口,这允许它执行未经修改的Linux ELF64二进制文件。一类内核接口是系统调用。系统调用是内核为用户态程序提供的一种服务。Linux内核和Windows NT内核都为用户态程序提供了几百个系统调用,但是他们有不同的语义,并且一般来说并不直接兼容。比如Linux提供fork, open和kill,Windows NT提供相兼容NtCreateProcess, NtOpenFile和 NtTerminateProcess。
Windows Subsystem for Linux 包含内核态驱动(lxss.sys和 lxcore.sys),以协调Linux系统调用的请求与Windows NT内核。驱动不包含Linux内核代码,但是是一个全新实现的Linux兼容的内核接口。在原生的Linux上,用户态程序请求一个系统调用,系统调用请求由Linux内核处理。在WSL,当一个系统调用由同一个可执行文件请求时,Windows NT内核把请求发送给lxcore.sys。 当可能时,lxcore.sys将Linux系统调用翻译成等价的Windows NT的调用,由它来完成繁重的工作。当没有可能的等价转换时,Windows内核态驱动需要直接处理请求。
比如说,Linux中的fork()系统调用没有直接的等价的windows版本。当一个fork系统调用由Windows Subsystem for Linux产生时,lxcore.sys需要做一些复制进程的准备工作,然后调用Windows NT内核APIs来产生一个进程来正确实现fork操作,完成为新进程复制额外的数据。
文件系统
VolFs提供了完整的Linux文件系统特性的支持,包括:
\1. Linux权限管理,访问权限可以通过如chmod和chroot来改变
\2. 文件的符号链接
\3. 文件名可以包含一些Windows上不合法的符号
\4. 大小写敏感
包含Linux系统的目录,应用程序文件(/etc, /bin, /usr等)和用户Linux家目录都使用的是VolFs。
与Windows应用和文件的互用在VolFs里并不支持。
wsl安装
按照官方文档安装: https://docs.microsoft.com/zh-cn/windows/wsl/install
wsl使用
可以在任意文件夹下, shift+鼠标右键 打开linux shell, 即可运行linux命令, 安装linux软件等.
安装好wsl后,还可以安装windows桌面环境的docker desktop.
wsl故障排查
某天,运行docker desktop时启动失败
参考这边博客,发现是wsl的问题: https://blog.csdn.net/qhd1994/article/details/111831427
powershell执行如下命令, 启动 WSL 2时警告“参考的对象类型不支持尝试的操作”
wsl
查看wsl状态,发现wsl已停止
wsl -l -v
参考如下两篇博客的方法,重启winsock服务 : https://blog.csdn.net/mysticboy/article/details/106632922, https://blog.csdn.net/qhd1994/article/details/111831427
管理员方式执行cmd命令 , 无效, wsl和docker还是启动失败
netsh winsock reset
进一步参考如下两篇博客: https://blog.csdn.net/MShow006/article/details/103774672, https://blog.csdn.net/marin1993/article/details/119841299
发现 “wsl在使用是会出现“参考的对象类型不支持尝试的操作”的故障导致无法使用, 出现上述问题原因是使用代理软件,或游戏加速服务,winsock出现问题。 可以通过注册表的方式,排除从winsock中排除wsl即可。
一劳永逸,wsl2出现“参考的对象类型不支持尝试的操作”的解决办法
转载来源: https://blog.csdn.net/marin1993/article/details/119841299

防止WinSock被hook所需的注册表。
当然,可以使用下面的reg注册表代码处理。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\AppId_Catalog\0408F7A3]
"AppFullPath"="C:\\Windows\\System32\\wsl.exe"
"PermittedLspCategories"=dword:80000000
新建文本文档,复制上面的文字,修改后缀为reg双击运行就会创建好上面的键值信息。
最近升级了windows11,发现问题再次出现,发现注册表又被恢复了,再次重复上面的操作就好了。
发表回复