прекъсват товарачи
Функцията, която изпълнява ядрото в отговор на специфичен прекъсване се нарича прекъсване манипулатор (прекъсване манипулатор) ил, и програмата за прекъсване услуга (рутинни прекъсне услуга). Всяко устройство, което генерира прекъсване съответства на прекъсване манипулатор. Например, една функция обработва прекъсва таймер система, и от друга - за прекъсване, генерирани от клавиатурата. Едно прекъсване манипулатор за устройство е част от устройство за водача - код на ядрото, която контролира устройството.
В операционната система Linux прекъсне товарачи - това е нормално функции. написан на език за програмиране C и той трябва да отговаря на определени предшестващо състояние на ядрото може по стандартния начин, за да получите информация за процесора, но това ostalnom- нормални функции. Единственото нещо, което отличава прекъсне манипулаторите от други основни функции - това е, което те се наричат от ядрото в отговор на прекъсване и се изпълнява в специален контекст, наречена контекста на прекъсване (прекъсване контекст), което ще бъде обсъдено по-късно.
Тъй като за прекъсване може да се случи по всяко време, а след това, съответно, и прекъсващият може да се нарече по всяко време. Наложително е прекъсващият оператор е много бърза, и възобнови контрола на прекъснат кода възможно най-бързо. Затова, въпреки че хардуера и е важно, че прекъсването се сервира веднага, че е важно за останалата част от системата за прекъсване манипулатор, изпълнен в най-кратък период от време. Минималната възможна работата, която трябва да направи едно прекъсване манипулатор - е да се изпрати устройство за потвърждение, че е получена прекъсне. Обикновено, обаче, прекъсване, работещи са длъжни да извършват повече работа. Например, помислете за прекъсване манипулатор на мрежовото устройство. Заедно с изпращане на потвърждение на хардуера, прекъсващият трябва да копирате пакети мрежа от хардуерно устройство в паметта на системата, обработва ги изпраща на съответния стека протокол или съответната програма. Очевидно е, че това изисква много работа.
Горните и долните части
Ясно е, че тези две изисквания, които прекъсват манипулатор трябва да се извършват бързо и, в допълнение, да извършва много работа, са противоречиви. Поради противоречиви изисквания, прекъсват манипулатор е разделен на две части или половини. Прекъсне треньор е в горната половина (горната половина) - тя се извършва веднага след приемане на прекъсването и изпълнява работата, критично забавяне във времето, като например изпращане на потвърждение за получаването на прекъсването или нулиране на хардуерно устройство. Работата, която се извършва по-късно, се нанася преди дъното (или основна) половина (долната половина). Долната част се обработва по-късно в по-удобно време, след като всички прекъсва. Доста често, долната половина се изпълнява веднага след завръщането от прекъсващият.
Операционната система предлага разнообразие от механизми за изпълнение, обработването на долните части, които са разгледани в Глава 7, "Работа в долната половина и разсрочено действие."
Да разгледаме пример за прекъсване манипулатор за разделяне на горните и долните части чрез обикновена NIC. Когато адаптерът за мрежов интерфейс получава входящи пакети от мрежата, той трябва да уведоми ядрото, че получаването на нови данни. Това трябва да стане незабавно, за да се получи оптимален трафик и латентност при прехвърляне на информация по мрежата. Ето защо, за прекъсване се генерира веднага: "Хей, има пресни пакети ядрото на ядрото реагира чрез извършване на регистрирания прекъсващ оператор от адаптера за променлив ток!..
Едно прекъсване манипулатор се изпълнява, хардуерни насочват пакети за потвърждение се копират в основната памет, и след това захранващия адаптер е готов да приема нови пакети. Тази задача е важна и критична към времето за изпълнение и специфични за всеки тип хардуер. Останалата част от обработката на мрежа за пакети се извършва по-късно - в долната половина прекъсващ оператор. В тази глава ние считаме, обработката на горната половина, а в следващия - по-ниска.
Регистрирайте се прекъсне треньор
прекъсне, работещи за отговорността на драйверите за устройствата, които управляват определен тип хардуер. Всеки водач е свързано устройство, и ако устройството използва за прекъсване (и най-използвани), водачът трябва да извърши регистрацията на прекъсващ оператор.
Водачът може да се регистрира за прекъсване манипулатор за обработка на определената линия със следните функции.
/ * Request_irq: разпредели даден прекъсване линия * /
Int request_irq (неподписан Int IRQ,
irqreturn_t (* манипулатор) (ср, нищожен *, структура pt_regs *), неподписани дълги irqflags,
Конст Чар * devname,
Първият параметър, IRQ. точки, възложени редица прекъсване. За някои устройства, като, например, конвенционален лични компютърни устройства, таймер и клавиатура, тази стойност обикновено се фиксира точно. За повечето други устройства, тази стойност се определя чрез изследване (сондиране) или друго динамичен начин.
Вторият параметър, манипулатор. - указател към функция от прекъсващият, която обслужва този прекъсване. Тази функция се нарича, когато операционната система идва прекъсване. Обръща се внимание на определен прототип на манипулатора. Отнема три параметъра и връща стойност на типа irqreturn_t. По-късно в тази глава, ние ще обсъдим по-подробно тази функция.
Третият параметър, irqflags. То може да бъде нула или да съдържа bitmask с един или повече от следните флагове.
• SA_INTERRUPT. Този флаг показва, че прекъсващ оператор - един bystryyobrabotchikpreryvaniya. Istoricheskitakslozhilos, chtooperatsionnaya Linux система прави разлика между бавно и бързо прекъсват манипулатори. Очаква се, че най-бързите процесори са бързи, но потенциално много често, така че поведението на прекъсващ оператор е променен, за да се осигури възможно най-голяма скорост на изпълнение. Днес има само една разлика: когато бързо прекъсващ оператор забранява всички прекъсвания на местния процесор. Това позволява бърз край на водача бързо, а други прекъсвания по начин, който не е pometat. По подразбиране (ако това не е уточнено) го позволи всички прекъсвания, с изключение на тези, маскиран на всички преработватели и манипулатори, които работят в момента. За всички прекъсвания, освен прекъсват таймер, не е необходимо да се създаде този флаг.
• SA_SAMPLE_RANDOM. Този флаг показва, че прекъсвам, генерирани от това устройство, трябва да допринася за басейна на ядрото ентропия. Kernel ентропия басейн осигурява генериране на истински случайни числа на базата на различни случайни събития. Ако не е посочен този флаг, времената, когато те идват прекъсване, ще бъдат въведени в басейна ентропия. Този флаг не може да се настрои, ако устройството генерира прекъсване при предвидими пъти (като системния таймер) или външен нападател устройство (като мрежово устройство) може да бъде повлияно. От друга страна, повечето от устройствата генерира прекъсва при непредвидими времена и затова са добър източник на ентропия. За по-подробно описание на ентропия басейна на ядрото види. Приложение B, "генератора на случайни числа на ядро".
• SA_SHIRQ. Този флаг показва, че броят на прекъсванията може да се споделя от няколко прекъсвания товарачи (споделена). Всеки манипулатор, който е регистриран на същата линия прекъсване, флагът трябва да посочи това. В противен случай, само едно прекъсване манипулатор може да съществува за всяка линия. За повече информация относно споделените прекъсват товарачи, вижте следващия раздел.
Четвъртият параметър, devname, - това е най-ASCII низ, който описва кое устройство е свързан с прекъсването. Например, за да се прекъсне клавиатурата на компютъра, стойността е "клавиатура". Имената на Word устройства се използват за взаимодействие с потребителя чрез интерфейси
/ Proc / ИЧ р и / PROC / прекъсва. които скоро ще бъдат взети под внимание.
Петият параметър, Девид. използва главно за споделени заявка за прекъсване линии. Когато водачът на прекъсване се освобождава (описано по-долу), dev_id параметър осигурява уникален идентификатор (бисквитки), което позволява да се отстранят само необходимо прекъсване манипулатор линия. Без тази възможност, би било невъзможно да се определи какво ядрото прекъсне треньор на линията трябва да бъдат отстранени. Ако искането линия и за прекъсване не се споделя, че е възможно за този параметър указва NULL, ако същото прекъсване брой се споделя, че е необходимо да се посочи единен идентификатор (бисквитка) (ако устройството не е свързано към калта ISA, най-хубавото е, че Той поддържа споделили номера прекъсване).
Този параметър също се предава на прекъсващ оператор за всяко повикване. Обичайната практика - указател към структура предаване устройство (контекста устройство), както този параметър е уникален, и в допълнение, може да е полезно да има указател към тази структура в прекъсване манипулатор.
Ако се окаже успешна, функция request_ir р на () връща нула. Назад стойност различна от нула, показва, че е станала грешка и определения прекъсващ оператор не е бил регистриран. Най-често срещаната грешка кодекс - -EBUSY тази стойност, което показва, че заявката за прекъсване линия вече е заето (и или текущия разговор или първото обаждане не е било указано SA_SHIRQ флаг).
Трябва да се отбележи, че request_ir функция р () е в режим на сън (сън) и, съответно, не може да бъде извикан от прекъсване контекст или в други ситуации, в които кодът не могат да бъдат блокирани. Често срещана грешка е вярата, че request_irq () функция, можете спокойно да се обадя в случаите, когато не може да отиде в състояние свободно. Това отчасти се от факта, че наистина просто не разбирам защо request_irq на функцията () трябва да очакваме нищо. Работата е там. че да се извърши регистрацията добавянето на информация за прекъсване линия в директорията / ргос / IRQ. функция proc_mkdir () се използва за създаване на нови елементи в procfs файловата система. Тази функция изисква функция proc_creat д (), за да създадете нови елементи procfs файлова система. което от своя страна причинява kmalloc (функция) за разпределяне на паметта. Както ще бъде показано в глава 11, "Управление на паметта", kmalloc () може да отиде в състояние свободно. Това е начина!
За регистрация линия прекъсване манипулатор и инсталиране на драйвери в кода, можете да използвате следния разговор.
ако (request_irq (irqn, my_interrupt, SA_SHIRQ "my_device", отклонение))
printk (KERN_ERR "my_device: не може да регистрира IRQ \ н.", irqn);
В този пример, прекъсването на параметъра п - е заявка за броя искания прекъсване линия, създаване my_interrup тона - е процесор за обработка на заявката за прекъсване линия за прекъсване може да се споделя, името на устройството - "my_device", отклонение - dev_id стойност параметър. В случай на код за грешка отпечатва съобщение, че е станала грешка, и се връща от функцията. Ако функцията за сеч връща нулева стойност, прекъсващият оператор е инсталиран успешно. От този момент за прекъсване манипулатор ще бъде ползвана в отговор на входящо прекъсване. Важно е да се инициализира на оборудването и проверете прекъсващ оператор в правилната последователност, за да се предотврати възможността за манипулатор на повикване, докато оборудването не е инициализиран.
Освобождаване прекъсне треньор
За да освободите прекъсване линия е необходимо да извикате функция
нищожен free_irq (неподписана вътр IRQ, нищожен * dev_id)
Ако определен ред не се споделя, тази функция премахва манипулатор и забранява прекъсване на линия. Ако заявка за прекъсване линия е споделена, а след това се отстранява манипулатор, съответстваща dev_id параметър. поискване линия прекъсване също е забранено, когато отстранен миналата манипулатор. Сега разбирам защо е важно да се предават на уникалната параметъра стойност dev_id. При използване на споделена прекъсване изисква уникален идентификатор различаването свързан с един прекъсване брой различни един от друг, работещи и да позволи на функции free_irq (), за да изтриете правилно манипулатор. Във всеки случай, лишена стойност параметър не е равно на NULL, то тогава трябва да съответства на манипулатор, който се отстранява.
Обадете free_irq () функция трябва да се извършва от контекста на процеса.
Таблица 6.1. управление Списък регистрация прекъсват функции
request_ir р () Регистрация посочено прекъсване манипулатор за даден прекъсване линия
е ree_ir р () Освободете посочено прекъсване манипулатор. Ако прекъсне линия вече не е свързана с никакви един процесор, забраната е посочено прекъсване линия