设备驱动

本文最后更新于:2024年8月12日 晚上

设备驱动

元器件

disk

时钟芯片

CPU

cpu调频

NUMA

设备I/O

iommu

io端口与io内存

ARM I/O内存(Memory-Mapped I/O):

  • 定义: ARM I/O内存是将外设寄存器映射到CPU的地址空间中的特殊内存区域。通过读写这些内存区域的值,可以实现对外设的控制和通信。
  • 用途: 用于与外设进行直接的内存读写交互,例如访问显示控制器、网络接口等。

I/O端口:

  • 定义: 在一些架构中,I/O端口是一种通过专用指令(in和out指令)而非内存地址进行访问的I/O设备寄存器。与内存映射I/O不同,I/O端口提供了一种专门的寄存器访问机制。
  • 用途: 用于与特定I/O设备进行通信,这些设备被分配到I/O地址空间的端口。

IOMMU(I/O Memory Management Unit):

  • 定义: IOMMU 是一种硬件设备,用于管理主内存和外设之间的内存映射,以提供更灵活的I/O设备访问。它可以防止I/O设备越界访问主内存,并提供内存隔离。
  • 用途: 用于支持虚拟地址空间的设备,提供更好的内存管理和安全性,特别是在虚拟化环境中。

在 ARM 架构中,ARM I/O内存通常是指使用内存映射I/O的方式,而I/O端口的概念在ARM中较为不常见。至于IOMMU,它在ARM平台上也有应用,用于提供更高级别的内存管理和隔离,以满足复杂的I/O设备需求。

dma

Cache

在计算机体系结构中,缓存一致性指的是如何确保多个处理器或核心在访问共享内存时看到相同的数据。不同的处理器架构采用不同的一致性模型。以下是 x86 和 ARM 在缓存一致性方面的区别:

x86 架构的缓存一致性

x86 架构实现了强一致性(Strong Consistency),这也被称为“总存储顺序”(Total Store Order,TSO)。在这种模型中,x86 处理器保证:

  1. 写入顺序一致性:所有处理器对单个内存地址的写操作将按照它们的顺序被看到。
  2. 读-写顺序一致性:一个处理器的读操作不能越过之前的写操作。
  3. 缓存一致性协议:x86 处理器使用缓存一致性协议(如 MESI 协议),确保所有处理器的缓存内容是一致的。

这些特性使得编写多线程程序时,程序员可以假设所有处理器看到的内存操作顺序是一致的,从而减少了编程复杂性。

ARM 架构的缓存一致性

ARM 架构则实现了弱一致性(Weak Consistency),具体表现为:

  1. 松散的内存顺序:ARM 允许处理器在某些条件下重新排序读写操作,这可以提高性能和效率。例如,ARM 的“弱顺序内存模型”(Weakly Ordered Memory Model)允许写操作在某些情况下被缓冲,且多个写操作可以被合并或延迟。
  2. 缓存一致性协议:ARM 处理器也使用缓存一致性协议(如 MOESI 协议),但它们的实现方式允许更多的灵活性。

由于 ARM 允许更松散的内存顺序,程序员需要使用内存屏障(Memory Barrier)指令来确保某些内存操作的顺序。例如,ARM 提供 dmb(数据内存屏障)指令,用于强制执行内存操作的顺序。

为什么会有这种差异?
  1. 性能和功耗:ARM 处理器广泛应用于移动设备和嵌入式系统,这些系统对性能和功耗有严格要求。通过允许更松散的内存顺序,ARM 可以在某些情况下提高性能和减少功耗。

  2. 设计哲学:x86 处理器主要应用于服务器、桌面和高性能计算领域,强一致性简化了多线程程序的编写,减少了程序员的负担,提高了系统的可靠性。

  3. 应用场景:x86 处理器常用于需要高一致性和可靠性的应用,而 ARM 处理器更多地用于对一致性要求较低但对功耗和性能要求较高的场景。

总之,x86 和 ARM 处理器在缓存一致性上的差异主要源于它们的应用场景、设计目标和技术取舍。x86 选择强一致性以简化编程和确保高可靠性,而 ARM 选择弱一致性以提高性能和减少功耗。

FPGA

JTAG

总线

pci

PCI配置寄存器

所有的PCI设备都有至少256字节的地址空间,其中前64字节是标准化的,被称为PCI配置寄存器,剩下的字节是设备相关的 (取决于具体的厂商,需要查看datasheet得知)。

PCI配置寄存器如下图所示。

PCI配置寄存器
  • Vendor ID: 标识硬件厂商,需要向特定组织进行注册。
  • Device ID: 由硬件厂商来分配的设备ID,无需对ID进行注册。
  • Subsystem ID、Subsystem Vendor ID: 用来进一步标识设备。

usb

USB子系统

I2C

SPI

gpio

acpi

acpi debug

  • ACPI AML debug and override ACPI tables using initrd

  • Upgrading ACPI tables via initrd

    • 通过initrd,可以直接修改acpi tables,方便调试,本次以修改dsdt表做demo展示:

      内核编译选项ACPI_TABLE_UPGRADE默认是开启的,故无需重新编译内核。

      安装acpica-toolsiasl导出dtst表:

      1
      2
      3
      4
      5
      sudo apt install acpica-tools iasl
      mkdir acpidump
      cd acpidump
      sudo acpidump -b
      iasl -d *.dat # 生成dsdt.dsl

      本次修改电池_HID值,将FTEC0002替换为FTEC0005

      修改前:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // vim dsdt.dsl +307
      307 Device (BAT1)
      308 {
      309 Name (_HID, "FTEC0002") // _HID: Hardware ID
      310 Name (_UID, Zero) // _UID: Unique ID
      311 Name (_CRS, Buffer (0x02) // _CRS: Current Resource Settings
      312 {
      313 0x79, 0x00 // y.
      314 })
      315 }

      修改后:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // vim dsdt.dsl +307
      307 Device (BAT1)
      308 {
      309 Name (_HID, "FTEC0005") // _HID: Hardware ID
      310 Name (_UID, Zero) // _UID: Unique ID
      311 Name (_CRS, Buffer (0x02) // _CRS: Current Resource Settings
      312 {
      313 0x79, 0x00 // y.
      314 })
      315 }

      增加dsdt.dsl中的OEM version从而达到覆盖原有的dsdt表:

      修改前:

      1
      2
      // vim dsdt.dsl +21
      21 DefinitionBlock ("", "DSDT", 2, "ARMLTD", "PHYTIUM ", 0x20180509)

      修改后:

      1
      2
      // vim dsdt.dsl +21
      21 DefinitionBlock ("", "DSDT", 2, "ARMLTD", "PHYTIUM ", 0x20180510)

      编译修改后的dsdt.dsl,生成新的dsdt.aml:

      1
      iasl -sa dsdt.dsl

      制作调试用的initrd,将新生成的dsdt.aml拷贝到initrd顶部:

      1
      2
      3
      4
      mkdir -p kernel/firmware/acpi
      cp dsdt.aml kernel/firmware/acpi
      find kernel | cpio -H newc --create > /boot/initrd_dsdt
      cat /boot/initrd.img-4.19.0-arm64-desktop >> /boot/initrd_dsdt

      在grub中增加以下acpi.debug参数,从而启用与ACPI硬件相关的所有日志:

      1
      acpi.debug_layer=0x2 acpi.debug_level=0xffffffff

      更新grub配置并重启系统:

      1
      2
      update-grub
      reboot

      在grub引导界面修改initrd:

      initrd /initrd.img-4.19.0-arm64-desktop这一行修改为initrd /boot/initrd_dsdt即可。

      按下Ctrl +x 或者F10引导系统启动,进入系统后可以再次导出dsdt表,可以看到FTEC0002已经替换成了FTEC0005

  • 解决ACPI问题的小窍门

  • Linux acpi off关于Suspend to Disk 问题分析

    • 基于linux源码调试DSDT表

      1
      2
      iasl -tc DSDT.dsl # 产生一个 DSDT. hex 文件
      cp DSDT.hex $SRC/include/ # 将这个文件复制到 Linux 源代码的 include 文件夹下

      1
      2
      3
      4
      向 .config 文添加以下描述
      CONFIG_STANDALONE = n # 将原 .config 的 y 改写为 n
      CONFIG_ACPI_CUSTOM_DSDT = y
      CONFIG_ACPI_CUSTOM_DSDT_FILE = ″DSDT.hex″

acpi表定位

ACPI电源管理

pm-debug

pm-graph

电源按钮

acpi事件

acpid

logind

设备树

设备树导出

安装DTC工具:

1
sudo apt install device-tree-compiler

在运行的linux系统中获取设备树:

1
dtc -I fs -O dts /sys/firmware/devicetree/base > hw.dts

udev

通过udev monitor捕获uevent包含的信息:

1
udevadm monitor --kernel --property --udev

也可采用简写命令:

1
udevadm monitor -kpu

也可直接采用udev mointor -p命令查看信息,推荐使用上方两个命令:

1
udevadm mointor -p

借助udev中的udevadm info工具查找规则文件能利用的内核信息和sysfs属性信息:

1
udevadm info -a -p /sys/devices/virtual/misc/globalfifo

如果/dev/下面的节点已被创建,但是不知道它对应的/sys具体路径,可以使用udevadm info -a -p $(udevadm info -q path -n /dev/<节点名>)命令反向分析:

1
udevadm info -a -p $(udevadm info -q path -n /dev/globalfifo)

input

evtest

中断

  • Linux中断子系统(八)一个外设硬件中断如何找到自己注册的中断处理程序

  • AArch64 TrustZone

  • Arm通用中断控制器GICv3和GICv4

  • 一文讲透计算机的“中断”

  • 嵌入式基础知识-中断处理过程

  • 从软硬件交互的角度去看中断的一生

  • PCIe中断机制(4): MSI和MSI-X

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    MSI(Message Signaled Interrupts)和MSI-X(Message Signaled Interrupts eXtended)是用于替代传统的PCI中断线机制的中断分配和传递机制。它们具有一些优势,如减少中断冲突、提高系统性能和可扩展性。

    以下是MSI和MSI-X中断机制的主要特点:

    MSI(Message Signaled Interrupts):

    MSI允许设备发送消息来请求中断,而不是使用共享的中断线。
    每个设备都有自己的MSI寄存器,可以用来发送中断消息给CPU。
    中断消息通常包括中断向量和标识特定设备的信息。
    MSI机制减少了中断冲突,因为每个设备都有自己的中断向量,不再需要共享中断线。
    MSI支持的中断数量通常受硬件的限制。

    MSI-X(Message Signaled Interrupts eXtended):

    MSI-X是MSI的扩展,它提供更多的中断向量,更灵活的配置和更好的性能。
    MSI-X支持的中断向量数目通常比MSI多,这意味着更多的设备可以同时拥有自己的中断。
    MSI-X还提供了更灵活的配置选项,允许设备在多个中断向量之间进行映射,从而更好地支持虚拟化和多处理器系统。

    使用场景:

    MSI和MSI-X通常用于高性能计算和服务器领域,以减少中断冲突并提高系统性能。
    它们也对虚拟化技术非常有帮助,因为它们可以更好地支持虚拟机之间的中断隔离和映射。
    总之,MSI和MSI-X是一种现代化的中断机制,它们提供了更好的性能、可扩展性和虚拟化支持,特别适用于高性能计算和服务器环境。它们有助于减少中断冲突,提高系统效率。

open release

RK3588S

1
2
3
4
5
6
sudo apt install -y repo git python
mkdir rk3588_sdk
cd rk3588_sdk
repo init --no-clone-bundle --repo-url https://gitlab.com/firefly-linux/git-repo.git -u https://gitlab.com/firefly-linux/manifests.git -b master -m rk3588_linux_release.xml
.repo/repo/repo sync -c --no-tags
.repo/repo/repo start firefly --all
1
2
git checkout -b rk3588_v1.0.6e 29f0634
git checkout rk3588_v1.0.6e
1
2
readlink -f .repo/manifest.xml
/home/wujing/code/rk3588_sdk/.repo/manifests/rk3588/rk3588_linux_release_20230301_v1.0.6e.xml

注释掉kernel/arch/arm64/configs/firefly-linux.config 194行CONFIG_SPI_WK2XXX=y

其他


设备驱动
https://realwujing.github.io/linux/kernel/drivers/设备驱动/
作者
Wu Jing
发布于
2023年8月29日
许可协议