Вход в системный вызов и выход из него
Приложения, "родные" для Linux1, могут делать системные вызовы двумя различными способами:
- выполнив ассемблерную инструкцию int $0x8о; в ранних версиях ядра Linux это был единственный способ переключения из режима пользователя в режим ядра;
- выполнив ассемблерную инструкцию sysenter, появившуюся в микропроцессорах Intel Pentium II; эта инструкция теперь поддерживается ядром Linux .
Аналогичным образом, ядро может выйти из системного вызова (и тем самым вернуть процессор в режим пользователя) двумя способами:
- выполнив ассемблерную инструкцию iret;
- выполнив ассемблерную инструкцию sysexit, появившуюся в микропроцессорах Intel Pentium II, вместе с инструкцией sysenter.
Однако поддержка двух разных способов входа в ядро является не таким простым делом, как может показаться:
- ядро должно поддерживать как старые библиотеки, в которых используется только инструкция int $0x80, так и новые, в которых используется и инструкция sysenter;
- стандартная библиотека, в которой применяется только инструкция sysenter, должна уметь работать со старыми версиями ядра, которые поддерживают только инструкцию int $0x80;
- ядро и стандартная библиотека должны уметь работать как на старых процессорах, не имеющих инструкции sysenter, так и на новых, у которых она есть.
Мы увидим, как Linux справляется с этими трудностями, в разд. "Выполнение системного вызова с помощью инструкции sysenter ” далее в этой главе.
Выполнение системного вызова с помощью инструкции int $0x80.
"Традиционным" способом выполнения системного вызова является выполнение ассемблерной инструкции int, Вектор 128 (0x80 в шестнадцатеричной системе счисления) ассоциирован с точкой входа в ядро. Функция trap init о, вызываемая на этапе инициализации ядра, устанавливает запись таблицы дескрипторов прерываний, соответствующую вектору 128, следующим образом:
set_system_gate(0x80, &system_call);
Этот код загружает в поля дескриптора шлюза следующие значения:
- селектор сегмента — селектор сегмента кода ядра kernel cs;
- смещение — указатель на обработчик системного вызова system caii ;
- тип — число 15, означающее, что исключение имеет тип Trap, а соответствующий обработчик не отключает маскируемые прерывания;
- DPL (Descriptor Privilege Level, уровень привилегий дескриптора) — число 3, означающее, что процессам режима пользователя разрешено вызывать обработчик исключений Таким образом, когда процесс режима пользователя выдает инструкцию int $0x80, процессор переключается в режим ядра и приступает к выполнению инструкций, начиная с адреса system caii.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница