Что такое заголовочные файлы ядра
Ядро Linux - это основа любой Linux системы. Это то, что делает Linux собой. Когда компьютер включается и загружает систему Linux, самым первым загружается ядро. Ядро инициализирует аппаратные компоненты: последовательные и параллельные порты, звуковые карты, сетевые карты, контролеры IDE, контролеры SCSI и много чего еще. Собственно, ядро делает доступным аппаратные элементы cbcntvs и позволяет запускаться программам.
Устанавливаемые файлы: ядро и заголовки ядра
Зависимости установки Linux
Linux зависит от: Bash, Binutils, Coreutils, Findutils, GCC, Glibc, Grep, Gzip, Make, Modutils, Perl, Sed.
Установка заголовков ядра
На данном этапе мы не будем компилировать ядро -- мы сделаем это после установки всех пакетов. Однако, в связи с тем, что некоторые пакеты требуют заголовочных файлов ядра, мы распакуем ядро, настроим его и скопируем заголовки туда, где их будут искать пакеты при компиляции.
Важно отметить. что файлы в директории с исходниками ядра не являются файлами с владельцем root. Когда вы распакуете пакет как пользователь root (как это происходит здесь, в среде chroot), конечные файлы будут иметь ID владельца и группы как на компьютере, где создавался пакет. Это обычно не создает проблемы для любых других пакетов потому, что вы обычно удаляете директорию с исходниками после установки. Но директории с исходниками ядра Linux будут еще нужны очень долго, и может получиться, что какой-либо пользователь вашей системы получит доступ к исходникам ядра.
Подготовим заголовки к установке:
Это гарантирует нам, что дерево с исходниками ядра будет абсолютно "чистым". Команда разработчиков ядра рекомендует выполнять эту команду перед каждой компиляцией ядра. Вы не можете быть абсолютно уверены в чистоте дерева исходников ядра даже после распаковки.
Создадим файл include/linux/version.h:
Создадим платформо-зависимую ссылку include/asm:
Установим платформо-зависимые файлы заголовков:
Установим кросс-платформенные файлы заголовков:
Некоторые из заголовков ядра используют файл заголовков autoconf.h. Поскольку мы пока не сконфигурировали ядро, нам надо создать этот файл для того, чтобы компиляция следующих пакетов не закончилась ошибкой. Создадим пустой файл autoconf.h:
Почему мы копируем заголовки ядра, а не создаем для них символические ссылки?
Раньше было принято создавать символические ссылки директорий /usr/include/ на /usr/src/linux/include/. Однако, это была плохая идея, как объясняет Линус Торвальдс в списке рассылки ядра Linux (Linux Kernel Mailing List, отрывок):
Заметьте, что не страшно если исходники ядра находятся в /usr/src/linux, главное, чтобы у вас не было ссылок на /usr/include/ .
Я знаю, что если я хочу скомпилировать свое собственное ядро Linux, мне нужны заголовки ядра Linux, но для чего именно они хороши?
Я узнал, что под /usr/src/ Похоже, существуют десятки заголовочных файлов Си. Но какова их цель, не включены ли они непосредственно в исходные тексты ядра?
Заголовочные файлы определяют интерфейс: они определяют, как определяются функции в исходном файле.
Они используются для того, чтобы компилятор мог проверить правильность использования функции, поскольку сигнатура функции (возвращаемое значение и параметры) присутствует в заголовочном файле. Для этой задачи фактическая реализация функции не требуется.
Вы можете сделать то же самое с полными исходниками ядра, но вы установите много ненужных файлов.
Пример: если я хочу использовать функцию
в программе мне не нужно знать, какова реализация foo , мне просто нужно знать, что она принимает один параметр ( double ) и возвращает целое число.
Как уже говорилось, заголовочные файлы определяют интерфейсы для функций, а также структуры, используемые программами.
В случае заголовочных файлов ядра эти функции и структуры находятся внутри самого ядра.
Если вы собираете полное ядро, то, очевидно, вам нужны полные исходные файлы, а не только заголовки. Однако, если вы компилируете драйвер устройства или другой загружаемый модуль, который связывается с ядром, вам нужны только файлы заголовков, поэтому вы можете сэкономить место, не устанавливая полные исходные коды.
Разделение пакетов, так что вы можете установить только заголовочные файлы, отчасти является историческим, так как разница в использовании дисков была важным фактором, когда диски были меньше. В наши дни наличие всего источника на диске (без необходимости) не будет основным соображением дискового пространства.
Термин заголовочные файлы происходит от языка программирования C , используемого при написании ядра Linux.
Чтобы объяснить это с очень высокого уровня .
В C вы должны иметь предварительное объявление функции перед ее использованием. Другими словами, описание функции, ее параметров и того, какие данные она возвращает. Обычная практика - помещать все предварительные объявления в один файл, называемый заголовком . Файлы исходного кода для других программ могут затем include этот заголовок и иметь доступ ко всем функциям в результирующем исполняемом файле программы после его компиляции.
Заголовочные файлы Linux - это все .h файлы, содержащие функции, предоставляемые ядром Linux, которые можно вызывать из других программ.
Ядро — это та часть операционной системы, работа которой полностью скрыта от пользователя, т. к. пользователь с ним не работает напрямую: пользователь работает с программами. Но, тем не менее, без ядра невозможна работа ни одной программы, т.е. они без ядра бесполезны. Этот механизм чем-то напоминает отношения официанта и клиента: работа хорошего официанта должна быть практически незаметна для клиента, но без официанта клиент не сможет передать заказ повару, и этот заказ не будет доставлен.
В Linux ядро монолитное, т.е. все его драйвера и подсистемы работают в своем адресном пространстве, отделенном от пользовательского. Сам термин «монолит» говорит о том, что в ядре сконцентрировано всё, и, по логике, ничего не может в него добавляться или удаляться. В случае с ядром Linux — это правда лишь отчасти: ядро Linux может работать в таком режиме, однако, в подавляющем большинстве сборок возможна модификация части кода ядра без его перекомпиляции, и даже без его выгрузки. Это достигается путем загрузки и выгрузки некоторых частей ядра, которые называются модулями. Чаще всего в процессе работы необходимо подключать модули драйверов устройств, поддержки криптографических алгоритмов, сетевых средств, и, чтобы уметь это правильно делать, нужно разбираться в строении ядра и уметь правильно работать с его модулями. Об этом и пойдет речь в этой статье.
В современных ядрах при подключении оборудования модули подключаются автоматически, а это событие обрабатывается демоном udev, который создает соответствующий файл устройства в каталоге "/dev". Все это выполняется в том случае, если соответствующий модуль корректно установлен в дерево модулей. В случае с файловыми системами ситуация та же: при попытке монтирования файловой системы ядро подгружает необходимый модуль автоматически, и выполняет монтирование.
Если необходимость в модуле не на столько очевидна, ядро его не загружает самостоятельно. Например, для поддержки функции шифрования на loop устройстве нужно вручную подгрузить модуль «cryptoloop», а для непосредственного шифрования — модуль алгоритма шифрования, например «blowfish».
Поиск необходимого модуля
Модули хранятся в каталоге "/lib/modules/<версия ядра>" в виде файлов с расширением «ko». Для получения списка всех модулей из дерева можно выполнить команду поиска всех файлов с расширением «ko» в каталоге с модулями текущего ядра:
find /lib/modules/`uname -r` -name ‘*.ko’
Полученный список даст некоторое представление о доступных модулях, их назначении и именах. Например, путь «kernel/drivers/net/wireless/rt2x00/rt73usb.ko» явно указывает на то, что этот модуль — драйвер устройства беспроводной связи на базе чипа rt73. Более детальную информацию о модуле можно получить при помощи команды modinfo:
Загрузка и выгрузка модулей
Загрузить модуль в ядро можно при помощи двух команд: «insmod» и «modprobe», отличающихся друг от друга возможностью просчета и удовлетворения зависимостей. Команда «insmod» загружает конкретный файл с расширением «ko», при этом, если модуль зависит от других модулей, еще не загруженных в ядро, команда выдаст ошибку, и не загрузит модуль. Команда «modprobe» работает только с деревом модулей, и возможна загрузка только оттуда по имени модуля, а не по имени файла. Отсюда следует область применения этих команд: при помощи «insmod» подгружается файл модуля из произвольного места файловой системы (например, пользователь скомпилировал модули и перед переносом в дерево ядра решил проверить его работоспособность), а «modprobe» — для подгрузки уже готовых модулей, включенных в дерево модулей текущей версии ядра. Например, для загрузки модуля ядра «rt73usb» из дерева ядра, включая все зависимости, и отключив аппаратное шифрование, нужно выполнить команду:
После загрузки модуля можно проверить его наличие в списке загруженных в ядро модулей при помощи команды «lsmod»:
Module | Size | Used by | |
rt73usb | 17305 | 0 | |
crc_itu_t | 999 | 1 | rt73usb |
rt2x00usb | 5749 | 1 | rt73usb |
rt2x00lib | 19484 | 2 | rt73usb,rt2x00usb |
Из вывода команды ясно, что модуль подгружен, а так же в своей работе использует другие модули.
Чтобы его выгрузить, можно воспользоваться командой «rmmod» или той же командой «modprobe» с ключем "-r". В качестве параметра обоим командам нужно передать только имя модуля. Если модуль не используется, то он будет выгружен, а если используется — будет выдана ошибка, и придется выгружать все модули, которые от него зависят:
Для автоматической загрузки модулей в разных дистрибутивах предусмотрены разные механизмы. Я не буду вдаваться здесь в подробности, они для каждого дистрибутива свои, но один метод загрузки всегда действенен и удобен: при помощи стартовых скриптов. В тех же RedHat системах можно записать команды загрузки модуля прямо в "/etc/rc.d/rc.local" со всеми опциями.
Файлы конфигурация модулей находится в каталоге "/etc/modprobe.d/" и имеют расширение «conf». В этих файлах преимущественно перечисляются альтернативные имена модулей, их параметры, применяемые при их загрузке, а так же черные списки, запрещенные для загрузки. Например, чтобы вышеупомянутый модуль сразу загружался с опцией «nohwcrypt=1» нужно создать файл, в котором записать строку:
options rt73usb nohwcrypt=1
Черный список модулей хранится преимущественно в файле "/etc/modules.d/blacklist.conf" в формате «blacklist <имя модуля>». Используется эта функция для запрета загрузки глючных или конфликтных модулей.
Сборка модуля и добавление его в дерево
Иногда нужного драйвера в ядре нет, поэтому приходится его компилировать вручную. Это так же тот случай, если дополнительное ПО требует добавление своего модуля в ядро, типа vmware, virtualbox или пакет поддержки карт Nvidia. Сам процесс компиляции не отличается от процесса сборки программы, но определенные требования все же есть.
Во первых, нужен компилятор. Обычно установка «gcc» устанавливает все, что нужно для сборки модуля. Если чего-то не хватает — программа сборки об этом скажет, и нужно будет доустановить недостающие пакеты.
Во вторых, нужны заголовочные файлы ядра. Дело в том, что модули ядра всегда собираются вместе с ядром, используя его заголовочные файлы, т.к. любое отклонение и несоответствие версий модуля и загруженного ядра ведет к невозможности загрузить этот модуль в ядро.
Если система работает на базе ядра дистрибутива, то нужно установить пакеты с заголовочными файлами ядра. В большинстве дистрибутивов это пакеты «kernel-headers» и/или «kernel-devel». Для сборки модулей этого будет достаточно. Если ядро собиралось вручную, то эти пакеты не нужны: достаточно сделать символическую ссылку "/usr/src/linux", ссылающуюся на дерево сконфигурированных исходных кодов текущего ядра.
После компиляции модуля на выходе будет получен один или несколько файлов с расширением «ko». Можно попробовать их загрузить при помощи команды «insmod» и протестировать их работу.
Если модули загрузились и работают (или лень вручную подгружать зависимости), нужно их скопировать в дерево модулей текущего ядра, после чего обязательно обновить зависимости модулей командой «depmod». Она пройдется рекурсивно по дереву модулей и запишет все зависимости в файл «modules.dep», который, в последствие, будет анализироваться командой «modprobe». Теперь модули готовы к загрузке командой modprobe и могут загружаться по имени со всеми зависимостями.
Стоит отметить, что при обновлении ядра этот модуль работать не будет. Нужны будут новые заголовочные файлы и потребуется заново пересобрать модуль.
Ошибка «Invalid argument» может говорить о чем угодно, саму ошибку ядро на консоль написать не может, только при помощи функции «printk» записать в системный лог. Посмотрев логи можно уже узнать в чем ошибка:
В этом примере выведена только последняя строка с ошибкой, чтобы не загромаждать статью. Модуль может написать и несколько строк, поэтому лучше выводить полный лог, или хотя бы последние строк десять.
Ошибку уже легко найти: значение «2» неприемлемо для параметра «nohwcrypt». После исправления, модуль корректно загрузится в ядро.
Из всего сказанного можно сделать один вывод: ядро Linux играет по своим правилам и занимается серьезными вещами. Тем не менее — это всего лишь программа, оно, по сути, не сильно отличается от других обычных программ. Понимание того, что ядро не так уж страшно, как кажется, может стать первым шагом к пониманию внутреннего устройства системы и, как результат, поможет быстро и эффективно решать задачи, с которыми сталкивается любой администратор Linux в повседневной работе.
Главное меню » Kali Linux » Как установить заголовки Linux в Kali Linux
По умолчанию Kali Linux не поставляется с установленными заголовками Linux, вам придется делать это вручную.
Установка заголовков Linux с помощью APT
Перед успешной установкой заголовков ядра вам может потребоваться выполнить полное обновление системы.
Отредактируйте файл sources.list и добавьте правильные репозитории, представленные в следующем ресурсе,
Затем обновите репозитории и запустите полное обновление дистрибутива.
После завершения перезагрузите установку Kali Linux и установите заголовки.
Введите команду ниже, чтобы установить заголовки Linux для вашей версии ядра. Мы воспользуемся командой uname –r, чтобы напрямую получить версию ядра.
Эта команда должна успешно запуститься и установить необходимые заголовки для вашей версии ядра. Однако, если описанный выше метод не работает, вы можете установить их вручную.
Установка заголовков ядра вручную
Перед установкой заголовков ядра вручную запустите полное обновление дистрибутива и перезагрузитесь, чтобы убедиться, что у вас установлена последняя версия ядра.
Откройте свой браузер и перейдите к
Загрузите необходимые заголовки ядра в виде пакета deb.
Затем используйте команду dpkg для установки заголовков:
Это должно установить необходимые заголовки ядра.
Вывод
В этой статье показано, как вручную установить заголовки ядра в Kali Linux и использовать диспетчер пакетов apt.
Читайте также: