Разработка ядра Linux | страница 80
Определение необходимого системного вызова
Простой переход в пространство ядра сам по себе не является достаточным, потому что существует много системных вызовов, каждый из которых осуществляет переход в режим ядра одинаковым образом. Поэтому ядру должен передаваться номер системного вызова.
Для аппаратной платформы x86 номер системного вызова сохраняется в регистре процессора >eax
перед тем, как вызывается программное прерывание. Обработчик системных вызовов после этого считывает это значение из регистра >eax
. Для других аппаратных платформ выполняется нечто аналогичное.
Функция >system_call()
проверяет правильность переданного номера системного вызова путем сравнения его со значением постоянной >NR_syscalls
. Если значение номера больше или равно значению >NR_syscalls
, то функция возвращает значение >-ENOSYS
. В противном случае вызывается соответствующий системный вызов следующим образом:
>call *sys_call_table(,%eax,4)
Так как каждый элемент таблицы системных вызовов имеет длину 32 бит (4 байт), то ядро умножает данный номер системного вызова на 4 для получения нужной позиции в таблице системных вызовов (рис. 5.2).
Рис. 5.2. Запуск обработчика системных вызовов и выполнение системного вызова
Передача параметров
В дополнение к номеру вызова, большинство системных вызовов требует передачи им одного или нескольких параметров. Во время перехвата исключительной ситуации пространство пользователя должно каким-либо образом передать ядру эти параметры. Самый простой способ осуществить такую передачу — это сделать по аналогии с передачей номера системной функции: параметры хранятся в регистрах процессора. Для аппаратной платформы x86 регистры >ebx
, >ecx
, >edx
, >esi
, >edi
содержат соответственно первые пять аргументов. В случае редких ситуаций с шестью или более аргументами, используется один регистр, который содержит указатель на память пространства пользователя, где хранятся все параметры.
Возвращаемое значение также передается в пространство пользователя через регистр. Для аппаратной платформа x86 оно хранится в регистре >eax
.
Реализация системных вызовов
Реализация системного вызова в ОС Linux не связана с поведением обработчика системных вызовов. Добавление нового системного вызова в операционной системе Linux является сравнительно простым делом. Тяжелая работа связана с разработкой и реализацией самого системного вызова. Регистрация его в ядре проста. Давайте рассмотрим шаги, которые необходимо предпринять, чтобы написать новый системный вызов в операционной системе Linux.