Інші два відповіді (на момент написання) говорять про перебої та ІДТ. Це правильно, однак у сучасному процесорі Intel-esque не менше трьох способів викликати ядро.
Метод №1: Переривання.
Це пояснено вище. Ви встановлюєте запис у таблиці дескрипторів переривання / вектор переривання, а потім виконуєте програмне переривання для введення в ядро.
Основна перевага цього методу полягає в тому, що типове ядро потрібно мати можливість в будь-якому разі обробляти переривання, і воно працює на архаїчному обладнання.
Спосіб №2: Ворота викликів.
Ворота виклику - це особливий вид селекторного вибору. Ціль виклику потрібно завантажити в глобальну або локальну таблицю дескрипторів сегмента (GDT та LDT відповідно). Якщо потім виконувати вказівку віддаленого виклику, використовуючи ворота виклику як сегмент (зміщення дзвінка ігнорується), це дозволяє викликати більш привілейований код. Ворота викликів надзвичайно гнучкі; архітектура IA-32 має чотири рівні привілеїв, а ворота виклику дозволяють вам телефонувати на будь-якому рівні.
Я не вірю, що Linux ніколи не використовував ворота викликів, але Windows 95 зробив. Послуги ядра Win95 ( krnl386.exe
і kernel.dll
) фактично працювали в режимі користувача (кільце 3). Найвищий рівень привілеїв (дзвінок 0) використовувався лише для драйверів та мікроядер, які виконували лише комутацію процесу. Виклик драйверів здійснювався за допомогою воріт викликів. Це дозволило застарілому 16-бітовому коду (якого було багато!) Використовувати драйвери Win95 просто за допомогою стандартного дальнього виклику, як і завжди.
Недостатній захист таблиці глобальних дескрипторів став причиною декількох подвигів Windows 95, яким вдалося встановити власні ворота викликів, записавши на пам'ять.
Спосіб №3: SYSCALL / SYSRET та SYSENTER / SYSEXIT
Це два набори інструкцій, самостійно винайдені AMD та Intel, але вони по суті роблять те саме. SYSCALL / SYSRET вийшов першим і був лише AMD, SYSENTER / SYSEXIT був Intel, але AMD реалізує це зараз. Тому я опишу SYSENTER / SYSEXIT.
На відміну від воріт виклику, SYSENTER може використовуватися лише для передачі на дзвінок 0 і може передаватися лише в одне місце. Однак, вона має перевагу в надзвичайно низькій затримці, оскільки на відміну від дзвінка або переривання, він не торкається стека.
Місце передачі встановлюється за допомогою трьох конкретних моделей регістрів: один для інформації про сегмент і один для вказівника інструкції та вказівника стека коду ядра. Оскільки нічого не «штовхається» на стек, код режиму користувача відповідає за те, щоб сказати ядро, куди слід повернутися, передавши покажчик повернення інструкції та покажчик стека в регістри. Ядро відповідає за відновлення покажчика стека, а інструкція SYSEXIT відновлює покажчик інструкцій.
Детальна інформація про інструкції SYSENTER та SYSEXIT.