【问题标题】:How does an OS find a peripheral's assigned address(es)?操作系统如何找到外围设备的分配地址?
【发布时间】:2018-02-05 04:22:21
【问题描述】:

好的,这就是我的意思:

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

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

其实很简单,它只包含一条指令。

您的可引导代码将向外围设备上的寄存器或 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 输入什么数字?如何找到这个外设的寄存器地址?

【问题讨论】:

  • 欢迎来到stackoverflow。请,您能否提供一些您的具体问题的代码。这证明了您尝试了多远,它将帮助其他成员更好地理解您的问题,当时,您将向他们提供您的问题的背景。请检查以下链接:stackoverflow.com/help/mcvestackoverflow.com/help/how-to-ask

标签: operating-system bios uefi memory-mapping bootable


【解决方案1】:

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

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

读取每个 BDF 的偏移量 0 和 2 以获得 Vendor ID 和 Device ID。找到要编程的设备后,在 10h 和 24h 之间的偏移处读取正确的 32 位 BAR 值。您需要知道哪个 BAR 包含您要编程的寄存器,具体到您使用的设备。

本文描述了如何访问 PCI 配置空间,并提供了 C 语言示例代码,展示了如何扫描 PCI 总线。 http://wiki.osdev.org/PCI

【讨论】:

    猜你喜欢
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 2016-12-22
    • 2018-09-23
    • 1970-01-01
    相关资源
    最近更新 更多