Связь ISR с векторным прерыванием 80x86 32-битная сборка AT & T - PullRequest
1 голос
/ 29 сентября 2011

Я работаю на Intel-Atom 32bit (сборка AT & T).

Я хочу связать свой ISR с векторным прерыванием 0x33:

push %ebp   //save the context to swith back
movl %esp,%ebp

movl $OSTickISR, %eax //address of int 0x33 = address of OSTickISR
movl $0x33*4, %ebx
movl %eax, (%ebx)

pop %ebp //Return to the calling function
ret

Когда я пытаюсь использовать свой int $ 0x33, ничего не происходит !!!

Что не так?

Ответы [ 3 ]

3 голосов
/ 29 сентября 2011

В 32-битном x86 информация ISR сохраняется в IDT.IDT - это не просто список адресов, и он не обязательно хранится по адресу 0. Описание формата IDT см. На странице OSDev Wiki .Местоположение IDT определяется ОС, и оно может быть недоступно для программного обеспечения пользовательского режима.Предполагая, что у вас есть право изменить его, вы можете получить местоположение IDT с помощью инструкции sidt.

sidt -6(%esp)

В 32-битном режиме sidt будет хранить данные размером 6 байт вуказанное место.Я использовал -6(%esp) для моего примера, который будет хранить данные чуть ниже текущего стека.Два младших байта - это длина IDT в байтах, а следующие 4 (в 32-битном режиме) - это адрес IDT.Поскольку каждая запись IDT имеет длину 8 байтов, местоположение требуемой записи будет 0x33*8 байтов после начала IDT.Перед изменением записи вы должны убедиться, что IDT действительно содержит эту запись (ее длина не менее 0x34*8 байт).

Вот пример, который находит IDT, гарантирует, что он достаточно длинный, и устанавливаетзапись для прерывания 0x33.

sidt    -6(%esp)          // Get the location and size of the IDT
cmpw    $0x34*8, -6(%esp) // Make sure the IDT is long enough
jb      IDT_too_short     //  and handle the error if it isn't
mov     -4(%esp), %ebx    // Get the IDT's address
add     $0x33*8, %ebx     //  and move to the entry for 0x33
mov     $OSTickISR, %eax  // Get the ISR's address
mov     %ax, (%ebx)       // Store the low 16 bits of the ISR's address
movw    $ISR_CS, 2(%ebx)  // Store the code segment which should be used with this ISR
movb    $0, 4(%ebx)       // This has to be 0
movb    $0xEE, 5(%ebx)    // See the OSDev link for information on this byte.
                          // 0xEE is most common for interrupts available from user mode
shr     $16, %eax
mov     %ax, 6(%ebx)      // Store the high 16 bits of the ISR's address
1 голос
/ 29 сентября 2011

Адрес на x86 состоит из сегмента и смещения. В реальном режиме это сегмент * 16 + смещение. В защищенном режиме есть некоторая косвенность: регистр сегмента - это действительно селектор, который указывает на дескриптор сегмента, который содержит базу и предел сегмента, а также другие атрибуты сегмента. Инструкции, которые обращаются к памяти, могут принимать явный спецификатор сегмента (например, DS:BX), или же они принимают неявный сегмент, который зависит от используемого регистра (например, если вы используете SP, неявный сегмент - SS).

IVT в реальном режиме находится по адресу 0000: 0000, IDT в защищенном режиме - по адресу IDT: 0000, где к IDT можно обращаться с помощью команд LIDT / SIDT.

Следует также учитывать, что если вы работаете в операционной системе с виртуальной памятью, у вас нет прямого доступа к физической памяти, адреса в вашей программе - это виртуальные адреса, которые преобразуются в физические адреса после сегментации и подкачки. .

0 голосов
/ 28 октября 2011

Решено :), поскольку есть BIOS, он уже собрал GDT / IDT, поэтому я нашел адрес IDT, используя инструкции sidt и sgdt, и добавил свой ISR в sidt

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