使用Windows11 WSL2进行Android系统开发
原文链接:https://ovea-y.cn/using_windows_11_wsl2_for_android_system_development/
背景介绍
由于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具备的优点:
- 完整的Linux内核支持
- 原生支持GUI显示,并且支持GPU加速
- 支持原生的文件系统
- 与Windows集成紧密
- 性能较高
WSL2安装与配置、挂载和使用一块硬盘
如果只有一块硬盘,并且足够大,那就不必进行这个操作了,直接参照下面的文档解除256GiB的空间限制即可,这一大章可以直接跳过了:
Expand the size of your WSL 2 Virtual Hard Disk
如果是从Linux转到Windows,Linux的磁盘还保留着(并且是WSL 2 Kernel支持的文件系统),下面的操作可以选择性的做(例如准备和挂载Ext4分区、创建新分区、创建加密分区、格式化加密分区映射的虚拟设备全都可以直接跳过)。
配置环境
- 启用Linux子系统功能(需要管理员权限),下面这个指令可以自动配置好所有环境,默认使用WSL 2,Ubuntu系统。
wsl --install
2. 重启系统,重启后会自动弹出下面这个安装框
3. 按照提示设置好用户名和密码
准备与挂载Ext4分区
千万不要用F2FS,因为WSL2的kernel内核不支持F2FS!
通过/proc/filesystems查看当前内核支持的文件系统
- 通过下面这条指令查看Windows当前磁盘
GET-CimInstance -query "SELECT * from Win32_DiskDrive"
- 使用diskpart,清空一个需要用于WSL 2的磁盘
管理员权限执行以下指令
diskpart.exe
然后再diskpart中通过下面指令查看当前存在的磁盘信息
list disk
选择需要挂载到WSL2的磁盘(此处可以根据第4步的deviceID判断),清空所有信息,执行以下指令
# 选择要操作的磁盘
# select disk 0
select disk [Disk id(可以根据deviceID的数字编号判断)]
# 清除包括分区表在内的全部信息
clean
# 建立GPT(GUID)
convert gpt
# 退出
exit
此时这块磁盘就处理完毕了!
6. 执行以下指令进行设备挂载(将一个物理磁盘“挂载”到WSL2中)
# wsl --mount \\.\PHYSICALDRIVE0 --bare
wsl --mount [DeviceID] --bare
# 卸载指令是 wsl --unmount \\.\PHYSICALDRIVE0
此时可以看到已经将设备映射到WSL 2中了
创建新分区(WSL2中操作)
大家可以看到,上面默认已经有了一个sde1分区,但是不要使用这个分区,这个是Windows默认设置的msr保留分区!删除这个分区有可能会产生一些BUG,具体情况可以看:Windows 10 开启快速启动关机回到登入界面的问题!原因已经找到,求解决方案! - Microsoft Community
# 用fdisk工具进行新分区添加
# sudo fdisk /dev/sde
sudo fdisk [disk path]
# fdisk Command介绍
# n —— 新建分区(后面如果没特殊要求全部直接回车即可)
# w —— 将此前的操作全部同步到磁盘上,并退出
上面的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
现在的效果就像上图这样。
格式化加密分区映射出的虚拟设备为Ext4,并挂载
注意!WSL 2在管理员权限打开和普通权限打开部分配置是隔离的!(例如磁盘挂载信息是不一样的)管理员权限和普通权限打开WSL2,可以理解为有2个不同的用户使用自己的版本,共享大部分配置信息。如果VS Code不是全局安装,只有普通权限下才能在WSL 2中执行code .
等操作。
»> 总之一般情况下请使用非管理员权限使用WSL,可以避免大部分问题! «<
- 格式化磁盘为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 [当前用户名字] [挂载点路径]
下次开机需要的操作
到这里,挂载部分就完成了!下次开机只要做以下操作即可:
# 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/[映射名称] [挂载点路径]
用某恢复软件查看硬盘数据(会发现完全看不到任何数据!全盘加密是非常重要的,这样即使电脑被偷走,或者回收掉了,硬盘被掉包,只要密码够复杂,都没有人有任何手段可以再恢复里面的数据了)
Windows 11甚至可以直接在文件管理器看到这个WSL 2的目录结构!操作就很方便了!
性能测试
- 搞份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 代码拉取与构建测试
- 首先拉取代码
- 其次创建一块swap(用的笔记本,内存空间有点吃紧)
sudo dd if=/dev/zero of=swapfile bs=1G count=40
sudo chmod 0600 swapfile
sudo mkswap swapfile
sudo swapon swapfile
- 构建Android代码,以下是构建结果
只要Swap足够,即使卡顿也不会触发OOM(但是使用Java编译的时候会OOM,Swap跟空气一样),用SSD其实一点都不卡
3.8GiB的内存(笔记本是8GiB,但是WSL只分到了3.8GiB,虽然可以增大,但是会让Windows非常卡)在Java编译Framework的时候会OOM,所以就编译不包含Java代码的源码来测试了,可以看到编译boot.img可以成功。
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,现在就可以用几乎全部的内存了!
然后再次构建代码,会发现可以构建成功了!
WSL2接入USB设备
还未原生支持,可以参考以下文档,或者使用WSL1(WSL2和WSL1可以共存):
按照文档尝试一下
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
下载完成后,会自动弹出安装程序的框,点击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
添加USB设备到WSL2
# usbipd wsl attach --busid 1-4
usbipd wsl attach --busid <busid>
此时可以在WSL2中看到这个USB设备了,并且可以对它进行操作!
lsusb
Windows启用sshd
如果将日常工作台式机和笔记本都设置为Windows11,除了可以使用Windows的远程桌面以外(不稳定),还可以启用sshd,使用ssh进行连接(比远程桌面稳定不少)。以下包括了如何在用SSH连接远程Windows时启用管理员权限的方法,此时就可以挂载硬盘到WSL 2,使用wsl指令即可进入WSL2模式
1. 开启openSSH server功能模块
2. 配置和启动openSSH server
# Start the sshd service
# 启动sshd
Start-Service sshd
# OPTIONAL but recommended:
# 设置自动启动sshd
Set-Service -Name sshd -StartupType 'Automatic'
# Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify
# 用这条指令确认Windows防火墙是否配置了SSHD的端口(即打开端口),一般安装sshd的时候会自动配置
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
}
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/[映射名称] [挂载点路径]
额外信息
此前我有8个月都是使用Windows10+WSL1+VMware Workstation进行工作的,但是切换成Windows11+WSL2效率会更高一些,并且性能比VMware Workstation要好很多。
(虽然后面有2个月又回到Linux了,毕竟没有“中间商”也没有此前大部分限制了,可以尝试F2FS或其他新的文件系统和其他新功能,重点是飞书有Linux版本,用飞书文档做学习笔记也很不错!但是果然无法正常驱动所有硬件… 比如指纹模块,驱动了但是无法正常使用,TPM芯片的使用场景也几乎没有,GPU必须安装Nvidia提供的闭源驱动才能发挥接近100%的性能)
参考资料
Windows 下哪个软件能把硬盘分区转换为 ext4 格式? - 知乎 (zhihu.com)
Get started mounting a Linux disk in WSL 2 | Microsoft Docs
Connecting USB devices to WSL - Windows Command Line (microsoft.com)
Linux LUKS加密硬盘分区 - CyberSecurityBook - 博客园
win下使用diskpart重建U盘磁盘分区 - jun’s - 博客园
Use sudo with SSH-Session from PowerShell
Advanced settings configuration in WSL
原文链接:https://ovea-y.cn/using_windows_11_wsl2_for_android_system_development/