Что такое системный вызов Linux?

What Is Linux System Call



Прежде чем мы углубимся в определение системного вызова Linux и исследуем детали его выполнения, лучше всего начать с определения различных программных уровней типичной системы Linux.

Ядро Linux - это специализированная программа, которая загружается и работает на самом низком доступном уровне на вашем оборудовании. Его задача - организовать все, что работает на компьютере, включая обработку событий клавиатуры, диска и сети, чтобы предоставить временные интервалы для параллельного выполнения нескольких программ.







Когда ядро ​​выполняет программу пользовательского уровня, оно виртуализирует пространство памяти, чтобы программы считали себя единственным процессом, выполняющимся в памяти. Этот защитный пузырь аппаратной и программной изоляции повышает безопасность и надежность. Непривилегированное приложение не может получить доступ к памяти, принадлежащей другим программам, и если эта программа выйдет из строя, ядро ​​завершится, чтобы не нанести вред остальной системе.



Преодоление барьера с помощью системных вызовов Linux

Этот уровень изоляции между непривилегированными приложениями обеспечивает отличную границу для защиты других приложений и пользователей в системе. Однако без какого-либо способа взаимодействия с другими элементами компьютера и внешнего мира программы ничего бы не смогли сделать.



Чтобы облегчить взаимодействие, ядро ​​обозначает программный шлюз, который позволяет запущенной программе запрашивать ядро ​​действовать от ее имени. Этот интерфейс известен как системный вызов.





Поскольку Linux следует философии UNIX, согласно которой все является файлом, многие функции могут быть выполнены путем открытия и чтения или записи файла, который может быть устройством. В Windows, например, вы можете использовать функцию CryptGenRandom для доступа к случайным байтам. Но в Linux это можно сделать, просто открыв файл / dev / urandom и прочитав из него байты, используя стандартные системные вызовы ввода / вывода файлов. Это важное отличие позволяет упростить интерфейс системного вызова.

Тонкая обертка для вафель

В большинстве приложений системные вызовы не выполняются напрямую к ядру. Практически все программы связаны в стандартной библиотеке C, которая обеспечивает тонкую, но важную оболочку для системных вызовов Linux. Библиотека проверяет, скопированы ли аргументы функции в правильные регистры процессора, а затем выполняет соответствующий системный вызов Linux. Когда данные получены от вызова, оболочка интерпретирует результаты и возвращает их обратно в программу согласованным способом.



За кулисами

Каждая функция в программе, которая взаимодействует с системой, в конечном итоге переводится в системный вызов. Чтобы увидеть это в действии, давайте начнем с базового примера.

пустотаглавный() {
}

Это, вероятно, самая простая программа на языке C, которую вы когда-либо видели. Он просто получает контроль через основную точку входа, а затем выходит. Он даже не возвращает значения, поскольку main определен как void. Сохраните файл как ctest.c и давайте скомпилируем его:

gcc ctest.c -ctest

После компиляции мы видим размер файла 8664 байта. Он может незначительно отличаться в вашей системе, но должен быть около 8 КБ. Это много кода для входа и выхода! Причина 8k в том, что включена среда выполнения libc. Даже если мы уберем символы, их все равно будет чуть больше 6 тысяч.

В еще более простом примере мы можем сделать системный вызов Linux для выхода, а не зависеть от среды выполнения C, которая сделает это за нас.

пустота_Начните() {
как м('movl $ 1,% eax;'
'xorl% ebx,% ebx;'
'int $ 0x80');
}

Здесь мы перемещаем 1 в регистр EAX, очищаем регистр EBX (который в противном случае содержал бы возвращаемое значение), затем вызываем прерывание системного вызова Linux 0x80 (или 128 в десятичном виде). Это прерывание заставляет ядро ​​обработать наш вызов.

Если мы скомпилируем наш новый пример с именем asmtest.c, вычеркнем символы и исключим стандартную библиотеку:

gcc-s-nostdlib asmtest.c -о asmtest

мы получим двоичный файл размером менее 1 КБ (в моей системе это 984 байта). Большая часть этого кода - это исполняемые заголовки. Теперь мы вызываем прямой системный вызов Linux.

Для всех практических целей

Практически во всех случаях вам никогда не придется выполнять прямые системные вызовы в ваших программах на языке C. Однако, если вы используете язык ассемблера, может возникнуть необходимость. Однако при оптимизации лучше всего позволить функциям библиотеки C выполнять системные вызовы и иметь только ваш критически важный для производительности код, встроенный в директивы сборки.

Как программировать учебные пособия по системному вызову

Список всех системных вызовов

Если вы хотите увидеть список всех доступных системных вызовов для Linux, вы можете проверить эти справочные страницы: Полный список системных вызовов на LinuxHint.com, filippo.io/linux-syscall-table/ и или syscalls.kernelgrok.com