Найти файл с образом ядра linux. Анатомия ядра Linux. Где хранятся файлы ядра

Прочие модели 17.03.2019
Прочие модели

Состоящее почти из 20 миллионов строк кода ядро Linux является одним из самых крупных Opensource проектов в мире.

Что такое ядро

Ядро представляет собой нижний уровень программного обеспечения, которое взаимодействует с оборудованием компьютера. Оно отвечает за взаимодействие всех приложений, которые работают в т.н. «пользовательском режиме» с физическим оборудованием и позволяет процессам передавать информацию друг другу с помощью (IPC ).

Типы ядер

Имеется три основных типа ядер — монолитные (monolithic ), микроядра (microkernel ) и гибридные (hybrid ).

К примеру Linux является монолитным ядром, тогда как OS X и Windows используют гибридные ядра.

Microkernel

Микроядра занимаются управлением только CPU, памятью и IPC. Практически все остальное в компьютере может рассматриваться как дополнительное оборудование и может обслуживаться в пользовательском режиме. Микроядра имеют большую переносимость, т.к. вам не приходиться беспокоиться если вы задумали сменить видеокарту или даже всю операционную систему — если новая ОС работает с оборудованием так же, как и предыдущее. Микроядра так же требуют меньше дискового простанства и RAM. Кроме того — они могут считаться более безопасными в силу того, что большая часть процессов работает в режиме пользователя и не имеет доступа к критически важным частям ситемы.

Плюсы

  • переносимость
  • меньший размер занимаемой RAM и на жестком диске
  • безопасность

Минусы

  • в целом система может работать медленнее из-за дополнительных слоев программной абстракции между ядром и оборудованием
  • процессы могут тратить время на ожидание в очереди для получения информации

Monolithic ядра

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

Плюсы

  • более быстрый доступ процессов к оборудованию
  • проще связь между самими процессами
  • проще реализация поддержки оборудования без необходимости установки дополнительных драйверов
  • процессы взаимодействуют быстрее, так как не требуется ожидание в очереди

Минусы

  • больший объем занимаемой памяти и жесткого диска
  • больше проблем с безопасностью

Гибридные ядра

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

Плюсы

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

Минусы

  • возможны недостатки в производительности
  • установка драйверов устройств зависит от пользователя и производителя оборудования

Файлы ядра Linux

В большинстве GNU/Linux -систем файлы ядра располагаются в каталоге /boot , например CentOS 6:

# ls -l /boot/ | grep linu -rwxr-xr-x 1 root root 4221232 Dec 15 23:48 vmlinuz-2.6.32-573.12.1.el6.x86_64 -rwxr-xr-x 1 root root 4221968 Feb 10 01:15 vmlinuz-2.6.32-573.18.1.el6.x86_64 -rwxr-xr-x 1 root root 4221776 Aug 14 2015 vmlinuz-2.6.32-573.3.1.el6.x86_64 -rwxr-xr-x 1 root root 4220144 Sep 23 01:29 vmlinuz-2.6.32-573.7.1.el6.x86_64 -rwxr-xr-x 1 root root 4220368 Nov 10 20:31 vmlinuz-2.6.32-573.8.1.el6.x86_64

Файл с vmlinuz в имени и есть файл ядра. Имя vmlinuz пришло из мира UNIX , в котором c 60-годов файл ядра назывался просто unix . Когда Linus Torvalds начал разработку Linux в 90-х — он назвал его просто linux .

Когда появилась реализация виртуальной памяти — к имени linux была добавлена приставка « vm » (virtual memory ). Так какое-то время файл ядра назывался просто vmlinux , однако рамзер файла постоянно увеличивался и со временем его стали сжимать а последняя буква в имени была заменена c x на z (zlib compression ). Ядро так же зачастую сжимается с помощью LZMA или BZIP2 и некоторые ядра называются просто zImage .

В каталоге /boot так же находятся файлы initrd.img-version (или initramfs-version), System.map-version и config-version . Файл initrd.img-version используется для первоначальной загрузки системы, во время которой распаковывается и загружается само ядро. Файл System.map используется для управления памятью перед загрузкой смого ядра, а файл config содержит в себе параметры ядра и список модулей для загрузки в ядро во время его компиляции.

Архитектура ядра Linux

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

Модули ядра Linux

Что если бы Windows изначально содержило в себе все необходимые драйвера, и все что требовалось бы от пользователя — это просто включить некоторые из них?

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

Как правило — модули расширяют возможности ядра для работы с устройствами, файловыми системами и системными вызовами. LKM имеют рсширение файлов.ko:

# find /lib/modules/2.6.32-573.18.1.el6.x86_64/kernel/ -name "*.ko" -type f | wc -l 2033

Благодаря модульной структуре — вы можете настраивать ядро под себя, выбирая только необходимые модули в menuconfig , отредактировав файл /boot/config* или загружая и выгружая модули прямо во время работы с помощью утилит типа modprobe , insmod и rmmod .

Ядро не является чем-то волшебным, но является жизненно необходимым для работы любого компьютера. Ядро Linux отличается от ядер в Windows или OS X системах, так как включает в себя драйвера на уровне ядра системы и поддерживает многие возможности «из коробки».

В многочисленном семействе операционных систем на основе GNU/Linux. Наверняка вы слышали, что оные коды являются открытыми, свободно распространяемыми и бесплатными. Дескать, бери кто хочешь, но только условия лицензии GPL соблюдай, что совсем нетрудно. Однако мало кто объясняет достаточно внятно, в чём же суть данного явления, в чём его смысл. Поэтому попытку такого объяснения осуществим мы.

Суть вкратце

Всё началось в 1991-м, когда финский студент Линус Торвальдс выложил в открытый доступ коды ядра новой операционной системы Linux. Почему в открытый? Потому что поддерживал . Но это, вы, пожалуй, и так знаете (или легко узнаете). Мы же обратим внимание на моменты, которые требуют чёткой классификации.

Linux

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

GNU

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

GNU/Linux - это уже ОС, а не просто ядро. Вместо GNU может быть что-то другое, например, Dalvik в Android .

Драйверы

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

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

Приложения

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

Естественно, открыты коды всех вариантов - для всех поддерживаемых операционных систем. Та же самая ситуация - с различными утилитами.

Кто это изготавливает

Ядро Linux совершенствуется группой энтузиастов. Иногда сам Линус Торвальдс принимает участие. Код ядра, запакованный в архив, можно скачать с kernel.org с целью последующей самостоятельной компиляции.

Драйверы, если они свободные, тоже нередко изготавливаются сообществами. Для принтера, сканера, видеокарты, адаптера Wi-Fi... В общем, много для чего.

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

Иногда производители «железки» сами открывают код под какой-нибудь подходящей лицензией, той же GPL или BSD. Такие события обычно вызывают неописуемую радость сторонников Open Source.

Как вы уже догадываетесь, пользовательские приложения тоже создаются либо сообществами, либо энтузиастами-одиночками. Однако и коммерческие конторы любят рекламировать себя, давая народонаселению часть своей продукции в виде Свободного ПО. Яркий пример: офисный пакет OpenOffice.org долгое время выпускался компанией Oracle.

Более того, некоторые фирмы даже целые дистрибутивы делают. Red Hat, SuSE, Xandros берут деньги за бинарные сборки, готовые к употреблению, но коды прятать не имеют право. То есть, эти коды, как бы их ни переработали, должны оставаться открытыми. Таково требование лицензии GPL.

Кто этим пользуется

Смотрит программист на софт и думает: «Хорошая штука, но можно сделать лучше!» Качает с сайта разработчика архив с кодом - и совершенствует. К нему присоединяется группа специалистов, пожелавших участвовать, - и рождается новый проект.

Так появляются «форки» (от английского «fork», что в данном случае переводится как «ответвление»). Новые программы на кодовой базе уже существующих.

К примеру, из хорошего аудиоплеера Amarok сделан ещё лучший - Clementine. А из пакета офисных приложений OpenOffice.org - LibreOffice, бурно развивающийся и весьма перспективный.

Так вот, по такому принципу клонируются целые операционные системы. Из исходных кодов платной Red Hat Enterprise Linux компилируется бесплатная ОС CentOS . Конечно, боссы компании Red Hat наверняка кусают локти от досады, но сделать ничего не могут, поскольку исходный код им не принадлежит.

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

Заключение

Открытость кода - основополагающая концепция и Linux, в частности, и всего Свободного ПО в целом. Коды можно использовать для собственных проектов, усилиями сообщества проверять на безвредность, изучать, повышать свою квалификацию, участвуя в разработке, улучшать и оказывать помощь людям в их благородном деле.

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

Предыдущие публикации:

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

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

5 Solutions collect form web for “Почему ядро ​​Linux называется «образ»?”

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

Только намного позже были добавлены такие вещи, как (де-комп), и хотя теперь более мощные загрузчики уже установлены, имя изображения застряло.

Изображение слова также имеет определение «Файл, содержащий всю информацию, необходимую для создания живой рабочей копии».

Это не означает, что «образ» – это всего лишь 1: 1 копия диска. Поскольку фотография представляет собой реальность точно так же, как и при съемке, изображение исполняемой программы (или ядра) представляет собой программу в состоянии, где она может загружаться (или распаковываться) в системной памяти точно так, как она есть, а затем дается контроль над ним. Затем эта программа может запускаться из этого состояния согласованным образом. Таким образом, образ ядра Linux представляет собой изображение (изображение состояния) ядра Linux, которое может запускаться само по себе, предоставляя ему контроль.

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

BIOS загружает загрузчик, который также является изображением, например, boot.img в случае grub . Этот boot.img не является файлом (если установлен grub); это имя для части, которая находится в главной загрузочной записи (MBR). Если вы выгрузите файл в файл, это будет образ в виде файла, который не будет записан на жесткий диск, но написанный в файле. Это также представление (изображение) самого раннего состояния, в котором grub может загрузить остальную часть себя. grub затем имеет свой механизм, как полностью загружать себя, загружая другие изображения. Это представлено различными этапами в grub . После этого загрузчик загружает образ ядра, заменяя себя извлеченным содержимым этого файла.

Древняя история. термин «изображение» происходит от старого термина «Digital Equipment Corporation» для вывода компилятора-> линкера. файл – это изображение, созданное путем интерпретации кода и т. д. через компоновщик для создания исполняемого «изображения» вашего дизайна.

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

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

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

Ядро – в основном просто элементы из исходного набора, которые сопоставляются изображению, но только отображают элемент идентичности изображения. В основном элементы, которые отображают 0, как вещь в изображении.

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

Мы можем видеть, что если мы выберем исходное множество как конечные последовательности двоичных или 1 и 0, а кодомен (набор, сопоставленный к), также являемся последовательностями двоичного, то мы можем построить такие вещи тогда и только тогда, когда подходящая групповая структура можно определить (это немного глубже и не связано с вопросом).

Поэтому мы с полной уверенностью видим, что «ядро» и «образ» ОС полностью определены и имеют математическое значение. Независимо от, возможно, других видов использования терминов.

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

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

Конфигурация ядра

Первый шаг - найти исходники ядра наиболее близкие к тому образу ядра, насколько это возможно. Наверное, получение правильной конфигурации - наиболее сложная составляющая всего процесса сборки модуля. Начните с того номера версии ядра, который может быть прочитан из /proc/version . Если, как я, вы собираете модуль для устройства Android, попробуйте ядра Android от Code Aurora, Cyanogen или Android, те, что наиболее ближе к вашему устройству. В моем случае, это было ядро msm-3.0. Заметьте, вам не обязательно необходимо искать в точности ту же версию исходников, что и версия вашего образа ядра. Небольшие отличия версии, наиболее вероятно, не станут помехой. Я использовал исходники ядра 3.0.21, в то время как версия имеющегося образа ядра была 3.0.8. Не пытайтесь, однако, использовать исходники ядра 3.1, если у вас образ ядра 3.0.x.

Если образ ядра, что у вас есть, достаточно любезен, чтобы предоставить файл /proc/config.gz , вы можете начать с этого, в противном случае, вы можете попытаться начать с конфигурацией по умолчанию, но в этом случае нужно быть крайне аккуратным (хотя я и не буду углубляться в детали использования дефолтной конфигурации, поскольку мне посчастливилось не прибегать к этому, далее будут некоторые детали относительно того, почему правильная конфигурация настолько важна).

Предполагая, что arm-eabi-gcc у вас доступен по одному из путей в переменной окружения PATH, и что терминал открыт в папке с исходными файлами ядра, вы можете начать конфигурацию ядра и установку заголовочных файлов и скриптов:

$ mkdir build $ gunzip config.gz > build/.config # или что угодно, для того, чтобы приготовить.config $ make silentoldconfig prepare headers_install scripts ARCH=arm CROSS_COMPILE=arm-eabi- O=build KERNELRELEASE=`adb shell uname -r`
Сборка silentoldconfig , наиболее вероятно, спросит, хотите ли вы включить те или иные опции. Вы можете выбрать умолчания, но это вполне может и не сработать.

Можно использовать что-нибудь другое в KERNELRELEASE , однако это должно совпадать в точности с версией ядра, с которого вы планируете подгружать модуль.

Написание простого модуля

Чтобы создать пустой модуль, необходимо создать два файла: исходник и Makefile . Расположите следующий код в файле hello.c , в некоторой отдельной директории:

#include /* Needed by all modules */ #include /* Needed for KERN_INFO */ #include /* Needed for the macros */ static int __init hello_start(void) { printk(KERN_INFO "Hello world\n"); return 0; } static void __exit hello_end(void) { printk(KERN_INFO "Goodbye world\n"); } module_init(hello_start); module_exit(hello_end);
Поместите следующий текст в файл Makefile в той же директории:

Obj-m = hello.o
Сборка модуля достаточна проста, однако на данном этапе полученный модуль не сможет загрузиться.

Сборка модуля

При обычной сборки ядра система сборки ядра создает файл hello.mod.c , содержимое которого может создать различные проблемы:

MODULE_INFO(vermagic, VERMAGIC_STRING);
Значение VERMAGIC_STRING определяется макросом UTS_RELEASE , который располагается в файле include/generated/utsrelease.h , генерируемом системой сборки ядра. По умолчанию, это значение определяется версией ядра и статуса git-репозитория. Это то, что устанавливает KERNELRELEASE при конфигурации ядра. Если VERMAGIC_STRING не совпадает с версией ядра, загрузка модуля приведет к сообщению подобного рода в dmesg:

Hello: version magic "3.0.21-perf-ge728813-00399-gd5fa0c9" should be "3.0.8-perf"
Далее, также имеем здесь определение структуры модуля:

Struct module __this_module __attribute__((section(".gnu.linkonce.this_module"))) = { .name = KBUILD_MODNAME, .init = init_module, #ifdef CONFIG_MODULE_UNLOAD .exit = cleanup_module, #endif .arch = MODULE_ARCH_INIT, };
Само по себе, это определение выглядит безобидно, но структура struct module , определенная в include/linux/module.h , несет в себе неприятный сюрприз:

Struct module { (...) #ifdef CONFIG_UNUSED_SYMBOLS (...) #endif (...) /* Startup function. */ int (*init)(void); (...) #ifdef CONFIG_GENERIC_BUG (...) #endif #ifdef CONFIG_KALLSYMS (...) #endif (...) (... plenty more ifdefs ...) #ifdef CONFIG_MODULE_UNLOAD (...) /* Destruction function. */ void (*exit)(void); (...) #endif (...) }
Это означает, что для того, чтобы указатель init оказался в правильном месте, CONFIG_UNUSED_SYMBOLS должен быть определен в соответствии с тем, что использует наш образ ядра. Что же насчет указателя exit, - это CONFIG_GENERIC_BUG , CONFIG_KALLSYMS , CONFIG_SMP , CONFIG_TRACEPOINTS , CONFIG_JUMP_LABEL , CONFIG_TRACING , CONFIG_EVENT_TRACING , CONFIG_FTRACE_MCOUNT_RECORD и CONFIG_MODULE_UNLOAD .

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

Static const struct modversion_info ____versions __used __attribute__((section("__versions"))) = { { 0xsomehex, "module_layout" }, { 0xsomehex, "__aeabi_unwind_cpp_pr0" }, { 0xsomehex, "printk" }, };
Эти определения берутся из файла Module.symvers , который генеруется в соответствии с заголовочными файлами.

Каждая такая запись представляет символ, требуемый модулю, и то, какую сигнатуру должен иметь символ. Первый символ, module_layout , зависит от того, как выглядит struct module , то есть, зависит от того, какие опции конфигурации, упомянутые ранее, включены. Второй, __aeabi_unwind_cpp_pr0 , - функция, специфичная ABI ARM, и последний - для наших вызовов функции printk .

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

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

Hello: disagrees about version of symbol symbol_name
Что значит, что нам нужен правильный, соответствующий образу ядра, файл Module.symvers , которым мы не располагаем.

Изучаем ядро

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

Ядро использует следующую функцию для поиска в своей таблицы символов (в kernel/module.c):

Bool each_symbol_section(bool (*fn)(const struct symsearch *arr, struct module *owner, void *data), void *data) { struct module *mod; static const struct symsearch arr = { { __start___ksymtab, __stop___ksymtab, __start___kcrctab, NOT_GPL_ONLY, false }, { __start___ksymtab_gpl, __stop___ksymtab_gpl, __start___kcrctab_gpl, GPL_ONLY, false }, { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future, __start___kcrctab_gpl_future, WILL_BE_GPL_ONLY, false }, #ifdef CONFIG_UNUSED_SYMBOLS { __start___ksymtab_unused, __stop___ksymtab_unused, __start___kcrctab_unused, NOT_GPL_ONLY, true }, { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl, __start___kcrctab_unused_gpl, GPL_ONLY, true }, #endif }; if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data)) return true; (...)
Структура, используемая в данной функции, определена в include/linux/module.h:

Struct symsearch { const struct kernel_symbol *start, *stop; const unsigned long *crcs; enum { NOT_GPL_ONLY, GPL_ONLY, WILL_BE_GPL_ONLY, } licence; bool unused; };
Примечание: данный код ядра не изменился значительно за последние четыре года (видимо, с момента рассматриваемого релиза ядра 3.0, - прим. пер.).

То, что мы имеем выше в функции each_symbol_section - три (или пять, когда конфиг CONFIG_UNUSED_SYMBOLS включен) поля, каждое из которых содержит начало таблицы символов, ее конец и два флага.

Данные эти статичны и постоянны, что означает, что они появятся в бинарнике ядра как есть. Сканируя ядро на предмет трех идущих друг за другом последовательностей состоящих из трех указателей в адресном пространстве ядра и следом идущих значений типа integer из определений в each_symbol_section , мы можем определить расположение таблиц символов и сигнатур, и воссоздать файл Module.symvers из бинарника ядра.

К несчастью, большинство ядер сегодня сжатые (zImage), так что простой поиск по сжатому образу невозможен. Сжатое ядро на самом деле представляет небольшой бинарник, следом за которым идет сжатый поток. Можно просканировать файл zImage с тем, чтобы найти сжатый поток и получить из него распакованный образ.

Теги: Добавить метки

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

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

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

Самое первое что нужно сделать - это скачать исходники ядра. Исходники лучшие брать с сайта вашего дистрибутива, если они там есть или официального сайта ядра: kernel.org. Мы рассмотрим загрузку исходников с kernel.org.

Перед тем как скачивать исходники нам нужно определиться с версией ядра которую будем собирать. Есть две основных версии релизов - стабильные (stable) и кандидаты в релизы (rc), есть, конечно, еще стабильные с длительным периодом поддержки (longterm) но важно сейчас разобраться с первыми двумя. Стабильные это, как правило, не самые новые, но зато уже хорошо протестированные ядра с минимальным количеством багов. Тестовые - наоборот, самые новые, но могут содержать различные ошибки.

Итак когда определились с версией заходим на kernel.org и скачиваем нужные исходники в формате tar.xz:

В этой статье будет использована самая новая на данный момент нестабильная версия 4.4.rc7.

Получить исходники ядра Linux можно также с помощью утилиты git. Сначала создадим папку для исходников:

mkdir kernel_sources

Для загрузки самой последней версии наберите:

git clone https://github.com/torvalds/linux

Распаковка исходников ядра

Теперь у нас есть сохраненные исходники. Переходим в папку с исходниками:

cd linux_sources

Или если загружали ядро linux с помощью браузера, то сначала создадим эту папку и скопируем в нее архив:

mkdir linux_sources

cp ~/Downloads/linux* ~/linux_sources

Распаковываем архив с помощью утилиты tar:

И переходим в папку с распакованным ядром, у меня это:

cd linux-4.4-rc7/

Автоматическая настройка сборки ядра Linux

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

Параметры используемого ядра хранятся в архиве по адресу /proc/config.gz. Распакуем конфиг и поместим его в нашу папку утилитой zcat:

В процессе его работы нужно будет ответить на несколько вопросов. Это новые параметры, которые изменились или были добавлены в новое ядро и поддержка нового оборудования, в большинстве случаев можно выбирать вариант по умолчанию. Обычно есть три варианта y - включить, n - не включать, m - включить в качестве модуля. Рекомендованный вариант написан с большой буквы, для его выбора просто нажмите Enter.

На все про-все у вас уйдет около 10-ти минут. После завершения процесса, ядро готово к сборке. Дальше мы рассмотрим настройку ядра вручную, а вы можете сразу перелистать к сборке ядра Linux.

Ручная настройка ядра Linux

Ручная настройка - сложный и трудоемкий процесс, но зато она позволяет понять как работает ваша система, какие функции используются и создать ядро с минимально нужным набором функций под свои потребности. Мы рассмотрим только главные шаги, которые нужно выполнить чтобы ядро собралось и заработало. Со всем остальным вам придется разбираться самому опираясь на документацию ядра. Благо в утилите настройки для каждого параметра есть обширная документация которая поможет вам понять какие еще настройки нужно включить.

Начнем. Для запуска меню настроек ядра linux наберите:

Откроется вот утилита с интерфейсом ncurses:

Как видите, некоторые обязательные опции уже включены, чтобы облегчить вам процесс настройки. Начнем с самых основных настроек. Чтобы включить параметр нажмите y, чтобы включить модулем - m, для перемещения используйте клавиши стрелок и Enter, возвратиться на уровень вверх можно кнопкой Exit Откройте пункт General Setup .

Здесь устанавливаем такие параметры:

Local Version - локальная версия ядра, будет увеличиваться при каждой сборке на единицу, чтобы новые ядра при установке не заменяли собой старые, устанавливаем значение 1.

Automatically append version information to the version string - добавлять версию в название файла ядра.

Kernel Compression Mode - режим сжатия образа ядра, самый эффективный lzma.

Default Hostname - имя компьютера, отображаемое в приглашении ввода

POSIX Message Queues - поддержка очередей POSTIX

Support for paging of anonymous memory - включаем поддержку swap

Control Group support - поддержка механизма распределения ресурсов между группами процессов

Kernel .config support и Enable access to .config through /proc/config.gz - включаем возможность извлечь конфигурацию ядра через /proc/config.gz

Здесь все, возвращаемся на уровень вверх и включаем Enable loadable module support, эта функция разрешает загрузку внешних модулей,дальше открываем его меню и включаем:

поддержка отключения модулей

принудительное отключение модулей

Опять возвращаемся назад и открываем Processor type and features:

Processor family (Opteron/Athlon64/Hammer/K8) - выбираем свой тип процессора.

Опять возвращаемся и переходим в раздел File systems , тут установите все нужные галочки.

Обязательно включите The Extended 3 (ext3) filesystem и The Extended 4 (ext4) filesystem - для поддержки стандартных ext3 и ext4 файловых систем

Возвращаемся и идем в Kernel hacking.

Здесь включаем Magic SysRq key - поддержка магических функций SysRq, вещь не первой необходимости, но временами полезная.

Остался еще один пункт, самый сложный, потому что вам его придется пройти самому. Device Drivers - нужно пройтись по разделам и повключать драйвера для своего оборудования. Под оборудованием я подразумеваю нестандартные жесткие диски, мышки, USB устройства, веб-камеры, Bluetooth, WIFI адаптеры, принтеры и т д.

Посмотреть какое оборудование подключено к вашей системе можно командой:

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

Чтобы выйти нажмите пару раз кнопку Exit .

Сборка ядра Linux

После завершения всех приготовлений может быть выполнена сборка ядра linux. Для начала процесса сборки выполните:

make && make modules

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

Установка нового ядра

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

cp arch/x86_64/boot/bzImage /boot/vmlinuz

А можно просто выполнить установочный скрипт, сразу установив заодно и модули:

sudo make install && sudo make modules_install

После установки не забудьте обновить конфигурацию загрузчика Grub:

grub-mkconfig -o /boot/grub/grub.cfg

И перезагружаем компьютер чтобы увидеть новое ядро в работе:

Выводы

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



Рекомендуем почитать

Наверх