Kernel hacking 方法 - 如何找出在哪里可以破解 linux 内核

Fla*_*ius 5 linux drivers c linux-kernel

我有一台想摆弄的一次性廉价笔记本电脑,Thinkpad SL 500。

困扰我的是两个 LED,一个用于无线连接,一个用于休眠,它们根本不亮,尽管它们可以正常工作,但我已在 Windows 上尝试过。

所以我想为他们编写一个内核驱动程序,没什么大不了的,只是玩弄内核看起来是个好主意。

我的问题是我应该系统地遵循什么方法来找出哪些设备负责这些 LED(一般来说,不一定特定于我的硬件),以及哪些驱动程序负责其他两个 LED 工作,蓝牙和电池指示灯?

当我说方法论时,我真正的意思是方法论,一步一步,每一步都有原因,就像我在这里给其他人的答案一样:&&在 void *p = &&abc; 中是什么意思;

我精通使用静态代码分析器和 co 对大型代码存储库进行 fgrepping,但我认为我缺乏硬件知识阻碍了我解决这个问题。

PS:我使用的是 ArchLinux,所以几乎是最新的内核版本。

saw*_*ust 3

我认为我缺乏硬件知识阻碍了我解决这个问题。

那么我们就从基础开始吧。LED 指示灯可以通过多种方式进行控制:

  • LED 由外围芯片/器件直接控制。在这种情况下,CPU 和内核驱动程序将无法控制 LED。以太网 RJ-45 插孔上的“活动”和“链路速度”LED 指示灯通常就是这种情况;这些 LED 将受到以太网 PHY 设备的直接/排他控制。

  • LED 由 CPU 或 SoC 的 GPIO(通用输入/输出)引脚控制。

  • LED 是外部逻辑(例如FPGA 芯片)的输出。

  • LED 是外围芯片上的输出。

最后三种情况在源码中可能无法区分。端口或设备寄存器中的一位将打开或关闭 LED。检查头文件以了解寄存器中的其他位将控制什么。根据处理器架构,将使用 I/O 指令或存储器读取/存储指令来读取/写入寄存器。

0请注意,LED 通常是一个电流吸收器并连接到逻辑高电压,因此通过写入一个位值将引脚接地来打开 LED 。相反,LED 通常通过写入位值来关闭1。由于仅更改寄存器的一位,因此在位修改之前通常需要读取整个寄存器。寄存器本身可能是一个关键区域,这将需要获取(和释放)互斥锁或自旋锁来保护整个操作。

源代码检查

如果设备驱动程序是专有的,那么你就完蛋了。否则你应该能够获得源代码。您的发行版应该提供其源代码。有一些在线查看器,例如带有内置交叉引用超链接的Linux 内核树。如果驱动程序不在主线内核源代码树中,那么您应该要求硬件制造商根据 GPL 条款提供源代码。

您提到了四个指标:

  • 无线连接
  • 冬眠
  • 蓝牙连接
  • 电池

获取命令的输出lsmod,其中将列出附加到内核的运行时模块。从模块列表中,您需要确定哪些驱动程序与这些 LED 的功能相对应,例如无线网络、电源等。假设此 ThinkPad 具有 Intel 无线控制器芯片,那么您需要在目录中查找drivers/net/wireless/iwlwifi。检查该驱动程序目录中的KconfigMakefile文件,了解实际硬件设备名称、配置符号、.ko构建的模块和相应源代码之间的相关性。

查看用于操作 LED 指示灯的驱动程序源代码。如果该操作没有注释,那么您将不得不寻找位操作、宏或过程调用。有多种方法可以组织此代码,具体取决于代码的模块化程度,或者是否采用 OOP 技术,并且这些 LED 操作是否封装在其他驱动程序的过程中。请注意宏(即#define)和头文件中的文本(可执行代码)。也就是说,仅查看.c文件是错误的。另请注意,某些设备代码可能位于 或 下arch/xxx/platformarch/xxx/machine特别是对于嵌入式单板计算机。