Assembly 如何从程序集引导加载程序与x86 I/O设备交互?

Assembly 如何从程序集引导加载程序与x86 I/O设备交互?,assembly,io,port,interaction,Assembly,Io,Port,Interaction,这个问题的基本目标是 是否连接了设备 如果连接了某个设备,该设备是什么 设备信息是什么 到目前为止,我了解的是(x86英特尔体系结构Z370芯片组) I/O设备可以与输入/输出指令交互 现代计算机采用PCI Express总线体系结构。通过枚举PCI配置空间可以找到连接的设备 这将至少包括图形卡、磁盘驱动器、键盘和鼠标 我想做的是 迭代所有I/O端口 检查设备是否存在/连接 检查设备信息 继续枚举PCI Express配置空间 然而,关于I/O端口的文章很少,而且还不够 问题1。是否

这个问题的基本目标是

  • 是否连接了设备
  • 如果连接了某个设备,该设备是什么
  • 设备信息是什么
到目前为止,我了解的是(x86英特尔体系结构Z370芯片组)

  • I/O设备可以与输入/输出指令交互
  • 现代计算机采用PCI Express总线体系结构。通过枚举PCI配置空间可以找到连接的设备
  • 这将至少包括图形卡、磁盘驱动器、键盘和鼠标
我想做的是

  • 迭代所有I/O端口
  • 检查设备是否存在/连接
  • 检查设备信息
  • 继续枚举PCI Express配置空间
然而,关于I/O端口的文章很少,而且还不够

问题1。是否有一些文章或书籍详细解释了使用输入和输出指令的I/O端口交互

发现的物品是

布罗肯霍恩

操作系统开发

我之所以需要更详细的文章,是因为我有一些问题,比如如果插入了两个USB键盘,如果其中一个是通过0x60访问的,那么如何访问其他键盘?可以通过命令检查设备是否已启用,但是否必须先进行设备存在/连接检查

问题2。此外,这些端口似乎没有标准的PCI配置头,那么如何操作其他端口呢

即使是一个小小的善意的回答也将不胜感激

附言。
也许我要做的是编写一个驻留在I/O端口(=I/O设备控制器)I/O设备驱动程序之间的阶段中的逻辑。这项工作似乎是由ACPI,ACPICA完成的。但我希望自己在组装中完成这些工作。

不,它不是那样工作的

您正处于枚举所有设备的心态,相反,您必须开始枚举所有总线

正如您所知,现代x86s中的中央总线是PCI express。
它与更简单的传统PCI向后兼容。使用传统的PCI将使您走得更远,但不会一直走到最后

PCI总线上找不到传统设备,如8042键盘控制器或8259A PIC。
它们在它之前就存在了。
一些设备同时位于PCI总线和传统端口地址中,因为这些设备仍然公开传统接口以及PCI条(基址寄存器,它告诉在IO地址空间中放置此接口的位置)。
例如,PCI、过时的ATA控制器就是这种情况

通常无法知道端口后面的设备,如果设备有可识别的行为,您可以检查(探测)设备。
但这不是100%安全。
仅从所有64KiB端口读取数据不会让您到达任何地方,在中,
的返回值是total,这意味着在发生错误时它不会返回任何特殊值(出于传统原因,对于不存在的设备,它会返回所有值,但这是存在的设备可以发送的合法值)。
这就是为什么没有书

USB是目前使用的另一种大型总线,同样,您的方法应该以总线为中心。
枚举所有PCI设备,包括USB适配器,枚举总线中的所有USB设备等。
通常,从中央总线开始,列举所有设备,找到其他总线适配器(I2C、LPC、SPI、USB等),并相应地处理该总线

唉,您还必须处理省略此枚举过程的遗留设备。
一般来说,我对传统设备的建议是:根据需要尽快处理设备,但不要过早。
拉尔夫·布朗以其中断列表而闻名,但他也有一个非常有用的列表。
问题是它包含了很多x86变体,一开始不容易阅读,但非常详细。
如评论所述

每个人都喜欢编写管理所有硬件的软件,但事实是,我们只能编写管理我们所知道的硬件的软件。
当你觉得需要一台设备时,记录下你自己对它的看法,了解它是如何连接的,它的接口是什么

另一个好方法是至少阅读CPU和芯片组的数据表(例如英特尔的PCH)。
笔记本电脑和类似电脑也有嵌入式控制器,而台式电脑有超级IO芯片。
也可以找到他们的数据表(如果公开提供)。
要查找这些组件和所有其他组件的ICs零件号,您可能需要打开计算机。
在某些网站上,您可能会找到主板的示意图,但您仍然需要它的零件号,而不是它的型号名称+编号


硬件编程很有趣,不要放弃

这很有用。请注意,端口0x60上的键盘是PS/2键盘或BIOS模拟的键盘。关闭BIOS模拟后,两个键盘都只能通过USB堆栈访问。非常感谢Margaret Bloom!综上所述,您所说的“以总线为中心”是指PCI Express兼容枚举(传统PCI枚举),它将总线/设备/函数(=B/D/F)从0/0/0迭代到每个的最大值。对吗?这涵盖了设备“我们所知道的”,因为PCI Express是中央总线。为了覆盖一些额外的传统设备(如8042键盘控制器),可以使用in和OUT指令进行管理,但“检查”设备是不可能的,因为我所能做的只是向端口发送“信号”,而不管设备是否存在。这就是为什么您将“以总线为中心”表述为覆盖所有传统设备是不可能的。非常感谢您提供了广泛的答案。再次感谢您的鼓励@Yoonseoko今天,这些设备形成了一个层次结构。在设备和CPU之间可能有一条或多条总线。每个总线作为发现连接到其上的设备的方法(l