如何远程(x86)调用给定的32位地址?

时间:2009-05-01 00:18:14

标签: assembly x86

好的,我需要对PCI BIOS服务目录(32位模式)执行CALL FAR以验证PCI BIOS是否存在。

注意:我正在开发一个简单的磁盘驱动程序,用于我们正在开发一所大学的简单操作系统。我知道这是非常具体的,但我将从内核代码中完成所有这些。

假设我已找到相关地址。执行远程调用给定地址的正确汇编语言是什么?有人可以发布一些远程调用给定32位地址的汇编代码吗?到目前为止我看到的例子的语法令人困惑。

谢谢!

编辑:在我的具体情况下,我已经找到了PCI BIOS服务目录,它给了我物理地址(32位)。鉴于这个32位地址,我需要什么类型的远程调用?例如,我在英特尔手册中读到,远程调用可以改变任务,什么不可以。我怎么知道我要做什么来远远调用这个PCI BIOS服务目录的物理地址?

更新:

以下是我发现的一些令我困惑的代码(内联):


    asm("lcall (%%edi)"
        : "=a" (return_code),
          "=b" (address),
          "=c" (length),
          "=d" (entry)
        : "0" (service),
          "1" (0),
          "D" (&bios32_indirect));

我在此源文件中找到了:http://www.pell.portland.or.us/~orc/Code/Archive/linux-1.2.13/arch/i386/kernel/bios32.c

我认为我想要做的是在实际装配中相当于上面的内联。

3 个答案:

答案 0 :(得分:2)

从手册:

to make a asm call use the below format

asm(  command1 %0
      command2
      :output registers with there mapping to variable
      :input registers with mapping.
   );

example
    asm ("movl %1, %%ebx;"
         "movl %%ebx, %0;"
         : "=r" ( val )
         : "r" ( no )
         : "%ebx"         // clobbered register
        );

    here %1 is input variable %0 is output.

要创建lcall您需要的段和实际的32位地址:

bios32_indirect.address = directoy_address;
  uint32 kernelcodesegment = 0;
  asm ("movl %%cs, %0;"
       : "=r" (kernelcodesegment)
       :);
bios32_indirect.segment = kernelcodesegment;

答案 1 :(得分:1)

如果存储器是平坦的,即CS的基数为0并覆盖整个32位地址空间

call <address>

其中address是32位目标地址。

编辑:啊,我看到你有一个实际地址。我假设这是在Linux上运行的设备驱动程序。我对linux内核没有任何经验,但我认为这个物理地址没有按1:1映射到虚拟地址。您需要将其映射到虚拟地址(抱歉,不知道如何在Linux中),然后调用该虚拟地址。

但这提出了一个问题,即您需要什么样的PCI BIOS功能,直接进入操作系统外的BIOS通常是错误的方法。

答案 2 :(得分:0)

如果您提到您正在处理的操作系统,那肯定会有所帮助。 让我们说它是Windows 32Bit然后假设您确定知道物理地址,您仍然需要获得与之相关的PTE。您不能只是拨打该特定地址,因为您处于保护模式,而您拥有的地址是虚拟地址。您可以将物理映射到虚拟,但它很复杂。

如果你想知道你是否可以查看该地址的内容,请使用WinDBG并执行:

!dd <address>

这将在您指定的物理地址处显示DWORD。 当您知道该做什么时,从物理到虚拟的翻译很简单(看着CR3赢了,不会帮助您:)

现在,如果你正在使用不同的操作系统,这是一个不同的故事,因为PTE的映射方式不同。

另外,如前所述,你不能只调用bios,因为它实际上是16位而不是32位。 在保护模式下(在i386中,可能在之后),有一种特定的技术可以使用vx86或其他类似的东西,但我忘记了确切的术语。虽然可行但成本很高,因为它涉及任务切换和其他各种事情。

如果您需要开发磁盘驱动程序,那么组中的硬件人员应该能够为您提供可用的端口,以便您可以对设备进行IO调用,从而无需访问BIOS。 / p>