2012-06-03 4 views
14

На mainbord у нас есть контроллер прерываний (IRC), который выступает в качестве мультиплексора между устройствами, которые могут вызвать прерывание и процессор:обработки прерываний (Linux/Общие вопросы)

       |--------| 
      |-----------|  |  | 
-(0)------| IRC _____|______| CPU | 
-(...)----| ____/  |  |  | 
-(15)-----|/   |  |--------| 
      |-----------| 

Каждое устройство, связанное с IRQ (число слева). После каждого выполнения CPU определяет линию запроса прерывания. Если обнаружен сигнал, будет выполнено сохранение состояния, а ЦП загрузит процедуру обработчика прерываний, которая может быть найдена в векторе прерываний, который находится по фиксированному адресу в памяти. Насколько я могу видеть, число IRQ и номер вектора в векторе прерываний не совпадают, поскольку у меня есть, например, моя сетевая карта, зарегистрированная в IRQ 8. На процессоре Intel Pentium это будет указывать на рутину, которая используется чтобы сигнализировать одно условие ошибки, поэтому должно быть отображение где-нибудь, что указывает на правильный обработчик.

Вопросы:

1) Если я пишу драйвер устройства и зарегистрировать IRQ X для него. Откуда система знает, какое устройство должно быть обработано? Например, я могу использовать request_irq() с IRQ номером 10, но как система знает, что обработчик должен использоваться для мыши или клавиатуры или для того, что я пишу драйвер?

2) Как выглядит вектор прерывания? Я имею в виду, что если я использую IRQ 10 для своего устройства, это перепишет стандартный обработчик, который предназначен для обработки ошибок в таблице (первая используемая версия - 32 согласно Silberschatz (понятия операционной системы)).

3) Кто инициализирует IRQ? Биос? ОС?

4) Кто отвечает за соответствие IRQ и смещение в векторе прерывания?

5) Можно разделить IRQS. Как это возможно? На материнской плате есть аппаратные дорожки, которые подключают устройства к контроллеру прерываний. Как можно настроить полосы для одного и того же прерывания? Должна быть таблица, в которой говорится, что дорожка 2 и 3 обрабатывает IRQ15, например. Где находится эта таблица и как она называется?

+0

Более подробное описание по установке прерываний, обработки и отображения можно найти здесь: [код ходьбы в рамках прерываний ядра] (http://linuxburps.blogspot.in/2013/10/linux-interrupt- handling.html) –

ответ

18

Ответы на ядро ​​Linux. Должен работать и для большинства других ОС.

1) Если я напишу драйвер устройства и зарегистрирую IRQ X для него. Откуда система знает, какое устройство должно быть обработано? Например, я могу использовать request_irq() с IRQ номером 10, но как система знает, что обработчик должен использоваться для мыши или клавиатуры или для того, что я пишу драйвер?

На него нет 1 ответа. Например, если это пользовательская встроенная система, разработчик оборудования скажет автору драйвера «Я собираюсь перенаправить устройство x на irq y». Для большей гибкости, например, для сетевой карты, которая обычно использует протокол PCI. Существует арбитраж уровня аппаратного обеспечения/прошивки для назначения номера irq новому устройству при его обнаружении. Затем это будет записано в один из регистров конфигурации PCI. Сначала драйвер считывает этот регистр устройства и затем регистрирует обработчик прерываний для этого конкретного irq. Будут аналогичные механизмы для других протоколов.

Что вы можете сделать, это искать вызовы request_irq в коде ядра и как драйвер получил значение irq. Это будет отличаться для каждого типа драйвера.

Ответ на этот вопрос, таким образом, система не знает. Разработчик аппаратного обеспечения или аппаратные протоколы предоставляют эту информацию автору драйверов. И затем писатель драйвера регистрирует обработчик для этого конкретного irq, сообщая системе, что делать, если вы видите, что irq.

2) Как выглядит вектор прерывания? Я имею в виду, что если я использую IRQ 10 для своего устройства, это перепишет стандартный обработчик, который предназначен для обработки ошибок в таблице (первая используемая версия - 32 согласно Silberschatz (понятия операционной системы)).

Хороший вопрос. Есть две части.

a) Когда вы request_irq (irq, обработчик). Система действительно не программирует запись 0 в IVT или IDT. Но запись N + irq. Где N - количество обработчиков ошибок или исключений общего назначения, поддерживаемых на этом CPU. Детали варьируются от системы к системе.

b) Что произойдет, если вы ошибочно запросите irq, который используется другим водителем. Вы получаете ошибку, и IDT не запрограммирован с помощью вашего обработчика.

Примечание: IDT - таблица дескриптора прерывания.

3) Кто инициализирует IRQ? Биос? ОС?

Bios сначала, а затем ОС. Но есть некоторые ОС, например, MS-DOS, которые не перепрограммируют IVT, установленный BIOS. Более сложные современные ОС, такие как Windows или Linux, не хотят полагаться на определенные функции bios, и они перепрограммируют IDT. Но биос должен сделать это изначально только тогда, когда ОС входит в картину.

4) Кто отвечает за соответствие IRQ и смещение в векторе прерывания?

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

5) Можно разделить IRQS. Как это возможно? На материнской плате есть аппаратные дорожки, которые подключают устройства к контроллеру прерываний. Как можно настроить полосы для одного и того же прерывания? Должна быть таблица, в которой говорится, что дорожка 2 и 3 обрабатывает IRQ15, например. Где находится эта таблица и как она называется?

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

The code looks like this: 

driver1: 

d1_int_handler: 
     if (device_interrupted()) <------------- This reads the hardware 
     { 
      do_interrupt_handling(); 
      return MY_INTERRUPT; 
     }else { 
      return NOT_MY_INTERRUPT; 
     } 

driver2: 
     Similar to driver 1 


kernel: 
     do_irq(irq n) 
     { 
      if (shared_irq(n)) 
      { 
       irq_chain = get_chain(n); 
       while(irq_chain) 
       { 
        if ((ret = irq_chain->handler()) == MY_INTERRUPT) 
         break; 
        irq_chain = irq_chain->next; 
       } 
       if (ret != MY_INTERRUPT) 
        error "None of the drivers accepted the interrupt"; 
      } 
     } 
+2

Отличный ответ, thx! – fliX

+0

Вы добавили описание на IDT, можете ли вы добавить его для IVT? – einstein

Смежные вопросы