Как сделать звонок далеко (x86) на заданный 32-битный адрес? - PullRequest
5 голосов
/ 01 мая 2009

Хорошо, мне нужно выполнить CALL FAR для каталога службы PCI BIOS (32-разрядный режим), чтобы убедиться, что PCI BIOS присутствует.

ПРИМЕЧАНИЕ. Я разрабатываю простой драйвер диска для простой операционной системы, которую мы разрабатываем в колледже. Я понимаю, что это очень специфично, но я буду делать все это из кода ядра.

Предположим, я уже нашел соответствующий адрес. Каков подходящий язык ассемблера для удаленного вызова по указанному адресу? Может кто-нибудь выложить какой-нибудь ассемблерный код, который делает дальний вызов по данному 32-битному адресу? Синтаксис примеров, которые я видел до сих пор, сбивает с толку.

Спасибо!

РЕДАКТИРОВАТЬ: В моем конкретном случае я уже нашел каталог службы PCI BIOS, который дает мне физический адрес (32-разрядный). Учитывая этот 32-битный адрес, какой тип удаленного вызова мне понадобится? Например, я читал в руководствах Intel, что дальние звонки могут изменить задачи, а что нет. Как я узнаю, что мне нужно сделать, чтобы назвать физический адрес этого каталога службы PCI BIOS?

UPDATE:

Вот код, который я нашел, который сбивает меня с толку (встроенный):

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

<p>

Я обнаружил, что в этом исходном файле: http://www.pell.portland.or.us/~orc/Code/Archive/linux-1.2.13/arch/i386/kernel/bios32.c

Я думаю, что я хочу сделать, это эквивалент вышеупомянутого встроенного в реальной сборке.

Ответы [ 3 ]

2 голосов
/ 16 сентября 2012

Из руководства:

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 голос
/ 01 мая 2009

Если память плоская, то есть CS имеет базу 0 и покрывает все 32-битное адресное пространство

call <address>

Где адрес - это 32-битный целевой адрес.

РЕДАКТИРОВАТЬ: Ах, я вижу, у вас есть физический адрес. Я предполагаю, что это для драйвера устройства, работающего в Linux. У меня нет опыта работы с ядром Linux, но я предполагаю, что этот физический адрес не отображается 1: 1 на виртуальный адрес. Вам нужно сопоставить его с виртуальным адресом (извините, не знаю как в Linux), а затем вызвать этот виртуальный адрес.

Но это поднимает вопрос о том, какая функция PCI BIOS вам нужна, переход к BIOS вне ОС обычно является неправильным подходом.

0 голосов
/ 02 августа 2015

Было бы очень полезно, если бы вы упомянули, над какой ОС вы работаете. Допустим, что это Windows 32Bit, тогда, если вы точно знаете физический адрес, вам все равно нужно связать PTE с ним. Вы не можете просто позвонить на этот конкретный адрес, так как вы находитесь в защищенном режиме, а у вас есть виртуальный адрес. Вы можете сопоставить физическое с виртуальным, но это сложно.

Если вы хотите посмотреть, можете ли вы посмотреть, что находится по этому адресу, используйте WinDBG и выполните:

!dd <address>

Это отобразит DWORD по указанному вами физическому адресу. Перевод с физического на виртуальный язык прост, когда вы знаете, что делать (смотреть на CR3 вам не поможет:)

Теперь, если вы используете другую ОС, это другая история, потому что PTE отображается по-разному.

Кроме того, как упоминалось ранее, вы не можете просто позвонить в BIOS, поскольку на самом деле это 16-битный, а не 32-битный. В защищенном режиме (в i386 и, возможно, позже) была особая техника, в которой вы могли использовать vx86 или что-то в этом роде, но я забыл точный термин. Это было выполнимо, но очень дорого, потому что требовало переключения задач и прочего.

Если вам нужно разработать драйвер диска, то специалисты по оборудованию в вашей группе должны быть в состоянии предоставить вам доступные порты, чтобы вы могли совершать IO-вызовы на устройство, исключая необходимость доступа к BIOS. 1014 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...