news 2026/5/26 8:31:12

我的嵌入式权限踩坑实录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
我的嵌入式权限踩坑实录

在 EBF6ULL 开发板上部署 Linux 驱动和测试程序时,我遭遇了一系列 “诡异” 报错,最终发现所有问题的根源都指向权限:​

  • 编译好的静态程序提示command not found(实际是 /home 分区 noexec 挂载);​
  • 执行程序报 Permission denied(文件缺少可执行权限);​
  • 设备文件 /dev/hello 存在却打不开(仅 root 有权限,普通用户无访问权)。​

这些问题在桌面 Linux 中少见,但在嵌入式精简系统中极为普遍。本文将从 Linux 权限底层逻辑出发,结合嵌入式场景特性,总结一套 “权限避坑方法论”,帮你少走弯路。

一、Linux 权限核心原理:搞懂 3 个核心概念​

Linux 是多用户多任务系统,权限机制的核心是 “控制不同用户对文件 / 目录的操作范围”,核心围绕 3 个维度展开:​

1. 权限的三大要素​

(1)主体(Who):谁在操作?​

Linux 用户分为三类,对应权限的不同层级:​

  • 所有者(Owner):文件 / 目录的创建者(用 chown 修改);​
  • 所属组(Group):所有者所在的用户组(用 chgrp 修改);​
  • 其他用户(Others):既不是所有者,也不属于所属组的用户。​

(2)对象(What):操作什么?​

  • 文件(File):普通文件(如可执行程序、源码)、设备文件(如 /dev/hello 字符设备);​
  • 目录(Directory):文件夹(权限控制是否能进入、创建 / 删除文件)。​

(3)操作(How):能做什么?​

权限用 3 个字符表示,对应 “读(r)、写(w)、执行(x)”,不同对象的权限含义不同:​

权限​

对文件的含义​

对目录的含义​

r(4)​

读取文件内容(如 cat)​

查看目录下的文件(如 ls)​

w(2)​

修改文件内容(如 echo)​

创建 / 删除目录下的文件(如 touch/rm)​

x(1)​

执行文件(如 ./program)​

进入目录(如 cd)​

权限的数字表示:r=4、w=2、x=1,组合后为 3 位数字(如 755 = rwxr-xr-x)。

2. 特殊权限与嵌入式场景关联​

除了基础权限,以下特殊权限在嵌入式开发中高频用到:​

  • SUID(Set User ID):执行文件时,临时获得文件所有者的权限(如 sudo 命令);​
  • SGID(Set Group ID):执行文件时,临时获得文件所属组的权限;​
  • Sticky Bit(粘滞位):仅目录所有者可删除目录下的文件(嵌入式中少用);​
  • noexec 挂载选项:分区挂载时添加 noexec,禁止在该分区执行任何程序(嵌入式 /home 分区常见)。​

3. 设备文件的特殊权限逻辑​

嵌入式开发中,/dev 目录下的设备文件(如 /dev/hello)权限有特殊性:​

  • 设备文件类型:字符设备(c 开头)、块设备(b 开头),无 “执行(x)” 权限(只需 r/w);​
  • 默认权限:驱动创建的设备文件默认是 rw-------(仅 root 可读可写),普通用户需手动授权;​
  • 权限修改:必须用 sudo chmod 666 /dev/xxx 开放权限(666 = rw-rw-rw-)。

二、嵌入式 Linux 权限的 “坑点”:和桌面系统的核心差异​

嵌入式 Linux(如 EBF6ULL 的根文件系统)为了精简体积和提升安全性,权限机制比桌面 Ubuntu 更严格,这是导致一系列报错的根本原因:​

1. 分区 noexec 挂载(最隐蔽的坑)​

  • 现象:文件有 x 权限,却提示 command not found 或 Permission denied;​
  • 原因:嵌入式系统会给非核心分区(如 /home、/mnt)添加 noexec 挂载选项,禁止执行程序;​(将在板端存放可执行程序的工作空间权限提升到最高 chmod 777 -R 工作空间名)
  • 验证:执行 mount | grep noexec,查看是否有 /home 分区;​
  • 示例:我的 EBF6ULL 中 /home 挂载参数为 /dev/mmcblk1p2 on /home type ext4 (rw,noexec,relatime)。​

2. 普通用户权限受限(最常见的坑)​

  • 现象:设备文件 /dev/hello 存在,普通用户执行程序提示 “打不开文件”;​
  • 原因:嵌入式系统默认只有 root 用户有硬件操作权限,普通用户(如 ubuntu)无访问 /dev 设备的权限;​
  • 对比:桌面 Ubuntu 会通过 udev 自动给设备文件添加普通用户权限,嵌入式系统常精简 udev 服务。​

3. 文件传输后权限丢失(最容易忽略的坑)​

  • 现象:虚拟机中编译好的程序,传输到板端后丢失 x 权限;​
  • 原因:scp/U 盘传输时,可能因文件系统特性(如 FAT32 不支持 Linux 权限)导致权限丢失;​
  • 验证:传输后执行 ls -l 程序名,发现无 x 标识( -rwxr--r-- 变成 -rw-r--r--)。

三、嵌入式权限避坑指南:从编译到执行全流程​

结合我的踩坑经历,总结一套 “编译→传输→执行→调试” 全流程权限避坑方案,直接套用即可:​

阶段 1:编译阶段 —— 从源头规避依赖权限问题​

避坑点:静态编译,摆脱动态库依赖​

  • 问题:动态链接程序可能因板端库权限 / 路径问题报错;​
  • 解决方案:编译时加 -static 参数,打包所有依赖库到程序中;​
  • 命令(交叉编译示例):​

arm-linux-gnueabihf-gcc -o hello_drv_test hello_drv_test.c -static​

  • 验证:编译后执行 file hello_drv_test,输出包含 statically linked 即成功。​

阶段 2:文件传输阶段 —— 确保权限不丢失​

避坑点 1:传输后立即添加执行权限​

  • 命令(板端执行):​

# 给可执行程序加执行权限(最小权限原则)​

chmod +x hello_drv_test​

# 测试用可放宽权限(所有用户可执行)​

sudo chmod 777 hello_drv_test​

  • 原理:chmod +x 仅给所有者添加执行权限,777 给所有用户添加读 / 写 / 执行权限(测试阶段可用,生产环境慎用)。​

避坑点 2:选择 “可执行分区” 存放程序​

  • 问题:/home 分区 noexec 导致程序无法执行;​
  • 解决方案:优先将程序拷贝到 /tmp 目录(嵌入式系统默认 exec 挂载,支持执行程序);​
  • 命令(板端执行):​

# 拷贝程序到/tmp​

sudo cp hello_drv_test /tmp/​

# 进入/tmp执行​

cd /tmp && sudo ./hello_drv_test​

阶段 3:驱动与设备文件阶段 —— 开放设备访问权限​

避坑点 1:手动创建设备节点(udev 未启动时)​

  • 问题:驱动加载成功,但 /dev/hello 未自动创建;​
  • 解决方案:通过内核日志获取主设备号,手动创建;​
  • 命令(板端执行):​

# 1. 查看内核日志,获取主设备号(示例:244)​

dmesg | grep "major ="​

# 2. 创建设备节点(c=字符设备,244=主设备号,0=次设备号)​

sudo mknod /dev/hello c 244 0​

避坑点 2:给设备文件开放权限​

  • 问题:设备文件存在,但普通用户无法访问;​
  • 解决方案:用 chmod 666 开放读写权限(设备文件无需执行权限);​
  • 命令(板端执行):​

sudo chmod 666 /dev/hello​

# 验证:执行ls -l /dev/hello,输出crw-rw-rw-即成功​

进阶方案:驱动代码中默认开放权限(长期使用)​

  • 问题:每次创建设备节点都要手动改权限,麻烦;​
  • 解决方案:修改驱动代码,在 device_create 后添加权限设置;​
  • 代码示例:​

#include ​

// 创建设备节点后添加:设置默认权限为666​

device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello");​

dev_set_permissions(hello_class->dev_root, MKDEV(major, 0), 0666);​

  • 原理:驱动加载时自动给 /dev/hello 分配 rw-rw-rw- 权限,无需手动修改。​

阶段 4:执行阶段 —— 用 sudo 提权,避免权限不足​

避坑点:普通用户执行程序必须加 sudo​

  • 问题:普通用户执行程序提示 “权限不足”;​
  • 解决方案:用 sudo 临时获取 root 权限;​
  • 命令(板端执行):​

# 执行测试程序(带参数)​

sudo /tmp/hello_drv_test -w YYZ​

# 加载/卸载驱动​

sudo insmod hello_drv.ko​

sudo rmmod hello_drv​

  • 原理:sudo 允许普通用户以 root 身份执行命令,规避设备访问 / 硬件操作的权限限制。​

阶段 5:调试阶段 —— 快速定位权限问题​

遇到权限相关报错,按以下步骤排查,高效定位问题:​

检查文件权限:ls -l 文件名,确认是否有对应的 x(程序)/r/w(设备文件)权限;​

检查分区挂载:mount | grep 目录名,确认分区是否有 noexec 选项;​

检查用户身份:whoami,确认是否为 root 用户(非 root 需加 sudo);​

查看内核日志:dmesg | tail -20,排查设备访问时的权限拒绝日志(如 permission denied)。​

四、常见权限报错速查表:遇到问题直接查​

报错信息​

核心原因​

解决方案​

command not found(文件存在)​

1. 无 x 权限;2. 分区 noexec 挂载​

1. chmod +x 程序名;2. 拷贝到 /tmp 执行​

Permission denied​

1. 无执行权限;2. 无设备访问权限​

1. chmod +x 程序名;2. sudo 执行程序​

can not open file /dev/xxx​

1. 设备文件不存在;2. 无 r/w 权限​

1. mknod 创建设备节点;2. chmod 666 /dev/xxx​

Operation not permitted​

普通用户无 root 权限​

加 sudo 执行命令​

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 3:08:54

XAPK转APK终极指南:零基础轻松搞定安卓安装难题

XAPK转APK终极指南:零基础轻松搞定安卓安装难题 【免费下载链接】xapk-to-apk A simple standalone python script that converts .xapk file into a normal universal .apk file 项目地址: https://gitcode.com/gh_mirrors/xa/xapk-to-apk 还在为无法安装XA…

作者头像 李华
网站建设 2026/5/26 6:46:14

快速实现Android滑动菜单:EasySwipeMenuLayout深度解析

快速实现Android滑动菜单:EasySwipeMenuLayout深度解析 【免费下载链接】EasySwipeMenuLayout A sliding menu library not just for recyclerview, but all views. 项目地址: https://gitcode.com/gh_mirrors/ea/EasySwipeMenuLayout 为什么这个轻量级库能帮…

作者头像 李华
网站建设 2026/5/25 8:45:42

css样式用flex 布局的时候元素尺寸展示不对

问题描述 我的代码是148px宽度,但是实际上显示的只有133px问题根源 在 Flex 布局中,flex-shrink是flex 子元素的收缩属性,默认值是1,意思是: 当父元素的宽度不足以容纳所有子元素的宽度总和时,子元素会按照…

作者头像 李华
网站建设 2026/5/26 6:46:22

Altium Designer Viewer:免费高效的电路设计查看终极指南

Altium Designer Viewer:免费高效的电路设计查看终极指南 【免费下载链接】AltiumDesignerViewer Altium Designer Viewer是一款高效且易于使用的查看工具,专为设计工程师和团队成员打造,旨在无需进行任何注册或激活的情况下,轻松…

作者头像 李华
网站建设 2026/5/25 8:26:10

GitHub加速终极方案:告别卡顿,畅享极速开发体验

GitHub作为全球开发者必备的代码托管平台,在国内访问时经常遇到页面加载缓慢、图片无法显示等网络问题。通过精心设计的网络优化方案,我们能够彻底解决这些困扰,让GitHub访问变得流畅稳定。🔥 【免费下载链接】github-hosts &…

作者头像 李华