Запуск программы в режиме ядра запрещает использование стандартной библиотеки C, поскольку единственное, с чем связана ваша программа, — это само ядро. Поэтому мне разрешено использовать функции, определенные в ядре. Но само ядро — это программа, написанная на C и скомпилированная для определенной архитектуры. И она не должна использовать стандартную библиотеку C, но она также не должна использовать никаких драйверов, поскольку драйверы — это загружаемые модули. Поэтому мой вопрос: какие фактические функции C используются при написании ядра? Как можно взаимодействовать с оборудованием не через ядро? Не говорите мне смотреть исходники, это слишком следующий уровень для меня, TY.
решение1
Ядро Unix традиционно включает в себянекоторыйКод на языке ассемблера. Я давно не смотрел его исходный код, но подозреваю, что это все еще правда.
ВидетьКак на самом деле драйвер взаимодействует с аппаратным устройством? для обзора этой темы. Ответы на этот вопрос обсуждают два типа компьютерной архитектуры. В системе, которая использует порт-отображенный ввод-вывод (PMIO), ядродолженбыть написаны частично на языке ассемблера — хотя вы можете обойтись парой очень коротких процедур. В системе, которая использует ввод-вывод с отображением в памяти (MMIO), даже драйверы устройств могут быть написаны полностью на C. Все, что им нужно сделать, это объявить указатель, установить его равным виртуальному адресу устройства, а затем использовать его для управления устройством, как если бы оно обращалось к памяти.
решение2
Не все драйверы являются загружаемыми модулями, возможность загрузки — это просто опция, но некоторые важные драйверы не загружаются динамически, они являются частью ядра.
решение3
Ядро статически воспроизводит внутри себя целый ряд функциональных возможностей, предоставляемых libc.
Как и в программировании на языке C в пользовательском режиме, функция может быть определена в одном модуле компиляции, а другой модуль может просто ссылаться на нее (обычно через заголовочный файл), компилятор сделает ее неопределенной ссылкой, а компоновщик свяжет ее с модулем компиляции, который фактически предоставляет символ.
Загрузка модулей ядра работает по тому же принципу, что идинамическая загрузкаи это описано здесь: http://www.tldp.org/LDP/tlk/modules/modules.html