跳转至

场景一:Windows PC 内置 WSL(无 Docker)

本场景适用于只有一台 Windows PC 的开发者:在 Windows 上启用 WSL2 并安装 Ubuntu 22.04,编译环境直接装在 WSL 内,不使用 Docker。

场景一架构


开发环境说明

本场景提供:

  • ARM 交叉编译器(arm-v01c02-linux-musleabi-gcc,GCC 10.3.0)
  • 嵌入式辅助工具(device-tree-compiler、mtd-utils)
  • Python 工具包(openpyxl、pdfplumber、PyGObject/dbus-python 等)
  • 可选:Rust 工具链(编译 zeroclaw 案例时需要,见文末可选章节)
  • 可选:USB 串口直连(usbipd-win 透传,在 WSL 内用 picocom 连接开发板串口,见文末可选章节)
  • 可选:TFTP server(配合镜像网络为开发板提供网络烧写镜像,见文末可选章节)

最后两项还能为后续在 WSL 中使用 AI Agent 提供便利:Agent 可直接读写串口、自动把烧写镜像拷入 TFTP 目录,实现「编译 → 烧写 → 串口观察 → 修复」的自动化闭环(详见文末两章)。

本场景固定使用 Ubuntu 22.04(jammy):工具链下载与 apt/pip 配置脚本均按 22.04 编写。Ubuntu 24.04 起 pip 受 PEP 668 限制(需 --break-system-packages)、apt 源改为 deb822 格式(3.3 的 sed 换源会失效)、hwclock 移入 util-linux-extra 包,不建议直接照搬本文命令。


前置要求

  1. 管理员身份运行 PowerShell(后续所有 Windows 端命令均在此窗口执行)。
  2. ARM 交叉编译器在第三步由命令从 gitcode 下载并安装,无需手动准备。
  3. 若电脑已启用 WSLwsl --version 有版本输出),可跳过第一步,无需重启,直接从第二步开始。

第一步:启用 WSL2 功能

PowerShell(管理员)

先检测 WSL 是否已启用:

wsl --version
  • 有版本输出(如 WSL 版本: 2.x.x.x):WSL 已启用,跳过本步、无需重启,直接进入第二步。
  • 报错或无输出:执行以下命令启用 WSL2 并安装内核(--no-distribution 仅装平台,发行版在第二步安装):

    wsl --install --web-download --no-distribution
    

执行后重启系统,重启后继续后续步骤。

若因网络失败(或太慢),改为离线安装:下载 WSL 内核安装包 https://github.com/microsoft/WSL/releaseswsl.x.x.x.x.x64.msi(如 wsl.2.7.3.0.x64.msi)或https://gh-proxy.com/https://github.com/microsoft/WSL/releases/download/2.7.3/wsl.2.7.3.0.x64.msi,执行 msiexec /i D:\wsl.2.7.3.0.x64.msi /quiet /norestart 后重启。


第二步:安装 Ubuntu 22.04

PowerShell(管理员)

# 安装 Ubuntu 22.04(WSL 内核已在第一步安装)
wsl --install -d Ubuntu-22.04 --web-download

# 验证安装(Version 应为 2)
wsl --list --verbose

安装完成后若自动进入 Ubuntu 并提示创建用户名/密码:可直接关闭该窗口(或随意创建一个),本文后续一律以 root 身份进入(见 3.1),默认用户稍后会由 wsl.conf 固定为 root。

磁盘空间与安装位置:默认安装到 C 盘,完整编译环境(系统依赖 + 工具链 + 源码 + 编译产物)建议预留 30 GB 以上空间:

  • 希望装到 D 盘:在安装命令后追加 --location "D:\WSL\Ubuntu-22.04";若提示不支持,可安装后用 wsl --manage Ubuntu-22.04 --move "D:\WSL\Ubuntu-22.04" 迁移。

若因网络失败(或太慢),改为提前下载系统文件离线安装:

  • https://mirrors.aliyun.com/ubuntu-releases/22.04/,下载 ubuntu-22.04.5-wsl-amd64.wsl(约 344 MB)保存到 D:\,再执行:
    # .wsl 是发行版包格式,须用 --from-file 安装(需 WSL 2.4.10+)
    # 注意不要用 wsl --import,它只接受 tar / vhdx 文件
    wsl --install --from-file "D:\ubuntu-22.04.5-wsl-amd64.wsl"
    # 确认发行版名称,下文 -d 参数以此输出为准
    wsl --list --verbose
    

第三步:配置 Ubuntu 开发环境

3.1 写入 wsl.conf

root 身份进入 Ubuntu(在线安装的发行版首次进入是普通用户,本文所有 WSL 内命令均以 root 执行):

wsl -d Ubuntu-22.04 -u root

WSL 终端(root) 内执行:

cat > /etc/wsl.conf << 'EOF'
[boot]
systemd=false
command=/bin/bash -c 'modprobe ch341 2>/dev/null; modprobe cp210x 2>/dev/null; modprobe cdc_acm 2>/dev/null'

[interop]
appendWindowsPath=false

[user]
default=root
EOF
exit

[user] default=root 将默认登录用户固定为 root,之后直接 wsl -d Ubuntu-22.04 进入即为 root 终端。 boot.command 预加载的 USB 串口驱动,需配合文末「WSL2 直连 USB 串口设备」一节才能真正访问开发板串口。

3.2 重启 WSL

PowerShell(管理员) 中:

wsl --terminate Ubuntu-22.04
wsl -d Ubuntu-22.04

3.3 安装开发环境

以下命令在 WSL 终端(root) 内逐段执行,约 30 分钟。

配置华为云 apt 源:

cp /etc/apt/sources.list /etc/apt/sources.list.bak 2>/dev/null || true
sed -i "s@http://archive.ubuntu.com@http://mirrors.huaweicloud.com@g"  /etc/apt/sources.list
sed -i "s@http://security.ubuntu.com@http://mirrors.huaweicloud.com@g" /etc/apt/sources.list
apt-get update -q

若 apt-get update 报 DNS 错误,先执行:

rm -f /etc/resolv.conf
printf 'nameserver 8.8.8.8\nnameserver 114.114.114.114\n' > /etc/resolv.conf

再重新 apt-get update。

注意:WSL 默认在每次重启时重新生成 /etc/resolv.conf,上述修改重启后会失效。需长期固定 DNS 时,在 3.1 的 /etc/wsl.conf 末尾追加:

[network]
generateResolvConf = false

执行 wsl --terminate Ubuntu-22.04 重启 WSL 后重新写入上面的 resolv.conf,即可持久生效。 若已按文末「WSL2 内运行 TFTP server」一节启用镜像网络(dnsTunneling=true),DNS 由 Windows 侧代理,一般无需此步骤,应排查 Windows 本机网络。

安装系统依赖(约 1~2 GB):

export DEBIAN_FRONTEND=noninteractive
apt-get install -y \
    apt-utils make \
    libc6-i386 lib32z1 lib32stdc++6 \
    zlib1g-dev liblzo2-dev rename pigz \
    libncurses5-dev libncursesw5-dev ncurses-term \
    ffmpeg autopoint g++ u-boot-tools texinfo gawk \
    libssl-dev openssl bc p7zip-full gperf \
    bison flex diffutils git git-lfs openssh-client unzip \
    libffi-dev libtool libfreetype6 dos2unix \
    uuid-dev pkg-config automake texlive unrar \
    vim sudo curl wget po4a fakeroot \
    python3-pip cmake ninja-build meson \
    libmpc-dev picocom net-tools iputils-ping \
    device-tree-compiler mtd-utils \
    python3-gi python3-dbus gir1.2-glib-2.0
apt-get clean
git lfs install --system

texlive 体积较大(数百 MB),若确认无需构建文档类产物,可将其从上面的安装列表中移除。

基础系统配置:

echo "dash dash/sh boolean false" | debconf-set-selections
dpkg-reconfigure dash -u 2>/dev/null || true
printf '' > /etc/ld.so.preload
ln -sf /usr/bin/python3 /usr/bin/python 2>/dev/null || true

安装 Python 工具包:

pip3 install -q -i https://repo.huaweicloud.com/repository/pypi/simple \
    wheel pycryptodome pyelftools cryptography kconfiglib requests \
    openpyxl pdfplumber

安装 ARM 交叉编译器(arm-v01c02,GCC 10.3.0):

工具链托管在 gitcode LFS,需先取 LFS 指针再经 batch API 拿临时下载链接(约 88 MB),解压后执行官方安装脚本即可:

# 1. 下载工具链压缩包(约 88 MB)
POINTER=$(curl -sL "https://gitcode.com/api/v5/repos/HiSpark/Hi3516CV610/raw/prebuilts/gcc-10.3-arm-musl-x86-linux-26.06.1-codesize.tgz?ref=main")
OID=$(echo "$POINTER" | grep -oE 'oid sha256:[a-f0-9]+' | cut -d: -f2)
SIZE=$(echo "$POINTER" | grep -oE 'size [0-9]+' | awk '{print $2}')
DL_URL=$(curl -s -X POST 'https://gitcode.com/HiSpark/Hi3516CV610.git/info/lfs/objects/batch' \
    -H 'Content-Type: application/vnd.git-lfs+json' \
    -d "{\"operation\":\"download\",\"objects\":[{\"oid\":\"$OID\",\"size\":$SIZE}]}" \
    | grep -oE '"href":"[^"]*"' | head -1 | sed 's/"href":"//;s/"$//' | sed 's/\\u0026/\&/g')
wget -O /tmp/gcc-toolchain.tgz "$DL_URL"

# 2. 解压并执行官方安装脚本(安装到 /opt/linux/x86-arm,自动配置 PATH 到 /etc/profile)
mkdir -p /opt/toolchains
tar -xzf /tmp/gcc-toolchain.tgz -C /opt/toolchains/
cd /opt/toolchains/gcc-10.3-arm-musl-x86-linux-26.06.1
bash install_gcc_toolchain.sh
cd ~ && rm -f /tmp/gcc-toolchain.tgz
source /etc/profile

# 验证(应输出 arm-v01c02-linux-musleabi-gcc 10.3.0)
arm-v01c02-linux-musleabi-gcc --version

进入编译环境

每次使用开发环境,在 PowerShell 中执行:

wsl -d Ubuntu-22.04

(默认用户已由 3.1 的 wsl.conf 固定为 root,直接进入即为 root 终端。)


可选:安装 Rust 工具链

编译 zeroclaw 案例时需要 Rust。linker 指向已安装的 arm-v01c02 gcc,在 WSL 终端(root) 内执行:

export CARGO_HOME=/root/.cargo
export RUSTUP_HOME=/root/.rustup
export RUSTUP_DIST_SERVER=https://repo.huaweicloud.com/rustup
export RUSTUP_UPDATE_ROOT=https://repo.huaweicloud.com/rustup/rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
    sh -s -- -y --no-modify-path --default-toolchain stable
source /root/.cargo/env
rustup target add armv7-unknown-linux-musleabi

# toolchain 安装路径由 install_gcc_toolchain.sh 决定,默认 /opt/linux/x86-arm
TOOLCHAIN_BIN="/opt/linux/x86-arm/gcc-10.3-arm-musl-x86-linux-26.06.1/arm-v01c02-linux-musleabi-gcc/bin"
TOOLCHAIN_GCC="${TOOLCHAIN_BIN}/arm-v01c02-linux-musleabi-gcc"
cat > /root/.cargo/config.toml << EOF
[target.arm-unknown-linux-musleabi]
linker = "${TOOLCHAIN_GCC}"

[target.armv7-unknown-linux-musleabi]
linker = "${TOOLCHAIN_GCC}"
EOF

# rustup --no-modify-path 安装,需手动加 PATH
cat > /etc/profile.d/rust-path.sh << 'EOF'
export PATH=/root/.cargo/bin:$PATH
EOF
chmod 755 /etc/profile.d/rust-path.sh

grep -qF 'source /etc/profile' /root/.bashrc 2>/dev/null || \
    echo 'if [ -f /etc/profile ]; then source /etc/profile; fi' >> /root/.bashrc

若华为云镜像不可用导致安装超时,改用官方源:unset RUSTUP_DIST_SERVER RUSTUP_UPDATE_ROOT


可选:WSL2 直连 USB 串口设备(usbipd-win)

WSL2 默认无法直接访问 Windows 宿主机的 USB 设备。若需在 WSL 内用 picocom 连接开发板串口,需先在 Windows 侧安装 usbipd-win,再把设备透传进 WSL。透传后节点类型由芯片决定:CH343P(官方板 J1318 调试口芯片,CDC-ACM 类)→ /dev/ttyACM0;CH340 / CP210x / FTDI(USB-serial)→ /dev/ttyUSB0。wsl.conf 中预加载的驱动(ch341 / cp210x / cdc_acm)正是为透传后的设备准备的。

使用场景:在 WSL 终端内直接查看开发板启动日志与内核输出、与 U-Boot 交互、经串口命令行调试,全程无需切换到 Windows 侧串口工具。

对后续在 WSL 中使用 Agent 的帮助:透传后 /dev/ttyACM0 是 WSL 内的普通设备,后续在 WSL 中运行的 AI Agent(命令行编码助手等)可直接读写串口,自动完成「观察启动输出 → 定位问题 → 修改代码」的调试闭环,无需人工在 Windows 侧中转串口操作。

Windows 端(PowerShell,管理员):

# 安装 usbipd-win(也可从 https://github.com/dorssel/usbipd-win/releases 下载 MSI 安装)
winget install --interactive --exact dorssel.usbipd-win

# 列出 USB 设备,找到串口设备对应的 BUSID(形如 1-3)
usbipd list

# 绑定(每台设备只需一次)并附加到 WSL
usbipd bind --busid <BUSID>
usbipd attach --wsl --busid <BUSID>

WSL 端验证(root):

dmesg | tail -5        # 应看到 cdc_acm 识别 CH343P 出 ttyACM0,或 ch341/cp210x 出 ttyUSB0
ls /dev/ttyACM* /dev/ttyUSB*   # 出现 /dev/ttyACM0(CH343P)或 /dev/ttyUSB0(CH340 类)后即可使用
picocom -b 115200 /dev/ttyACM0

wsl --shutdown、Windows 重启或 USB 重新插拔后,需重新执行 usbipd attach --wsl --busid <BUSID>


可选:WSL2 内运行 TFTP server

为开发板提供烧写镜像:把编译产物(U-Boot / 内核 / 根文件系统等)放入 WSL 内的 TFTP 目录,开发板 U-Boot 通过网线用 tftpboot 命令直接下载并烧写,免去 TF 卡来回插拔或串口传文件。

WSL2 默认 NAT 网络下,开发板无法访问 WSL 内的服务(WSL 处于虚拟内网)。因此需先开启镜像网络(WSL 与 Windows 共用同一 IP),开发板即可像访问 PC 一样访问 WSL 中的 TFTP server。仅基础编译不需要本章,可在需要网络烧写时再配置。

对后续在 WSL 中使用 Agent 的帮助:镜像网络 + TFTP 就绪后,烧写镜像只需拷贝到 /srv/tftp 即可供开发板 tftpboot 下载烧写。后续在 WSL 中运行的 AI Agent 可在编译完成后自动把镜像拷入 /srv/tftp;再配合上一章的串口直连,即可实现「编译 → 烧写 → 串口观察 → 修复」的全流程自动化。

1. 开启镜像网络(前置条件)

需 Windows 11 22H2 及以上、WSL 2.0.0 及以上版本。在 PowerShell(管理员) 中执行:

# networkingMode=mirrored 依赖 IPv6,先确保启用(设为 0 = 全部启用;该项未设置时系统默认即全部启用,可跳过)
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" `
    -Name "DisabledComponents" -Value 0 -Type DWord

# 写入 .wslconfig(内容为纯 ASCII,用 ascii 编码写入,避免 UTF-8 BOM 导致部分 WSL 版本解析失败)
@"
[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
"@ | Out-File "$env:USERPROFILE\.wslconfig" -Encoding ascii

注意Out-File整个覆盖已有的 .wslconfig。若文件已存在且有其他配置,改用记事本手动编辑,在文件末尾追加上面 [wsl2] 那段:

notepad "$env:USERPROFILE\.wslconfig"

配置后执行 wsl --shutdown,再次进入 WSL 即生效(IPv6 设置需重启系统生效)。验证:在 WSL 内执行 ip -4 addr,其中一块网卡的 IP 应与 Windows ipconfig 中物理网卡的 IP 完全一致。

Windows 10 用户:镜像网络需 Windows 11 22H2 及以上,Windows 10 无法使用;且 Windows 内置的 netsh interface portproxy 端口转发仅支持 TCP,无法转发 TFTP 的 UDP 69 端口。建议改为在 Windows 侧运行 TFTP server(如 tftpd64),根目录设为 D:\tftp,之后在 WSL 内把镜像拷到 /mnt/d/tftp、开发板 tftpbootserverip 设为 Windows IP 即可,其余流程相同(防火墙放行 UDP 69 见下文第 3 步)。

2. 安装并启动 TFTP server

WSL 终端(root) 内执行:

apt-get install -y tftpd-hpa
mkdir -p /srv/tftp
chmod 777 /srv/tftp

cat > /etc/default/tftpd-hpa << 'EOF'
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"
EOF

# wsl.conf 中 systemd=false,不能用 systemctl,用 service(init.d 脚本)启动
service tftpd-hpa start

# 验证:应看到一行 UDP *:69 的监听记录
ss -lun | grep ':69'

WSL 重启(wsl --terminate / wsl --shutdown)后 tftpd 不会自动运行,需重新执行 service tftpd-hpa start。若希望自启,可在 3.1 的 wsl.conf boot.command 末尾追加 ; service tftpd-hpa start

3. Windows 防火墙放行 UDP 69

镜像网络下,发往 WSL 的入站流量由 Hyper-V 防火墙管控(.wslconfigfirewall=true),需为 WSL 放行 TFTP 端口。在 PowerShell(管理员) 中执行:

New-NetFirewallHyperVRule -Name "WSL TFTP" -DisplayName "WSL TFTP" `
    -Direction Inbound -VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' `
    -Protocol UDP -LocalPorts 69 -Action Allow

提示找不到 New-NetFirewallHyperVRule(Windows 版本过低)时,改用经典规则:New-NetFirewallRule -DisplayName "WSL TFTP" -Direction Inbound -Protocol UDP -LocalPort 69 -Action Allow

4. 为开发板提供镜像

  1. 组网:开发板与 PC 网线直连,或接入同一交换机(同网段)。
  2. 配置 IP:镜像网络下 WSL 共用 Windows 的 IP,在 Windows「设置 → 网络 → 以太网」中把有线网卡设为静态 IP(如 192.168.1.2/24)。
  3. 放置镜像:在 WSL 终端(root) 内把编译产物复制到 TFTP 目录:
    cp <编译输出目录>/<镜像文件> /srv/tftp/    # 如 u-boot.bin、uImage 等,以实际产物为准
    
  4. 开发板下载:在开发板 U-Boot 命令行中执行(加载地址、文件名按芯片手册与实际产物调整):
    setenv ethaddr 00:5e:4d:0e:d2:b1
    setenv ipaddr 192.168.1.10       # 开发板 IP(与 PC 同网段)
    setenv serverip 192.168.1.2       # PC / WSL 共用 IP
    tftpboot <加载地址> <镜像文件>
    
    出现 # 递增的传输进度并提示传输成功,即表示 TFTP server 工作正常,随后即可按 U-Boot 流程烧写。

常见问题

现象 原因 / 解决
安装/启动 WSL 报 0x80370102 BIOS/UEFI 未开启虚拟化(Intel VT-x / AMD-V),进 BIOS 开启后重试
wsl --install --from-file 失败 需 WSL 2.4.10+(用 wsl --version 检查);确认 D:\ 可写、磁盘剩余 ≥ 30 GB
apt-get update 报 SSL 错误 系统时钟不准;执行 hwclock -s 同步时间后重试
apt-get update 报 DNS 错误 手动写入 /etc/resolv.conf(见 3.3 配置 apt 源的说明)
修改的 /etc/resolv.conf 重启后失效 WSL 每次重启会重新生成该文件,持久化方法见 3.3 说明
WSL 内找不到串口设备节点 WSL2 不能直接访问宿主 USB,需 usbipd-win 透传(见「WSL2 直连 USB 串口设备」一节)。透传后节点类型由芯片决定:CH343P(CDC-ACM,官方板 J1318 调试口)→ /dev/ttyACM*;CH340/CP210x(USB-serial)→ /dev/ttyUSB*,用 ls /dev/ttyUSB* /dev/ttyACM* 一并查找
开发板 tftpboot 一直超时(T T T) 按顺序检查:镜像网络是否生效(WSL 与 Windows IP 一致)、service tftpd-hpa start 是否已执行、防火墙是否放行 UDP 69、双方 IP 是否同网段(见「WSL2 内运行 TFTP server」一节)