3. 设备节点权限基础:文件权限(rwx)、用户/组/其他、权限位(0666/0644/0660)的含义
在 Linux 系统中,设备节点(Device Node)本质上是位于 /dev 目录下的特殊文件。HAL 驱动调试过程中,应用层无法打开设备节点、ioctl 调用返回 Permission denied,绝大多数情况都是因为设备节点的权限配置不正确。理解文件权限模型是正确配置设备节点的前提。
3.1 文件权限的三元组:rwx
Linux 使用 9 个字符表示一个文件或设备节点的权限,分为三组,每组三个字符:
| 分组 | 字符位置 | 权限位 | 含义 | 数值 |
|---|---|---|---|---|
| 所有者(User) | 2-4 | r w x | 读、写、执行 | 4 2 1 |
| 所属组(Group) | 5-7 | r w x | 读、写、执行 | 4 2 1 |
| 其他用户(Others) | 8-10 | r w x | 读、写、执行 | 4 2 1 |
对于设备节点,读(r) 允许读取设备数据;写(w) 允许向设备发送数据或控制命令;执行(x) 通常对设备节点无意义,但在某些驱动框架(如 UIO)中用于表示允许 mmap 操作。
调试要点: HAL 层通常需要同时具备 r 和 w 权限才能完成 open、read、write、ioctl 等操作。缺少写权限时,
ioctl 调用会直接返回 -EACCES。
3.2 用户/组/其他:三权分立模型
每个设备节点都关联一个 所有者(UID) 和 所属组(GID)。系统根据进程的 有效用户 ID(EUID) 和 有效组 ID(EGID) 决定访问权限:
- 所有者(User):设备节点的创建者,通常是
root。拥有最高控制权。 - 所属组(Group):通常将需要访问该设备的用户加入同一个组(如
gpio、i2c、video),实现组内共享。 - 其他(Others):既不是所有者也不属于所属组的用户。调试阶段通常设为
---以限制非授权访问。
最佳实践: 在 HAL 驱动调试中,建议将调试用户加入
root 组或设备专用组,避免将设备节点权限设为 0777,防止安全漏洞。
3.3 权限位数值表示:0666 / 0644 / 0660
权限位使用 八进制数 表示,每个数字对应一组权限(User / Group / Others),数字为各组权限值的累加和:
| 权限位 | 二进制 | User | Group | Others | 典型用途 |
|---|---|---|---|---|---|
| 0666 | 110 110 110 | rw- (6) | rw- (6) | rw- (6) | 所有用户可读写(调试阶段临时使用) |
| 0644 | 110 100 100 | rw- (6) | r-- (4) | r-- (4) | 所有者读写,其他只读(普通文件默认) |
| 0660 | 110 110 000 | rw- (6) | rw- (6) | --- (0) | 所有者与所属组读写,其他无权限(推荐设备节点) |
| 0600 | 110 000 000 | rw- (6) | --- (0) | --- (0) | 仅所有者可读写(安全敏感设备) |
安全警告: 切勿在生产环境中使用 0666 或 0777。调试完成后,应立即将设备节点权限恢复为 0660 或 0600,并确保所属组只包含受信任的用户。
3.4 设备节点权限查看与修改
使用 ls -l 查看设备节点权限:
$ ls -l /dev/gpiochip0
crw-rw---- 1 root gpio 254, 0 Apr 1 10:30 /dev/gpiochip0
输出解析:
- c:字符设备(
b为块设备) - rw-rw----:所有者 rw-,所属组 rw-,其他 ---
- 1:硬链接数
- root:所有者
- gpio:所属组
- 254, 0:主设备号、次设备号
使用 chmod 修改权限,chown 修改所有者/组:
# 修改权限为 0660
sudo chmod 660 /dev/gpiochip0
# 修改所有者为 root,所属组为 gpio
sudo chown root:gpio /dev/gpiochip0
# 将当前用户加入 gpio 组(需重新登录生效)
sudo usermod -aG gpio $USER
3.5 设备节点权限与 HAL 驱动调试的关联
在 HAL 驱动调试中,权限配置直接影响调试效率:
| 调试场景 | 推荐权限 | 原因 |
|---|---|---|
| 内核驱动开发阶段 | 0660,组设为 root |
仅 root 可操作,避免多进程干扰 |
| HAL 层集成调试 | 0660,组设为 system 或 hal |
HAL 进程以 system 组运行,需要读写权限 |
| 应用层快速验证 | 0666(临时) | 跳过权限检查,快速验证驱动功能 |
| 生产部署 | 0660 或 0600 | 最小权限原则,仅授权进程可访问 |
调试技巧: 在
init.rc 或 udev 规则中,可以为特定设备节点设置 MODE="0660"、GROUP="hal",确保设备节点在创建时自动应用正确的权限配置,避免每次手动修改。
3.6 常见权限配置错误与排查
- 错误 1: 设备节点权限为
0644,HAL 进程尝试ioctl失败。
原因: 缺少写权限。ioctl通常需要w权限。
解决: 改为0660并确认 HAL 进程在正确的组中。 - 错误 2: 使用
sudo可以访问,但普通用户无法访问。
原因: 设备节点所属组未包含用户,或 Others 权限为---。
解决: 将用户加入设备所属组,或调整组权限。 - 错误 3:
ls -l显示权限正确,但应用仍返回Permission denied。
原因: SELinux 或 AppArmor 等 LSM 模块拦截。
解决: 检查audit.log或临时设置为宽容模式(permissive)进行验证。
快速排查命令:
ls -l /dev/xxx — 查看当前权限id — 查看当前用户 UID/GID 及所属组sudo cat /sys/kernel/debug/device/xxx/permissions — 某些内核驱动提供调试接口