引入

在之前的文章里,我介绍过 godns 这个软件。其中我提到过在给 MIPS 架构的路由器使用时,会出现 Illegal instruction 错误。这是因为指令集没有完全支持 FPU,当时我找到的解决方案不但麻烦,而且已经过时,无法支持新版本下 Go 的特性。幸运的是,现在上游也有了比较好的解决方案,在这里简单介绍一下。

方案一:开启 OpenWrt 的 FPU 模拟

参考链接

步骤

在编译 OpenWrt 时,进行如下设置:

1
$ make kernel_menuconfig

进入 Kernel Type,勾选 MIPS FPU Emulator,保存。

然后编译 OpenWrt,生成的固件就会支持 FPU 了。

优点

  • 永久解决问题,此后不再需要其他处理;
  • 可以直接使用开发者预编译好的二进制文件,无须额外修改。例如 frpkcptun

缺点

  • 编译一个路由器固件较为麻烦,耗时长,还需要重新刷机;
  • 内核经过了自定义修改,无法再安装来自官方源的 kmod 包。

方案二:交叉编译时开启 softfloat 选项

参考链接

步骤

编译时执行如下命令,GOARCHmips 还是 mipsle 需要看路由器本身的架构:

1
GOOS=linux GOARCH=mips/mipsle GOMIPS=softfloat go build -a

优点

  • 相对于编译整个固件,单独编译一个程序更加简便。

缺点

  • 需要有软件的源码,如果不开源的话就没办法了;
  • 每次软件修改或更新后都需要自己重新编译一下。

总结

大家不要太依赖这些 workaround,因为不支持硬件 FPU 的话,运行 go 应用是很容易暴露出性能不行的问题的(逃