内存映射I/O地址从何而来?

7
我正在做一些爱好者级别的操作系统开发,对于内存映射I/O地址有些困惑。我理解整个内存映射I/O概念,但我试图弄清楚开发人员如何获得地址以操纵硬件。
这些地址是由硬件供应商指定的还是所有计算机都使用某种标准地址?例如,用于文本打印的VGA存储器的起始地址为0xB8000。这对于每台x86机器都是标准的吗?如果是,是谁设置了这个标准?如果我想与以太网卡通信,我如何知道它使用的地址或端口?
提前致谢。
3个回答

4

我不完全确定是谁设置地址,但据我所知,硬件供应商可以随意设置他们的内存映射。

值得注意的是,Linux 允许您通过执行 cat /proc/iomem 查看机器上当前的内存映射:

00000000-0000ffff : reserved
00010000-0009f3ff : System RAM
0009f400-0009ffff : reserved
000a0000-000bffff : PCI Bus 0000:00
  000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000ca000-000cbfff : reserved
  000ca000-000cafff : Adapter ROM
000cc000-000cffff : PCI Bus 0000:00
000d0000-000d3fff : PCI Bus 0000:00
000d4000-000d7fff : PCI Bus 0000:00
000d8000-000dbfff : PCI Bus 0000:00
000dc000-000fffff : reserved
  000f0000-000fffff : System ROM
00100000-3fedffff : System RAM
  01000000-01536143 : Kernel code
  01536144-017c007f : Kernel data
  01875000-0194bfff : Kernel bss
3fee0000-3fefefff : ACPI Tables
....

你是否知道有没有一个权威的端口列表可以在线或书籍中查阅? - QAH
如果你下载最新的Linux内核,一些架构会在 arch/XXX/mach-XXX 目录中声明他们的设备。此外,QEMU 在仓库的 hw/ 目录中手动声明了大量的映射,虽然我不确定这些映射是否具有权威性或现实性。要获取更多信息,请查看各种总线协议,例如PCI或SCSI,以查看它们是否具有映射发现功能。 - alexgolec
还有,只是为了避免错误,它应该是iomem,而不是ioports。我的错。 - alexgolec
只是想提供我的意见...在x86系统上,许多这些MMIO地址是由BIOS在启动时设置的,尽管有些是由传统(遗留的VGA地址范围)所决定的。使用设备可能意味着从PCI配置空间获取MMIO地址,但您可以从BIOS提供的ACPI表(特别是DSDT)中获得资源的相当完整的映射。很抱歉我把这个作为评论而不是答案,但看起来你已经接受了这个答案一段时间了! - Rose Lynn Embry

3
你可以通过一些硬件检测机制(如PCI总线扫描、USB和ACPI)获取端口。 例如,如果你在PCI上找到了一个支持的显示卡,你可以查询它的BAR(基址寄存器),从而获得物理地址、IO端口基址和/或IRQ号。对于网卡和其他卡也是如此。 对于不在任何总线上的设备,例如PS/2控制器,检测会更加困难,需要解析ACPI表。

1
在计算机体系结构中,i/o设备可以映射到i/o地址空间(i/o映射i/o)或内存地址空间(内存映射i/o)。 I/O映射I/O: 处理器可以区分内存和i/o设备。因此,i/o设备被映射到I/O地址空间,该空间比内存空间小得多。 例如,假设i/o地址空间为8位地址=2^8=256个地址,那么我们就有可能将256个i/o设备连接到系统上。 处理器使用独特的控制信号来控制i/o和内存,共4个信号。

MR(内存读取)、MW(内存写入)、IOR(输入输出读取)、IOW(输入输出写入)

用途:家庭电脑、小型办公室...

内存映射I/O: 处理器不区分内存和I/O设备。因此,I/O设备根据内存的位地址进行映射,内存地址被分配给设备。 例如,考虑一个RAM,其16位地址= 2^16(64K)= 65,536 即,有可能连接65,536个I/O设备。 微控制器用于管理设备操作,具有两个控制信号

RD(读取)和WR(写入)

用途:工业应用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接