Разное

Модули ядра linux: Пишем простой модуль ядра Linux / Хабр

Содержание

Модули ядра Linux — Losst

Как вы знаете из статьи что такое ядро Linux, ядро является монолитным. Это значит, что весь исполняемый код сосредоточен в одном файле. Такая архитектура имеет некоторые недостатки, например, невозможность установки новых драйверов без пересборки ядра. Но разработчики нашли решение и этой проблеме, добавив систему модулей.

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

Содержание статьи:

Модули ядра Linux

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

Модули ядра Linux собираются только под определенную версию ядра, есть способ запуска модуля независимо от версии ядра, если они совместимы с помощью dkms, но об этом мы поговорим позже.

Находятся все модули в папке /lib/modules/. Учитывая, что модули рассчитаны только для определенной версии ядра, то в этой папке создается отдельная подпапка, для каждой установленной в системе версии ядра. В этой папке находятся сами модули и дополнительные конфигурационные файлы, модули отсортированы по категориям, в зависимости от назначения например:

ls /lib/modules/5.4.0.45-generic/kernel/

Перед тем как переходить к практике, давайте коротко рассмотрим основные команды для управления модулями.

  • lsmod — посмотреть загруженные модули
  • modinfo — информация о модуле
  • insmod — загрузить модуль
  • rmmod
    — удалить модуль

Работа с модулями ядра Linux выполняется, в основном, с помощью этих команд, но могут использовать и другие.

Все модули

Такая задача возникает нечасто, но если вы хотите посмотреть все установленные модули ядра Linux в системе, делается очень просто. Все модули расположены в папке /lib/modules, а поэтому очень просто вычислить их все одной командой, или даже просто зайти в папку файловым менеджером и посмотреть.

В Ubuntu команда будет выглядеть вот так:

dpkg -S *.ko | grep /lib/modules

Можно смастерить такую конструкцию с помощью find:

find /lib/modules -name *.ko

Можем искать только для текущего ядра:

find /lib/modules/$(uname -r) -name *.ko

Также, все модули записаны в конфигурационном файле /lib/modules/modules.aliases, поэтому мы можем просто посмотреть его содержимое:

modprobe -c

Если хотим проверить установлен ли определенный модуль ядра Linux, отфильтруем вывод любой из команд с помощью grep:

find /lib/modules -name *. ko | grep vbox

Что загружено?

Все информация о загруженных модулях хранится в файле /proc/modules, мы можем ее вывести командой:

cat /proc/modules

Но для этого дела есть более цивилизованные методы. Это утилита lsmod и modinfo. Чтобы посмотреть загруженные модули ядра linux выполните:

sudo lsmod

Удобно проверять загружен ли модуль с помощью grep:

sudo lsmod | grep vbox

А более подробную информацию о каждом модуле можно получить с помощью утилиты modinfo:

modinfo fuse

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

Запуск модулей ядра

Загрузить модуль ядра Linux можно с помощью команд modprobe или insmod. Например, загрузим модуль vboxdrv

sudo modprobe vboxdrv

Чтобы загрузить модуль ядра linux с помощью insmod необходимо передать адрес файла модуля:

sudo insmod /lib/modules/4.1.20-11-default/weak-updates/misc/vboxdrv.ko

Напоминаю, что его можно узнать с помощью команды modinfo. Запуск модуля ядра Linux предпочтительно выполнять с помощью modprobe, поскольку эта команда не только находит файл модуля в файловой системе, но и загружает все его зависимости.

Удаление модулей ядра

Здесь аналогично две команды — modprobe, позволяет удалить модуль если ей передать опцию -r, а также есть команда rmmod. Начнем с modprobe:

sudo modprobe -r vboxdrv

Другая команда в этом случае выглядит немного проще:

sudo rmmod vboxdrv

Если вы получили ошибку во время выгрузки модуля, например: rmmod: ERROR: Module vboxdrv is in use by: vboxnetadp vboxnetflt, значит он еще используется другими модулями, и сначала нужно выгрузить их. В данном случае это vboxnetadp и vboxnetflt. Правильно отработавшая команда не должна ничего возвращать.

rmmod vboxnetadp vboxnetflt

Блокирование загрузки модулей

Иногда, во время загрузки системы для используемых нами устройств, загружаются не те модули ядра Linux, они либо не поддерживают нужную функциональность либо конфликтуют с другими модулями. Ярким примером можно назвать загрузку драйвера b43 вместо brcmsmac для беспроводных адаптеров Broadcom. Чтобы решить эту проблему вы можете добавлять модули в черный список. Для этого достаточно добавить одну строчку в файл /etc/modprobe.d/blacklist.conf:

sudo vi /etc/modprobe.d/blacklist.conf 

blacklist b43

Этот код добавит в черный список модуль b43.

Автозагрузка модулей

Кроме чёрного списка существует отдельный каталог, в котором можно настроить автоматическую загрузку модулей при старте системы. Это /etc/modules.load. d/. Этот каталог тоже содержит конфигурационные файлы с расширением *.conf, в которых перечислены все модули, которые надо загружать при старте системы. Для добавления своего модуля можно воспользоваться файлом /etc/modules.load.d/modules.conf. Например, добавим brcmsmac:

sudo vi /etc/modules.load.d/modules.conf

brcmsmac

Установка модулей ядра Linux

Собранные для этой версии ядра модули вы можете просто скопировать в нужную папку, собственно, мы так и поступаем, когда собираем ядро из исходников. Но с проприетарными драйверами и другими внешними драйверами, не поставляемыми в комплекте с ядром дело обстоит иначе. Эти модули поддерживают несколько версий ядра, но для их установки используется специальная технология — DKMS (Dynamic Kernel Module Support). Причем модуль, установленный таким образом один раз, будет пересобираться для каждой новой версии ядра автоматически. Обычно такие модули поставляются в виде пакетов, которые устанавливаются как и все другие приложения пакетным менеджером. Ручная установка модулей с помощью dkms выходит за рамки данной статьи.

Выводы

Скорее всего, вам редко придется возиться с этими модулями. Но работа с модулями ядра будет необходима, если ваш дистрибутив не поддерживает аппаратное обеспечение вашего устройства из коробки, а также когда вы работаете со сторонним программным обеспечением, таким как VirtualBox, Vmware и т д. Но очень полезно знать как обращаться с модулями, когда вам нужно добавить или удалить их. Даже если у вас нет необходимости в этом сейчас, вы можете протестировать, как все работает, чтобы быть вооруженным потом.

Загружаемые модули ядра Linux — ИТ Проффи

Системное ядро Linux способно к модификации за счёт расширения функциональных возможностей. Это достигается несколькими способами, но самым оптимальным является подключение загружаемых модулей ядра. Этот способ позволяет вести разработку нужного функционала для ядра независимо от самого ядра. Процесс подключения модулей к ядру, как правило, никаких трудностей не вызывает (в отличие от конфигурирования и компиляции). Если конечно модули разработаны грамотно и должным образом протестированы. Системным администраторам стоит помнить, что если нужно «расширить» ядро под требуемый функционал, то в первую очередь следует воспользоваться вариантом в виде загружаемых модулей ядра.

Содержание

  1. Зачем нужны загружаемые модули ядра?
  2. Особенности работы с модулями ядра Linux
  3. Загрузка и подключение модулей ядра

Зачем нужны загружаемые модули ядра?

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

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

Среди всех UNIX-подобных операционных систем наиболее приспособленными для работы с загружаемыми модулями ядра (а также поддерживающими самый широкий спектр оборудования и аппаратных платформ, в том числе и новинок) являются системы Linux и Solaris.

Особенности работы с модулями ядра Linux

Как уже было отмечено, Linux способна предоставить системным администраторам довольно широкие возможности для работы с загружаемыми модулями ядра. Так например в Linux любой системный компонент возможно сделать загружаемым модулем за исключением двух системных объектов: драйвера устройства, используемого для работы корневой файловой системы (ФС) и драйвера мыши типа PS/2.

Все загружаемые модули хранятся (и устанавливаются) в каталог /lib/modules/версия_ядра. Здесь версия_ядра может определена командой:

$ uname -r

Для то, чтобы получить список загруженных и используемых в данный момент модулей ядра, можно воспользоваться командой lsmod:

$ sudo lsmod
Module Size Used by
ipmi_devintf 13064 2
ipmi_si 36648 1
ipmi_msghandler 31848 2 ipmi_devintf,ipmi_si
iptable_filter 6721 0
ip_tables 21441 1 iptable_filter

Как видно из данного вывода, в системе настроена поддержка брандмауэра iptables, а также используются модули для интеллектуального управления платформой IMPI – Intelligent Platform Management Interface. В колонке «Size» указывается размер в байтах, а в колонке «Used by» (кем используется) приводится количество связей на данный модуль от других компонентов, а также список самих этих компонентов.

Даже если системное ядро было сконфигурировано и скомпилировано с настройками и комплектностью по-умолчанию, то при использовании команды lsmod, как правило будет выведен довольно длинный список модулей. Если известно точное или примерное имя модуля, который необходимо проверить (используется он или нет), то вместе с командой lsmod удобно использовать и команду grep:

$ sudo lsmod | grep amdgpu

amdgpu 3166208 92
amdchash 16384 1 amdgpu
amd_shed 24576 1 amdgpu
i2c_algo_bit 16384 1 amdgpu
amdttm 110592 1 amdgpu
amdkcl 28672 4 amdkfd,amd_shed,amdttm,amdgpu
drm_kms_helper 172032 1 amdgpu
drm 401408 24 drm_kms_helper,amdkfd,amd_shed,amdttm,amdgpu,amdkcl

В данном выводе показаны результаты для используемых ядром модулях драйвера amdgpu.

Загрузка и подключение модулей ядра

Пусть имеется загружаемый модуль ядра для некоторого устройства. Например есть файл модуля somedevice.ko для устройства somedevice. Чтобы загрузить этот модуль для ядра прямо во время работы системы следует использовать команду insmod:

$ sudo insmod /путь/к/файлу/somrdevice.kо

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

$ sudo insmod /путь/куда/somedevice.kо io=0xXXX irq=X

Для удаления модуля нужно либо перезапустить систему или указать в явном запросе выгружаемый модуль с помощью команды rmmod:

$ rmmod somedevice

Следует заметить, что несмотря на то, что команду rmmod хоть и можно использовать в любой момент времени, однако модуль может быть удалён только в случае, если с ним не связано ни одной действующей ссылки, которые указываются в столбце «Used by» вывода команды lsmod.

Чтобы каждый раз поле перезапуска системы не загружать требуемые модули, в Linux существует возможность подключать их автоматически с помощью файла /etc/modprobe.conf и соответствующей команды modprobe. Эта команда является «обёрткой» команды insmod. Она способна определять порядок загрузки и выгрузки модулей, их параметры, а также зависимости от других модулей и/или параметров. Всю эту информацию команда modprobe читает из файла /etc/modprobe.conf, который, кстати способна и сама генерировать.

Чтобы сгенерировать файл modprobe.conf в соответствии с текущим набором загруженных модулей (которые необходимо загрузить заранее), нужно использовать команду:

$ sudo modprobe -c

В результате будет создан достаточно длинный файл, содержимое которого может выглядеть примерно так:

#This file was generated by: modprobe -c

path[pcmcia]=/lib/modules/preferred
path[pcmcia]=/lib/modules/default
path[pcmcia]=/lib/modules/2.6.6
path[misc]=/lib/modules/2. 6.6

# Aliases
alias block-major-1 rd
alias block-major-2 floppy
alias char-major-4 serial
alias char-major-5 serial
alias char-major-6 lp
alias dos msdos
alias plip0 plip
alias ppp0 ppp
options ne io=x0340 irq=9

Ключевые слова path определяют расположение конкретных модулей в файловой системе, а aliases задают привязку файловых систем, сетевых протоколов, старших номеров блочных и символьных устройств к требуемому модулю.

Значения для строк options администраторы должны задавать самостоятельно, поскольку эти инструкции командой modprobe автоматически не генерируются. Например, чтобы задать для модуля устройства somedevice адрес его ввода-вывода, а также вектор прерываний, можно это сделать таким образом:

options somedevice io=0xXXX irq=X

Стоит отметить также, что для команды modprobe доступны ключевые слова install и remove, при помощи которых можно указывать команды, которые будут выполняться во время загрузки и установки модулей ядра соответственно.

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

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

06-B.4: Модули ядра — Инженерные тексты LibreText

  1. Последнее обновление
  2. Сохранить как PDF
  • Идентификатор страницы
    32707
  • ЗАДАЧИ ЭКЗАМЕНА
    1.2 При заданном сценарии установка, настройка и мониторинг модулей ядра.
    1.3 Учитывая сценарий, настройте и проверьте параметры сетевого подключения.


    4.1 Учитывая сценарий, проанализируйте свойства системы и примите соответствующие меры.

    Модули ядра — это фрагменты кода, которые можно загружать и выгружать в ядро ​​по запросу. Они расширяют функциональность ядра без необходимости перезагрузки системы. Модуль может быть настроен как встроенный или загружаемый. Чтобы динамически загружать или удалять модуль, он должен быть настроен как загружаемый модуль в конфигурации ядра.

    Использование модулей ядра дает несколько преимуществ:

    • Ядру не нужно так часто пересобирать ядро. Это экономит время и предотвращает возможность внесения ошибки при пересборке и переустановке базового ядра. Если у вас есть работающее базовое ядро, хорошо оставить его нетронутым как можно дольше.
    • Легче диагностировать системные проблемы. Ошибка в драйвере устройства, связанном с ядром, может вообще остановить загрузку системы. Также может быть очень сложно определить, какая часть базового ядра вызвала проблему.
      Однако если тот же драйвер устройства является модулем, базовое ядро ​​​​запускается и работает еще до загрузки драйвера устройства. Если система умирает после того, как базовое ядро ​​запущено и работает, легко отследить проблему до вызывающего проблемы драйвера устройства и просто не загружать этот драйвер устройства, пока проблема не будет устранена.
    • Использование модулей может сэкономить память, поскольку они загружаются только тогда, когда система их фактически использует. Все части базового ядра остаются загруженными в реальном хранилище, а не только в виртуальном.
    • Модули намного быстрее в обслуживании и отладке. То, что потребовало бы полной перезагрузки драйвера файловой системы, встроенного в ядро, можно сделать с помощью нескольких быстрых команд с использованием модулей. Можно опробовать различные параметры или даже быстро изменить код несколько раз подряд, не дожидаясь загрузки.
    • Модули, кстати, не медленнее базовых модулей ядра. Вызов любого из них — это просто ответвление к ячейке памяти, в которой он находится.

    Местоположение модуля

    Код, необходимый для создания нового ядра с включенным новым модулем или удаленными старыми модулями, обычно выглядит следующим образом: /lib/modules/$(uname -r)/kernel , хотя в некоторых дистрибутивах код находится в /usr/lib/modules/$(uname -r)/kernel . Каталоги /usr/lib и /lib — это место, где Linux хранит библиотеки объектов и общие библиотеки, необходимые для выполнения определенных команд, включая код ядра.

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

    Модули ядра Подкаталоги:

    Каталог Описание
    арка Подкаталог arch содержит весь код ядра, относящийся к конкретной архитектуре. Он имеет дополнительные подкаталоги, по одному на каждую поддерживаемую архитектуру, например, i386 и alpha.

    включает

    Хотя дистрибутивы man помещают включаемые файлы в /usr/src/$(uname -r)

    Подкаталог include содержит большинство включаемых файлов, необходимых для сборки кода ядра. Он также имеет дополнительные подкаталоги, в том числе по одному для каждой поддерживаемой архитектуры. Подкаталог include/asm — это программная ссылка на реальный каталог include, необходимый для этой архитектуры, например include/asm-i386. Чтобы изменить архитектуру, вам нужно отредактировать make-файл ядра и перезапустить программу настройки ядра Linux.
    инициализация Этот каталог содержит код инициализации ядра, и с него очень удобно начинать смотреть, как работает ядро.
    мм Этот каталог содержит весь код управления памятью. Код управления памятью для конкретной архитектуры находится в файле arch/*/mm/, например, arch/i386/mm/fault.c.
    водители Все системные драйверы устройств находятся в этом каталоге. Далее они подразделяются на классы драйверов устройств, например блочные.
    МПК Этот каталог содержит код межпроцессного взаимодействия ядра.
    модули Это просто каталог, используемый для хранения встроенных модулей.
    фс Весь код файловой системы. Далее он подразделяется на каталоги, по одному на каждую поддерживаемую файловую систему, например vfat и ext2.
    ядро ​​ Основной код ядра. Опять же, код ядра для конкретной архитектуры находится в arch/*/kernel.
    нетто Сетевой код ядра.
    библиотека Этот каталог содержит код библиотеки ядра. Код библиотеки для конкретной архитектуры можно найти в arch/*/lib/.
    сценарии Этот каталог содержит сценарии (например, сценарии awk и tk), которые используются при настройке ядра.

    Адаптировано из:
    «2. Introduction to Linux Loadable Kernel Modules» от Unlisted, проект документации Linux под лицензией CC BY-SA 3.0
     


    06-B.4: Модули ядра распространяются по лицензии CC BY-SA 3.0 и были созданы, изменены и/или курированы LibreTexts.

    1. Наверх
      • Была ли эта статья полезной?
      1. Тип изделия
        Раздел или Страница
        Лицензия
        CC BY-SA
        Версия лицензии
        3,0
        Программа OER или Publisher
        Программа ASCCC OERI
        Показать оглавление
        да
      2. Теги
          На этой странице нет тегов.

      Сборка внешних модулей — Документация ядра Linux

      В этом документе описывается, как собрать модуль ядра вне дерева.

      1. Введение

      «kbuild» — это система сборки, используемая ядром Linux. Модули должны использовать kbuild, чтобы оставаться совместимым с изменениями в инфраструктуре сборки и подобрать правильные флаги для «gcc». Функционал для построения модулей обеспечивается как в дереве, так и вне дерева. Способ построения либо аналогично, и все модули изначально разрабатываются и строятся вне дерева.

      В этом документе содержится информация, предназначенная для разработчиков, заинтересованных при построении внешних (или «внешних») модулей. Автор Внешний модуль должен предоставить make-файл, который скрывает большую часть сложности, поэтому для сборки модуля достаточно набрать «make». Это легко выполнить, и полный пример будет представлен в раздел 3.

      2. Как построить внешние модули

      Для сборки внешних модулей у вас должно быть готовое ядро. который содержит файлы конфигурации и заголовки, используемые в сборке. Кроме того, ядро ​​должно быть собрано с включенными модулями. Если ты используя дистрибутив ядра, будет пакет для ядра, которое вы работают, предоставляемые вашим дистрибутивом.

      Альтернативой является использование цели «make» «modules_prepare». Это будет убедитесь, что ядро ​​содержит необходимую информацию. Цель существует исключительно как простой способ подготовить исходное дерево ядра для создание внешних модулей.

      ПРИМЕЧАНИЕ: «modules_prepare» не будет собирать Module.symvers, даже если CONFIG_MODVERSIONS установлен; следовательно, полная сборка ядра должна быть выполняется, чтобы управление версиями модуля работало.

      2.1 Синтаксис команды

      Команда для сборки внешнего модуля:

       $ make -C  M=$PWD
       

      Система kbuild знает, что строится внешний модуль из-за опции «M=

      », указанной в команде.

      Для сборки работающего ядра используйте:

       $ make -C /lib/modules/`uname -r`/build M=$PWD
       

      Затем, чтобы установить только что построенный(е) модуль(и), добавьте цель «modules_install» в команду:

       $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install
       

      2.

      2 Опции

      ($KDIR указывает путь к исходному каталогу ядра.)

      make -C $KDIR M=$PWD

      -C $KDIR

      Каталог, в котором находится исходный код ядра. «make» фактически изменится на указанный каталог при выполнении и изменится обратно после завершения.

      M=$PWD

      Сообщает kbuild о сборке внешнего модуля. Значение, присвоенное «M», является абсолютным путем каталог, в котором находится внешний модуль (файл kbuild) располагается.

      2.3 Мишени

      При построении внешнего модуля используется только подмножество «make». цели доступны.

      make -C $KDIR M=$PWD [цель]

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

      модули

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

      modules_install

      Установить внешние модули. Расположение по умолчанию /lib/modules//extra/, но префикс может быть добавлен с помощью INSTALL_MOD_PATH (обсуждается в разделе 5).

      очистить

      Удалить все сгенерированные файлы только в каталоге модуля.

      help

      Список доступных целей для внешних модулей.

      2.4 Создание отдельных файлов

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

      Пример (Модуль foo.ko, состоит из bar.o и baz.o):

       make -C $KDIR M=$PWD bar.lst
      make -C $KDIR M=$PWD baz.o
      make -C $KDIR M=$PWD foo.ko
      make -C $KDIR M=$PWD ./
       

      3. Создание файла Kbuild для внешнего модуля

      В последнем разделе мы видели команду для создания модуля для работающее ядро. Однако на самом деле модуль не создается, потому что требуется файл сборки. В этом файле будет имя строящийся модуль (модули) вместе со списком необходимого исходного кода файлы. Файл может состоять из одной строки:

      .
       obj-m := <имя_модуля>.o
       

      Система kbuild соберет .o из .c, и после компоновки получится модуль ядра <имя_модуля>.ko. Приведенную выше строку можно поместить либо в файл «Kbuild», либо в «Makefile». Когда модуль собирается из нескольких источников, добавляется дополнительная строка. нужно перечислить файлы:

       -y := .o .o ...
       

      ПРИМЕЧАНИЕ. Дополнительная документация, описывающая синтаксис, используемый kbuild, находится в находится в файлах Makefile ядра Linux.

      В приведенных ниже примерах показано, как создать файл сборки для модуль 8123.ko, который собирается из следующих файлов:

       8123_if.c
      8123_if.h
      8123_pci.c
      8123_bin.o_shipped <= Двоичный большой двоичный объект
       

      3.

      1 Общий Makefile

      Внешний модуль всегда включает make-файл оболочки, который поддерживает сборку модуля с помощью make без аргументов. Эта цель не используется kbuild; это только для удобства. Могут быть включены дополнительные функции, такие как тестовые цели. но должен быть отфильтрован из kbuild из-за возможного имени столкновения.

      Пример 1:

       --> имя файла: Makefile
      ifneq ($(KERNELRELEASE),)
      # kbuild часть makefile
      объект-м := 8123.о
      8123-y := 8123_if.o 8123_pci.o 8123_bin.o
      еще
      # обычный make-файл
      KDIR ?= /lib/modules/`uname -r`/сборка
      по умолчанию:
              $(СДЕЛАТЬ) -C $(KDIR) M=$$PWD
      # Конкретные цели модуля
      Генбин:
              эхо "X" > 8123_bin.o_shipped
      конец
       

      Проверка KERNELRELEASE используется для разделения двух частей make-файла. В этом примере kbuild увидит только два назначения, тогда как «make» увидит все, кроме этих два задания. Это связано с двумя проходами файла: первый проход выполняется экземпляром «make», запускаемым по команде линия; второй проход осуществляется системой kbuild, которая инициируется параметризованным «make» в цели по умолчанию.

      3.2 Отдельный файл Kbuild и Makefile

      В новых версиях ядра kbuild сначала ищет файл с именем «Kbuild», и только если он не будет найден, он затем найдите make-файл. Использование файла «Kbuild» позволяет нам чтобы разделить make-файл из примера 1 на два файла:

      Пример 2:

       --> имя файла: Kbuild
      объект-м := 8123.о
      8123-y := 8123_if.o 8123_pci.o 8123_bin.o
      --> имя файла: Makefile
      KDIR ?= /lib/modules/`uname -r`/сборка
      по умолчанию:
              $(СДЕЛАТЬ) -C $(KDIR) M=$$PWD
      # Конкретные цели модуля
      Генбин:
              эхо "X" > 8123_bin.o_shipped
       

      Разделение в примере 2 сомнительно из-за простоты каждый файл; однако некоторые внешние модули используют make-файлы состоящий из нескольких сотен строк, и здесь это действительно окупается off, чтобы отделить часть kbuild от остальных.

      В следующем примере показана версия с обратной совместимостью.

      Пример 3:

       --> имя файла: Kbuild
      объект-м := 8123.о
      8123-y := 8123_if. o 8123_pci.o 8123_bin.o
      --> имя файла: Makefile
      ifneq ($(KERNELRELEASE),)
      # kbuild часть makefile
      включить Kbuild
      еще
      # обычный make-файл
      KDIR ?= /lib/modules/`uname -r`/сборка
      по умолчанию:
              $(СДЕЛАТЬ) -C $(KDIR) M=$$PWD
      # Конкретные цели модуля
      Генбин:
              эхо "X" > 8123_bin.o_shipped
      конец
       

      Здесь файл «Kbuild» включен из make-файла. Этот позволяет использовать старую версию kbuild, которая знает только make-файлы, которые будут использоваться, когда части «make» и «kbuild» разбить на отдельные файлы.

      3.3 Двоичные BLOB-объекты

      Некоторые внешние модули должны включать объектный файл в виде большого двоичного объекта. kbuild поддерживает это, но требует, чтобы файл blob был с именем <имя файла>_shipped. Когда вступают в силу правила kbuild, копия из _shipped создается с удаленным _shipped, давая нам <имя файла>. Это сокращенное имя файла можно использовать в задание на модуль.

      В этом разделе 8123_bin. o_shipped используется для собрать модуль ядра 8123.ko; он был включен как 8123_bin.o:

       8123-y := 8123_if.o 8123_pci.o 8123_bin.o
       

      Хотя нет разницы между обычным источником файлы и бинарный файл, kbuild подберет разные правила при создании объектного файла для модуля.

      3.4 Создание нескольких модулей

      kbuild поддерживает сборку нескольких модулей с помощью одной сборки файл. Например, если вы хотите собрать два модуля, foo.ko и bar.ko, строки kbuild будут такими:

       obj-m := foo.o bar.o
      foo-y := 
      бар-y := 
       

      Это так просто!

      4. Включить файлы

      В ядре файлы заголовков хранятся в стандартных местах. по следующему правилу:

      • Если заголовочный файл описывает только внутренний интерфейс модуль, то файл помещается в тот же каталог, что и исходные файлы.

      • Если заголовочный файл описывает интерфейс, используемый другими частями ядра, расположенные в разных каталогах, то файл помещается в include/linux/.

        ПРИМЕЧАНИЕ.

        Из этого правила есть два заметных исключения: подсистемы имеют свой собственный каталог в include/, например включить/scsi; и заголовки, специфичные для архитектуры, расположены под аркой/$(SRCARCH)/include/.

      4.1 Ядро включает

      Чтобы включить заголовочный файл, расположенный в include/linux/, просто используйте:

       #include 
       

      kbuild добавит параметры в «gcc», чтобы соответствующие каталоги разыскиваются.

      4.2 Один подкаталог

      Внешние модули имеют тенденцию помещать заголовочные файлы в отдельный include/ каталог, где находится их источник, хотя это не является обычным стилем ядра. Информировать kbuild о используйте либо ccflags-y, либо CFLAGS_.o.

      Используя пример из раздела 3, если мы переместили 8123_if.h в подкаталог с именем include, результирующий файл kbuild будет выглядеть так:

       --> имя файла: Kbuild
      объект-м := 8123. о
      ccflags-y := -Iinclude
      8123-y := 8123_if.o 8123_pci.o 8123_bin.o
       

      Обратите внимание, что в присваивании нет пробела между -I и путь. Это ограничение kbuild: не должно быть настоящее пространство.

      4.3 Несколько подкаталогов

      kbuild может работать с файлами, разбросанными по нескольким каталогам. Рассмотрим следующий пример:

       .
      |__ источник
      | |__ complex_main.c
      | |__ хал
      | |__ оборудованиеif.c
      | |__ включить
      | |__ аппаратное обеспечениеif.h
      |__ включить
      |__ комплекс.ч
       

      Для сборки модуля complex.ko нам понадобится следующее kbuild-файл:

       --> имя файла: Kbuild
      объект-м := комплекс.о
      комплекс-y := src/complex_main.o
      комплекс-y += src/hal/hardwareif.o
      ccflags-y := -I$(источник)/включить
      ccflags-y += -I$(src)/src/hal/include
       

      Как видите, kbuild знает, как обращаться с объектными файлами, расположенными в других каталогах. Хитрость заключается в том, чтобы указать каталог относительно местоположения файла kbuild. При этом это НЕ рекомендуется.

      Для файлов заголовков в kbuild должно быть явно указано, куда смотреть. Когда kbuild выполняется, текущим каталогом всегда является корень дерева ядра (аргумент «-C») и, следовательно, нужен абсолютный путь. $(src) предоставляет абсолютный путь указывая на каталог, где в данный момент выполняется kbuild файл находится.

      5. Установка модуля

      Модули, входящие в состав ядра, устанавливаются в каталог:

      /lib/modules/$(KERNELRELEASE)/kernel/

      И внешние модули установлены в:

      /lib/modules/$(KERNELRELEASE)/дополнительно/

      5.1 INSTALL_MOD_PATH

      Выше указаны каталоги по умолчанию, но, как всегда, некоторый уровень Возможна настройка. Префикс может быть добавлен к путь установки с использованием переменной INSTALL_MOD_PATH:

       $ make INSTALL_MOD_PATH=/frodo modules_install
      => Установите каталог: /frodo/lib/modules/$(KERNELRELEASE)/kernel/
       

      INSTALL_MOD_PATH может быть установлен как обычная переменная оболочки или, как показано выше, можно указать в командной строке, когда вызов «сделать». Это действует при установке как внутри дерева и внешние модули.

      5.2 INSTALL_MOD_DIR

      Внешние модули по умолчанию устанавливаются в каталог /lib/modules/$(KERNELRELEASE)/extra/, но вы можете размещать модули для определенной функциональности в отдельном каталог. Для этого используйте INSTALL_MOD_DIR, чтобы указать альтернативное название «extra.»:

       $ make INSTALL_MOD_DIR=gandalf -C $KDIR \
             M=$PWD modules_install
      => Установите каталог: /lib/modules/$(KERNELRELEASE)/gandalf/
       

      6. Управление версиями модуля

      Управление версиями модуля включается тегом CONFIG_MODVERSIONS и используется как простая проверка согласованности ABI. Значение CRC полного прототипа для экспортированного символа создается. Когда модуль загружается/используется, Значения CRC, содержащиеся в ядре, сравниваются с аналогичными значениями в модуль; если они не равны, ядро ​​отказывается загружать модуль.

      Module. symvers содержит список всех экспортированных символов из ядра. строить.

      6.1 Символы из ядра (vmlinux + модули)

      Во время сборки ядра файл с именем Module.symvers будет сгенерировано. Module.symvers содержит все экспортированные символы из ядро и скомпилированные модули. Для каждого символа также сохраняется соответствующее значение CRC.

      Синтаксис файла Module.symvers:

           
      0xe1cc2a05 usb_stor_suspend драйверы/usb/хранилище/usb-хранилище EXPORT_SYMBOL_GPL USB_STORAGE
       

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

      Для сборки ядра без включенной CONFIG_MODVERSIONS CRC будет читать 0x00000000.

      Module.symvers служит двум целям:

      1. В нем перечислены все символы, экспортированные из vmlinux и всех модулей.

      2. Список CRC, если CONFIG_MODVERSIONS включен.

      6.2 Символы и внешние модули

      При сборке внешнего модуля системе сборки требуется доступ к символам из ядра, чтобы проверить, все ли внешние символы определены. Это делается на шаге MODPOST. модпост получает символы, читая Module.symvers из исходного кода ядра дерево. На этапе MODPOST будет создан новый файл Module.symvers. записано, содержащее все экспортированные символы из этого внешнего модуля.

      6.3 Символы другого внешнего модуля

      Иногда внешний модуль использует символы, экспортированные из другой внешний модуль. Kbuild должен иметь полное представление о все символы, чтобы не выплевывать предупреждения о неопределенном символы. Для этой ситуации существует два решения.

      ПРИМЕЧАНИЕ. Рекомендуется метод с файлом kbuild верхнего уровня. но может быть непрактичным в определенных ситуациях.

      Используйте файл kbuild верхнего уровня

      Если у вас есть два модуля, foo. ko и bar.ko, где foo.ko нужны символы из bar.ko, вы можете использовать общий файл kbuild верхнего уровня, поэтому оба модуля скомпилирован в той же сборке. Рассмотрим следующее макет каталога:

       ./foo/ <= содержит foo.ko
      ./bar/ <= содержит bar.ko
       

      Тогда файл kbuild верхнего уровня будет выглядеть так:

       #./Kbuild (или ./Makefile):
              obj-m := foo/бар/
       

      И выполнение:

       $ make -C $KDIR M=$PWD
       
      Затем

      выполнит ожидаемое и скомпилирует оба модуля с полное знание символов из любого модуля.

      Используйте переменную make KBUILD_EXTRA_SYMBOLS

      Если добавление файла kbuild верхнего уровня нецелесообразно, вы можете назначить список, разделенный пробелами файлов в KBUILD_EXTRA_SYMBOLS в файле сборки. Эти файлы будут загружены модпостом во время инициализация его таблиц символов.

      7. Советы и рекомендации

      7.1 Тестирование CONFIG_FOO_BAR

      Модули часто должны проверять определенные параметры CONFIG_ для решить, включена ли конкретная функция в модуль.

      Добавить комментарий

      Ваш адрес email не будет опубликован. Обязательные поля помечены *