Відповіді:
Ось подання на високому рівні щодо обробки низького рівня. Я описую просту типову архітектуру, реальні архітектури можуть бути складнішими або відрізнятися способами, які не мають значення на цьому рівні деталізації.
Коли відбувається переривання , процесор виглядає, чи переривання маскуються. Якщо вони є, нічого не відбувається, поки їх не розкриють. Коли переривання не маскується, якщо є якісь очікувані переривання, процесор вибирає один.
Потім процесор виконує переривання шляхом розгалуження на певну адресу в пам'яті. Код за цією адресою називається обробником переривання . Коли процесор там розгалужується, він маскує переривання (тому обробник переривання має ексклюзивний контроль) і зберігає вміст деяких регістрів в якомусь місці (як правило, інших регістрів).
Обробник переривання робить те, що повинен робити, як правило, спілкуючись з периферійним пристроєм, який викликав переривання для надсилання або отримання даних. Якщо таймер підвищив таймер, обробник може спровокувати планувальник ОС, щоб перейти на інший потік. Коли обробник закінчує виконання, він виконує спеціальну інструкцію повернення-від-переривання, яка відновлює збережені регістри та розкриває переривання.
Обробник переривання повинен запускатися швидко, оскільки це заважає виконувати будь-які інші переривання. У ядрі Linux обробка перерв розділена на дві частини:
Як завжди в цій темі, для отримання додаткової інформації читайте драйвери пристроїв Linux ; глава 10 - про переривання.
Гілл вже описав загальний випадок перерви, наступне стосується спеціально для Linux 2.6 на архітектурі Intel (частина цього також базується на специфікаціях Intel).
Перерва - це подія, яка змінює послідовність інструкцій, виконаних процесором.
Існує два різних типи переривань:
Винятки спричинені помилками програмування (fe Divide error , Page Fault , Overflow ), з якими має працювати ядро. Він посилає сигнал програмі і намагається відновитись після помилки.
Наступні два винятки класифіковані:
Переривання можуть видаватися пристроями вводу / виводу (клавіатура, мережевий адаптер, ..), таймерами інтервалу та (у багатопроцесорних системах) іншими процесорами. Коли виникає перерва, ЦП повинен припинити свою поточну інструкцію та виконати щойно прибуте переривання. Йому потрібно зберегти старий стан перерваного процесу, щоб (ймовірно) відновити його після обробки переривання.
Поводження з перервами є чутливим завданням:
Визначено два різних рівні переривання:
Кожен апаратний пристрій має власну лінію запиту на переривання (IRQ). IRQ номерируються починаючи з 0. Всі лінії IRQ підключені до програмованого контролера переривання (PIC). PIC слухає IRQ та призначає їх до процесора. Також можливо відключити конкретну лінію IRQ.
Сучасні багатопроцесорні системи Linux зазвичай включають новіший Advanced PIC (APIC), який розподіляє запити IRQ порівну між процесорами.
Середнім кроком між перериванням або винятком та обробкою ним є Таблиця дескрипторів переривання (IDT). Ця таблиця пов'язує кожен перериваючий або винятковий вектор (число) із заданим обробником (fe Помилка поділки отримується функцією divide_error()
).
Через IDT ядро точно знає, як поводитися з перериванням або винятком.
Отже, що робить ядро, коли відбувається переривання?
VIP
-flag у реєстрі прапорів чи ще? Заздалегідь
Перш за все учасниками обробки перерв є периферійні апаратні пристрої, контролер переривання, процесор, ядро операційної системи та драйвери. Периферійні апаратні пристрої відповідають за генерування переривань. Вони стверджують лінії запитів на переривання, коли хочуть уваги з боку ядра операційної системи. Ці сигнали мультиплексовані контролером переривання, який відповідає за збір сигналів переривання. Він також відповідає за визначення порядку, в якому сигнали переривання будуть передані до процесора. Контролер переривання може тимчасово відключити певний рядок запиту на переривання (IRQL) та повторно впорядкувати його (маскування IRQL). Контролер переривання передає зібрані запити на переривання послідовно. CPU після завершення виконання кожної інструкції CPU перевіряє, чи є запити на переривання в очікуванні від контролера переривання. Якщо ЦП виявить, що існує запит очікування І встановлено прапор Включення переривання у внутрішньому реєстрі управління процесором, тоді ЦП починає обробку переривань. Як бачите, маніпулюючи прапором Переривання в процесорі та спілкуванням з контролером переривання, ядро Linux може контролювати прийняття переривання. Наприклад, Linux може відключити прийняття переривань від конкретного пристрою або взагалі відключити прийняття переривань. Ядро Linux здатне контролювати прийняття переривання. Наприклад, Linux може відключити прийняття переривань від конкретного пристрою або взагалі вимкнути прийняття переривання. Ядро Linux здатне контролювати прийняття переривання. Наприклад, Linux може відключити прийняття переривань від конкретного пристрою або взагалі вимкнути прийняття переривання.
Що відбувається, коли процесор отримує запит на переривання? По-перше, процесор автоматично відключає переривання, скидаючи прапор переривання. Вони будуть відновлені, як тільки робота з перервами буде закінчена. У той же час процесор здійснює мінімальну кількість роботи, необхідної для переходу CPU з користувальницького режиму в режим ядра таким чином, що дозволить відновити виконання перерваного коду. Процесор консультується зі спеціальними структурами управління процесором, заповненими ядром Linux, щоб знайти адресу коду, до якого буде передано керування. Ця адреса - це адреса першої інструкції обробника переривань, яка є частиною ядра Linux.
В якості першого кроку обробки переривань ядро ідентифікує вектор отриманого переривання для ідентифікації того, яка подія відбулася в системі. Вектор переривання визначає, які дії буде виконувати Linux для його впорядкування. На другому кроці Linux зберігає решту регістрів процесора (які не були збережені CPU автоматично) і які потенційно можуть бути використані перерваною програмою. Це дуже важлива дія, оскільки дозволяє Linux обробляти перериви прозоро з урахуванням перерваної програми. На третьому кроці Linux здійснює перехід до режиму ядра, встановлюючи середовище ядра та встановлюючи необхідний для нього стан CPU. І нарешті, викликається векторний обробник переривання. (Ви можете подивитися макрос BUILD_INTERRUPT3 в арці \ x86 \ kernel \ entry_32. S, щоб захопити додаткові деталі для прикладу, пов'язаного з архітектурою x86) У випадку периферійних пристроїв це програма do_IRQ (). (Загляньте в арку \ x86 \ kernel \ irq.c)
Векторозалежний обробник переривання зазвичай завершується дзвінками до irq_enter () та irq_exit (). Область коду, що знаходиться в межах пари цих функцій, є атомною відносно будь-яких інших таких областей, а також є атомною щодо пар кліп. Irq_enter () та irq_exit () також фіксує деякі статистичні дані, пов'язані з обробкою переривань. Нарешті, ядро заглядає в таблицю vector_irq, щоб знайти номер irq, присвоєний вектору отриманого переривання та виклику handle_irq () (з arch \ x86 \ kernel \ irq_32.c).
На цьому загальна частина обробки переривань в Linux закінчується, тому що ядро виглядає залежно від пристрою рутину обробника переривань, встановлену драйвером пристрою, як частину дескриптора irq і викликає його. Якщо такий обробник не був встановлений драйвером, ядро просто підтверджує переривання на контролері переривання і переходить до виходу із загального обробника переривання.
Після закінчення обробки переривання ядро відновлює стан програми, яка була перервана раніше, і відновлює виконання цієї програми.
CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.
Так! Цікаво, що це за спеціальні структури управління ...
З теоретичного аспекту майже все було пояснено. Але якщо ви шукаєте пояснення щодо структури коду обробки переривань ядра, перейдіть за наступним посиланням: Прогулянка кодом всередині обробки переривання ядра
І якщо ви все ще дивитесь на теорію про переривання та оброблювачі переривань, то рекомендую прочитати наступне: Розуміння переривань та обробників переривань