Linux设备节点基础知识

在 Linux 系统中,设备驱动与用户层的通信方式较为多样,设备节点只是其中一种常见的通信途径,且并非所有驱动函数都依赖它来与用户层交互。

  • 基于设备节点通信的情况 :对于字符设备和块设备驱动,通常会创建设备节点(一般位于/dev目录下)。设备节点作为用户层与内核驱动交互的接口,用户层应用程序通过对设备节点进行文件操作(如open、read、write、ioctl等),间接调用内核驱动中对应的函数。
  • 例如,字符设备驱动通过register_chrdev函数注册设备时,会分配主设备号和次设备号,并创建对应的设备节点,应用层可通过操作该设备节点,触发驱动中实现的file_operations结构体里的函数 ,像read、write等函数,从而实现与内核驱动的通信。I2C 设备驱动也会创建设备节点,用户空间应用程序能通过打开这些节点,使用标准的读写操作与 I2C 设备进行通信。
  • 其他通信方式
    • 系统调用 :应用程序可通过系统调用来请求内核执行某些操作,像ioctl系统调用,可向内核驱动发送特定命令。它不依赖专门的设备节点,而是直接利用系统调用机制与内核驱动交互,常用于传递复杂控制命令或获取设备特定状态信息。
    • proc 文件系统和 sysfs 文件系统 :proc文件系统提供虚拟文件,应用程序通过读写这些文件与内核通信,比如读取/proc/cpuinfo获取 CPU 信息。sysfs文件系统用于向用户空间提供硬件设备信息,应用程序可读写相关文件控制设备行为,它们都不是基于特定的设备节点与内核驱动函数通信。
    • Netlink 套接字 :这是内核与用户空间通信的机制,应用程序创建和使用 Netlink 套接字与内核驱动通信,常用于实现用户空间与内核之间的异步通信和事件通知,同样不依赖设备节点。

内核驱动与用户层通信的 "专属节点"(设备文件或属性文件)在文件系统中的路径,取决于驱动类型和设计规范,不同类型的驱动会使用不同的路径约定。以下是几类常见驱动节点的具体路径及说明:

一、字符设备 / 块设备: /dev/ 目录下的设备文件

最常见的设备节点路径,字符设备(如 GPIO、UART、传感器)和块设备(如硬盘、分区)的节点通常直接位于 /dev/ 目录或其下子目录,命名由驱动定义。

示例:

  1. GPIO 字符设备
    路径:/dev/gpiochip0、/dev/gpiochip1
    说明:现代 GPIO 驱动(基于gpiochip框架)会在/dev下创建gpiochipX节点,用户层通过open/ioctl操作这些节点,间接调用内核的GPIO控制函数(如gpiochip_get_line)。
  2. 串口设备
    路径:/dev/ttyS0(传统串口)、/dev/ttyUSB0(USB 转串口)
    说明:UART 驱动会创建tty系列节点,用户层通过read/write操作与串口通信,对应内核中的uart_ops函数集。
  3. 块设备(硬盘 / 分区)
    路径:/dev/sda(SATA 硬盘)、/dev/mmcblk0p1(eMMC 分区)
    说明:块设备驱动创建的节点,用户层通过文件系统挂载或直接读写(如dd命令)与内核块设备函数交互。

二、sysfs 虚拟文件系统: /sys/ 目录下的属性文件

sysfs 是内核向用户层暴露设备属性的主要途径,路径通常以 /sys/class/、/sys/devices/ 或 /sys/bus/ 为前缀,节点为文本文件(属性文件),通过读写文本内容与内核函数通信(如之前操作的 GPIO 导出节点)。

示例:

  1. 设备类属性( /sys/class/
    • GPIO 导出 / 取消导出:/sys/class/gpio/export、/sys/class/gpio/unexport
      对应内核函数:export_store/unexport_store(你脚本中操作的节点)。
    • 背光亮度控制:/sys/class/leds/lcd-backlight/brightness
      对应内核函数:背光驱动的brightness_store(写入亮度值触发)。
  2. 设备实例属性( /sys/devices/
    路径:/sys/devices/platform/soc/12340000.i2c/i2c-0/0-0050/eeprom
    说明:I2C 设备(如 EEPROM)的属性文件,写入数据会触发内核i2c_driver中的write函数。
  3. 总线属性( /sys/bus/
    路径:/sys/bus/i2c/devices/0-0050/name
    说明:I2C 总线上设备的名称属性,读取时触发内核i2c_device的show函数。

三、proc 文件系统: /proc/ 目录下的虚拟文件

proc 文件系统主要用于暴露内核状态和进程信息,部分驱动会通过/proc节点与用户层通信,路径通常为 /proc/驱动名 或 /proc/devices 等系统级文件。

示例:

  1. 设备号信息
    路径:/proc/devices
    说明:记录所有已注册的字符设备和块设备的主设备号,读取时触发内核proc_devices相关函数,用于查询驱动是否已加载。
  2. 自定义驱动节点
    路径:/proc/my_driver/status
    说明:驱动可通过proc_create创建自定义节点,用户层读写该文件时,触发内核proc_ops中的read/write函数(如返回设备状态)。

四、设备树与平台设备: /sys/firmware/devicetree/

对于基于设备树(Device Tree)的嵌入式系统,设备树节点的信息会被内核解析并暴露在/sys/firmware/devicetree/下,用于用户层查询硬件配置(非直接通信,而是信息暴露)。

示例:

路径:/sys/firmware/devicetree/base/gpio@12340000/compatible

说明:读取该文件可获取 GPIO 控制器的兼容属性(如"vendor,gpio-v2"),对应设备树中定义的compatible字段,帮助用户层识别驱动类型。

五、关键规律:路径与驱动类型的对应关系

|------------|---------------------------|------------------|-----------------|
| 驱动类型 | 典型路径前缀 | 节点用途 | 通信方式 |
| 字符设备 / 块设备 | /dev/ | 直接操作硬件(读写、控制) | open/read/ioctl |
| sysfs 属性设备 | /sys/class/、/sys/devices/ | 暴露设备属性(亮度、开关状态) | 读写文本文件 |
| 内核状态 / 进程 | /proc/ | 暴露系统状态(设备号、内存使用) | 读取文本文件 |
| 设备树配置 | /sys/firmware/devicetree/ | 暴露硬件配置信息(非通信) | 读取文本文件 |

总结

内核驱动与用户层通信的节点路径没有 "统一固定格式",但遵循以下原则:

  1. /dev/ :用于需要频繁、快速交互的设备(如串口、GPIO 芯片),通过文件操作函数通信;
  2. /sys/ :用于暴露设备属性和控制接口(如亮度、导出 GPIO),通过读写文本内容通信;
  3. /proc/ :用于系统级信息查询(如设备号、进程状态),以读操作为主。

具体路径需参考驱动文档或通过ls /dev、ls /sys/class等命令在开发板上实际查询(驱动加载后会自动创建对应的节点)。

相关推荐
大树8812 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠12 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush412 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行52013 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz13 小时前
Maven依赖冲突
java·服务器·maven
不会C语言的男孩14 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈14 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix
程序猿阿伟15 小时前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome
凡人叶枫15 小时前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
AC赳赳老秦15 小时前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw