ARM 和 x86 之间的区别是PIO。ARM 上没有访问 I/O 设备的特殊指令。一切都是通过内存映射 I/O 完成的。
第二个区别是 ARM(和一般的 RISC)有一个独立的加载/存储单元,它与普通逻辑是分开的。
第三个区别是 ARM 对架构和逻辑内核都进行了许可。第一个被 Apple、Samsung 等公司使用,它们制造了无尘室版本的内核。对于实际购买逻辑的第二组,ARM CPU 将包含来自AMBA家族的东西。
ARM 的其他外设,例如 GIC(Cortex-A 中断控制器)、NVIC(Cortex-M 中断控制器)、L2 控制器、UART 等,都将带有 AMBA 类型的接口。第 3 方公司(ChipIdea USB 等)也可以为特定 ARM 总线设置逻辑。
注意 Wikipedia 上的 AMBA 记录了几种总线类型。
- APB - 低速外围总线;有点像南桥。
- AHB - 几个版本(旧的北桥)。
- AXI - 一种较新的多 CPU(主)高速总线。示例NIC301。
- ACE - AXI 扩展。
单个 CPU/内核可能有一个、两个或多个主连接到 AXI 总线。可能有多个内核连接到 AXI 总线。内核的加载/存储和指令获取单元可以使用多个端口将请求分派到单独的从属设备。SOC 供应商将平衡端口数量与预期的内存带宽需求。GPU 也经常与 DDR 从设备一起连接到 AXI BUS。
确实没有 100% 标准的拓扑;特别是如果您考虑所有可能的未来 ARM 设计。但是,典型的拓扑将包括一个连接了一些AHB外设的顶级AXI 。一个或多个第 2 级APB(总线)将提供对低速外围设备的访问。并非每个 SOC 供应商都愿意花时间重新设计外设,而较旧的 AHB 接口速度对于设备来说可能相当不错。
您的问题被标记为embedded-linux。在大多数情况下,Linux 只需要知道物理地址。有时,外围总线控制器可能需要配置。例如,可以将 APB 配置为允许或禁止用户模式。此配置可以在引导时锁定。一般来说,Linux 不会直接过多关心总线结构。程序员可能已经编写了具有结构知识的驱动程序(例如 IRAM 更快等)。
不过,我的问题是操作系统如何知道如何解决它们?
较旧的 Linux 内核将这些定义放在一个机器文件中,并传递一个平台资源结构,包括中断号和寄存器组的物理地址。在较新的 Linux 版本中,此信息包含在Open Firmware或设备树文件中。
具体来说,我问的是哪个组件负责为外围设备和 MMIO 地址分配地址?
物理地址由 SOC 制造商设置。Linux平台支持将使用 MMU 将它们映射为不可缓存到某些未使用的范围。通常物理地址可能非常稀疏,因此虚拟重映射包更密集。每一个都会导致 TLB 命中(MMU 缓存)。
这是一个使用 AXI 并连接了 Cortex-M 和 Cortex-A 的示例 SOC 总线结构。
PBRIDGE 组件是 APB 网桥,并以星形拓扑连接。正如其他人所建议的那样,您需要查看特定的 SOC 文档以了解详细信息。但是,如果您没有 SOC 并试图大致了解 ARM,那么上面的一些信息将对您有所帮助,无论您拥有什么 SOC。