拿到 Jetson Orin 系列开发板的第一件事,绝大多数人都会被同一个问题卡住:NVIDIA 官方提供的 SDK Manager 只支持 Linux 系统。可主力机偏偏是 Windows,难道真要为了刷个系统装双系统,或者再去整一台 Ubuntu 主机?我在折腾 Orin Nano 和 Orin NX 的时候,把双系统、虚拟机、WSL2 三条路都试了一遍,最后稳定跑通的方案,就是用 WSL2 承载 SDK Manager,配合 USB 设备透传完成刷机。这篇文章就完整记录这套方案的每一个步骤、每一个坑,以及为什么这么选。
这套方案能解决什么问题?简单说,你只要有一台 Windows 10/11 的电脑,不需要重装系统,不需要虚拟机里折腾显卡直通,就能通过 WSL2 里的 SDK Manager 给 Jetson Orin 系列开发板烧录系统、安装 JetPack 组件。无论你是刚入门的嵌入式爱好者,还是要在 Orin 上做深度学习部署的工程师,只要 Windows 是主力系统,这篇文章都值得收藏。
1. 为什么非要用 WSL2:方案选型的真实考量
1.1 双系统、虚拟机、WSL2 三条路的对比
先把三个方案摆出来,说说我为什么最终放弃了前两个。
第一个方案是装双系统。听起来最“正统”,但实际用起来非常折腾。你得给 Ubuntu 单独分一个分区,每次切换系统要重启,开完 Ubuntu 想回 Windows 又要重启一次。开发过程中经常需要在 Windows 上查资料、拷文件、跑一些 Windows 特有的工具,来回重启的效率损失是实打实的。更难受的是,双系统安装过程中一旦引导出问题,Windows 启动项直接被覆盖,修复起来又是一顿折腾。我当时是在一块闲置 SSD 上装的 Ubuntu,结果有一次 Windows 更新后引导丢失,花了一个晚上才救回来,从此对这个方案彻底死心。
第二个方案是虚拟机跑 Ubuntu,比如 VirtualBox 或 VMware。这个方案的好处是不用重启,虚拟机随时开关。但问题也很致命:SDK Manager 刷机靠的是 USB 设备直连,而虚拟机要把 Windows 的 USB 设备直接映射给虚拟机,需要装扩展包,兼容性时好时坏。Jetson 开发板进入 Recovery 模式后,USB 设备在系统里的枚举状态比较特殊,虚拟机偶尔会把设备识别成未知设备,刷机刷到一半失败,板子直接变砖(其实是变半砖,还能重新进 Recovery 救回来,但吓人)。
第三个方案就是 WSL2。WSL2 本质上是一个轻量级虚拟机,但它和 Windows 的融合度远高于传统虚拟机。配合 usbipd-win 这个工具,可以把 Windows 的 USB 设备直接“透传”给 WSL2,让 Linux 系统里的 SDK Manager 直接操作 Jetson 板子。而且 WSL2 支持 WSLg,也就是说 SDK Manager 的图形界面可以直接显示在 Windows 桌面上,体验上基本和原生 Ubuntu 没什么区别。
1.2 WSL2 跑 SDK Manager 的可行性与边界
先说结论:WSL2 跑 SDK Manager 完全可行,这也是 NVIDIA 官方后来在 Jetson 文档里认可的一种方式。但要说清楚边界,不是什么场景都适合。
SDK Manager 的本质是一个图形化的包管理器,它做的事情分两大块:第一块是通过 USB 把系统镜像烧写到 Jetson 的存储里,这个过程中它会调用一堆 Linux 下的刷机工具链,比如 Tegra 系列的 flash 工具、驱动打包脚本;第二块是刷完系统后,再把 CUDA、cuDNN、TensorRT 这些 SDK 组件通过 SSH 推到板子上安装。这两块操作在 WSL2 里都能正常工作,因为 USB 透传把板子挂在了 WSL2 的 USB 总线上,而 SSH 走的是网络。
边界在哪里?第一,WSL2 对 USB 设备的支持不是原生的,它靠的是 usbip 协议把 USB 设备通过网络转发到 WSL2 虚拟机里,所以对设备的兼容性有一点要求,绝大多数开发板都支持,但也不能百分之百保证所有 USB 设备都正常。第二,刷机过程对 USB 稳定性要求极高,WSL2 的 USB 透传偶尔会抽风,比如传输中断、设备丢失,需要做好重试的心理准备。第三,WSL2 的磁盘性能不如原生 Linux,SDK Manager 下载和写镜像的速度会受一点影响,但不会明显拉长整个刷机时间,因为瓶颈在 USB 写入速度上。
另外要强调一点:如果你用的是 WSL1(老版本),这条路走不通,必须升级到 WSL2。WSL1 没有完整的 Linux 内核,usbip 功能根本跑不起来。下面所有操作都默认你已经用上了 WSL2。
2. 开工前的硬性检查:这些条件不满足别白忙
2.1 硬件和系统的底线要求
先把硬性条件过一遍。首先是 Windows 版本:Windows 10 版本 21H2 或更高,或者 Windows 11 都行。Windows 10 太老的版本跑 WSL2 会遇到内核更新失败的问题,建议能升 Windows 11 就直接升,省得后面踩坑。
内存方面,WSL2 默认会分走宿主机一半的内存。Jetson 刷机过程中,SDK Manager 本身占用不大,但如果你同时开着浏览器查资料、开着微信,16GB 内存是底线。我自己的机器是 32GB,WSL2 分到 8GB,跑 SDK Manager 加各种工具绰绰有余。如果只有 8GB 内存,也勉强能跑,但建议把其他程序都关掉,避免内存压力导致系统卡顿。
CPU 方面要求不高,只要支持虚拟化(Intel VT-x 或者 AMD-V)就行,现在的主流 CPU 都支持。但要注意,WSL2 是基于 Hyper-V 虚拟化平台的,如果你平时在用 VMware 或 VirtualBox 跑其他虚拟机,可能会遇到 Hyper-V 和其他虚拟机软件的冲突,需要在 Windows 功能里开启必要的虚拟化组件。
磁盘空间是最容易被忽略的。WSL2 的 Ubuntu 系统本身占 5-10GB,SDK Manager 下载 JetPack 组件会占 20-40GB(取决于你选择的组件数量),再加上编译缓存、日志等杂七杂八的空间,建议你提前给 WSL2 分配至少 80GB 的磁盘配额。这里说的“分配”不是创建虚拟机时设定大小,而是确保你的系统盘有 80GB 空闲空间。WSL2 默认把虚拟磁盘文件放在 C 盘用户目录下,如果你的 C 盘空间紧张,务必先把 WSL2 迁移到其他盘,这一步我在后面的实操部分会详细说。
2.2 检查 BIOS 虚拟化与 Windows 功能
很多时候 WSL2 装不上,问题不在软件,而在 BIOS。先按Ctrl + Shift + Esc打开任务管理器,切到“性能”标签页,看右下角的“虚拟化”是否显示“已启用”。如果显示“已禁用”,需要进 BIOS 开启 Intel VT-x 或 AMD-V,这个每个主板的位置不一样,一般是 Advanced 或者 Security 菜单下找 Virtualization Technology 之类的选项。
接下来确保 Windows 功能里已经开启了“适用于 Linux 的 Windows 子系统”和“虚拟机平台”两项。最快的方式是在 PowerShell(以管理员身份运行)里执行:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完重启系统。如果之前没装过 WSL,建议直接用wsl --install一条命令搞定,新版 WSL 会把内核和默认发行版一起装好。装完之后查看一下版本:
wsl --set-default-version 2 wsl --status确认输出里的默认版本是 2 就行。这里我多一句嘴:不要用 Microsoft Store 里那个旧的“Windows Subsystem for Linux”应用,要用新版的 WSL,因为新版才支持wsl --install这种省心的安装方式,而且对新硬件的兼容性更好。
2.3 磁盘空间的隐藏杀手:WSL2 虚拟磁盘的存放位置
这一步我在第一次装的时候没注意,结果三个月后 C 盘直接标红。WSL2 的虚拟磁盘默认存储在C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited...这个目录下,文件名叫ext4.vhdx。这个文件会随着你在 WSL2 里安装的软件越来越多而逐渐膨胀,而且它有个特点:在 WSL 里删了文件,虚拟磁盘文件也不会自动缩小。
如果你担心 C 盘空间,最好在一开始就把 WSL2 导出再导入到其他盘符。操作方法是先查看当前安装的发行版名称(一般是 Ubuntu),然后执行导出和导入,导出前记得先wsl --shutdown关闭 WSL:
wsl --export Ubuntu D:\wsl\ubuntu-backup.tar wsl --unregister Ubuntu wsl --import Ubuntu D:\wsl\ubuntu E:\wsl\ubuntu-backup.tar --version 2注意导入后默认用户会变成 root,需要用ubuntu config --default-user 你的用户名重新设置默认用户。嫌麻烦的话,也可以直接在 Windows 设置里把整个系统盘之外的路径作为 WSL 的安装位置(新版 WSL 支持在安装时指定路径),但如果你已经装完了,导出导入就是最稳妥的办法。我目前是把 WSL 放在 D 盘的一个虚拟磁盘文件里,C 盘空间再也没有告过急。
3. 把 WSL2 环境搭到能用的状态
3.1 安装 Ubuntu 并更换国内软件源
WSL 安装 Ubuntu 很简单,wsl --install -d Ubuntu-22.04一条命令就能拉下来。选 22.04 还是 20.04?SDK Manager 对 Ubuntu 版本的官方要求是 20.04 或 22.04,我用 22.04 跑了 JetPack 5.x 和 6.x 都没问题,选 22.04 更稳妥一些。
装完进入 WSL 之后,第一件事就是换软件源。不换源的话,后面apt install下载速度会让你怀疑人生。Ubuntu 22.04 的源文件在/etc/apt/sources.list,里面有archive.ubuntu.com和security.ubuntu.com两个地址,把这两个地址都替换成国内的镜像源。我用的是清华源,也可以选阿里云、中科大,国内源速度都差不多。
替换完执行sudo apt update和sudo apt upgrade。这一步耗时比较长,建议在等待的时候把后面的 usbipd 部分先看一遍,因为刷机环境主要就差 USB 透传这一块了。
3.2 解决 USB 透传的关键一环:usbipd-win
这是整套方案里最关键的一步,也是坑最多的地方。先解释一下原理:WSL2 是一个轻量级虚拟机,它没有权限直接访问宿主机的 USB 控制器。微软和社区给出的方案是,在 Windows 上安装一个叫 usbipd-win 的服务,它负责把 Windows 的 USB 设备“共享”出去;然后在 WSL2 里安装 usbip 客户端工具,通过网络协议把设备挂载到 Linux 内核上。整个过程对 WSL2 里的程序来说是透明的,SDK Manager 看到的就是一个普通的 USB 设备。
usbipd-win 的安装直接在 Windows 上用 winget 一条命令搞定:
winget install usbipd装完后需要重启一下终端或者整个 Windows,让服务生效。之后在 PowerShell(管理员权限)里执行usbipd list,就能看到当前插在 Windows 上的所有 USB 设备,格式大概是1-2 4d9:1234 Device Name这样。
WSL2 里面的客户端工具也要装齐,否则 attach 不上去。进入 WSL 后执行:
sudo apt install linux-tools-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20第一行安装工具,第二行是把 usbip 命令链接到一个固定位置,因为不同内核版本的工具路径不一样,不链接的话后面执行 usbip 会一直提示找不到命令。装完验证一下:
usbip version能输出版本号就说明客户端工具没问题。
3.3 网络模式与防火墙的注意事项
WSL2 默认的网络模式是 NAT,每次启动 IP 都可能变化,这个对 SDK Manager 不构成影响,因为 SDK Manager 刷机阶段走的是 USB,装完系统后走的是 SSH,而 SSH 连接板子是通过板子的 IP,和 WSL 自己的 IP 没关系。
但有一个坑值得注意:WSL2 里的程序访问 Windows 宿主机服务,用的是/etc/resolv.conf里的 DNS 地址或者通过$(hostname).local解析,这个在 SDK Manager 场景下基本用不到,可以不用管。真正要留意的是 Windows 防火墙。usbipd 服务在 Windows 上监听 3240 端口,WSL2 通过这个端口和 Windows 通信。我在实际使用中遇到过一次 Windows 防火墙弹窗拦截了 usbip 的通信,导致 attach 设备后 WSL 里死活看不到设备。如果遇到这种情况,在 Windows 防火墙里放行“usbipd”就行。
还有一种情况是公司网络策略屏蔽了设备直连,这个比较少见,但如果你在办公环境折腾,遇到 USB 透传失败,可以先排查一下防火墙策略。
4. SDK Manager 安装与刷机实操全流程
4.1 下载安装 SDK Manager 以及登录问题
SDK Manager 的下载地址在 NVIDIA 的开发者官网,需要注册 NVIDIA 账号才能下载。下载的是 .deb 安装包,文件名类似sdkmanager_2.x.x_XXXX_amd64.deb。把这个安装包放到一个 Windows 和 WSL 都能访问的目录,比如C:\Users\你的用户名\Downloads,在 WSL 里这个路径对应/mnt/c/Users/你的用户名/Downloads。
安装 SDK Manager 前,先确认 WSL2 里把依赖装好:
sudo apt install -y python3 python3-pip sshpass sudo apt --fix-broken install cd /mnt/c/Users/你的用户名/Downloads sudo dpkg -i sdkmanager_*.deb如果 dpkg 报依赖错误,执行sudo apt -f install自动修复。安装完成后,在 WSL 里执行sdkmanager启动。这里说明一下,新版 SDK Manager 是图形界面(Java 写的),通过 WSLg 可以直接显示在 Windows 桌面。如果sdkmanager命令启动报错,大概率是 Java 环境问题,先java -version检查,没装就sudo apt install default-jre。
打开后第一步是登录 NVIDIA 账号。这个账号必须提前注册好,刷机过程中如果登录环节卡住,检查网络能不能正常访问 NVIDIA 的服务器。
4.2 进入 Recovery 模式并把设备透传给 WSL2
这一步是整个流程的高危区,一不小心就会在错误的地方折腾很久。Jetson 开发板进入 Recovery 模式的方法大致相同,但不同型号的按键位置和刷机口不一样,我以最常见的 Orin Nano Developer Kit(8GB 版本)为例。
先准备好:开发板接好电源,用 USB-C 数据线连接开发板的 USB-C 刷机口(Orin Nano 开发套件的刷机口是靠近电源口的那一个 USB-C),另一端插在 Windows 电脑上。注意,USB 线一定要用支持数据传输的线,有些线只能充电不能传数据,插上去板子没反应你会怀疑是板子坏了。
接下来进入 Recovery 模式:按住开发板上的 Force Recovery 按键不放,同时按一下 Reset 按键(或者重新插拔电源),等待两秒后松开 Force Recovery。这时在 Windows 的 PowerShell 里执行:
usbipd list如果正常,你会看到一个设备,描述类似NVIDIA Corp. APX,Busid 一般是1-6或者2-4。APX 就是 NVIDIA 设备处于 Recovery 模式时的状态名,这个名称出现在列表里,说明板子已经成功进入 Recovery 模式。
现在把这个设备透传给 WSL2。整个过程分三步:绑定、附加、验证。
# 以管理员身份运行 PowerShell usbipd bind --busid 1-6 usbipd attach --wsl --busid 1-6第一条命令把设备绑定到 usbip 协议,第二条命令附加到 WSL2。执行第二条命令后,切回 WSL 终端,执行:
lsusb如果能看到类似Bus 001 Device 002: ID 0955:7023 NVIDIA Corp. APX这样的输出,说明设备已经成功透传进来了。这里有个细节:0955是 NVIDIA 的 USB Vendor ID,后面跟着的设备 ID 会因芯片型号不同而不同。如果 lsusb 里看不到任何 NVIDIA 设备,先别急着重刷,重点检查 attach 命令有没有报错,以及 WSL 里usbip工具链是否完好。
4.3 SDK Manager 刷机参数怎么选
设备透传成功后,回到 SDK Manager 界面。它会让你选择目标硬件,这个列表里会显示通过 USB 检测到的 Jetson 设备。如果 SDK Manager 没有识别到你的板子,可以点击界面上的刷新按钮,或者检查一下刚才 attach 的 USB 设备是否还在。
接下来是选择系统版本和组件。这一步要特别说明,SDK Manager 会让选择 Jetson OS 版本,也就是 JetPack 的底包版本。我的建议是:不要选最新版本,选 LTS 版本。比如 JetPack 6.0 发布后,如果它的版本号是 DP(Developer Preview),就选 JetPack 5.1.2 或者 6.0 GA(Generally Available)这种稳定版本。稳定版本用的人多,遇到的坑少,社区资料也多。
组件选择界面会列出 CUDA、cuDNN、TensorRT、DeepStream 等一大堆组件。如果你是第一次刷机,可以全选,让 SDK Manager 一次性装好。但要注意,组件越多,下载量越大,刷机时间越长。如果只是先跑起来,建议只选核心组件(CUDA、cuDNN、TensorRT),DeepStream 这种应用层面的组件后面再手动装也不迟。
SDK Manager 刷机过程分为两个阶段:第一阶段把系统镜像写入板子的存储,这个过程板子屏幕可能会亮(如果接了 HDMI 的话),显示一个 Linux 系统的安装界面,这时候千万别断电;第二阶段是 SDK Manager 通过网络 SSH 连接已启动的板子,把之前勾选的 SDK 组件推送到板子上。整个流程耗时在 30 分钟到 1 小时之间,取决于你的网速和选择的组件数量。
提示:刷机过程中 SDK Manager 会要求你在系统安装界面设置用户名和密码,这个用户名密码要记好,后续 SSH 连接、安装软件都要用到。设置完系统账号后,SDK Manager 会提示板子重启,重启完会自动开始安装 SDK 组件,这时候唯一要做的就是等待。
5. 刷机过程中那些让人血压飙升的问题
5.1 设备透传失败的常见原因与排查
先列一个我多次遇到的场景:usbipd list能看到 APX 设备,但usbipd attach --wsl --busid 1-6执行后,WSL 里lsusb什么都没有。
排查思路分三步。第一步,确认 WSL 里 usbip 工具是否正常,执行usbip version,如果提示找不到命令,回到前面 3.2 的部分重新配置。第二步,确认设备是否处于绑定状态,在 PowerShell 里执行usbipd bind --busid 1-6,如果提示已经绑定,可以先usbipd unbind --busid 1-6再重新绑定。第三步,检查是否正确使用了--wsl参数。usbipd-win 新版支持多个 WSL 发行版同时存在,如果没有指定发行版名称,它默认附加到默认发行版,如果你装了多个发行版,需要手动指定:usbipd attach --wsl Ubuntu-22.04 --busid 1-6。
另外一个非常隐蔽的坑:WSL2 必须在内核层面编译了 usbip 支持,默认的 WSL2 内核是支持的,但如果你手动更新过内核(比如为了某些硬件兼容性用的自定义内核),usbip 支持可能没有被编译进去,这时候只能回到默认内核。
5.2 刷到一半中断怎么救
刷机最怕的就是刷到一半中断,但说实话,这个方案里遇到中断的概率比原生 Ubuntu 要高一点,因为多了一层 USB 透传。SDK Manager 刷机过程中,最常见的失败点是 Uboot 烧写阶段或者根文件系统写入阶段,报错信息一般是Failed to flash或者Device not found。
遇到中断先别慌,Jetson 板子没那么容易变砖。处理流程是:先关闭 SDK Manager(如果它还在运行的话),在 PowerShell 里usbipd detach --busid 1-6分离设备,然后按一下开发板的 Reset 按键,重新进入 Recovery 模式,再重新 attach,最后重新打开 SDK Manager 再刷一次。
如果 SDK Manager 反复在同一个步骤失败,就要考虑是不是 USB 线的问题。我踩过最冤枉的一次坑,是一根看起来没什么问题的 USB-C 线,数据传输不稳定,导致刷机中途反复断连。换了一根粗一点的、带屏蔽层的线之后,一次就过了。刷机的 USB 线一定要用高质量的线,这一点我觉得值得在所有教程里重复强调。
还有一点要注意:如果是第二次刷机,SDK Manager 默认会保留之前的配置,有时候它们之间会产生冲突。建议每次刷机失败重试前,把 SDK Manager 的缓存目录清一下。SDK Manager 的缓存目录在~/nvidia下面,有个sdkmanager_downloads文件夹,删除后重新下载会得到一份干净的安装包。
5.3 下载速度慢和网络中断的应对措施
SDK Manager 在刷机前会从 NVIDIA 的服务器下载几个 GB 的系统镜像。如果你没有内网加速手段,这个下载过程可能会比较煎熬,甚至下载到一半直接失败。针对这个场景,我的建议是:如果环境允许,尽量把 Windows 系统本身的网络配置好;同时,不要反复取消重来,因为 SDK Manager 有断点续传能力,下载中断后重新点开始,它会继续从断点下载。
另外一个实用技巧:SDK Manager 下载的镜像文件会缓存在~/nvidia/sdkmanager_downloads目录。如果你有另一台电脑已经下载过同样的镜像,可以把这个目录直接拷贝过来,SDK Manager 检测到本地缓存后就会跳过下载步骤,直接开始刷机。这个技巧在团队协作、多块板子刷机的时候特别实用。
还有一个小细节:整个刷机过程中,WSL2 的窗口不要关闭,不要执行wsl --shutdown,否则 USB 设备会被强制分离,刷机必然失败。
6. 刷完之后的收尾工作与日常使用建议
系统刷好、SDK 组件装完之后,并不意味着万事大吉。还有一个必做的收尾步骤:把 USB 设备从 WSL2 里分离,还给 Windows 宿主机。
在 PowerShell 里执行:
usbipd detach --busid 1-6分离之后,开发板的 USB-C 线就可以拔下来了。如果你下次还要刷机,重复之前的 attach 流程就行。
日常使用中最常遇到的一个情况是,WSL2 的虚拟磁盘文件经过多次安装、卸载软件之后越来越大。前面提到过,WSL 里删除文件不会让 vhdx 自动缩小。我这里补充一个安全瘦身的方法:在 Windows 里以管理员身份打开 PowerShell,执行wsl --shutdown关闭 WSL2,然后运行diskpart,依次执行:
diskpart select vdisk file="D:\wsl\ubuntu\ext4.vhdx" attach vdisk readonly compact vdisk detach vdisk exit这样会把虚拟磁盘里空缺的空间物理缩小,效果相当明显。我第一次执行的时候,把一个膨胀到 60GB 的 vhdx 压缩到了 25GB,C 盘空间压力瞬间减轻。
另外说下开发衔接。Jetson 刷完机后,日常开发时经常需要在电脑和板子之间同步代码。我的习惯是电脑上用 VSCode 的 Remote - SSH 插件直接连板子,在 Windows 里就能写代码、调试。WSL2 本身也有 VSCode 支持(通过 Remote - WSL 插件),如果你有一个项目已经配置好了 WSL2 的交叉编译环境,刷完机后直接复用即可,不需要额外配置。
如果你后续要在 Jetson 上跑 Isaac Sim 或者做机器人仿真,WSL2 本身也可以用,但那是另一个比较大的话题了。至少在这篇文章的场景里,WSL2 已经帮我把刷机和基础环境配置的痛苦降到了最低。
最后分享一个我的使用习惯:每次刷机之前,先把 Windows 上其他占用 USB 的设备(比如无线鼠标接收器、外接 U 盘)暂时拔掉,只保留 Jetson 的 USB 线。倒不是说一定会冲突,但刷机这种一个小时的操作,任何一点不确定性都值得提前消除。毕竟真正干活的时候,你最不想遇到的就是刷完后发现板子起不来,还得从头再来一遍。