使用Windows11 WSL2进行Android系统开发

8,560 阅读8分钟

背景介绍

由于Linux上缺少很多常用的软件,并且Linux加上图形界面时,有时会出现很多匪夷所思的BUG(包括但不限于压缩文件的默认打开方式变成了文本编辑器、界面卡死等情况),因此将工作流迁移到Windows上也不失为一种选择。

WSL 2相比WSL 1最大的缺点就是它运行在虚拟化层中,并且对Windows磁盘的读写性能极差!毕竟切换成使用网络实现方式将Windows的分区挂载到WSL 2了(还有一个问题是硬件和网络端口不再共享了)。但是优点是它是完整的linux系统,可以发挥Linux全部的功能(但是systemctl依旧不可用)。

如果要使用WSL 2进行日常工作,就必须避免使用NTFS,而是使用其他Linux上原生支持的文件系统。本篇文章的重点就是如何让WSL 2用上原生支持的文件系统,以及如何让USB设备接入WSL 2两大部分内容。

WSL2安装与配置、挂载和使用一块硬盘

如果只有一块硬盘,并且足够大,那就不必进行这个操作了,直接参照下面的文档解除256GiB的空间限制即可,这一大章可以直接跳过了:

Expand the size of your WSL 2 Virtual Hard Disk

如果是从Linux转到Windows,Linux的磁盘还保留着(并且是****WSL 2 Kernel支持的文件系统 ),下面的操作可以选择性的做(例如准备和挂载Ext4分区、创建新分区、创建加密分区、格式化加密分区映射的虚拟设备全都可以直接跳过)。

配置环境

  1. 启用Linux子系统功能(需要管理员权限),下面这个指令可以自动配置好所有环境,默认使用WSL 2,Ubuntu系统。
wsl --install

image.png

  1. 重启系统,重启后会自动弹出下面这个安装框

image.png

  1. 按照提示设置好用户名和密码

image.png

准备与挂载Ext4分区

千万不要用F2FS,因为WSL2的kernel内核不支持F2FS!

通过/proc/filesystems查看当前内核支持的文件系统

  1. 通过下面这条指令查看Windows当前磁盘
GET-CimInstance -query "SELECT * from Win32_DiskDrive"

image.png 5. 使用diskpart,清空一个需要用于WSL 2的磁盘

管理员权限执行以下指令

diskpart.exe

然后再diskpart中通过下面指令查看当前存在的磁盘信息

list disk

image.png

选择需要挂载到WSL2的磁盘(此处可以根据第4步的deviceID判断),清空所有信息,执行以下指令

# 选择要操作的磁盘
# select disk 0
select disk [Disk id(可以根据deviceID的数字编号判断)]
# 清除包括分区表在内的全部信息
clean
# 建立GPT(GUID)
convert gpt
# 退出
exit

image.png

此时这块磁盘就处理完毕了!

  1. 执行以下指令进行设备挂载(将一个物理磁盘“挂载”到WSL2中)
# wsl --mount \\.\PHYSICALDRIVE0 --bare
wsl --mount [DeviceID] --bare
# 卸载指令是 wsl --unmount \\.\PHYSICALDRIVE0

此时可以看到已经将设备映射到WSL 2中了

image.png

创建新分区(WSL2中操作)

大家可以看到,上面默认已经有了一个sde1分区,但是不要使用这个分区,这个是Windows默认设置的msr保留分区!删除这个分区有可能会产生一些BUG,具体情况可以看:Windows 10 开启快速启动关机回到登入界面的问题!原因已经找到,求解决方案! - Microsoft Community

# 用fdisk工具进行新分区添加
# sudo fdisk /dev/sde
sudo fdisk [disk path]
# fdisk Command介绍
# n —— 新建分区(后面如果没特殊要求全部直接回车即可)
# w —— 将此前的操作全部同步到磁盘上,并退出

image.png

上面的sde2就是我们新建的分区。

创建加密分区

# 创建加密分区
# sudo cryptsetup luksFormat /dev/sde2
sudo cryptsetup luksFormat [part path]
# 对加密分区解密,并且映射一个虚拟设备,这个设备会放入在/dev/mapper/[映射名称]
# sudo cryptsetup luksOpen /dev/sde2 FastStore
sudo cryptsetup luksOpen [加密的part path] [映射名称]
# 可以通过 sudo cryptsetup luksClose [映射名称]关闭映射
# sudo cryptsetup luksClose FastStore

image.png

现在的效果就像上图这样。

格式化加密分区映射出的虚拟设备为Ext4,并挂载

注意!WSL 2在管理员权限打开和普通权限打开部分配置是隔离的!(例如磁盘挂载信息是不一样的)管理员权限和普通权限打开WSL2,可以理解为有2个不同的用户使用自己的版本,共享大部分配置信息。如果VS Code不是全局安装,只有普通权限下才能在WSL 2中执行code .等操作。

>>> 总之一般情况下请使用非管理员权限使用WSL,可以避免大部分问题! <<<

  1. 格式化磁盘为Ext4,并挂载
# mkfs to ext4
# sudo mkfs.ext4 /dev/mapper/FastStore
sudo mkfs.ext4 /dev/mapper/[映射名称]
# mount FastStore (别白费力气因为挂载的是固态就想使用TRIM了,因为WSL2根本不支持这种映射的TRIM指令传递)
# mount -o discard 挂载是完全没用的,我已经全部试过了
# 手动触发TRIM用 fstrim指令跟着对应的挂载点根目录即可

# mkdir ~/AndroidCodes
# sudo mount /dev/mapper/FastStore ~/AndroidCodes
mkdir [挂载点路径]
sudo mount /dev/mapper/[映射名称] [挂载点路径]
# Change owner
# sudo chown ovea ~/AndroidCodes
sudo chown [当前用户名字] [挂载点路径]

image.png

下次开机需要的操作

到这里,挂载部分就完成了!下次开机只要做以下操作即可:

# In Windows [管理员权限]
# wsl --mount \\.\PHYSICALDRIVE0 --bare
wsl --mount [DeviceID] --bare

# In WSL 2
# sudo cryptsetup luksOpen /dev/sdd1 FastStore
# sudo mount /dev/mapper/FastStore ~/AndroidCodes
sudo cryptsetup luksOpen [加密的part path] [映射名称]
sudo mount /dev/mapper/[映射名称] [挂载点路径]

用某恢复软件查看硬盘数据(会发现完全看不到任何数据!全盘加密是非常重要的,这样即使电脑被偷走,或者回收掉了,硬盘被掉包,只要密码够复杂,都没有人有任何手段可以再恢复里面的数据了)

image.png

Windows 11甚至可以直接在文件管理器看到这个WSL 2的目录结构!操作就很方便了!

image.png

性能测试

  1. 搞份redis代码编译一下,顺便看看时间(尤其是NTFS和Ext4的时间,可以看出WSL 2在NTFS上的IO有多低(因为使用网络方式挂载),以至于一定要挂载一块Ext 4硬盘用于Android编译)

NTFS分区(已经禁用了Windows Security)上redis构建完成时间:4分47秒

Ext4分区上redis构建完成时间:1分37秒

原生Ubuntu 21.10:1分34秒

Android 代码拉取与构建测试

  1. 首先拉取代码
  2. 其次创建一块swap(用的笔记本,内存空间有点吃紧)
sudo dd if=/dev/zero of=swapfile bs=1G count=40
sudo chmod 0600 swapfile
sudo mkswap swapfile
sudo swapon swapfile

image.png

  1. 构建Android代码,以下是构建结果

只要Swap足够,即使卡顿也不会触发OOM(但是使用Java编译的时候会OOM,Swap跟空气一样),用SSD其实一点都不卡

image.png

3.8GiB的内存(笔记本是8GiB,但是WSL只分到了3.8GiB,虽然可以增大,但是会让Windows非常卡)在Java编译Framework的时候会OOM,所以就编译不包含Java代码的源码来测试了,可以看到编译boot.img可以成功。

image.png

WSL 2的物理内存、Swap大小 ,以及其他配置

修改C:\Users\<UserName>\.wslconfig,参照下面的配置方式进行配置(都要是整数,不能是7.9G内存这样子

# Settings apply across all Linux distros running on WSL 2
[wsl2]

# Limits VM memory to use no more than 4 GB, this can be set as whole numbers using GB or MB
# 设置使用的物理内存大小,如果此处设置的值大于实际物理内存,会默认使用最大值
memory=8GB

# Sets the VM to use two virtual processors
# processors=8

# Specify a custom Linux kernel to use with your installed distros. The default kernel used can be found at https://github.com/microsoft/WSL2-Linux-Kernel
# kernel=C:\\temp\\myCustomKernel

# Sets additional kernel parameters, in this case enabling older Linux base images such as Centos 6
# kernelCommandLine = vsyscall=emulate

# Sets amount of swap storage space to 8GB, default is 25% of available RAM
# 设置交换分区的大小
swap=40GB

# Sets swapfile path location, default is %USERPROFILE%\AppData\Local\Temp\swap.vhdx
# swapfile=C:\\temp\\wsl-swap.vhdx

# Disable page reporting so WSL retains all allocated memory claimed from Windows and releases none back when free
# pageReporting=false

# Turn off default connection to bind WSL 2 localhost to Windows localhost
# localhostforwarding=true

# Disables nested virtualization
# nestedVirtualization=false

# Turns on output console showing contents of dmesg when opening a WSL 2 distro for debugging
# debugConsole=true

然后重启WSL2,现在就可以用几乎全部的内存了!

image.png

然后再次构建代码,会发现可以构建成功了!

WSL2接入USB设备

未原生支持,可以参考以下文档,或者使用WSL1(WSL2和WSL1可以共存)

Connect USB devices

按照文档尝试一下

WSL2内核版本要>=5.10.60.1才能使用此功能

无法使用apt对WSL2的内核进行更新!

WSL2更新内核的方法:Microsoft Update Catalog

安装完后重启WSL2生效,方法是Windows中执行wsl --shutdown,然后再运行WSL。或者直接重启Windows 11。

环境配置——Windows

在Windows中,执行

winget install --interactive --exact dorssel.usbipd-win

image.png

下载完成后,会自动弹出安装程序的框,点击Install即可。

环境配置——WSL2

# 与kernel版本无关
sudo apt install linux-tools-5.4.0-77-generic hwdata
sudo visudo

在secure_path首部添加“/usr/lib/linux-tools/5.4.0-77-generic:”

使用方式

在Windows中显示所有USB设备

usbipd wsl list

image.png

添加USB设备到WSL2

# usbipd wsl attach --busid 1-4
usbipd wsl attach --busid <busid>

此时可以在WSL2中看到这个USB设备了,并且可以对它进行操作!

lsusb

image.png

image.png

Windows启用sshd

如果将日常工作台式机和笔记本都设置为Windows11,除了可以使用Windows的远程桌面以外(不稳定),还可以启用sshd,使用ssh进行连接(比远程桌面稳定不少)。以下包括了如何在用SSH连接远程Windows时启用管理员权限的方法,此时就可以挂载硬盘到WSL 2使用wsl指令即可进入WSL2模式

1. 开启openSSH server功能模块

image.png

image.png

image.png

image.png

2. 配置和启动openSSH server

# Start the sshd service
# 启动sshd
Start-Service sshd

# OPTIONAL but recommended:
# 设置自动启动sshd
Set-Service -Name sshd -StartupType 'Automatic'

3. 远程连接sshd

注意!此处如果powershell是管理员权限,那么此时ssh后默认有管理员权限,反之则没有

# ssh miove@192.168.31.229
ssh [用户名]@[ip]

4. 远程使用WSL2

# In Windows [管理员权限]
# wsl --mount \\.\PHYSICALDRIVE0 --bare
wsl --mount [DeviceID] --bare

# In WSL 2
# sudo cryptsetup luksOpen /dev/sdc2 FastStore
# sudo mount /dev/mapper/FastStore ~/AndroidCodes
sudo cryptsetup luksOpen [加密的part path] [映射名称]
sudo mount /dev/mapper/[映射名称] [挂载点路径]

image.png

额外信息

此前我有8个月都是使用Windows10+WSL1+VMware Workstation进行工作的,但是切换成Windows11+WSL2效率会更高一些,并且性能比VMware Workstation要好很多。

(虽然后面有2个月又回到Linux了,毕竟没有“中间商”也没有此前大部分限制了,可以尝试F2FS或其他新的文件系统和其他新功能,重点是飞书有Linux版本,用飞书文档做学习笔记也很不错!但是果然无法正常驱动所有硬件… 比如指纹模块,驱动了但是无法正常使用,TPM芯片的使用场景也几乎没有,GPU必须安装Nvidia提供的闭源驱动才能发挥接近100%的性能)

参考资料

Install WSL | Microsoft Docs

Windows 下哪个软件能把硬盘分区转换为 ext4 格式? - 知乎 (zhihu.com)

Get started mounting a Linux disk in WSL 2 | Microsoft Docs

Redis仓库

Connecting USB devices to WSL - Windows Command Line (microsoft.com)

Linux LUKS加密硬盘分区 - CyberSecurityBook - 博客园

win下使用diskpart重建U盘磁盘分区 - jun's - 博客园

Get started with OpenSSH

Use sudo with SSH-Session from PowerShell

Advanced settings configuration in WSL