4. Linux 系统驱动安装:udev 规则、权限组与内核模块

Linux 下装驱动,跟 Windows 还真不一样。Windows 通常是双击一个 exe 完事,Linux 呢?你得跟 udev 打交道,得把用户加到特定组里,有时候还得手动加载内核模块。听起来复杂,其实拆开看就几件事。

我个人习惯,先把整个流程理清楚,再动手。不然权限不对,烧录器死活连不上,你都不知道问题出在哪。

核心思路: 让系统识别硬件 → 给用户访问权限 → 加载必要内核功能 → 验证通信正常。

4.1 udev 规则配置:让系统认识你的设备

udev 是 Linux 的设备管理器。你插个 USB 转串口,它得知道这个设备叫什么、该给谁用。规则文件放在 /etc/udev/rules.d/ 目录下,以 .rules 结尾。

我遇到过好几次,烧录器插上后 ls /dev/ttyUSB* 啥也没有。一查,udev 没认出来。这时候就得手动写规则。

4.1.1 获取设备信息

先把设备插上,跑这条命令:

lsusb

你会看到类似这样的输出:

Bus 001 Device 003: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge

记下 VID(厂商 ID)和 PID(产品 ID)。上面例子中,10c4 是 VID,ea60 是 PID。

4.1.2 编写规则文件

新建一个规则文件,比如 99-cp210x.rules:

sudo nano /etc/udev/rules.d/99-cp210x.rules

写入以下内容:

# CP210x USB to UART Bridge
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0666", GROUP="dialout", SYMLINK+="ttyUSB_CP210x"

解释一下:

  • SUBSYSTEM=="tty":只匹配 tty 类设备
  • ATTRS{idVendor} 和 ATTRS{idProduct}:匹配 VID/PID
  • MODE="0666":权限设为 666,所有用户可读写
  • GROUP="dialout":设备组设为 dialout
  • SYMLINK+="ttyUSB_CP210x":创建一个固定的符号链接
我的习惯: 用 SYMLINK 创建固定名称,比如 ttyUSB_CP210x。这样不管插哪个 USB 口,设备名都不会变。写脚本时特别省心。

4.1.3 重载规则

保存文件后,执行:

sudo udevadm control --reload-rules
sudo udevadm trigger

拔掉设备再插上,或者直接重启 udev 服务。然后检查:

ls -l /dev/ttyUSB*

你应该能看到新设备,权限是 crw-rw-rw-,组是 dialout。

4.2 权限组添加:dialout 与 plugdev

规则写好了,设备也认了,但你还是打不开?大概率是用户权限不够。

Linux 下,访问串口设备通常需要属于 dialout 组。有些系统也用 plugdev。我建议两个都加上,省得后面折腾。

4.2.1 添加用户到组

sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER

注意:$USER 会自动替换成当前用户名。如果你要加其他用户,直接写用户名就行。

4.2.2 使组生效

加完组后,必须重新登录或者重启。不想重启的话,可以开一个新终端:

newgrp dialout

或者直接注销再登录。我一般直接重启,省得漏掉什么。

我曾经踩过的坑: 加完组没重新登录,直接跑烧录工具,报权限错误。折腾了半小时才发现组没生效。记住,组变更必须重新登录。

4.3 加载内核模块

有些烧录器需要内核模块支持,比如 USB 转串口驱动 cp210x、ch341、ftdi_sio 等。这些模块通常内核已经带了,但没自动加载。

4.3.1 检查模块是否已加载

lsmod | grep cp210x

如果没输出,说明没加载。手动加载:

sudo modprobe cp210x

4.3.2 设置开机自动加载

编辑 /etc/modules 文件,把模块名加进去:

sudo nano /etc/modules

在文件末尾添加:

cp210x

保存退出。这样每次开机都会自动加载。

4.3.3 常见烧录器对应模块

烧录器/芯片 内核模块 备注
CP2102 / CP2104 cp210x 最常用的 USB 转串口芯片
CH340 / CH341 ch341 国产芯片,很多开发板在用
FT232 / FT2232 ftdi_sio FTDI 家的,稳定但贵
PL2303 pl2303 Prolific 的,注意假货多
小技巧: 如果 modprobe 报错说找不到模块,先查内核版本:uname -r。然后看看 /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ 目录下有没有对应的 .ko 文件。没有的话,得装内核头文件或者自己编译。

4.4 验证驱动是否生效

前面几步都做了,怎么知道驱动到底生效没?我一般用三个方法验证。

4.4.1 检查设备节点

ls -l /dev/ttyUSB*

能看到设备,权限是 crw-rw-rw-,组是 dialout,基本就成功了。

4.4.2 用 dmesg 看内核日志

dmesg | tail -20

插拔设备后,你会看到类似这样的信息:

[ 1234.567890] usb 1-1: new full-speed USB device number 3 using xhci_hcd
[ 1234.678901] usb 1-1: cp210x converter now attached to ttyUSB0

看到 attached to ttyUSB0,说明驱动加载成功。

4.4.3 用工具测试通信

装个 minicom 或者 screen,试试能不能打开串口:

sudo apt install minicom
minicom -D /dev/ttyUSB0 -b 115200

能打开,说明驱动和权限都没问题。如果报 Permission denied,回去检查组有没有加对。

一句话总结: udev 规则让系统认识设备,权限组让用户能用设备,内核模块让设备能工作。三步走完,烧录器就能正常用了。
Linux 驱动安装完整流程 插入 USB 设备 lsusb 获取 VID/PID 编写 udev 规则文件 udevadm 重载规则 添加 dialout/plugdev 组 modprobe 加载模块 关键点 • udev 规则匹配 VID/PID • 权限组必须重新登录 • 模块开机自动加载 验证:dmesg / ls / minicom

4.5 常见问题与避坑

  • 设备节点不出现: 检查 udev 规则语法,用 udevadm test 测试规则是否匹配。
  • 权限错误: 确认用户是否在 dialout 组,用 groups 命令查看。
  • 模块加载失败: 检查内核版本,确认模块是否被编译进内核。
  • 符号链接不生效: 确保规则文件名以 .rules 结尾,且优先级数字小于 99。
我曾经遇到一个奇葩问题: 同一台电脑,同一个烧录器,插不同的 USB 口,设备名不一样。后来用 SYMLINK 固定名称,再也没出过问题。所以,别依赖动态设备名。

好了,Linux 下驱动安装就这么几步。说白了就是:让系统认识它,让用户能用它,让内核能驱动它。下次遇到烧录器连不上,按这个流程排查,基本都能搞定。