1. 安装Ubuntu

  • 首先检查windows是否可以更新, 必须保持在可以更新的状态才可以下载ubuntu镜像.

  • 管理员模式打开终端, 查看wsl可以安装的linux版本

    PS C:\wsl_ubuntu> wsl --list --online
    
    以下是可安装的有效分发的列表。
    请使用“wsl --install -d <分发>”安装。
    
    NAME                                   FRIENDLY NAME
    Ubuntu                                 Ubuntu
    Debian                                 Debian GNU/Linux
    kali-linux                             Kali Linux Rolling
    Ubuntu-18.04                           Ubuntu 18.04 LTS
    Ubuntu-20.04                           Ubuntu 20.04 LTS
    Ubuntu-22.04                           Ubuntu 22.04 LTS
    OracleLinux_8_5                        Oracle Linux 8.5
    OracleLinux_7_9                        Oracle Linux 7.9
    SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
    openSUSE-Leap-15.4                     openSUSE Leap 15.4
    openSUSE-Tumbleweed                    openSUSE Tumbleweed
    
  • 安装ubuntu

    如果windows无法更新这里会出现错误代码: 0x80070005.

    PS C:\wsl_ubuntu> wsl --install -d Ubuntu-20.04
    
    正在安装: Ubuntu 20.04 LTS
    已安装 Ubuntu 20.04 LTS。
    正在启动 Ubuntu 20.04 LTS…
    
  • 启动ubuntu

    安装完可能出现报错: WslRegisterDistribution failed with error: 0x800701bc

2. 开启ssh

修改/etc/ssh/sshd_config结尾加上密码登录, 端口等参数

PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication no
Port xxx
  • 重启ssh

    sudo service ssh start
    
    • 可能出现报错: sshd: no hostkeys available -- exiting
    • 解决方法: sudo ssh-keygen -A
  • wsl启动时,自动启动ssh

    • 在~/.bashrc或~/.profile添加以下命令

      # 检查 SSH 服务是否正在运行,如果没有,则启动它
      if ! pgrep -x "sshd" > /dev/null; then
          sudo service ssh start
      fi
      
    • 无sudo密码启动ssh服务

      sudo visudo
      # 添加以下内容,在[username]处填写自己的用户名
      [username] ALL=(ALL) NOPASSWD: /usr/sbin/service ssh start
      

3. 自动化windows虚拟网卡ip修改+启动ssh服务

wsl的虚拟网卡在windows重启的时候, ip地址会自动改变. 编写bat文件, 管理员运行.

  • 由于每次wsl重启都会重置网卡配置, 所以可以写一个脚本自动修改网卡

  • 在 wsl Ubuntu home 目录下添加一个脚本set_eth0.sh(注意脚本保存的位置), 桥接网卡到host, 并打开 ssh 服务

    #!/bin/bash
    new_ip=192.168.31.xxx
    brd=192.168.31.255
    gateway=192.168.31.1
    nameserver=192.168.31.1
    net_dev=eth0
    echo "password" | sudo -S ip addr del $(ip addr show $net_dev | grep 'inet\b' | awk '{print $2}' | head -n 1) dev $net_dev
    sudo ip addr add $new_ip/24 broadcast $brd dev $net_dev
    sudo ip route add 0.0.0.0/0 via $gateway dev $net_dev
    sudo sed -i "\$c nameserver $nameserver" /etc/resolv.conf
    sudo service ssh start
    
  • powershell桥接网络脚本

    在windows中新建开启脚本: wsl-bridge-on.ps1

    # 检查并以管理员身份运行PS并带上参数
    $currentWi = [Security.Principal.WindowsIdentity]::GetCurrent()
    $currentWp = [Security.Principal.WindowsPrincipal]$currentWi
    if( -not $currentWp.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
    {
        $boundPara = ($MyInvocation.BoundParameters.Keys | foreach{'-{0} {1}' -f  $_ ,$MyInvocation.BoundParameters[$_]} ) -join ' '
        $currentFile = $MyInvocation.MyCommand.Definition
        $fullPara = $boundPara + ' ' + $args -join ' '
        Start-Process "$psHome\powershell.exe"   -ArgumentList "$currentFile $fullPara"   -verb runas
        return
    }
    #首先随意执行一条wsl指令,确保wsl启动,这样后续步骤才会出现WSL网络
    echo "正在检测wsl运行状态..."
    wsl --cd ~ -e ls
    echo "正在获取网卡信息..."
    Get-NetAdapter
    echo "`n正在将WSL网络桥接到以太网..."
    Set-VMSwitch WSL -NetAdapterName 以太网
    echo "`n正在修改WSL网络配置..."
    wsl --cd ~ -e sh -c ./setup/set_eth0.sh
    echo "`ndone"
    
    • 注意这里的Start-Process "$psHome\powershell.exe" , 需要用终端输入$psHome 查看 powershell 路径, 该路径下是 powershell.exe 还是 pwsh.exe.
  • powershell 取消桥接脚本, 可以不使用

    在 windows 中新建关闭脚本: wsl-bridge-off.ps1

    # 检查并以管理员身份运行PS并带上参数
    $currentWi = [Security.Principal.WindowsIdentity]::GetCurrent()
    $currentWp = [Security.Principal.WindowsPrincipal]$currentWi
    if( -not $currentWp.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
    {
        $boundPara = ($MyInvocation.BoundParameters.Keys | foreach{'-{0} {1}' -f  $_ ,$MyInvocation.BoundParameters[$_]} ) -join ' '
        $currentFile = $MyInvocation.MyCommand.Definition
        $fullPara = $boundPara + ' ' + $args -join ' '
        Start-Process "$psHome\pwsh.exe"   -ArgumentList "$currentFile $fullPara"   -verb runas
        return
    }
    echo "正在解除wsl桥接..."
    Set-VMSwitch WSL  -SwitchType Internal
    echo "正在重启wsl"
    wsl --shutdown
    wsl --cd ~ -e ls
    echo "`ndone"
    pause
    
  • windows 下设置 ps1 文件运行程序

    分别右键 wsl-bridge-on.ps1 和 wsl-bridge-off.ps1 这两个脚本, 直接默认powershell运行 (或在打开方式中选择其它应用, 找到powershell安装路径下的可执行文件pwsh.exe, 勾选始终使用此应用打开.ps1文件, 这样就可以直接双击运行了).

    不过, 默认情况下 windows powershell 不允许执行自定义脚本, 所以需要修改设置打开执行权限.

    管理员方式打开 powershell, 执行 Set-ExecutionPolicy Unrestricted 或 Set-ExecutionPolicy RemoteSigned

  • 将 ps1 文件添加到开始屏幕

    给 ps1 文件创建一个快捷方式, 复制到C:\ProgramData\Microsoft\Windows\Start Menu\Programs文件夹下, 修改文件名.

    之后, 开始菜单搜索目标文件名, 右键添加开始屏幕即可.

3.1. mirror模式设置网络

https://blog.gazer.win/essay/wsl2-mirrored-network.html/comment-page-2#comments

注意,设置的时候TUN模式需要关掉,防止wsl虚拟机的首选网卡从连接互联网的口变成TUN的虚拟网卡的口。可以通过ip addr来查看。

4. WSL 安装 ubuntu 之后, ubuntu 内使用 nvidia-smi 失效

加入 .bachrc 文件中

export PATH=/usr/lib/wsl/lib:$PATH

5. WSL 无法 ping 通 Windows 宿主机

因为 windows 防火墙屏蔽了外来的 icmp 包, 需要给防火墙添加规则

WSL2 网络异常排查 [ping 不通、网络地址异常、缺少默认路由、被宿主机防火墙拦截] - SocialistYouth - 博客园

6. 安装图形化界面

7. WSL 中的cuda驱动是和宿主机共享

由于 CUDA 驱动的地址在 Windows 路径下, 所以安装 opencv 等 python 库关联的模块会出现各种环境问题. 如果需要做开发用的话, 不建议使用 WSL.

安装opencv

clone opencv和opencv_contrib 版本改为4.5.5

mkdir build in opencv

sudo apt-get update
sudo apt install -y build-essential cmake git pkg-config libgtk-3-dev \
    libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
    libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
    gfortran openexr libatlas-base-dev python3-dev python3-numpy \
    libtbb2 libtbb-dev libdc1394-22-dev gcc-8 g++-8

使用 update-alternatives 切换到 GCC 8:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 100
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
gcc --version
g++ --version
# 如果要切换回原来的 GCC 版本
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

cmake编译

cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
      -D WITH_CUDA=ON \
      -D ENABLE_FAST_MATH=1 \
      -D CUDA_FAST_MATH=1 \
      -D WITH_CUBLAS=1 \
      -D BUILD_opencv_python3=ON \
      -D PYTHON3_EXECUTABLE=$(which python) \
      -D PYTHON3_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
      -D PYTHON3_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \
      -D CMAKE_CXX_FLAGS="-Wno-unused-command-line-argument" \
      -D CMAKE_C_FLAGS="-Wno-unused-command-line-argument" \
      ..

编译安装

make -j$(nproc)
sudo make install

如果安装了图形化界面,再图形化界面使用终端会发现nvidia-smi不能用。

所以需要安装cuda驱动

	sudo apt install nvidia-driver-535
	sudo apt install nvidia-cuda-toolkit # 或者本地安装
	
	 -   PATH includes /usr/local/cuda-12.8/bin
 -   LD_LIBRARY_PATH includes /usr/local/cuda-12.8/lib64, or, add /usr/local/cuda-12.8/lib64 

8. WSL 安装smb挂在ext4磁盘

  • 挂载磁盘

    wmic diskdrive list brief  # 找到物理连接的磁盘
    wsl --mount \\.\PHYSICALDRIVE0 --type ext4 --partition 2  # 挂载磁盘并注意分区