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":创建一个固定的符号链接
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,回去检查组有没有加对。
4.5 常见问题与避坑
- 设备节点不出现: 检查 udev 规则语法,用
udevadm test测试规则是否匹配。 - 权限错误: 确认用户是否在 dialout 组,用
groups命令查看。 - 模块加载失败: 检查内核版本,确认模块是否被编译进内核。
- 符号链接不生效: 确保规则文件名以
.rules结尾,且优先级数字小于 99。
好了,Linux 下驱动安装就这么几步。说白了就是:让系统认识它,让用户能用它,让内核能驱动它。下次遇到烧录器连不上,按这个流程排查,基本都能搞定。