背景

在 Linux 系统中,有些硬件驱动并不完全依赖发行版内核自带模块,而是需要额外使用第三方源码、DKMS 或手动安装脚本进行维护。常见场景包括无线网卡、特殊声卡、旧硬件驱动、笔记本专用补丁模块等。

这类源码最初往往会被临时 clone 到用户目录,例如:

~/workspace/some-driver

这种做法在测试阶段很方便,但如果这个驱动后来成为系统长期运行所依赖的一部分,继续放在临时工作目录里就不太合适了。

一次 MacBook 声卡驱动维护过程中,就遇到了这个问题:驱动源码原本放在用户的 workspace 目录中,但该驱动实际上已经成为系统升级内核后恢复声音的重要维护组件。因此,有必要把源码移动到更合适的长期位置。

用户工作目录不适合长期保存系统驱动源码

类似下面的位置更适合作为临时工作区:

~/workspace/
~/Downloads/
~/tmp/

这些目录的特点是:

适合临时测试
适合下载和编译
适合短期修改
适合随时清理

但如果里面存放的是长期依赖的系统驱动源码,就会出现几个问题:

容易被误删
容易和普通项目混在一起
不利于系统维护脚本引用
不适合被 root 执行的 hook 长期依赖
目录语义不清晰

尤其是 DKMS 驱动源码,它虽然最初只是一个 git 仓库,但后续可能会被反复用于:

git pull 更新源码
重新安装 DKMS 模块
内核升级后手动恢复驱动
pacman hook 自动重建模块

这种性质已经不再是普通用户项目,而是本机系统维护资源。

推荐位置:/usr/local/src

对于本机管理员手动维护、非发行版包管理器安装的源码,一个比较合理的位置是:

/usr/local/src/

例如:

/usr/local/src/snd_hda_macbookpro

这个位置的语义比较清楚:

/usr/local
    本机管理员手动安装或维护的内容

/usr/local/src
    本机管理员手动保留的源码

它不同于发行版包管理器主要管理的 /usr/bin/usr/lib/usr/share 等路径,也不同于用户自己的普通文档目录。

因此,把第三方驱动的上游源码仓库放在 /usr/local/src,可以理解为:

这是本机长期维护用源码
不是普通用户项目
不是临时下载文件
不是 DKMS 自动生成目录
也不是 pacman 软件包内容

需要区分的三个目录

以一个 DKMS 声卡驱动为例,整理后的结构可以分为三层。

1. 上游源码仓库

/usr/local/src/snd_hda_macbookpro

这是手动保留的 git 仓库,用于以后更新源码和重新安装驱动。

它的用途包括:

git pull --ff-only
./install.cirrus.driver.sh -i
./install.cirrus.driver.sh -r

这个目录是人为维护的,不是 DKMS 自动生成的。

2. DKMS 注册源码目录

/usr/src/snd_hda_macbookpro-0.1

这是 DKMS 实际注册和构建时使用的源码目录。安装脚本或 DKMS 会把源码放到这里。

这个路径属于系统级内核模块构建体系,不建议随便移动或手动清理,除非明确知道自己在重新注册 DKMS 模块。

3. DKMS 构建状态目录

/var/lib/dkms/snd_hda_macbookpro/0.1

这是 DKMS 的构建记录、状态和不同内核版本安装信息所在的位置。

例如执行:

dkms status

看到的模块状态,就与这里的记录有关。

为什么不直接只依赖 /usr/src

有人可能会问:既然 DKMS 已经把源码放进 /usr/src,是否还需要保留 /usr/local/src 下的 git 仓库?

答案是:最好保留。

原因是 /usr/src/snd_hda_macbookpro-0.1 更像是 DKMS 当前注册使用的源码副本,不一定适合作为长期更新和维护上游项目的 git 仓库。

/usr/local/src/snd_hda_macbookpro 的作用是:

保留上游 git 历史
方便 git pull
方便重新运行安装脚本
方便在 DKMS 状态损坏时重新注册
方便作为 pacman hook 或维护脚本的稳定来源

也就是说:

/usr/local/src
    人维护的上游源码

/usr/src
    DKMS 使用的注册源码

/var/lib/dkms
    DKMS 的构建状态

这三个目录用途不同,不应混为一谈。

实际移动方式

假设源码原本位于:

~/workspace/snd_hda_macbookpro

可以移动到:

/usr/local/src/snd_hda_macbookpro

操作命令如下:

OLD="$HOME/workspace/snd_hda_macbookpro"
NEW="/usr/local/src/snd_hda_macbookpro"

test -d "$OLD" || { echo "旧目录不存在: $OLD"; exit 1; }
test ! -e "$NEW" || { echo "目标目录已存在: $NEW"; exit 1; }

sudo mkdir -p /usr/local/src
sudo mv "$OLD" "$NEW"
sudo chown -R root:root "$NEW"

sudo git -C "$NEW" status --short
sudo git -C "$NEW" remote -v
ls -ld "$NEW"

移动完成后,如果 git status --short 显示本地有修改,例如:

 M dkms.conf
?? dkms.conf.orig

通常表示安装脚本曾经修改或备份过配置文件。为了让 /usr/local/src 下的仓库保持干净,可以重置为上游状态:

NEW="/usr/local/src/snd_hda_macbookpro"

sudo git -C "$NEW" reset --hard HEAD
sudo rm -f "$NEW/dkms.conf.orig"

sudo git -C "$NEW" status --short
sudo git -C "$NEW" remote -v
ls -ld "$NEW"

如果 status --short 没有输出,就说明仓库已经恢复为干净状态。

移动源码会不会影响当前驱动

一般不会。

因为当前已经安装好的 DKMS 模块主要依赖:

/usr/src/snd_hda_macbookpro-0.1
/var/lib/dkms/snd_hda_macbookpro/0.1

而不是原来的 clone 目录。

换句话说,移动 /home/.../workspace/snd_hda_macbookpro/usr/local/src/snd_hda_macbookpro,不会直接改变当前已经加载的内核模块。

真正需要更新的是以后手动维护时使用的路径。

原来可能是:

cd ~/workspace/snd_hda_macbookpro

移动后应改为:

cd /usr/local/src/snd_hda_macbookpro

后续维护命令

以后内核升级后,如果需要重新安装或恢复该 DKMS 驱动,可以使用:

cd /usr/local/src/snd_hda_macbookpro
sudo git pull --ff-only
sudo ./install.cirrus.driver.sh -r || true
sudo ./install.cirrus.driver.sh -i
sudo depmod -a
reboot

重启后检查:

dkms status
modinfo -n snd-hda-codec-cs8409
aplay -l

对于 DKMS 覆盖内核自带模块的场景,尤其要确认模块路径是否位于:

/lib/modules/当前内核版本/updates/dkms/

如果仍然位于:

/lib/modules/当前内核版本/kernel/

就说明系统可能仍在使用内核自带原始模块,而不是 DKMS 修正版模块。

是否适合放在用户目录

如果只是临时测试,放在用户目录没有问题。例如:

~/workspace/
~/src/
~/Projects/

但如果这个源码已经成为系统维护的一部分,尤其是会被 root 权限脚本、DKMS、pacman hook 或内核升级恢复流程引用,那么放在 /usr/local/src 更合理。

可以简单按下面的原则判断:

临时编译、临时测试、普通项目
    放用户目录

长期维护、本机依赖、系统驱动、root 脚本会引用
    放 /usr/local/src

DKMS 自动注册源码
    放 /usr/src

DKMS 构建状态
    放 /var/lib/dkms

总结

手动维护的 Linux 驱动源码不一定适合长期放在用户的 workspace 目录中。对于已经成为系统运行依赖的第三方驱动源码,放在 /usr/local/src 更清晰、更稳定,也更符合目录语义。

整理后的结构可以概括为:

/usr/local/src/snd_hda_macbookpro
    上游源码仓库,长期保留,用于 git pull 和重新安装

/usr/src/snd_hda_macbookpro-0.1
    DKMS 当前注册使用的源码

/var/lib/dkms/snd_hda_macbookpro/0.1
    DKMS 构建状态与模块安装记录

这样的结构比把系统驱动源码长期放在用户 workspace 中更干净,也更适合后续内核升级、DKMS 重建和系统维护。

Leave a Reply

Your email address will not be published. Required fields are marked *