Что такое заголовки ядра, которые можно использовать в пользовательском пространстве? Отличаются ли их сигнатура или интерфейс от заголовков в разных каталогах?

Что такое заголовки ядра, которые можно использовать в пользовательском пространстве? Отличаются ли их сигнатура или интерфейс от заголовков в разных каталогах?

Это может быть невнятный вопрос о заголовках ядра, так как у меня нет четкого понимания о них, где и как они используются. Я думаю, что это может быть отклонено. Мой вопрос состоит из 3 частей:

  1. Я думаю, что заголовки ядра предоставляют интерфейс, чтобы другие части ядра, например модули, могли их использовать. Это мои книжные знания. Я не видел и не находил кода, который использовал бы заголовки ядра (буду признателен, если кто-нибудь укажет мне на него). Можно ли его использовать и в пользовательском пространстве? Буду признателен за любой пример кода.

  2. Я обнаружил, что использование make headers_installзаголовков ядра выставляется для пользовательского пространства, но в то же время не рекомендуется использовать заголовки ядра в пользовательском пространстве. Если это не рекомендуется, то какой смысл выставлять его в пользовательское пространство?

  3. Согласноэтотиэтот, файлы заголовков ядра (файлы .h) должны находиться в 3 местах: a. /usr/include/linux/kernel.hкоторое предназначено для пользовательского пространства b. /lib/modules/$(uname -r)/build/include/linux/sched.hкоторое является внешними модулями c. /usr/src/...которое используется для модулей ядра Означает ли это, что файлы заголовков в разных каталогах имеют разное назначение или разный интерфейс или сигнатуру? Другими словами, имеет ли #include <linux/xyz.h> код в пользовательском пространстве другое значение, чем #include <linux/xyz.h>в модуле ядра? Также является ли внешний модуль тем же самым, что и модуль ядра?

Спасибо.

решение1

Добро пожаловать на Unix и Linux StackExchange!

Да, заголовочные файлы ядра предоставляют интерфейс для других частей ядра - в этом вы полностью правы. Они также включают определения для интерфейса между ядром и пользовательским пространством - но обычно "сырой" интерфейс ядра не используется напрямую, а через библиотеку C (часто glibc).

Интерфейс userspace-kernel может включать несколько версий конкретного системного вызова по причинам обратной совместимости. При выполнении системного вызова через библиотеку C все приложения получают одну и ту же версию фактического системного вызова, и, таким образом, гарантируют единообразное поведение. Кроме того, когда соответствующая часть интерфейса ядра обновляется, вам нужно будет обновить только библиотеку C, чтобы воспользоваться новыми функциями.

(Например, когда time_t расширяется до 64-бит в 32-битных архитектурах, чтобы избежать проблемы Y2K38, библиотека C может перейти на постоянное использование 64-битной версии интерфейса ядра, но иметь настраиваемое в пользовательском пространстве сопоставление для приложений, которые все еще используют 32-битную версию. В этот момент функции, использующие 32-битный time_t, могут быть признаны устаревшими и удалены из ядра, а библиотека C может предоставить лучшие обходные пути для устаревших приложений, которые все еще используют 32-битный тип.)

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

Заголовки /usr/include/linux/обычно поставляются с пакетом заголовков разработки библиотеки C и описывают версию ядра, для которой была скомпилирована библиотека C. Это то, что обычно нужно разработчику приложений пользовательского пространства.

/lib/modules/$(uname -r)/buildчасто является символической ссылкой на /usr/src/...место, где хранятся заголовки или полный исходный код фактической работающей версии ядра. Он используется при компиляции внешних (т. е. сторонних) модулей ядра, т. е. модулей ядра из источников, которые не интегрированы в основной исходный код ядра. Эти заголовки включают необходимые сигнатуры версий API ядра, чтобы модули могли использовать внутренние API ядра, специфичные для версии.

Связанный контент