龙芯 loongnix25 下载工具 Gopeed 安装小记
- 2026-09-29 03:30:45
一台龙芯 3A6000,一个官方根本没适配的架构,一个下载器。记录从"装不上"到"用得顺"的完整过程。
先说结论
在龙芯 loongnix 25(loongarch64)上,Gopeed 可以完整跑起来,界面和功能与官方版本一致。但它不像 x86 那样 apt install 一句话搞定——上游只发 x86_64 和 arm64 包,龙芯用户必须自己动手组装。
整个事情分三段:

先说一句最关键的:Gopeed 的界面是 Web 技术做的。服务端自带界面资源,编译进去之后,浏览器打开就能用。理解这一点,后面很多选择就顺了。
为什么龙芯装不了
Gopeed 的技术栈是 Go 语言写下载引擎 + Flutter 写界面。问题就出在这两处:
- Flutter 没有 loongarch64 支持
。官方的 Flutter SDK 不提供 loong64 构建,loongnix 的软件源里也没有——桌面版从第一步就编不出来。 - 官方发布的 Web 版是"自包含"单文件二进制
。界面资源通过 //go:embed dist/*编译进可执行文件里,直接执行没问题,但想拿里面的静态资源?它是打包进去的,取不出来。
所以第一个念头是:能不能用 box64 直接跑官方的 x64 版本?
结论是不行。 官方二进制是静态链接的 Go 程序,box64 跑起来直接 SIGILL 崩溃——这类二进制与二进制翻译层天然不兼容。这条路实测堵死,没有继续折腾的价值。
那还剩什么路
剩下的是原生组装:后端在本机编译成 loong64 原生代码,界面从官方二进制里取出来。两边拼起来,就是一个界面和功能都不降级的版本。
这个思路的成立有两个前提,都验证过了:
Go 语言官方支持 loongarch64( GOARCH=loong64),本机编译无障碍;界面资源虽然嵌在二进制里,但表结构可以重建,能精确地把每一个文件取出来。 下面按顺序说这三步。
第一步:准备 Go 工具链(不动系统)
loongnix 的源里有 golang-1.24-go,版本满足 Gopeed 的要求。但如果直接 apt install,会往系统目录里写东西,以后想清理就麻烦了。
我选择用户态安装——把 deb 包下载下来直接解压到自己的目录,完全不经过包管理器:
# 免 root 下载 deb mkdir -p ~/opt/golang-dl && cd ~/opt/golang-dl apt-get download golang-1.24-go # 解压并安装到用户目录 mkdir -p ~/opt/goroot-tmp dpkg -x golang-1.24-go_*.deb ~/opt/goroot-tmp mv ~/opt/goroot-tmp/usr/lib/go-1.24 ~/opt/go rm -rf ~/opt/goroot-tmp 这样装出来的工具链,验证一下:
~/opt/go/bin/go version # go version go1.24.4 linux/loong64 再写一个环境脚本 ~/opt/go-env.sh,用的时候 source 一下就行:
export GOROOT=/home/huzhou/opt/go export GOPATH=/home/huzhou/go export PATH="$GOROOT/bin:$GOPATH/bin:$PATH" # github.com 直连不通,走国内代理 export GOPROXY=https://goproxy.cn,direct export GOSUMDB=sum.golang.google.cn export GOTOOLCHAIN=auto 这里有个细节值得说:GOTOOLCHAIN=auto 让 Go 可以按项目 go.mod 的要求自动拉取匹配的工具链版本。Gopeed 要求 Go ≥ 1.24.9,而源里是 1.24.4,靠这个开关从 goproxy.cn 自动补齐到 1.24.11,省去手工找包。
用户态安装最大的好处是可回滚:不想要了,rm -rf ~/opt/go 一句就干净,系统目录里什么都没留。
第二步:搞清入口在哪(这里踩了个坑)
Gopeed 的模块里,命令行版本的入口目录叫 cmd/cli——按直觉我就这么编译了,结果报错:
package github.com/GopeedLab/gopeed/cmd/cli is not in std 翻一下目录才发现,服务端 + Web 界面的入口是 cmd/web,不是 cmd/cli:
ls $(go env GOPATH)/pkg/mod/github.com/!gopeed!lab/gopeed@v1.9.3/cmd/ # api web 小坑,但值得记一笔:遇到入口找不到,别猜,直接 ls 看目录。
接着往下走,cmd/web/main.go 里赫然一行:
//go:embed dist/* 意思是界面资源编译期嵌入——可模块包里根本没有 dist 目录。构建产物不进版本库,这是常态。所以界面只能从官方发布的可执行文件里取。
第三步:从官方二进制里取出界面
这是整件事技术含量最高的一段。
//go:embed 生成的资源表在二进制里是连续的结构体数组,每一项在 64 位平台上占 48 字节:
namePtr / | |
dataPtr / | |
hash |
关键在于:指针以虚拟地址(vaddr)的形式直接落盘——链接期已经把重定位算完了。这意味着我们只要解析 ELF 的段表,就能在"虚拟地址"和"文件偏移"之间自由换算:
文件偏移 = 虚拟地址 − 段基址 有了这个换算关系,再拿一个已知文件名做锚点,就能双向步进,把整张表还原出来。

这里踩了本次唯一的坑。 第一版脚本跑完只提取到 8 个文件,明显不对。排查发现:表里除了文件项,还有目录项——目录项的长度字段是 0,被我的合法性校验当成异常值过滤掉了。过滤条件一收紧,遍历就在目录项那里提前终止了。
修正过滤逻辑(允许长度为 0 的目录项)之后,提取到 499 个文件、48.4 MB,包含 canvaskit.wasm、全套图标与字体。
提取完做了一次交叉验证,手段比"看文件数对不对"靠谱得多:
# 关键文件的字节数与提取结果逐一核对 ls -l dist/main.dart.js # 4,405,174 B ls -l dist/canvaskit/canvaskit.wasm # 7,155,780 B 这两个数字后来在服务端返回时再次核对,完全一致——说明取出来的资源一个字节都没错。
顺手把 version.json 看了一眼,写的是 1.9.3,与目标版本对得上。
第四步:拼起来编译
界面就位,编译就一句话:
cd ~/opt/gopeed-src source ~/opt/go-env.sh go build -tags nosqlite,web \ -ldflags="-s -w -X github.com/GopeedLab/gopeed/pkg/base.Version=v1.9.3" \ -o ~/opt/gopeed-build/gopeed ./cmd/web 两个参数解释一下:
-tags nosqlite,web: web启用 Web 界面支持;nosqlite走不含 CGO 的存储实现,避免依赖系统的 sqlite 开发库。-ldflags: -s -w去掉调试符号压缩体积;-X把版本号写进二进制,这样界面上显示的才是真实版本,而不是dev。
编译产出 87 MB 的 LoongArch 原生二进制。
验证:三项都是实测
装完之后我按三个层面验证,都是真实跑出来的结果:

第一,静态资源逐项对齐。 浏览器请求 main.dart.js、canvaskit.wasm 等资源,返回的字节数与提取时完全一致,内容类型也对。
第二,运行时接口自报家门。 请求 /api/v1/info 返回:
{ "arch": "loong64", "os": "linux", "runtime": "go1.24.11", "version": "v1.9.3" } arch 是 loong64——这一行字就是"原生运行"最直接的证据。
第三,端到端下载测试。 建一个任务下载 5 MB 测试文件,等待完成,然后比对源文件与下载文件的 MD5——完全一致。测试任务和测试文件在验证结束后即清理,没有在下载目录留下残留。
怎么用
服务默认只监听本机回环地址,浏览器打开 http://127.0.0.1:9999 就是完整界面。
我另外做了个启动脚本 gopeed-web,带 start / stop / status 三个子命令,方便日常开关;同时在应用菜单里放了个图标,点一下就能起。
~/.local/bin/gopeed | |
~/.local/bin/gopeed-web | |
~/.local/share/applications/gopeed.desktop | |
~/.local/share/gopeed | |
~/Downloads | |
~/opt/go~/opt/go-env.sh |
支持协议覆盖 HTTP/HTTPS、FTP、BitTorrent 与磁力、eD2K、HLS/DASH 流媒体,另有扩展系统可托管 ffmpeg 与 yt-dlp。
两条安全提醒
第一,不要随手把监听地址改成 0.0.0.0。 Gopeed 的 Web 界面默认没有访问认证,一旦监听全网卡,同网段的任何机器都能直接操作你的下载器。要开放就必须同时配好用户名口令参数。启动脚本里已经硬编码成 127.0.0.1,改之前请想清楚。
第二,编译原料占空间要心里有数。 这次为了编译装了 Go 工具链(约 112 MB)、模块缓存(约 1.5 GB)。用完之后如果不再编译其他 Go 项目,可以清理——注意清 Go 模块缓存要用官方命令:
go clean -modcache 直接 rm -rf 会报一堆"权限不够",因为 Go 把模块文件设成了只读。这是它的正常设计,不是文件坏了。
一点感想
这次折腾下来,最大的感触是:在国产架构上装 Linux 应用,"能不能装"和"能不能用"是两件事,而"能用"和"好用"又是两件事。
桌面版编不了,不代表这个软件就用不了——Gopeed 的架构里,引擎和界面本来就是分开的,界面又是 Web 技术做的。绕开 Flutter,直接取官方二进制里的界面资源,反而比硬啃 Flutter 工具链更省事,而且拿到的是官方原版界面,功能一点不打折。
另一个体会是:遇到"数字不对"的时候,先怀疑自己的过滤条件,而不是怀疑数据源。 这次从 8 个文件到 499 个文件,问题不在二进制,在我那行写得太严的校验。二进制里的数据是死的,程序读它的方式是活的。
还有一个实用的小习惯:每一步都留下可复核的证据。字节数、接口返回、MD5——这些东西写下来只要几行,但下一次升级或者出问题时,能省掉大量"到底是哪一步不对"的排查时间。
龙芯的生态还在建设中,很多路得自己走一遍。走通了写下来,下一个人就能少踩几个坑——这也是我把这些细节都记下来的原因。
参考文档
项目与源码
Gopeed 主仓库:https://github.com/GopeedLab/gopeed Gopeed 官网:https://gopeed.com Gopeed 官方文档(CLI / Web 部署):https://docs.gopeed.com 官方发布包(本次提取界面所用): v1.9.3/gopeed-web-v1.9.3-linux-amd64.zip
本机安装路径
~/.local/bin/gopeed | |
~/.local/bin/gopeed-web | |
~/.local/share/applications/gopeed.desktop | |
~/.local/share/gopeed | |
~/.local/share/gopeed/gopeed.db | |
~/.local/share/gopeed/gopeed.log | |
~/opt/gopeed-src | |
~/opt/go~/opt/go-env.sh |
构建参数备忘
cmd/webcmd/cli) | |
-tags nosqlite,web | |
GOPROXY=https://goproxy.cn,direct | |
GOTOOLCHAIN=auto | |
相关技能文档
~/.workbuddy/skills/loong64-webapp-native-port/SKILL.md — 龙芯原生移植全流程(含官方二进制资源提取) ~/.workbuddy/skills/loong64-webapp-native-port/scripts/extract_go_embed.py — Go embed 表提取脚本