О блоге

Все новые материалы размещаются на Блогосайте alv.me. Старые - в процессе переноса.

24.07.2008

Сборка ядра: Debian Way

Citkit, 23 марта 2006 г

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

$ apt-get install linux-image-2.6.XX-##-arch

Где XX - номер версии ядра (например, 2.6.15), ## - номер сборки пакета образа, а arch - архитектура, под которую этот образ сокмпилирован (например, 386 и 686 - под абстрактные процессоры Intel вообще и под Pentium Pro и выше, соответственно, k7 и amd64 - под обычный Atlhon и под Athlon 64-битный).

Установленное таким образом ядро будет поддерживать те его функции, которые показались необходимыми майнтайнерам. А как быть, если возникнет необходимость в ядре, сконфигурированном собственноручно? Конечно, времена, когда первым делом линуксоида после установки системы было - пересборка ядра, давно прошли. Нынче, по крайней мере в большинстве пакетных дистрибутивов, хорошим тоном считается пользовать прекомпилированное ядро, собранное майнтайнером (или одно из предоставляемых им ядер). И, надо признать, к тому есть немало оснований: в поставляемых с дистрибутивами, рассчитанными на широкие массы трудящихся, ядрах задействована модульная поддержка всех распространенных устройств, таких, как контроллеры жестких дисков SATA и ATA-RAID. А штатный способ загрузки их ныне - через специально сконфигурированный образ виртуального загрузочного диска initrd, - обеспечивает работу системы даже в том случае, если в качестве модулей поддерживаются загрузочные устройства и устройства, несущие корневую файловую систему.

Тем не менее, необходимость в перекомпиляции ядра иногда возникает. И причин к ней - две. Во-первых, модульная поддержка широкого круга устройств и загрузка системы через initrd, неизбежные для ядер инсталляционных дисков (действительно, не будешь же жестко встраивать в ядро поддержку всех возможных типов ATA- и SCSI-контроллеров или бесчисленных сетевых карт), далеко не идеальна для индивидуальной пользовательской машины. А во-вторых, модульная поддержка не всегда обеспечивает оптимальную работу устройств, в частности - максимальную производительность тех же жестких дисков.

В документации к Ubuntu и Kubuntu указаний по части сборки ядра, пожалуй, не найти. Однако тут впору опять вспомнить, что это - дети обширного Debian-семейства, и обратиться к документации по этому дистрибутиву. Каковая предлагает два метода выполнения этой процедуры - "как всегда" и "как лучше". На первом останавливаться не буду - он многократно описывался во всех книгах по Linux и бесчисленных Сетевых источниках. Скажу только, что он обычно сводится (при наличии исходников ядра, разумеется) к выполнению команды make menuconfigure, включению нужных и отключению ненужных опций через меню этой программы (каких именно - разговор совершенно особый, который мог бы составить предмет отдельной книги), собственно компиляции образа ядра и его модулей командами типа make и make modules, и установке получившихся бинарников в должные ветви файлового древа (как и куда - опять-таки, возможны варианты, на которых задерживаться не буду). В общем, любой линуксоид нашего поколения знает, как собирать ядро традиционным способом - не хуже, чем любой советский ребенок знал, как очищается политура, а наичнающим пользователям знать детали необходимости нет.

А вот метод "как нужно" - Debain-специфический, и избавляет пользователя от ряда деталей, копаться в которых ему совсем не обязательно. Он предусматривает для пересборки ядра специальный пакет - kernel-package, каковой и надлежит установить с помощью зазубренных ранее волшебных заклинаний:

S apt-get install kernel-package

Заодно следует обзавестись и сопутствующими пакетами - debhelper, modutils и libncurses5-dev (последний нужен для генерации меню по команде make menuconfig). И еще - пакетом fakeroot, который отвечает за запуск команд в имитируемом root-окружении.

Далее, естественно, требуются исходники ядра. В качестве таковых можно взять последнюю версию ядра канонического, с http://www.kernel.org, можно - дополнить их патчами других разработчиков. А можно - просто пересобрать штатное ядро дистрибутива. В последнем случае нужно установить соответствующий пакет с исходниками, например:

S sudo apt-get install kernel-source-2.6.XX

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

И еще: почти все последующие процедуры потребуют привилегий администратора, так что, дабы не прибегать к sudo перед каждой, их можно получить на все время "ядерных" упражнений - напоминаю, как:
$ sudo -s -H

Результатом выполнения последней команды будет появление в каталоге /usr/src тарбалла исходников. Переходим туда и распаковываем тарбалл обычным образом:

S tar xjvf kernel-source-2.6.XX.tar.bz2

Да, в промежутке можно отредактировать файл /etc/kernel-pkg.conf - правда, кроме собственного имени и электронного адреса, вписывать в него вроде нечего. Следующий этап Debian-метода построения ядра выполняется, "как всегда". То есть - переходом в соответствующий каталог

S cd /usr/src/linux-source-2.6.12/

копированием в него нашего рабочего конфига ядра:

S cp /boot/config-2.6.12-1-amd64-generic .config

(дабы не начинать конфигурирование с нуля, а лишь вносить необходимые коррективы) и запуском команды

S make menuconfig

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

Далее руководство в приказном порядке рекомендует выполнить очистку дерева исходников:

$ make-kpkg clean

что требуется для уничтожения следов от номеров предыдущих ревизий ядра - следующей командой мы определим свою их нумерацию. А командой этой будет

$ fakeroot make-kpkg --append_to_version \
-amd64 --revision=rev.01 kernel_image

Здесь fakeroot создает "правильное" root-окружение (то есть команда может быть запущена от имени пользователя), make-kpkg - собственно программа для построения бинарного "ядерного" пакета, ее опции предписывают добавлять к имени пакета номер версии ядра, архитектуру, под которую оно собиралось, и номер ревизии, то есть нашей собственной сборки, а kernel_image - имя целевого пакета.

В результате указанной директивы сначала происходит компиляция ядра, а потом из него собирается самый обычный deb-пакет вида kernel-image-2.6.12-amd64_rev.01_amd64.deb, помещаемый в каталог /usr/src. Так что дело остается за малым - установить его обычным же образом:

$ cd ..
$ dpkg -i kernel-image-2.6.12-amd64_rev.01_amd64.deb

При этом файл образа ядра и соответствующий ему System.map будут не только скопированы куда следует (то есть в каталог /boot - если он составляет отдельную ветвь файлового древа, нужно не забыть предварительно его примонтировать!), но и внесены изменения в файл конфигурации загрузчика (например - в /boot/grub/menu.lst, если таковым выступает GRUB): новое ядро займет умолчальную позицию в его меню, старое же сохранится в качестве резервного.