Реализациясистемыобработкипрерываний

Можливо, не викличе здивування, що реалізація системи обробки переривань в операційній системі Linux дуже сильно залежить від апаратної платформи Вона залежить від типу процесора, типу контролера переривань, особливостей апаратної платформи і пристрою самої обчислювальної машини

На рис 61 показана діаграма шляху, який проходить запит на переривання в апаратному забезпеченні та в ядрі

Апаратура

Генерація запиту на переривання

Функція

handle_IRQ_event()

Так

Контролер переривань

Процесор перериває роботу ядра

Чи обробник для даної лінії переривання

Ні

Виконати всі обробники даної лінії переривання

Функція

do_IRQ()

\

Функція

Повернеться

до виконання

ret_from_int()

перерваного

коду ядра

Процесор

Рис 61 Проходження запиту на переривання в апаратному забезпеченні і в ядрі

Пристрій ініціює переривання е шляхом відправки електричного сигналу контролеру переривання по апаратній шині Якщо відповідна лінія запиту на переривання не заборонена (лінія може бути в даний момент часу замаскована), то контролер переривань відправляє переривання процесору Для більшості апаратних платформ це здійснюється шляхом подачі сигналу на спеціальний висновок процесора Якщо переривання заборонені в процесорі (може статися, що вони заборонені), то процесор негайно припиняє ту роботу, яку він виконував, забороняє систему переривань, здійснює перехід на спеціальний зумовлений адреса памяті і починає виконувати програмний код, який знаходиться за цією адресою Цей зумовлений адреса памяті встановлюється ядром і є точкою входу в обробники переривань

Проходження переривання в ядрі починається з жорстко певної точки входу, так само як і у випадку системних викликів Для кожної лінії переривання існує своя унікальна точка, куди переходить процесор Саме цим способом ядро ​​отримує інформацію про номер IRQ приходить переривання У точці входу спочатку в стеку ядра зберігається значення номера переривання і значення всіх регістрів процесора (які відповідають перерваного завданням) Після цього ядро ​​викликає функцію do_IRQ () Далі, починаючи з цього моменту, майже весь код обробки переривань написаний на мові програмування С, хоча незважаючи на це код все ж залишається залежним від апаратної платформи

Функція do_IRQ () визначена таким чином

unsigned int do_IRQ(struct pt_regs regs)

Так як угоду про виклики функцій в мові С передбачає збереження аргументів функцій у вершині стека, то структура ptreg s містить початкові значення всіх регістрів процесора, які були збережені ассемблерной підпрограмою в точці входу Так як значення номера переривання також зберігається, то функція do_IRQ () може це значення відновити Для апаратної платформи х86 код буде наступним

int irq = regsorig_eax &amp 0xff

Після обчислення значення номера лінії переривання, функція do_IRQ () відправляє повідомлення про отримання переривання і забороняє доставку переривань з даної лінії Для звичайних машин платформи PC, ці дії виконуються за допомогою функції mask_and_ack_8295A (), яку викликає функція do_IRQ () Далі функція do_IRQ () виконує перевірку, що для даної лінії переривання зареєстрований правильний обробник переривання, що цей обробник дозволений і що він не виконується в даний момент Якщо всі ці умови виконані, то викликається функція handle_IRQ_event (), яка виконує встановлені для даної лінії обробники переривання Для апаратної платформи х86 функція handle_IRQ_event () має наступний вигляд

int handle_IRQ_event (unsigned int irq, struct pt_regs *regs, struct irqaction *action)

{

int status = 1

if ((action-&gtflags &amp SA_INTERRUPT))

local_irq_enable ()

do {

status = action-&gtflags

action-&gtchandler (irq, action-&gtdev_id, regs)

action = action-&gtnext

} while (action)

if (status &amp SA_SAMPLE_RANDOM)

add_interrupt_randomness (irq)

local_irq_disable()

return status

}

Оскільки процесор заборонив переривання, вони знову дозволяються, якщо не вказано прапорець SA_INTERRUPT при реєстрації обробника Згадаймо, що прапор SA_INTERRUPT вказує, що обробник повинен виконуватися при всіх заборонених перериваннях Далі в циклі викликаються всі потенційні обробники переривань Якщо ця лінія не є спільно використовуваної, то цикл закінчується після першої ітерації У Інакше викликаються всі обробники Після цього викликається функція add_interrupt_randomnes s (), якщо при реєстрації вказаний прапор SA_SAMPLE_RANDOM Ця функція використовує тимчасові характеристики переривання, щоб згенерувати значення ентропії для генератора випадкових чисел У додатку Б, Генератор випадкових чисел ядра, наведена більш докладна інформація про генератор випадкових чисел ядра

Наприкінці переривання знову забороняються (для функції do_IRQ () потрібно, щоб переривання були заборонені) Функція do_IRQ () здійснює очищення стека і повернення до первісної точці входу, звідки здійснюється перехід до функції ret_from_intr ()

Функція ret_from_int r (), так само як і код входу, написана на мові асемблера Ця функція перевіряє, чи є що очікує запит на перепланування виконання процесів (слід згадати главу 4, Планування виконання процесів, і прапор need_resched) Якщо є запит на перепланування і ядро ​​повинно передати управління в простір користувача (тобто переривання перервало роботу користувача процесу), то викликається функція schedul e () Якщо повернення здійснюється в простір ядра (тобто переривання перервало роботу коду ядра), то функція schedul e () викликається, тільки якщо значення лічильника preempt_coun t дорівнює нулю (в іншому випадку небезпечно виробляти витіснення коду ядра), Після повернення з функції schedul e () або якщо немає ніякої яка чекає роботи, відновлюються початкові значення регістрів процесора і ядро ​​продовжує роботу там, де воно було перервано

Для платформи х86, підпрограми, написані мовою асемблера, знаходяться у файлі arch/i386/kernel/entryS, а відповідні функції на мові С – у файлі arch/i386/kernel/irqс Для інших підтримуваних апаратних платформ є аналогічні файли

Інтерфейс / proc / interrupts

Файлова система procfs— це віртуальна файлова система, яка існує тільки в памяті ядра і зазвичай монтується на каталог / ргос Читання або запис файлів на файловій системі procfs призводить до викликів функцій ядра, які імітують читання або запис звичайних файлів Важливий приклад-це файл / ргос / interrupts, який містить статистику, повязану з перериваннями в системі, Нижче наведений приклад виведення з цього файлу на однопроцесорному персональному компютері

CPU0

0:

3602371

XT-PIC

timer

1:

3048

XT-PIC

i8042

2:

0

XT-PIC

cascade

4:

2689466

XT-PIC

uhci-hed, ethO

5:

0

XT-PIC

EMU10K1

12: 85077

15: 24571

XT-PIC XT-PIC

uhei-hcd aic7xxx

NMI: 0

LOC: 3602236

ERR: 0

Перша колонка містить назви ліній переривання У показаної системі присутні лінії переривань з номерами 0-2, 4, 5, 12 і 15 Лінії, для яких не інстальований обробник, не показуються Друга колонка – це кількість запитів на переривання з даним номером Насправді така колонка є окремою для кожного процесора, але в даній машині тільки один процесор

Як легко бачити, обробник переривань таймера отримав 3602371 2 запит на переривання, в той час як обробник переривань звукового адаптера (EMU10K1) не отримав жодного переривання (Це говорить про те, що він не використовувався з того моменту, як машина була завантажена) Третя колонка-це контролер переривань, який обслуговує дане переривання Значення XT-PIC відповідає програмовані контролери переривань PC (PC programmable interrupt controller) Для систем з пристроєм I / Про APIC для більшості переривань в якості контролера переривань буде вказано значення IO-APIC-level або IO-APIC-edge І нарешті, остання колонка-це пристрій, який повязано з перериванням Імя пристрою вказується в параметрі dev_name при виклику функції request_ir q (), як обговорювалося раніше Якщо переривання використовується спільно, як у випадку переривання номер 4 в цьому прикладі, то перераховуються всі пристрої, зареєстровані на даній лінії переривання

Для цікавих, код, повязаний з файлової системою procfs, знаходиться у файлі fs / proc Функція, яка забезпечує роботу інтерфейсу / proc / interrupts, називається show_interrupt s () і є залежною від апаратної платформи

Джерело: Лав, Роберт Розробка ядра Linux, 2-е видання : Пер з англ – М: ТОВ «ІД Вільямс »2006 – 448 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*