I/O 地址空间如何映射到设备?
我希望这个问题的措辞足够好,以便有人能够理解。
据我所知,主存储器(RAM)和端口 I/O 驱动的 I/O,它有自己的地址空间,可供 IN、OUT 等指令使用。
如果要编写一个实模式汇编程序,开发人员是否需要拥有必要的文档来显示主板上特定插槽的地址范围在什么地址范围内?假设 PCIe 插槽的地址为 X,打印机为 Y。
这些地址是否是取决于总线类型的标准地址范围?
我可以读什么来更好地理解这一点?希望有人能帮忙。谢谢。
~ 编辑
指的是 PC 系统。
I hope the question is phrased well enough for someone to understand.
I understand that main memory (RAM) and for Port I/O driven I/O, it has it's own Address Space that Instructions like IN, OUT use.
If one were to write a real-mode assembler program, would it be up to the developer to have the necessary documentation showing what address ranges specific slots on the motherboard are in what address range? Say the PCIe slot is address X, Printer Y.
Are the addresses a standard address range depending on the Bus type?
What can I read to understand this better? Hope someone can help. Thanks.
~ edit
Referring to PC systems.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 x86 电脑上,BIOS 通常管理平面/物理地址空间的分配,并且所有内容都使用该空间中的某个位置。因此,BIOS 将通过在每个 PCIe 插槽上查看是否有人在那里来“枚举” PCIE 设备。 PCIe 设备必须具有一些标准配置寄存器,其中一些指示地址空间的大小和类型(基于 I/O 或内存映射)。 BIOS 试图让每个人都高兴并给他们想要的东西。 Windows 或 Linux 不会重新映射这些设备或地址,它们会采用 BIOS 提供的内容。并非每个 PCIe 系统都以这种方式工作,但不幸的是,这就是 PC 的工作方式。
因此,如果您想深入了解具体细节,请阅读这本书
http://www.mindshare.com/shop/?c=b§ion =0A6B150A
我认为如果你用谷歌搜索“pci系统架构”,然后找到lspci的源代码,就会有一个下载链接
,有一些库和示例,你可以拆开并制作自己的库和示例来检查你的设备中有哪些设备。系统以及它们的基地址和内存范围是什么。您很可能只想执行其他操作系统所做的操作,并读取 PCIe 主机控制器以查看已分配的内容,并将该信息提供给该系统上运行的软件。您可能会启动一次,打印机获取地址 0xE0000000,下一次则获取 0xDB000000,为您的环境提供一种机制来提供这些地址,或者将这些地址抽象到您的环境地址空间中的某个固定地址,并让您的代码管理到物理地址的转换。 /设备的真实地址。
我假设您使用术语“实模式”来谈论 x86 系统的某种风格,并且可能是某种风格的 PC。也许是一台麦克。不确定 mac 到底是如何做到的,对他们的枚举了解不够。硬件可能仍然是带有南北桥的英特尔处理器,后面是许多 PCIE 桥或其他英特尔 PCIE 芯片,最终出现在焊接到主板(视频芯片等)或 PCIE 插槽上的许多 PCIE 设备中用于插入卡。如果您运行 linux 并使用 lspci 并查看供应商和部件号,您可以在 intels 网站上找到 intel(供应商 ID 8086)设备的大部分手册/数据表,并且您可以使用 lspci 及其兄弟程序来检查控制以及那些 PCIe 控制器中的状态寄存器,如果您有兴趣深入研究这一点,我不确定您真正的兴趣是什么。
地址不是标准的,也不是固定的,每个 BIOS 都是针对该主板型号半定制的,PCIE 空间的地址范围通常是整个处理器空间的 1 GB 或更少,但是随着转向 64,该窗口正在发生变化位和需要更多空间(缓慢移动)。如果 BIOS 配置为在 32 位模式下运行,则该 pcie 窗口的位置取决于硬件(请参阅我提到的各种 intel 设备的数据表,或者通过或 nvidia 或任何人,如果它是 amd 系统)对于所有 PCIE 设备,可能介于 2 GB 之间,但当然低于 4 GB 标记,但这并不意味着所有这些系统都使用 3 GB 标记。对于 64 位,我认为它们也往往接近顶部,但从主板到主板它会发生变化。然后,当涉及到枚举总线时,它既是特定于主板的,也是特定于个人计算机的,某些设备被螺栓/焊接到主板上,并且每次都以相同的顺序进行枚举,但是插入插槽的卡必须响应主机,有时根据谁先回答而被枚举,您可能会启动 20 次并看到相同的布局,再启动一次,两张卡可能会交换位置,因为它们枚举的顺序发生了变化。因此,即使您的视频卡看起来始终位于同一个位置,也不要在任何地方对该数字进行硬编码,始终扫描 PCIe 总线或表或进行库调用以找出什么在哪里。一旦您找到某些内容,它可能就不会移动,直到您重新启动并重试,这样您就不必在每次想要访问它时不断重新扫描以查找某些内容的位置。
是的,如果你升级或降级你的BIOS,BIOS只是软件,有时BIOS的变化与PCIE枚举有关(这并不罕见,比如说流行的显卡在主板上不能很好地工作,他们在BIOS软件中添加了一个MOD更改重置或其他任何方式以使该卡有更好的工作机会),这可能会改变整个系统的枚举。
On an x86 pc the bios normally manages allocation of the flat/physical address space, and everything uses some place in that space. So the BIOS will "enumerate" the pcie devices by going out on each pcie slot to see if anyone is there. There are standard configuration registers that a pcie device must have some of which indicate how much address space and what kind (I/O based or Memory mapped). the bios attempts to make everyone happy and give them what they want. Windows or linux will not remap these devices or addresses, they take what is given to them by the bios. not every pcie system works that way but unfortunately this is how PC's work.
So if you want to get into the nuts and bolts, get this book
http://www.mindshare.com/shop/?c=b§ion=0A6B150A
I think there is a download link for it if you google "pci system architecture"
if you run linux then find the sources for lspci, there are some libraries and examples that you can rip apart and make your own to examine what devices are in your system and what their base address and memory range are. Most likely you are going to want to just do what other operating systems do and read the pcie host controllers to see what has been allocated where, and provide that information to the software running on that system. You might boot one time and the printer gets address 0xE0000000 and the next time 0xDB000000, provide a mechanism to your environment to give those addresses, or abstract those to some fixed address within your environments address space and have your code manage the translation to the physical/real address for the device.
I assume by using the term real mode you are talking about some flavor of x86 system, and that is probably a PC of some flavor. Maybe a mac. Not sure exactly how a mac does it, dont know enough about their enumeration. the hardware is likely still an intel processor with a north and south bridge followed by a number of pcie bridges or other intel pcie chips that ultimately end up in a number of pcie devices either soldered onto the board (video chips, etc) or pcie slots for plug in cards. If you run linux and use lspci and look at the vendor and part numbers you can find most of the manuals/datasheets for the intel (vendor ID 8086) devices at intels website, and you can use lspci and its sibling programs to examine the control and status registers in those pcie controllers, again if you are interested in digging deeper into this, I am not sure what your real interest is.
The addresses are not a standard, nor fixed, each bios is semi-custom to that motherboard model, the address range for the pcie space is typically one gig or less of the whole processor space, but that window is changing with the move to 64 bit and the need for more space (a slow move). the location of that pcie window is dependent on the hardware (See the datasheets I mentioned for those various intel devices, or via or nvidia or whoever if it is an amd system) if the bios is configured to run in 32 bit mode that pcie window for all pcie devices might be somewhere between the 2 gig but of course below the 4 gig mark, but that doesnt mean all of those systems use the 3 gig mark. for 64 bit I think they tend to be near the top as well but from motherboard to mother board it changes. Then when it comes to enumerating the bus it is both motherboard specific and individuals computer specific, some devices are bolted/soldered onto the motherboard and get enumerated in the same order every time, but cards you plug into the slots, have to respond to the host and sometimes get enumerated based on who answers first, you might boot 20 times and see the same layout, boot one more time and two cards might swap locations because the order they were enumerated changed. So even if it appears that your video card is always at the same place, dont hardcode that number anywhere, always scan the pcie bus or tables or make library calls to find out what is where. it is probably not going to move once you find something until you reboot and try again so you dont have to keep rescanning to find where something is every time you want to access it.
yes, if you upgrade or downgrade your bios, the bios is just software, sometimes the bios changes have to do with pcie enumeration (not that uncommon, say a popular video card doesnt work well on a motherboard they put a mod into the bios software to change the reset or whatever to give that card a better chance at working) and that may change the enumeration for the whole system.
如果要编写一个实模式汇编程序
ISR 就是您可能需要的
(中断服务例程)。
;
这是存储在内存第一段中的中断处理程序地址列表。
(段 0000)。每个中断号都有一个4字节的处理程序地址、段和偏移量,以
当调用该中断时,程序将分支。
该地址可以通过将中断号乘以 4 来找到,即存储处理程序地址的偏移量。
ISR 位置可定义为 0000:ax*4,DOS 中断的通用编号为 21h。所以只需用那个(或其他)加载 axe
这里有一个 DOS 中断列表...它相当大...
http://www.ctyme.com/intr/int-21.htm
If one were to write a real-mode assembler program
ISRs are what you may be after
(Interrupt Service Routines).
;
This is a list of interrupt handler addresses stored in the first segment of memory.
(segment 0000). Each interrupt number has a 4-byte handler address, segment and offset, to
which a program will branch when that interrupt is called.
The address can be found by multiplying the interrupt number by 4, that being the offset at which the handler's address is stored.
The ISRs location can be defined as 0000:ax*4, DOS interrupts have the generic number 21h. So just load ax with that (or al)
There's a list of DOS interrupts here... it's moderately large...
http://www.ctyme.com/intr/int-21.htm