I / O地址空间如何映射到设备?

时间:2012-02-10 03:20:37

标签: assembly architecture io cpu memory-address

我希望这个问题的措辞能够让人理解。

我理解主存储器(RAM)和端口I / O驱动的I / O,它有自己的地址空间指令,如IN,OUT使用。

如果要编写实模式汇编程序,开发人员是否需要获得必要的文档,说明主板上特定插槽的地址范围在哪个地址范围内?假设PCIe插槽是地址X,打印机Y.

地址是否为标准地址范围,具体取决于总线类型?

我可以阅读哪些内容以更好地理解这一点?希望有人能提供帮助。感谢。

〜编辑

参考PC系统。

2 个答案:

答案 0 :(得分:13)

在x86 pc上,bios通常管理平面/物理地址空间的分配,并且所有内容都使用该空间中的某个位置。所以BIOS将通过走出每个pcie插槽来“枚举”pcie设备,看看是否有人在那里。有一些标准配置寄存器,pcie设备必须具有一些指示有多少地址空间和类型(基于I / O或内存映射)。 bios试图让每个人都快乐并给他们想要的东西。 Windows或Linux不会重新映射这些设备或地址,它们采用bios给予它们的内容。不是每个pcie系统都以这种方式工作,但不幸的是这就是PC的工作方式。

因此,如果你想深入了解,请阅读本书 http://www.mindshare.com/shop/?c=b&section=0A6B150A 如果你谷歌“pci系统架构”

,我认为有一个下载链接

如果您运行linux然后找到lspci的源代码,那么您可以拆分一些库和示例,并自行检查系统中的设备以及它们的基址和内存范围。很可能您只想做其他操作系统所做的事情,并阅读pcie主机控制器以查看已分配的位置,并将该信息提供给该系统上运行的软件。您可以启动一次,打印机获取地址0xE0000000,下次使用0xDB000000,为您的环境提供一种机制来提供这些地址,或者将这些机制抽象到您的环境地址空间中的某个固定地址,并让您的代码管理到物理的转换/设备的真实地址。

我假设使用术语真实模式你正在讨论x86系统的某些风格,这可能是某种风格的PC。也许是一个mac。不确定mac是如何做到的,对它们的枚举不够了解。硬件很可能仍然是一个带有南北桥的英特尔处理器,后面跟着许多pcie网桥或其他英特尔pcie芯片,这些芯片最终会被许多pcie设备焊接到电路板上(视频芯片等)或pcie插槽用于插入卡。如果您运行linux并使用lspci并查看供应商和部件号,您可以在intels网站上找到intel(供应商ID 8086)设备的大部分手册/数据表,您可以使用lspci及其兄弟程序来检查控件和状态寄存器在那些pcie控制器中,如果你有兴趣深入研究这个,我不确定你的真正兴趣是什么。

这些地址不是标准的,也不是固定的,每个BIOS都是半主机定制的,主机模型空间的地址范围通常是整个处理器空间的一个或更少,但是那个窗口正在随着移动到64位并需要更多空间(缓慢移动)。该pcie窗口的位置取决于硬件(如果bios配置为在32位模式下运行,请参阅我为那些各种英特尔设备提供的数据表,或通过或者通过nvidia或任何人,如果它是amd系统)对于所有pcie设备可能介于2 gig之间但当然低于4 gig标记,但这并不意味着所有这些系统都使用3 gig标记。对于64位我认为它们往往也接近顶部,但从主板到主板它会发生变化。然后,当涉及到枚举总线时,它既是主板特定的,也是个人计算机特定的,一些设备用螺栓固定/焊接到主板上,并且每次都以相同的顺序进行枚举,但是插入插槽的卡片必须响应主机,有时根据谁先回答进行枚举,你可能会启动20次并看到相同的布局,再启动一次,两张卡可能会交换位置,因为它们被枚举的顺序发生了变化。因此,即使您的视频卡始终位于同一位置,也不要在任何地方对该号码进行硬编码,始终扫描pcie总线或表格或进行库调用以找出其中的位置。一旦你找到了什么东西,它可能不会移动,直到你重新启动并再次尝试,所以你不必重新扫描,以便找到每次你想要访问它的地方。

是的,如果你升级或降级你的BIOS,bios只是软件,有时候bios的变化与pcie枚举有关(不是那么罕见,比如一个流行的显卡在他们放入mod的主板​​上不能很好地工作bios软件改变重置或任何给予该卡更好的工作机会),这可能会改变整个系统的枚举。

答案 1 :(得分:0)

如果要写一个实模式汇编程序

ISR是你可能会追求的 (中断服务例程)。
;

这是存储在第一段内存中的中断处理程序地址列表。 (段0000)。每个中断号都有一个4字节的处理程序地址,段和偏移量 当调用该中断时程序将分支。

可以通过将中断号乘以4来找到地址,即存储处理程序地址的偏移量。

ISR位置可以定义为0000:ax * 4,DOS中断的通用编号为21h。所以只需用那个(或al)

加载ax

这里有一个DOS中断列表......它中等大......

http://www.ctyme.com/intr/int-21.htm