Ядро Linux в комментариях




System_call - часть 2


Читает указатель на текущую задачу из регистра ЕВХ. Это одно из немногих мест, где используется макрос, отвечающий за выполнение данных действий, GET_CURRENT (строка ). В подавляющем большинстве кода применяется функция get_current (строка ).

Начиная с этого места, выражения наподобие foo(%ebx) или foo(%esp) представляют собой код доступа к полям структуры, представляющей текущий процесс (struct task_struct в строке ), которая подробно рассматривается в . (Чтобы быть более точным, смещения относительно %ebx находятся в struct task_struct, а смещения относительно %esp — в struct pt_regs, связанной с struct task_struct. Однако, существующие различия здесь не важны.)

Превысил ли номер системного вызова (в регистре ЕАХ) свое максимальное значение? (Значение ЕАХ обрабатывается здесь как беззнаковое, поэтому оно не может быть отрицательным.) Если превышение имеет место, выполняется переход на badsys (строка ).

Отслеживаются ли системные вызовы? Программы, подобные strace, обеспечивают трассировку для особо заинтересованных разработчиков, а также дополнительную отладочную информацию — вы сможете сказать гораздо больше о такого рода программах после того, как с их помощью проследите за выполнением системных вызовов. В случае, если системные вызовы таки отслеживаются, управление передается tracesys (строка ).

Вызов системной функции. Здесь выполняются многие вещи. Во-первых, ничего не делающий макрос SYMBOL_NAME просто заменяется текстом его аргументов, поэтому его можно проигнорировать. sys_call_table определяется в конце файла arch/i386/kernel/entry.S, начиная со строки . Здесь расположена таблица указателей на функции ядра, которые реализуют разнообразные системные вызовы.

Второй набор скобок в строке содержит аргументы, разделенные запятыми (первый аргумент — пустой); все это необходимо для индексирования элементов в массиве. Разумеется, индексируется массив sys_call_table; он-то и носит название смещения. Три аргумента представляют базовый адрес массива, индекс (ЕАХ, в котором хранится номер системного вызова) и размер, который суть количество байт, приходящихся на каждый элемент массива (в данном случае 4). Поскольку базовый адрес массива пуст, он трактуется как 0, тем не менее, он добавляется к адресу смещения sys_call_table, что в конечном итоге приводит к тому, что sys_call_table рассматривается в качестве базового адреса массива. Данная строка эквивалентна следующему выражению на С:

/* Вызов функции в массиве функций. */ (sys_call_table[eax]) ();




Содержание  Назад  Вперед