Документация по системным вызовам
Убедитесь, что у вас установлены инструменты разработчика XCode для руководств UNIX для Mac OS X, а затем запустите man 2 intro
в командной строке.Для получения списка системных вызовов вы можете использовать syscall.h (который полезен для номеров системных вызовов) или запустить man 2 syscalls
.Затем, чтобы посмотреть каждый конкретный системный вызов, вы можете запустить man 2 syscall_name
, то есть для чтения, вы можете запустить man 2 read
.
Справочные страницы UNIX являются исторически значимой справочной документацией для систем UNIX.Практически любая низкоуровневая функция или системный вызов POSIX будет документирована с использованием их, а также большинства команд.В разделе 2 рассматриваются только системные вызовы, и поэтому, когда вы запускаете man 2 pagename
, вы запрашиваете man-страницу в разделе системных вызовов.В разделе 3 также рассматриваются библиотечные функции, поэтому вы можете запустить man 3 sprintf
в следующий раз, когда захотите прочитать о sprintf.
Как библиотеки C связаны с системными вызовами
Что касается того, как библиотеки C реализуют свою функциональность, обычно они создают все поверх системных вызовов, особенно в UNIX-подобных операционных системах.malloc внутренне использует mmap () или brk () на многих платформах, чтобы получить реальную память для вашего процесса, а функции ввода-вывода часто используют буферы с вызовами чтения, записи.Если есть какой-то другой механизм или библиотека, обеспечивающая необходимую функциональность, они могут также использовать их вместо этого (то есть некоторые библиотеки C для DOS могут использовать прямые прерывания BIOS вместо вызова только прерываний DOS, тогда как библиотеки C для Windows могут использовать Win32 APIзвонки).
Зачастую только подмножеству библиотечных функций потребуются системные вызовы или базовые механизмы, которые должны быть реализованы, поскольку остальная часть может быть записана в терминах этого подмножества.
Чтобы на самом деле узнать, что происходит с вашей конкретной реализацией, вы должны исследовать, что происходит в отладчике (просто продолжайте входить во все вызовы функций), или просмотреть исходный код библиотеки C, которую вы используете.
Как ваш код C с использованием библиотек C связан с машинным кодом
В вашем вопросе вы также предложили:
C code -> C compiler -> kernel calls / asm -> assembler -> machine binary
Это объединяет два очень разныхконцепции.Функции и вызовы функций поддерживаются на уровне машинного кода и сборки, поэтому ваш код на C имеет прямое отображение на машинный код:
C code -> C compiler -> Assembler -> Linker -> Machine Binary
То есть компилятор переводит ваши вызовы функций в C в вызовы функцийв Assembly и системные вызовы в C для системных вызовов в Assembly.
Однако на большинстве платформ этот машинный код содержит ссылки на общие библиотеки и функции в этих библиотеках, поэтому ваш машинный код может иметь функцию, которая вызывает другие функции.из общей библиотеки.Затем ОС загружает машинный код этой общей библиотеки (если он еще не загружен для чего-то другого), а затем запускает машинный код для функции библиотеки.Затем, если эта библиотечная функция вызывает системные вызовы через прерывания, ядро получает запрос на системный вызов и выполняет низкоуровневые операции непосредственно с аппаратным обеспечением или BIOS.
Таким образом, в ОС защищенного режима ваш машинный код может бытьрассматривается как выполнение следующих действий:
<----------+
|
Function call to -> Other function calls --+
or -> System calls to -> Direct hardware access (inside kernel)
or -> BIOS calls (inside kernel)
Конечно, вы можете также вызывать системные вызовы непосредственно в вашей программе, пропуская необходимость в каких-либо библиотеках, но если вы не пишете свою собственную библиотеку, обычно естьочень мало нужно сделать это.Если вам нужен доступ даже более низкого уровня, вы должны написать код уровня ядра, такой как драйверы или подсистемы ядра.