Я прочитал несколько параграфов в LKD 1 и я просто не могу понять содержание ниже:
Доступ к системному вызову из пользовательского пространства
Как правило, библиотека C обеспечивает поддержку системных вызовов. Пользовательские приложения могут использовать прототипы функций из стандартных заголовков и связываться с библиотекой C, чтобы использовать ваш системный вызов (или библиотечную процедуру, которая, в свою очередь, использует ваш вызов syscall). Однако, если вы просто написали системный вызов, вряд ли glibc уже поддерживает его!
К счастью, Linux предоставляет набор макросов для переноса доступа к системным вызовам. Он устанавливает содержимое регистра и выдает инструкции об удержании. Эти макросы называются
_syscalln()
, гдеn
находится между нулем и шестью. Число соответствует количеству параметров, переданных в syscall, потому что макрос должен знать, сколько параметров ожидать и, следовательно, нажимать на регистры. Например, рассмотрим системный вызовopen()
, определенный какlong open(const char *filename, int flags, int mode)
Макрос syscall для использования этого системного вызова без явной поддержки библиотеки будет
#define __NR_open 5 _syscall3(long, open, const char *, filename, int, flags, int, mode)
Затем приложение может просто вызвать
open()
.Для каждого макроса есть 2 + 2 & times; n параметров. Первый параметр соответствует типу возврата в syscall. Второй - это имя системного вызова. Далее следует тип и имя для каждого параметра в порядке системного вызова. Определение
__NR_open
находится в<asm/unistd.h>
; это номер системного вызова. Макрос_syscall3
расширяется в C-функцию с встроенной сборкой; сборка выполняет шаги, описанные в предыдущем разделе, чтобы направить номер и параметры системного вызова в правильные регистры и выдать прерывание программного обеспечения для ловушки в ядро. Размещение этого макроса в приложении - это все, что требуется для использования системного вызоваopen()
.Пусть напишите макрос, чтобы использовать наш великолепный новый системный вызов
foo()
, а затем напишите некоторый тестовый код, чтобы продемонстрировать наши усилия.#define __NR_foo 283 __syscall0(long, foo) int main () { long stack_size; stack_size = foo (); printf ("The kernel stack size is %ld\n", stack_size); return 0; }
Что означает приложение может просто вызвать open()
?
Кроме того, для последнего фрагмента кода, где есть объявление foo()
? И как я могу сделать этот кусок кода компилируемым и исполняемым? Какие файлы заголовков мне нужно включить?
__________
1 Linux Kernel Development, Роберт Лав.
PDF файл на wordpress.com (см. стр. 81); Результат Google Книги.