0%

Linux 学习 QA


  2026/3/10
  Q1、为什么在驱动文件中,fops 中的 open 函数要将 filp 的 private_data 指向设备地址,read 函数再从 private_data 获取设备信息,而不是直接访问呢?
  第一、驱动可能不止一个设备实例,一个驱动可能会支持多个设备,如果 read() 里直接访问全局变量,你根本不知道打开的是哪一个设备。而在 open 时内核已经通过 inode 知道设备号,可以在 open 找到对应设备结构体存到 private_data ,之后read、write 都可以拿到正确设备。
  第二、一个设备可以被多个进程打开。在多个线程同时访问同一设备时,内核会创建多个不同的 struct file,每个现成的 fop 独立,不能互相访问。


  2026/3/12
  Q2、为什么在驱动文件中,设备结构体的类和设备结构体要设置为指针?
  因为这些对象不是驱动程序创建的,而是内核创建的。驱动只是登记了一个设备类和设备节点,真正的对象是在内核设备模型里分配的,设备对象必须由内核统一管理,而不是驱动自己随便创建或释放。


  2026/3/16
  Q3、probe 和 init 的区别是什么,我在装载模块时和打开设备时候分别调用什么函数
  当执行 insmod xxx.ko 文件时,先调用 init 函数,只在模块加载时调用一次,在这个函数中通常做的是注册驱动。probe 函数是 设备和驱动匹配成功时调用,他的任务是获取硬件资源、初始化硬件、注册字符设备、创建 /dev 节点。如果系统里有多个设备,probe 可能会执行多次。
  在打开设备时,内核不会再调用 init 或 probe,而是进入 file_operations 里的函数。把三个阶段连起来之后就是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
insmod 驱动

module_init()

xxx_init()

设备匹配

probe()

用户访问设备

open()
read()
write()

  2026/3/19
  Q4、如何更好的理解 Linux 中 SPI 通信需要将 spi_transfer 放到 spi_message 队列中
  Linux SPI 子系统管理的不是某一段字节流,而是完整的 SPI 事务,而一个事务往往由多个传输片段组成,所以需要 spi_message 将他们组织起来。
  我们先来搞清楚 spi_transfer 和 spi_message 的分工。spi_transfer 描述的是一次具体传输数据,比如 tx_buf、rx_buf、len 等等信息,它关注的是某一小段如何传输;而 spi_message 本质上是一个链表容器,用来挂载 spi_transfer,它关注的是这些小段合起来构成什么事务。


  2026/3/24
  Q5、ABS_MT_SLOT 和 ABS_MT_TRACKING_ID 的关系是什么?
  slot 表示的是位置,若最大支持触摸点数量为 5,系统会创建 5 个 slot,驱动上报数据前要先选择 slot。ABS_MT_TRACKING_ID 表示身份,表示这个 slot 中的手指是不是同一根,比如 ABS_MT_TRACKING_ID = 12,表示当前手指 ID 为 12,如果 ABS_MT_TRACKING_ID = -1,表示当前 slot 已经没有手指。
  若同时两根手指触摸,则

1
2
slot0 tracking_id=10 x=100 y=200
slot1 tracking_id=11 x=300 y=400

  当第一个手指移动,slot0 的 tracking_id 不会变,只会改变其坐标。当手指抬起时,tracking_id 变为 -1,表示 slot0 释放,当下次 slot0 被启用时,会有一个新的 ID。