Разработка ядра Linux | страница 78
Системные вызовы, конечно, имеют определенное поведение. Например, системный вызов >getpid()
определен для того, чтобы возвращать целочисленное значение, равное значению идентификатора >PID
текущего процесса. Реализация этой функции в ядре очень проста.
>asmlinkage long sys_getpid(void) {
> return current->tgid;
>)
Следует заметить, что в определении ничего не говорится о способе реализации. Ядро должно обеспечить необходимую функциональность системного вызова, но реализация может быть абсолютно свободной, главное, чтобы результат был правильный. Конечно, рассматриваемый системный вызов в действительности является таким же простым, как и показано, и существует не так уж много различных вариантов для его реализации (на самом деле более простого метода не существует)[27].
Даже из такого примера можно сделать пару наблюдений, которые касаются системных вызовов. Во-первых, следует обратить внимание на модификатор >asmlinkage
в объявлении функции. Это волшебное слово дает компилятору информацию о том, что обращение к аргументам этой функции должно производиться только через стек. Для всех системных вызовов использование этого модификатора является обязательным. Во-вторых, следует обратить внимание, что системный вызов >getpid()
объявлен в ядре, как >sys_getpid()
. Это соглашение о присваивании имен используется для всех системных вызовов операционной системы Linux: системный вызов >bar()
должен быть реализован с помощью функции >sys_bar()
.
Номера системных вызовов
Каждому системному вызову операционной системы Linux присваивается номер системного вызова (syscall number). Этот уникальный номер используется для обращения к определенному системному вызову. Когда процесс выполняет системный вызов из пространства пользователя, процесс не обращается к системному вызову по имени.
Номер системного вызова является важным атрибутом. Однажды назначенный номер не должен меняться никогда, иначе это нарушит работу уже скомпилированных прикладных программ. Если системный вызов удаляется, то соответствующий номер не может использоваться повторно. В операционной системе Linux предусмотрен так называемый "не реализованный" ("not implemented") системный вызов — функция >sys_ni_syscall()
, которая не делает ничего, кроме того, что возвращает значение, равное >-ENOSYS
, — код ошибки, соответствующий неправильному системному вызову. Эта функция служит для "затыкания дыр" в случае такого редкого событии, как удаление системного вызова.