如何从程序集引导加载程序与 x86 I/O 设备交互?
How to interact with x86 I/O device from assembly bootloader?
这道题的原始目标是
- 是否连接了设备?
- 如果已连接,设备是什么?
- 设备信息是什么?
到目前为止我的理解是(x86 intel架构Z370芯片组)
- I/O设备可以通过IN/OUT指令进行交互
- 现代计算机采用 PCI Express 总线架构。可以通过枚举 PCI Configuration Space.
找到连接的设备
- 这将至少涵盖显卡、磁盘驱动器、键盘和鼠标。
我想到的是
- 迭代所有 I/O 个端口
- 检查设备存在/连接
- 查看设备信息
- 继续枚举 PCI Express 配置 Space
然而,关于 I/O 端口的文章很少,而且还不够。
Q1。是否有一些文章或书籍广泛解释了 I/O 使用 IN 和 OUT 指令进行端口交互?
找到的文章是
断索峰
http://www.brokenthorn.com/Resources/OSDev7.html
http://www.brokenthorn.com/Resources/OSDev9.html
OS开发
https://wiki.osdev.org/I/O_Ports
https://wiki.osdev.org/%228042%22_PS/2_Controller
之所以需要更详细的文章,是因为我有这样的问题,如果插入了 2 个 USB 键盘,如果一个被 0x60 访问,那么另一个如何访问?可以通过命令检查启用的设备,但是否必须先检查设备是否存在/连接?
Q2。还有,这些端口好像没有像PCI Configuration Header这样的标准,那其他端口怎么操作呢?
我们将不胜感激。
P.S。
也许我想做的是编写一个驻留在 I/O Port (=I/O Device Controller) <-> I/O Device Driver 之间阶段的逻辑。而这项工作似乎是由 ACPI,ACPICA 完成的。但是我想自己在汇编中做。
不,不是这样的。
您的想法是枚举所有设备,而您必须开始枚举所有总线。
如您所知,现代 x86 的中央总线是 PCI express。
它向后兼容更简单的传统 PCI。使用旧版 PCI 会让您走得更远,但不会一直走到尽头。
遗留设备,如 8042 键盘控制器或 8259A PIC,在 PCI 总线上找不到。
他们在它之前就存在了。
一些设备同时在 PCI 总线和旧端口地址中,因为这些设备仍然暴露旧接口以及 PCI BAR(基地址寄存器,它告诉将这个接口放在 IO 地址中的什么地方space)。
例如,PCI、过时的 ATA 控制器就是这种情况。
通常无法知道端口后面的设备,如果设备具有可识别的行为,您可以检查(探测)该设备。
但这并非 100% 安全。
简单地从所有 64KiB 端口读取不会让你到任何地方,in
的 return 值是 total,这意味着它没有特殊值 returns 以防出错(出于遗留原因,它 returns 用于不存在的设备,但这是现有设备可以发送的合法值)。
这就是为什么没有书。
USB 是今天使用的另一种 大 总线,同样,您的方法应该以总线为中心。
枚举所有的PCI设备,包括USB适配器,枚举一条总线上的所有USB设备等等。
通常,从中央总线开始,枚举所有设备,找到其他总线适配器(I2C、LPC、SPI、USB 等)并相应地处理该总线。
唉,您还必须处理省略此枚举过程的遗留设备。
总的来说,我对遗留设备的建议是:尽快处理设备,但不能更早。
Ralf Brown 以其中断列表而闻名,但他也有一个非常有用的 port files (A, B, C, D, ...).
问题是它包含很多 x86 变体,一开始不容易阅读,但它非常详细。
作为 commented, bochs also have a list of devices it emulates.
每个人都喜欢编写管理所有硬件的软件,但事实是我们只能编写管理我们所了解的硬件的软件。
当你觉得需要一个设备时,记录下你自己的情况并找出它是如何连接的以及它的接口是什么。
另一个好方法是至少阅读 CPU 和芯片组的数据表(例如英特尔的 PCH)。
笔记本电脑和类似设备也有一个嵌入式控制器,而台式机有 Super IO 芯片。
如果公开可用,也可以找到他们的数据表。
要查找这些组件和所有其他组件的 IC 部件号,您可能需要打开计算机。
在某些站点上,您可能会找到主板的原理图,但您仍然需要它的部件号,而不是它的型号名称+编号。
硬件编程很有趣,不要放弃!
这道题的原始目标是
- 是否连接了设备?
- 如果已连接,设备是什么?
- 设备信息是什么?
到目前为止我的理解是(x86 intel架构Z370芯片组)
- I/O设备可以通过IN/OUT指令进行交互
- 现代计算机采用 PCI Express 总线架构。可以通过枚举 PCI Configuration Space. 找到连接的设备
- 这将至少涵盖显卡、磁盘驱动器、键盘和鼠标。
我想到的是
- 迭代所有 I/O 个端口
- 检查设备存在/连接
- 查看设备信息
- 继续枚举 PCI Express 配置 Space
然而,关于 I/O 端口的文章很少,而且还不够。
Q1。是否有一些文章或书籍广泛解释了 I/O 使用 IN 和 OUT 指令进行端口交互?
找到的文章是
断索峰
http://www.brokenthorn.com/Resources/OSDev7.html
http://www.brokenthorn.com/Resources/OSDev9.html
OS开发
https://wiki.osdev.org/I/O_Ports
https://wiki.osdev.org/%228042%22_PS/2_Controller
之所以需要更详细的文章,是因为我有这样的问题,如果插入了 2 个 USB 键盘,如果一个被 0x60 访问,那么另一个如何访问?可以通过命令检查启用的设备,但是否必须先检查设备是否存在/连接?
Q2。还有,这些端口好像没有像PCI Configuration Header这样的标准,那其他端口怎么操作呢?
我们将不胜感激。
P.S。 也许我想做的是编写一个驻留在 I/O Port (=I/O Device Controller) <-> I/O Device Driver 之间阶段的逻辑。而这项工作似乎是由 ACPI,ACPICA 完成的。但是我想自己在汇编中做。
不,不是这样的。
您的想法是枚举所有设备,而您必须开始枚举所有总线。
如您所知,现代 x86 的中央总线是 PCI express。
它向后兼容更简单的传统 PCI。使用旧版 PCI 会让您走得更远,但不会一直走到尽头。
遗留设备,如 8042 键盘控制器或 8259A PIC,在 PCI 总线上找不到。
他们在它之前就存在了。
一些设备同时在 PCI 总线和旧端口地址中,因为这些设备仍然暴露旧接口以及 PCI BAR(基地址寄存器,它告诉将这个接口放在 IO 地址中的什么地方space)。
例如,PCI、过时的 ATA 控制器就是这种情况。
通常无法知道端口后面的设备,如果设备具有可识别的行为,您可以检查(探测)该设备。
但这并非 100% 安全。
简单地从所有 64KiB 端口读取不会让你到任何地方,in
的 return 值是 total,这意味着它没有特殊值 returns 以防出错(出于遗留原因,它 returns 用于不存在的设备,但这是现有设备可以发送的合法值)。
这就是为什么没有书。
USB 是今天使用的另一种 大 总线,同样,您的方法应该以总线为中心。
枚举所有的PCI设备,包括USB适配器,枚举一条总线上的所有USB设备等等。
通常,从中央总线开始,枚举所有设备,找到其他总线适配器(I2C、LPC、SPI、USB 等)并相应地处理该总线。
唉,您还必须处理省略此枚举过程的遗留设备。
总的来说,我对遗留设备的建议是:尽快处理设备,但不能更早。
Ralf Brown 以其中断列表而闻名,但他也有一个非常有用的 port files (A, B, C, D, ...).
问题是它包含很多 x86 变体,一开始不容易阅读,但它非常详细。
作为
每个人都喜欢编写管理所有硬件的软件,但事实是我们只能编写管理我们所了解的硬件的软件。
当你觉得需要一个设备时,记录下你自己的情况并找出它是如何连接的以及它的接口是什么。
另一个好方法是至少阅读 CPU 和芯片组的数据表(例如英特尔的 PCH)。
笔记本电脑和类似设备也有一个嵌入式控制器,而台式机有 Super IO 芯片。
如果公开可用,也可以找到他们的数据表。
要查找这些组件和所有其他组件的 IC 部件号,您可能需要打开计算机。
在某些站点上,您可能会找到主板的原理图,但您仍然需要它的部件号,而不是它的型号名称+编号。
硬件编程很有趣,不要放弃!