2017-08-27 118 views
0

好的,这里是我的意思:操作系统如何找到外设的分配地址?

假设你想编写自己的可启动代码。

此外,您的代码将非常简单。

这么简单,实际上它只包含一条指令。

您的可启动代码将写入一个字节或字或双字或任何内容到外围设备上的寄存器或RAM位置,而不是主RAM或CPU寄存器。

你如何知道BIOS/UEFI分配给外设存储单元的地址?

这里有一个更具体的例子:

我的引导代码的第一个也是唯一指令将数11H写到位于声卡上的寄存器。

如果BIOS/UEFI初始化代码正常工作,则声卡寄存器应映射到CPU的内存空间和/或IO空间。

我需要找到该地址来完成该写入。

我该如何找到它?

这是真正的操作系统必须在某些时候做的事情。

当您在Windows中打开控制面板/设备管理器时,可以看到列出的所有外围设备的内存范围。

在某些时候,Windows必须查询BIOS/UEFI才能找到该数据。

再次,这是如何完成的?

编辑:

这是我在写这篇启动汇编程序的尝试:

BITS 16 
    ORG  100h 
start: 
    ;I want to write a byte into a register on the sound card or NIC or 
    ;whatever. So, I'm using a move instruction to accomplish that where X 
    ;is the register's memory mapped or IO mapped address. 
    mov X,11h 
times 510 - ($ - $$) db 0 
dw 0xaa55 

我把什么号为X?我如何找到这个外设寄存器的地址?

+0

欢迎使用stackoverflow。请,你能提供一些你的具体问题的代码吗?这可以证明你尝试了多远,它会帮助其他成员更好地理解你的问题,当时,你会给他们一个你的问题的背景。请检查以下链接:https://stackoverflow.com/help/mcve和https://stackoverflow.com/help/how-to-ask –

回答

2

如果你想用一条指令来做到这一点,你可以从Windows设备管理器获取设备的地址。但是,如果您想以“正确”方式执行此操作,则需要扫描PCI总线以找到要编程的器件,然后读取器件的基地址寄存器(BAR)以查找其MMIO范围。这是Windows所做的;它不查询BIOS。

要查找要访问的设备,请扫描PCI总线寻找设备。设备通过其“BDF”(总线/设备/功能的简称)在PCI总线上寻址。设备由供应商分配的供应商ID和设备ID标识。

读取每个BDF的偏移量0和2以获得供应商ID和设备ID。当您找到想要编程的设备时,请在10小时和24小时之间的偏移量处读取正确的32位BAR值。您需要知道哪个BAR包含您要编程的寄存器,这是特定于您正在使用的设备的。

本文介绍如何访问PCI配置空间,并在C中显示示例代码,显示如何扫描PCI总线。 http://wiki.osdev.org/PCI

+0

谢谢,先生(或女士)! – tensor

相关问题