.NET 生态系统中 LoongArch 与 RISC-V 的整合深度分析
摘要
随着全球计算架构逐渐从 x64/ARM 的双寡头垄断向更加多元化的方向演进,开源指令集架构(ISA)RISC-V 与中国自主研发的 LoongArch(龙架构)正迅速成为嵌入式系统、物联网(IoT)及服务器领域不可忽视的力量。微软.NET 平台作为跨平台应用开发的基石,在迈向.NET 10 的演进过程中,虽然对主流架构的支持愈发稳固,但对这两个新兴架构的支持却呈现出一种复杂且微妙的“半官方”状态。
本文旨在对这一现状进行详尽的技术调研与战略分析。研究发现,尽管.NET 核心代码库(CoreCLR、CoreFX)已在主分支中包含了对 RISC-V 和 LoongArch 的大量上游支持代码,但由于微软严格的分层支持策略(Tiered Support Policy),这两个架构目前仍处于“社区支持(Tier 3)”层级。这意味着官方 NuGet.org 并不提供针对 linux-riscv64 或 linux-loongarch64 的预编译运行时包(Runtime Packs),导致开发者无法通过标准的 dotnet publish 流程直接构建应用。
目前的生态系统依赖于非官方的“补给线”:RISC-V 领域主要依靠 Filip Navara 等核心贡献者维护的社区构建与 GitHub Actions 流水线;而 LoongArch 则呈现出一种由龙芯中科(Loongson Technology)主导的“旧世界”与开源社区推动的“新世界”ABI(应用程序二进制接口)并存的割裂局面,龙芯中科重点转向支持“新世界”ABI 2.0,主要依赖 nuget.loongnix.cn 等专用源。本文将深入剖析这些非官方解决方案的技术细节、跨平台编译(Cross-Compilation)的构建链挑战、Native AOT(本机提前编译)在嵌入式场景下的具体实施路径,以及企业在采用这些架构时必须考量的供应链安全风险。
1. 新兴架构在.NET 战略版图中的定位
1.1 架构多元化的驱动力
.NET 10 的发布周期正值计算硬件发生深刻变革的时期。RISC-V 凭借其模块化和免许可费的特性,正在重新定义边缘计算和微控制器市场;而 LoongArch 则承载着特定地域市场对计算自主可控的战略需求,正试图从桌面端向高性能服务器端突围。对于.NET 生态而言,支持这些架构不仅是技术上的扩展,更是保持平台普适性和生命力的关键 。
然而,这种支持并非一蹴而就。微软在.NET 10 的官方发布说明中,虽然强调了运行时(Runtime)在 JIT 内联、栈分配优化以及对 AVX10.2 的支持,但对于 RISC-V 和 LoongArch 的提及主要集中在代码层面的兼容性,而非产品层面的交付 。这种差异揭示了微软对于架构支持的严谨态度:代码合并意味着技术可行性的验证,而官方二进制发布则意味着商业承诺与服务等级协议(SLA)的绑定。
1.2 “半官方”状态的深层含义
“半官方”一词准确地概括了当前的局面。从代码仓库的角度看,dotnet/runtime 已经接受并合并了由三星(Samsung)、龙芯中科以及社区开发者提交的大量针对 RISC-V 和 LoongArch 的代码 。这些架构的代码与 x64 代码并存于同一个仓库中,甚至共享部分测试基础设施。
但是,从交付物的角度看,它们完全缺席。微软的构建基础设施(CI/CD)虽然在一定程度上涵盖了这些架构(例如通过 QEMU 仿真或合作伙伴提供的有限硬件),但并不生成发布到 NuGet.org 的官方包。这意味着:
- 缺乏官方 SDK 安装器:用户无法在微软官网下载到针对 LoongArch 或 RISC-V 的.NET SDK 安装包 。
- NuGet 供应链断裂:标准的 dotnet build 或 dotnet publish 命令会尝试从 NuGet.org 拉取如 Microsoft.NETCore.App.Runtime.linux-riscv64 的包,由于该包不存在,构建过程会直接失败 。
- 依赖社区修补:开发者必须手动配置 NuGet.config 以指向第三方源,或者自行编译整个运行时,这大大提高了入门门槛 。
这种状态将持续到.NET 10 及其后续版本,直到这些架构的硬件普及率、稳定性以及 CI 基础设施的可靠性达到微软认定为 Tier 2 或 Tier 1 的标准 。
2. LoongArch(龙架构):主权、割裂与生态重构
LoongArch 是一个独特的案例,它不仅是一个新的指令集,更代表了一个完整的、由单一厂商强力推动的软件生态系统。在.NET 的支持路径上,LoongArch 面临着比技术本身更为复杂的生态割裂问题,即所谓的“旧世界”与“新世界”之争。
2.1 ABI 鸿沟:旧世界 vs. 新世界
理解 LoongArch 上的.NET 支持,首先必须理解其 ABI(二进制接口)的演进。
- 旧世界(Old World / ABI 1.0):这是龙芯早期为了快速兼容 MIPS 生态遗留软件而定义的接口。龙芯自家的操作系统 Loongnix 以及早期的.NET Core 3.1、.NET 6/7 移植工作主要基于此 ABI。由于它是龙芯专有的,并未被上游 Linux 社区广泛接受 。
- 新世界(New World / ABI 2.0):这是经过标准化并被 Linux 内核(5.19+)、GCC(12+)、LLVM(16+)等上游社区正式接纳的规范。它是 LoongArch 的未来,但与旧世界二进制不兼容 。
这一分裂直接冲击了.NET 开发者。目前,.NET 8 的主要支持力量仍集中在“旧世界”环境(Loongnix),这主要是为了满足存量商业软件的需求。然而,随着.NET 9 和.NET 10 的推进,社区(以及未来的官方支持)正坚决地转向“新世界”ABI。这意味着开发者在 Loongnix 上编译的.NET 应用程序,可能无法在安装了最新 Arch Linux 或 Debian 的 LoongArch 机器上运行,反之亦然 。
2.2 龙芯社区的应对策略与 NuGet 源
为了弥补官方支持的缺失,龙芯开源社区构建了一套独立的基础设施。这不仅仅是一个 GitHub 仓库,而是一个完整的镜像生态。
2.2.1 专用 NuGet 源:nuget.loongnix.cn
这是目前在 LoongArch 平台上开发.NET 应用的生命线。由于微软官方 NuGet 源中没有 LoongArch 的运行时包(Runtime Packs),龙芯团队维护了这个私有源。
-
功能:该源托管了经过修改并适配 LoongArch 的 Microsoft.NETCore.App.Runtime 包。
-
配置:开发者必须在项目根目录添加或修改 NuGet.config 文件,显式加入该源。根据调研,典型的配置如下:
XML
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="loongnix" value="https://nuget.loongnix.cn/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>此配置的优先级至关重要。如果 nuget.org 排在前面且包含同名但不兼容的包(虽然目前概率较低,但未来可能发生),可能会导致还原错误。通过明确指定源,构建系统能够正确拉取 LoongArch 的特定依赖 9。
2.2.2 非官方自动化构建(Unofficial Builds)
除了 NuGet 源,龙芯社区还在 GitHub 上维护了一个名为 dotnet-unofficial-build 的仓库。该仓库定期发布预编译的.NET SDK 二进制包(tar.gz 格式)。
- 版本策略:这些构建通常紧跟.NET 的上游发布节奏(如.NET 8.0.x, 9.0.x),但存在一定的时间滞后。
- 使用方式:这是一种“旁路”安装方式。开发者下载压缩包后,将其解压到 /opt/dotnet 或 $HOME/dotnet,并手动设置 DOTNET_ROOT 和 PATH 环境变量。这是在 LoongArch 物理机上进行原生开发的最直接途径 14。
2.3 技术挑战与现状
尽管有了这些工具,LoongArch 的.NET 支持仍面临挑战:
- JIT 优化滞后:虽然 LoongArch64 的 JIT 后端已能正常工作,但针对其特有的 LSX/LASX 向量指令集的优化尚未完全并在.NET 10 的早期预览版中普及,这导致其在密集计算任务下的性能可能不如经过高度优化的 x64 平台 。
- 调试工具缺失:官方的诊断工具(如 dotnet-sos, dotnet-dump)往往依赖于特定的原生库构建。调研显示,LoongArch 平台的这些诊断工具包并未完全发布或集成到标准发布流程中,这使得生产环境下的故障排查变得异常困难 。
3. RISC-V:分布式协作与跨平台构建的艺术
与 LoongArch 由单一厂商主导不同,RISC-V 在.NET 生态中的崛起是典型的分布式开源协作成果。三星(Samsung)、阿里巴巴(Alibaba)以及个人开发者(如 Filip Navara)共同构成了这一生态的支柱。
3.1 社区驱动的开发模式
目前,RISC-V 的.NET 移植工作主要由三星的 Tizen 团队领衔,重点在于确保运行时(Runtime)和基类库(BCL)在 RISC-V 64位架构(RV64GC)上的功能完整性。
- CI 基础设施:不同于微软 Azure 上庞大的 x64 服务器市场,RISC-V 的持续集成测试依赖于 VisionFive 2 等单板计算机(SBC)以及 QEMU 仿真器。这种硬件资源的限制是其未能进入 Tier 1 支持的主要瓶颈之一 。
- 目标平台:主要的移植目标是通用的 Linux 环境(linux-riscv64),这使得其比 LoongArch 更容易融入现有的 Linux 发行版生态(如 Ubuntu, Debian, Fedora)。
3.2 Filip Navara 与 dotnet-riscv
在缺乏官方二进制包的情况下,Filip Navara 的 GitHub 仓库 dotnet-riscv 成为了 RISC-V.NET 开发者的事实标准。
- 角色定位:该项目不仅仅是一个代码分支,更是一个构建农场。它利用 GitHub Actions 自动从上游 dotnet/runtime 同步代码,并执行交叉编译,生成可用的 SDK 和运行时包 16。
- 本地源模式(Local Feed Pattern):由于微软不允许非官方构建上传至 NuGet.org,Navara 推荐的解决方案是“本地 NuGet 源”。开发者下载他发布的 NuGet 包(.nupkg 文件),将其放入本地文件夹,然后在 NuGet.config 中将该文件夹配置为包源。这种方法绕过了 NuGet.org 的限制,使得 dotnet restore 能够找到 runtime.linux-riscv64.Microsoft.NETCore.App 包 。
3.3 跨平台编译的必要性
RISC-V 设备(如 Lichee Pi, StarFive)的性能虽然在提升,但编译大型项目(特别是.NET 运行时本身)仍然极其缓慢。因此,交叉编译(Cross-Compilation) 成为了主流工作流。这引入了极高的复杂性,核心在于“Sysroot”的构建。
- Sysroot 困境:要在 x64 主机上编译出能在 RISC-V 上运行的代码,编译器必须链接到目标系统的基础库(libc, libstdc++, openssl 等)。如果主机使用的 Sysroot(例如基于 Debian Sid)与目标设备(例如基于 Alpine Linux)不匹配,程序将在运行时崩溃(如 glibc 版本错误)17。
4. 技术实施指南:构建、部署与 Native AOT
本节将基于调研收集的技术片段,整合出一套针对.NET 10 环境下 LoongArch 和 RISC-V 的操作实施指南。
4.1 托管应用部署(Managed Deployment)
对于标准的.NET 应用程序(依赖 JIT),部署的核心在于获取正确的运行时包。
LoongArch 实施步骤
-
环境准备:在开发机上安装.NET SDK(x64版本即可,利用 SDK 的跨平台发布功能)。
-
配置源:在项目目录创建 NuGet.config,加入 nuget.loongnix.cn。
-
发布:
Bash
dotnet publish -r linux-loongarch64 --self-contained该命令会触发 SDK 从龙芯源下载 LoongArch 特定的运行时包,并将其打包到输出目录。注意,由于 ABI 问题,需确保所选的 NuGet 包版本与目标系统的 Loongnix 版本兼容(旧世界 vs. 新世界)11。
RISC-V 实施步骤
-
获取包:从 filipnavara/dotnet-riscv 的 Releases 页面下载最新的 .nupkg 文件。
-
建立本地源:
Bash
mkdir -p local-feed
cp *.nupkg local-feed/ -
发布:
Bash
dotnet publish -r linux-riscv64 --self-contained -s./local-feed -s https://api.nuget.org/v3/index.json通过 -s 参数显式指定本地源,确保 SDK 能找到 RISC-V 的运行时资产 7。
4.2 Native AOT(本机提前编译)深度解析
Native AOT 是嵌入式场景的“圣杯”,它能显著减少启动时间和内存占用,且无需在目标设备上安装.NET 运行时。然而,在 RISC-V 和 LoongArch 上启用 Native AOT 面临严峻的工具链挑战。
核心挑战:链接器与 ObjCopy
.NET SDK 默认假定使用宿主机的工具链。在交叉编译时,必须强制指定目标架构的工具。调研发现,常见的错误包括 NU1102(找不到包)和链接错误(invalid linker name)8。
关键 MSBuild 属性
为了成功进行 Native AOT 交叉编译,必须在 .csproj 或命令行中覆盖以下属性 19:
| 属性名称 | 作用 | 典型值 (RISC-V 示例) | 典型值 (LoongArch 示例) |
|---|---|---|---|
| PublishAot | 启用 AOT 编译 | true | true |
| CppCompilerAndLinker | 指定 C++ 编译器 | clang (需支持 riscv64) | gcc (LoongArch 版) |
| ObjCopyName | 指定 ObjCopy 工具 | llvm-objcopy | loongarch64-linux-gnu-objcopy |
| SysRoot | 指定目标系统根文件系统路径 | /crossrootfs/riscv64 | /crossrootfs/loongarch64 |
| LinkerFlavor | 指定链接器类型 | lld (推荐配合 Clang) | bfd 或 ld |
| StripSymbols | 是否剥离符号(减小体积) | true | true |
构建 Sysroot 的官方脚本
微软在 dotnet/runtime 仓库中提供了一个鲜为人知但至关重要的脚本:eng/common/cross/build-rootfs.sh。这是构建高可用 Sysroot 的标准方法。
-
用法示例:
Bash
# 克隆运行时仓库
git clone https://github.com/dotnet/runtime.git
cd runtime/eng/common/cross# 构建 Ubuntu Noble (24.04) 的 RISC-V Sysroot
./build-rootfs.sh riscv64 noble --rootfsdir /tmp/riscv-sysroot
```
该脚本会利用 debootstrap 或 apt 下载目标架构的 .deb 包并解压,生成一个包含正确头文件和库文件的目录结构。这是 Native AOT 交叉编译成功的基石 18。
4.3 容器化构建策略
鉴于本地配置交叉编译工具链极其繁琐且容易出错(“Dependency Hell”),最稳健的策略是使用 Docker。微软维护了包含所需工具链的构建镜像(例如 mcr.microsoft.com/dotnet-buildtools/prereqs 系列),但针对 RISC-V 的镜像通常需要社区自行构建或从 VMR(虚拟单体仓库)流程中获取。Filip Navara 的 GitHub Actions 配置文件即展示了如何利用容器环境来标准化这一流程,确保每次构建的环境一致性 23。
5. 供应链安全与风险评估
在依赖“半官方”支持时,供应链安全是一个无法回避的问题。
5.1 非官方源的信任链断裂
使用 nuget.loongnix.cn 或个人 GitHub Release 中的二进制包意味着绕过了微软的代码签名和安全扫描机制。
- 风险:如果 nuget.loongnix.cn 被劫持,攻击者可以注入恶意的运行时代码,而在构建过程中开发者几乎无法察觉。
- 缓解措施:企业级用户应避免直接连接外部非官方源。建议搭建内部 NuGet 代理(如 Artifactory 或 Azure Artifacts),将需要的第三方包下载、扫描并上传至内部源,从而切断构建环境与不可信外部源的实时连接。
5.2 版本碎片化
社区构建往往无法做到与微软官方版本严格同步。这可能导致安全补丁(CVE 修复)在 LoongArch 或 RISC-V 平台上的发布滞后数周甚至数月。对于面向公网的服务器应用,这种滞后是不可接受的安全隐患。
6. 总结与展望
.NET 10 对 LoongArch 和 RISC-V 的支持现状,是技术理想与商业现实妥协的产物。
从技术层面看,障碍已基本扫清。核心运行时已能在这两个架构上稳定运行,Native AOT 更是为其在嵌入式领域的应用打开了广阔大门。dotnet/runtime 仓库中活跃的提交记录证明了这一点。
从产品层面看,“半官方”的状态仍将持续。微软严格的 Tier 分级制度决定了在缺乏大规模商业用户和稳定硬件基础设施之前,这两个架构只能作为 Tier 3 存在。这意味着开发者必须具备更高的技术能力——能够驾驭交叉编译、管理自定义 NuGet 源,甚至在必要时自行修补运行时代码。
战略建议:
- 对于 LoongArch 用户:紧跟“新世界”ABI 的发展,尽量避免在.NET 10+ 的新项目中使用旧的 Loongnix 环境。利用 dotnet-unofficial-build 获取 SDK,但需对生产环境的依赖包进行本地化管理。
- 对于 RISC-V 用户:拥抱 Native AOT。鉴于 RISC-V 硬件通常性能有限,AOT 带来的启动速度和内存优势至关重要。务必掌握 build-rootfs.sh 脚本的使用,构建稳定可靠的交叉编译 Sysroot。
- 对于企业决策者:认识到目前的支持仍属于“实验性”或“社区级”。在关键任务系统中引入这些架构时,必须预留资源用于维护内部的构建管道,不能完全依赖外部社区的免费劳动成果。
未来,随着.NET 11 及后续版本的演进,我们有理由期待随着国产硬件的成熟和 RISC-V 服务器级芯片的普及,这些架构能最终晋升为 Tier 2,享受到与 x64/ARM64 同等的官方待遇。但在那之前,非官方源与社区解决方案仍将是通往新架构的唯一桥梁。
引用的链接
- What's new in .NET 10 - Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview
- RISC-V Support · Issue #1380 · microsoft/dotnet - GitHub, 访问时间为 十二月 5, 2025, https://github.com/microsoft/dotnet/issues/1380
- Port .NET Runtime to RISC-V - Home - RISE Project Confluence Wiki, 访问时间为 十二月 5, 2025, https://lf-rise.atlassian.net/wiki/spaces/HOME/pages/8587597/LR_04_001+Port+.NET+Runtime+to+RISC-V
- loongson-community/dotnet-runtime: .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-runtime
- NET and .NET Core official support policy, 访问时间为 十二月 5, 2025, https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
- .NET SDKs for Visual Studio | .NET - Microsoft .NET, 访问时间为 十二月 5, 2025, https://dotnet.microsoft.com/en-us/download/visual-studio-sdks
- RISC-V architecture support · Issue #49594 · dotnet/sdk - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/sdk/issues/49594
- Illegal instruction on SAMA5D35 (ARMv7, VFPv3-D16) due to VMOV d16 usage · Issue #115641 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/115641
- 在龙芯loongnix上编译玩开源红警OpenRA - LA UOSC, 访问时间为 十二月 5, 2025, https://bbs.loongarch.org/d/227-loongnixopenra
- When will the community release the LoongArch64's SDK package with ARM32/64 and X86/64? · Issue #116293 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/116293
- How can Avalonia UI use .NET 9 to create nuget packages? #18557 - GitHub, 访问时间为 十二月 5, 2025, https://github.com/AvaloniaUI/Avalonia/discussions/18557
- The unofficial yet comprehensive FAQ for LoongArch (last updated 2022-11-23) | write(2), 访问时间为 十二月 5, 2025, https://blog.xen0n.name/en/posts/tinkering/loongarch-faq/
- 龙芯下如何进行.net core程序开发部署转载 - CSDN博客, 访问时间为 十二月 5, 2025, https://blog.csdn.net/woaimx_1314/article/details/131166131
- Releases · loongson-community/dotnet-unofficial-build - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-unofficial-build/releases
- Unofficial automated builds of .NET SDK for LoongArch - GitHub, 访问时间为 十二月 5, 2025, https://github.com/loongson-community/dotnet-unofficial-build
- filipnavara/dotnet-riscv - GitHub, 访问时间为 十二月 5, 2025, https://github.com/filipnavara/dotnet-riscv
- Publish NativeAOT on Ubuntu doesn't work with -r linux-musl-x64 #92294 - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/92294
- runtime/eng/common/cross/build-rootfs.sh at main - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/blob/master/eng/common/cross/build-rootfs.sh
- NativeAOT: change used linker for cross compiling : r/dotnet - Reddit, 访问时间为 十二月 5, 2025, https://www.reddit.com/r/dotnet/comments/1ei4pek/nativeaot_change_used_linker_for_cross_compiling/
- Cross-compilation - .NET - Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile
- This repo is a sample of an Android JNI library compilated using NativeAOT - GitHub, 访问时间为 十二月 5, 2025, https://github.com/josephmoresena/NativeAOT-AndroidHelloJniLib
- Port CoreCLR PAL to linux-riscv64 · Issue #75749 · dotnet/runtime - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dotnet/runtime/issues/75749
- dkurt/dotnet_riscv: Build .NET SDK for RISC-V - GitHub, 访问时间为 十二月 5, 2025, https://github.com/dkurt/dotnet_riscv
- Create a build validation GitHub workflow - .NET | Microsoft Learn, 访问时间为 十二月 5, 2025, https://learn.microsoft.com/en-us/dotnet/devops/dotnet-build-github-action
欢迎大家扫描下面二维码成为我的客户,扶你上云

浙公网安备 33010602011771号