[随笔] 续:关于我在机房安装Arch Linux

背景

这是在机房安装Arch Linux系列的第三篇(可喜可贺)

随笔:关于我在机房安装Arch Linux一事

随笔:教程篇

在教程中我们不难注意到,本人提到了:

本人主要推荐两个桌面环境,KDE或者Niri+DMS,这两个在Shorin脚本都有支持。

对于有非国产显卡的用户!你可以尝试Niri。

对于国产显卡用户!请务必用KDE,否则你将痛不欲生。

那为啥这么说呢?

其实是因为国产显卡对非国产Linux的支持非常不好,需要自己编译,而即便是这样,也不一定能够编译成功。譬如说我这台电脑的显卡支持的Linux内核版本最高为7,但是我的Arch是7.2内核,即便我降了内核版本,在滚动更新时也可能会毁坏驱动。

KDE支持CPU解算画面,而Niri强制要求显卡,所以国产显卡或者没有显卡的机器请安装KDE。

但是经过我一天的尝试,国产显卡(此处特指格兰菲Glenfly Tech Co., Ltd. Arise1020显卡)驱动其实是可以在Arch上使用的。

最后的结果就是,我成功用上了Niri+DMS作为WM。 (顺带,我成为了第一个成功移植国产显卡驱动到Arch的人)

当然,总归是要有些水土不服的地方的,这就是所有Chrome系的App(包括以QQ、TRAE为代表的一众Electron框架App)都是不可以使用GPU加速的 ,原因我们稍后再讲。

(当然这丝毫不影响Niri的颜值碾压KDE成为我捣鼓这个的最大动力 ,我宣布我是颜控)

叠甲,放一张图证明我没有扯:

分析

那为啥我之前说显卡驱动用不了呢,打开他们的官网,我们不难发现,此显卡所支持的最高版本的Linux内核就是7.0,而且仅对国产的Linux支持很好。

而我的Arch内核是7.2,由于Linux每个内核都会改一些API,所以对于7.0的驱动我们直接安装是会有很严重的问题的,包括但不限于:系统卡死、黑屏无法进入登录界面等。

接下来,我们进入源码分析,此过程我和Agent一共用了3个多小时。(注:不想看技术部分的可以向下滑到Niri部分)

源码分析

在开始之前,需要明确的一个事实是:显卡、驱动本身都没有问题,我们缺的是驱动和内核之间可能不太匹配 的API接口,至于究竟匹不匹配,这完全取决于内核API与驱动了。

为此第一步是获取驱动的源码,这可以从驱动解包得到,用 bsdtar :

bash 复制代码
mkdir -p ~/arise-pkg && cd ~/arise-pkg
bsdtar -xf gf-arise-linux-graphics-driver-glvnd-dri_25.00.55_amd64.deb
mkdir data && bsdtar -xf data.tar.xz -C data

解压完得到的就是源码,于是我们开始查阅。

我先让Agent做了一轮排除,我担心的7.2修改的调度器这个驱动压根没有用到。

于是我满心欢喜的编译,报错。

那么真正的问题其实出现在了Linux Kernel 7.1:

7.1 把 struct drm_atomic_state 整个改名成了 struct drm_atomic_commit,跟着改名的还有一批原子操作函数。这是个全局重构,DRM 子系统里所有驱动都得跟着改。而格兰菲这个 25.00.55 是 4 月发的,适配到 7.0 为止,所以这些位置自然都报错了。如果逐处去改,那就要改50+文件,对于OIer来说这也太不优雅了(,而且下次内核再改还得再来一遍。

所以我们不妨在预处理阶段把它映射回去。

新加了一个 linux/gf_compat_71.h,用 #if LINUX_VERSION_CODE >= KERNEL_VERSION(7,1,0) 包住一组 #define,把 drm_atomic_state 这个类型名和随之改名的几个原子函数,统统映射成新名字;再在 Makefile 里加一行 -include,让整棵驱动树统一吃到这个头,而且对老内核完全无副作用(因为用的是条件编译)。

顺手还修了一个更隐蔽的:内核 7.1 起 strncpy 被移除了,驱动里 os_interface.c 的 gf_strncpy 和 gf_trace.h 的两处 trace 事件都得换成 strscpy。这个改动还顺手避掉了一个坑------strncpy 在源串长度等于缓冲区时不会补 \0,strscpy 会。

那么修改完成后当然就可以用啦,编译非常顺畅

编译、加载、点亮

DKMS 这边几乎不需要任何修改。

dkms.conf 自带 gcc 版本探测(会去匹配编译内核时用的那个 gcc),Arch 下系统 gcc 就是内核 gcc,我们继续编译即可。

bash 复制代码
sudo cp -a data/usr/src/arise-25.00.55 /usr/src/
sudo dkms add arise/25.00.55
sudo dkms build arise/25.00.55 -k "$(uname -r)"
sudo dkms install arise/25.00.55 -k "$(uname -r)"
sudo modprobe arise

这里最后一句就是要求显卡接管渲染的命令,会黑屏一下,随后立刻恢复。

相关的日志如下:

复制代码
[    8.682454] arise 0000:01:00.0: [drm] Registered 10 planes with drm panic
[    8.688578] [drm] Initialized arise 37.0.85 for 0000:01:00.0 on minor 1
[    8.768027] arise 0000:01:00.0: [drm] fb0: arisedrmfb frame buffer device

检查也很简单:

bash 复制代码
ls /dev/dri/                 # renderD128 出现了
glxinfo -B | grep renderer   # OpenGL renderer string: Glenfly Arise1020

OpenGL 4.5、GLES 3.2,KDE 都从 llvmpipe 换成了真显卡。到这一步,那台机器才算真的有显卡(当然,这也就意味着,我们可以用Niri了!!)

用户态

完成内核部分后,我们接下来就要让用户态的App使用GPU进行渲染了。

内核点亮只是拿到 render 节点,真正让应用吃上加速的是闭源用户态库。Debian 的 postinst 在安装时会替你做几件事,Arch 需要手动复刻,而且漏一个都不行(别问我怎么知道的)。

第一个是 GLVND 的 vendor 配置。usr/share/glvnd/egl_vendor.d/10_arise.json 里 library_path 字段是 ""。不填的话,EGL会dlopen一个滚木,装了驱动照样走 llvmpipe(而且是不报错的)。

bash 复制代码
sudo sed -i 's|"library_path" : ""|"library_path" : "libEGL_arise.so.0"|' \
  /usr/share/glvnd/egl_vendor.d/10_arise.json

修完这个你以为就能跑了吗,不不不,库路径又不对。Debian 的 multiarch 目录要剥前缀:库都在 usr/lib/x86_64-linux-gnu/ 下面,Arch 是 usr/lib/ 直接平铺。而且 arise_gbm.so 必须在 /usr/lib/gbm/,跟 Mesa 的 dri_gbm.so 同一个目录,它跟 dri_gbm.so 是同一套 ABI,这样libgbm 靠 DRM 驱动名 arise 就能自动发现它,不用额外配置。

最后 X11 还需要显式指定 GLX vendor。usr/share/X11/xorg.conf.d/10-arisegpu.conf 里 MatchDriver "arise" 后面得补一行:

复制代码
Option "GlxVendorLibrary" "arise"

最后 sudo ldconfig + 重启,eglinfo -B 里 vendor 就变成 Glenfly 了。

另外,etc/modprobe.d/arise_gfx.conf 在包里是空文件 ,usr/share/initramfs-tools/hooks/arise 是 Debian 专用的------独显不需要 early KMS,Arch 上这两个都可以跳过。

为什么所有 Chrome 系应用都不能开 GPU 加速

装完之后一开始看着还行,结果当你打开QQ或者TRAE,你会发现画面直接炸了。

那么会是哪里的问题呢?直接CoreDump即可:

复制代码
#0~17  libariseGLSLCompiler.so   段错误
#17    OGL_Compiler_CompileShader
#18    arise_vndri.so
#20    fast_data_types.so         ← kitty 在编译着色器

崩的是显卡驱动自带的闭源 GLSL 编译器。

Chrome/Electron 系内部用的是 ANGLE + Skia,对于这种复杂的着色器,格兰菲支持并不好,所以这就是原因,这张卡的闭源 GL 栈对 Chromium 的着色器兼容不了。

那咋办呢,直接增加命令行启动参数,.desktop 中加 --disable-gpu即可。

注意不要给 Electron 应用用 --use-angle=swiftshader,因为SwiftShader 是纯 CPU 光栅化,窗口一可见 CPU 就起飞。相比之下 --disable-gpu 走 Skia 的轻量软渲染,CPU 曲线平和得多。

Niri + DMS

注意此处不会再有技术分析了,到了大家喜闻乐见的环节。

之前Niri无法使用纯粹就是因为我们无法使用显卡,既然现在已经有了显卡,KDE又可以和Niri共存那么我们为何不安装一个呢?

于是就有了现在的结果:

个人认为是比KDE更好看的,而且滚动布局要更容易使用。

(让我们欢呼!!!Niri是对的!)

效果

又到了Arch用户喜闻乐见的展示环节:

依旧注意到本文是Arch写的:

依旧Neovim:

加入Arch神教谢谢喵~

码字不易,烦请点个推荐~