Чтение онлайн

на главную

Жанры

Разработка ядра Linux
Шрифт:

int irq = regs.orig_eax & 0xff;

После вычисления значения номера линии прерывания, функция

do_IRQ
отправляет уведомление о получении прерывания и запрещает доставку прерываний с данной линии. Для обычных машин платформы PC, эти действия выполняются с помощью функции
mask_and_ack_8295A
, которую вызывает функция
do_IRQ
. Далее функция
do_IRQ
выполняет проверку, что для данной линии прерывания зарегистрирован правильный обработчик прерывания, что этот обработчик разрешен и что он не выполняется в данный момент. Если все эти условия выполнены, то вызывается функция
handle_IRQ_event
, которая выполняет установленные для данной линии обработчики прерывания. Для аппаратной платформы x86 функция
handle_IRQ_event
имеет следующий вид.

int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,

 struct irqaction *action) {

 int status = 1;

 if (!(action->flags & SA_INTERRUPT))

local_irq_enable;

 do {

status != action->flags;

action->chandler(irq, action->dev_id, regs);

action = action->next;

 } while (action);

 if (status & SA_SAMPLE_RANDOM)

add_interrupt_randomness(irq);

 local_irq_disable;

 return status;

}

Так

как процессор запретил прерывания, они снова разрешаются, если не указан флаг
SA_INTERRUPT
при регистрации обработчика. Вспомним, что флаг
SA_INTERRUPT
указывает, что обработчик должен выполняться при всех запрещенных прерываниях. Далее в цикле вызываются все потенциальные обработчики прерываний. Если эта линия не является совместно используемой, то цикл заканчивается после первой итерации. В противном случае вызываются все обработчики. После этого вызывается функция
add_interrupt_randomness
, если при регистрации указан флаг
SA_SAMPLE_RANDOM
. Данная функция использует временные характеристики прерывания, чтобы сгенерировать значение энтропии для генератора случайных чисел. В приложении Б, "Генератор случайных чисел ядра", приведена более подробная информация о генераторе случайных чисел ядра.

В конце прерывания снова запрещаются (для функции

do_IRQ
требуется, чтобы прерывания были запрещены). Функция
do_IRQ
производит очистку стека и возврат к первоначальной точке входа, откуда осуществляется переход к функции
ret_from_intr
.

Функция

ret_from_intr
, так же как и код входа, написана на языке ассемблера. Эта функция проверяет, есть ли ожидающий запрос на перепланирование выполнения процессов (следует вспомнить главу 4, "Планирование выполнения процессов", и флаг
need_resched
). Если есть запрос на перепланирование и ядро должно передать управление в пространство пользователя (т.е. прерывание прервало работу пользовательского процесса), то вызывается функция
schedule
. Если возврат производится в пространство ядра (т.е. прерывание прервало работу кода ядра), то функция
schedule
вызывается, только если значение счетчика
preempt_count
равно нулю (в противном случае небезопасно производить вытеснение кода ядра), После возврата из функции
schedule
или если нет никакой ожидающей работы, восстанавливаются первоначальные значения регистров процессора и ядро продолжает работу там, где оно было прервано.

Для платформы x86, подпрограммы, написанные на языке ассемблера, находятся в файле

arch/i386/kernel/entry.S
, а соответствующие функции на языке С — в файле
arch/i386/kernel/irq.с
. Для других поддерживаемых аппаратных платформ имеются аналогичные файлы.

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

Файловая система procfs — это виртуальная файловая система, которая существует только в памяти ядра и обычно монтируется на каталог

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

CPU0

0: 3602371 XT-PIC timer

1: 3048 XT-PIC i8042

2: 0 XT-PIC cascade

4: 2689466 XT-PIC uhci-hcd, eth0

5: 0 XT-PIC EMU10K1

 12: 85077 XT-PIC uhci-hcd

 15: 24571 XT-PIC aic7xxx

NMI: 0

LOC: 3602236

ERR: 0

Первая колонка содержит названия линий прерывания. В показанной

системе присутствуют линии прерываний с номерами 0–2, 4, 5, 12 и 15. Линии, для которых не инсталлирован обработчик, не показываются. Вторая колонка — это количество запросов на прерывания с данным номером. В действительности такая колонка является отдельной для каждого процессора, но в данной машине только один процессор.

Как легко видеть, обработчик прерываний таймера получил

3.602.371
[32] запрос на прерывание, в то время как обработчик прерываний звукового адаптера (
EMU10K1
) не получил ни одного прерывания (это говорит о том, что он не использовался с того момента, как машина была загружена). Третья колонка— это контроллер прерываний, который обслуживает данное прерывание. Значение
XT-PIC
соответствует программируемому контроллеру прерываний PC (PC programmable interrupt controller). Для систем с устройством I/О APIC для большинства прерываний в качестве контроллера прерываний будет указано значение
IO-APIC-level
или
IO-APIC-edge
. И наконец, последняя колонка — это устройство, которое связано с прерыванием. Имя устройства указывается в параметре
dev_name
при вызове функции
request_irq
, как обсуждалось ранее. Если прерывание используется совместно, как в случае прерывания номер 4 в этом примере, то перечисляются все устройства, зарегистрированные на данной линии прерывания.

32

После прочтения главы 10, "Таймеры и управление временем", можно ли сказать, сколько времени (в единицах HZ) машина работала без перегрузки исходя из числа прерываний таймера?

Для любопытствующих, код, связанный с файловой системой

procfs
, находится в файле
fs/proc
. Функция, которая обеспечивает работу интерфейса
/proc/interrupts
, называется
show_interrupts
и является зависимой от аппаратной платформы.

Управление прерываниями

В ядре Linux реализовано семейство интерфейсов для управления состояниями прерываний в машине. Эти интерфейсы позволяют запрещать прерывания для текущего процессора или маскировать линию прерывания для всей машины. Эти функции очень сильно зависят от аппаратной платформы и находятся в файлах

<asm/system.h>
и
<asm/irq.h>
. В табл. 6.2 приведен полный список этих интерфейсов.

Причины, по которым необходимо управлять системой обработки прерываний, в основном, сводятся к необходимости обеспечения синхронизации. Путем запрещения прерываний можно гарантировать, что обработчик прерывания не вытеснит текущий исполняемый код. Более того, запрещение прерываний также запрещает и вытеснение кода ядра. Однако ни запрещение доставки прерываний, ни запрещение преемптивности ядра не дают никакой защиты от конкурентного обращения других процессоров. Так как операционная система Linux поддерживает многопроцессорные системы, в большинстве случаев код ядра должен захватить некоторую блокировку, чтобы предотвратить доступ другого процессора к совместно используемым данным. Эти блокировки обычно захватываются в комбинации с запрещением прерываний на текущем процессоре. Блокировка предоставляет защиту от доступа другого процессора, а запрещение прерываний обеспечивает защиту от конкурентного доступа из возможного обработчика прерывания. В главах 8 и 9 обсуждаются различные аспекты проблем синхронизации и решения этих проблем.

Тем не менее понимание интерфейсов ядра для управления прерываниями является важным.

Запрещение и разрешение прерываний

Для локального запрещения прерываний на текущем процессоре (и только на текущем процессоре) и последующего разрешения можно использовать следующий код.

local_irq_disable;

/* прерывания запрещены ... */

local_irq_enable;

Эти функции обычно реализуются в виде одной инструкции на языке ассемблера (что, конечно, зависит от аппаратной платформы). Для платформы x86 функция

local_irq_disable
— это просто машинная инструкция
cli
, а функция
local_irq_enable
 — просто инструкция
sti
. Для хакеров, не знакомых с платформой x86,
sti
и
cli
— это ассемблерные вызовы, которые соответственно позволяют установить (set) или очистить (clear) флаг разрешения прерываний (allow interrupt flag). Другими словами, они разрешают или запрещают доставку прерываний на вызвавшем их процессоре.

Поделиться:
Популярные книги

Его наследник

Безрукова Елена
1. Наследники Сильных
Любовные романы:
современные любовные романы
эро литература
5.87
рейтинг книги
Его наследник

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Системный Нуб 4

Тактарин Ринат
4. Ловец душ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Системный Нуб 4

Барон меняет правила

Ренгач Евгений
2. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон меняет правила

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

На границе империй. Том 5

INDIGO
5. Фортуна дама переменчивая
Фантастика:
боевая фантастика
попаданцы
7.50
рейтинг книги
На границе империй. Том 5

Сотник

Ланцов Михаил Алексеевич
4. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Сотник

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Не грози Дубровскому! Том II

Панарин Антон
2. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том II

Огни Эйнара. Долгожданная

Макушева Магда
1. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Огни Эйнара. Долгожданная

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Черный Маг Императора 9

Герда Александр
9. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 9