我花了一些时间在linux驱动程序上,这个问题总让我感到困惑:内核如何知道片上外设注册它运行的CPU有哪些?
例如,我正在使用内置ARM A9的Cyclone V SOC。它有4个I2C控制器,每个的基地址是0xFFC04000,0xFFC05000,0xFFC06000和0xFFC07000。每个基地址都有一个偏移量为0x0的控制寄存器,一个偏移量为0Xx10的数据寄存器,依此类推。
无论I2C驱动程序模型有什么数据结构,驱动程序C代码的所有操作都应该最终反映到这些寄存器的操作,对吧?如果你想获得你的I2C RX数据,最后应该在数据寄存器中获取一些操作,这是数据在整个CPU上的唯一位置。 内核如何知道CPU外围设备的注册位置以及它们的位置以及每个外围设备的功能?
我知道设备树在硬件资源上向内核提供一些信息,但通常就像:
i2c0: i2c@ffc04000
{
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc04000 0x1000>;
interrupts = <0 158 4>;
clocks = <&l4_sp_clk>;
status = "okay";
};
它只告诉CPU第一个I2C控制器的基地址为0xffc04000,其寄存器段的长度为0x1000。没有别的。 CPU仍然不知道这个0x1000部分内部是什么,有什么寄存器,目的是什么,地址偏移是什么。
我知道mmap / ioremap可以将物理地址映射到虚拟地址,但这不是我要求的。
非常感谢~~