2005-10-25
Прошли те времена, когда первым делом линуксоида после установки системы было - пересборка ядра. Нынче, по крайней мере в большинстве пакетных дистрибутивов, хорошим тоном считается пользовать прекомпилированное ядро, собранное майнтайнером (или одно из предоставляемых им ядер). И, надо признать, к тому есть немало оснований: в поставляемых с дистрибутивами, рассчитанными на широкие массы трудящихся, ядрах задействована модульная поддержка всех распространенных устройств, таких, как контроллеры жестких дисков SATA и ATA-RAID. А штатный способ загрузки их ныне - через initrd, обеспечивающий работу системы даже в том случае, если в качестве модулей поддерживаются загрузочные устройства и устройства, несущие корневую файловую систему.
Тем не менее, необходимость в перекомпиляции ядра иногда возникает. И причин к ней - две. Во-первых, модульная поддержка широкого круга устройств и загрузка системы через initrd, неизбежные для ядер инсталляционных дисков (действительно, не будешь же встраивать в ядро поддержку всех возможных типов ATA- и SCSI-контроллеров), далеко не идеальна для индивидуальной пользовательской машины. А во-вторых, модульная поддержка далеко не всегда обеспечивает оптимальную работу устройств, в частности - максимальную производительность тех же жестких дисков.
Именно с последней ситуацией я столкнулся в своем свежеустановленном Debian testing (Etch). Как я рассказывал в предыдущей заметке, эта система была установлена на 1-й и единственный SATA (Seagate Barracuda, 120 Мбайт, 7200 об./мин, буфер 8 Мбайт), определенный в качестве загрузочного. Кроме того, в машине присутствовали еще два PATA-диска на 1-м IDE-канале, оба - Seagate Barracuda IV, 7200 об./мин, буфер 2 Мбайт, 40 и 80 Гбайт, соответственно. Первый использовался для экспериментов, второй - для backup'а. А поскольку шутки с данными глупы и неприличны, backup я делаю достаточно часто (в том числе и полный).
Так вот, на первой же сессии тотального резервирования меня удручила исключительная медленность процесса - почти как во FreeBSD, и это - при ReiserFS и на источнике, и на приемнике. Ясно, что дело в дисках - хотя оба моих PATA, как можно видеть из их имен, достаточно старые, используются мной уже давно, и их характеристики я помню на память. В частности, во всех Linux'ах, к которым они прикручивались ранее, по hdparm -t они стабильно давали 38-40 Мбайт/с.
Новый SATA внешне никаких нареканий в работе не вызывал. Опробование его hdparm'ом дало скорость в 56 Мбайт/с - вполне сопоставимо с той разницей между ним и PATA, которая у меня получалась во FreeBSD. Хотя это - при 16-битном доступе, включать 32 бита на этом диске hdparm отказался.
А вот оба PATA показали в ответ на hdparm -t лишь жалкие 7,8 Мбайт/с, что не могло не удручать. И чего следовало ожидать - дальнейшее пытание их показало как 16-битный доступ, так и отключение DMA. Положим, задействовать 32 бита через
$ haparm -c 1 /dev/hd?
мне удалось - после этого скорость возросла до "потрясающей воображение" цифры в 12 Мбайт/с. Но вот DMA-режим включаться отказывался категорически, а без него, как вы понимаете, не жизнь.
Просмотр сетевых источников показал, что проблема эта - довольно часта для не-Intel'овских чипсетов (а у меня была "мать" на Nforce3). И как средство ее решения предлагалась пересборка ядра с жестким (не модульным) встраиванием в него поддержки наличных IDE- и SATA-контроллеров. Что я и решил проделать.
Руководство по Debian предлагало два метода выполнения этой процедуры - "как лучше", и "как всегда". Рекомендовался, естественно, первый, Debain-специфический. Да и для меня он был интересней: любой линуксоид моего поколения знает, как собирать ядро традиционным способом - не хуже, чем любой советский ребенок знал, как очищается политура. Так что к нему я и решил прибегнуть.
Стандартный Debian-метод предусматривает для пересборки ядра специальный пакет - kernel-package, каковой и надлежит установить с помощью зазубренных ранее волшебных заклинаний:
S apt-get install kernel-package
Заодно следует обзавестись и сопутствующими пакетами - debhelper, modutils и libncurses5-dev (последний нужен для генерации меню по команде make menuconfig). И еще - пакетом fakeroot, который отвечает за запуск команд в имитируемом root-окружении.
Далее, естественно, требуются исходники ядра. В качестве таковых можно взять последнюю версию ядра канонического, с http://www.kernel.org, можно - дополнить их патчами других разработчиков. А можно - просто пересобрать штатное ядро дистрибутива. В последнем случае (а я поступил именно так) нужно установить соответствующий пакет с исходниками, например:
S apt-get install kernel-source-2.6.12
Обращаю внимание, что имя пакета, содержащее исходники ядра, указывается с номером версии последнего. Кроме исходников, этот пакет содержит Debian-специфичные патчи, правда, нужные, насколько я понял, только для создания initrd.
Результатом выполнения последней команды будет появление в каталоге /usr/src тарбалла исходников. Переходим туда и распаковываем тарбалл обычным образом:
S tar xjvf kernel-source-2.6.12.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, необходимо жестко встроить в ядро поддержку всего, имеющего отношение к старту системы. То есть - контроллера "несущего" диска и типа файловой системы, содержащей корень файлового древа (в моем случае - Nforce, вместе с SATA и сопутствующим SCSI, и ReiserFS). Неплохо также избавиться от поддержки "лишних" чипсетов и прочего не имеющего быть оборудования.
Далее руководство в приказном порядке рекомендует выполнить очистку дерева исходников:
$ 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): новое ядро займет умолчальную позицию в его меню, старое же сохранится в качестве резервного.
Должен сказать, что в моей конфигурации система упорно продолжает считать первым винчестером 1-й PATA (тогда как в BIOS выставлена загрузка с SATA, и grub полагает первым именно его). Так что на всякий случай файл /boot/grub/menu.lst нужно проверить и, при необходимости, поправить руками.
Теперь остается только перезагрузиться с новым ядром и посмотреть, что получилось. Надо сказать, что, не смотря на отказ от initrd и изобилия модулей, скорость загрузки на глаз не изменилась (а мерить ее мне было лень, да и не волнует меня это). А вот ситуация с дисками существенно выправилась.
Правда, для SATA-диска ничего не изменилось - 32-битный режим доступа так и остался недоступным, и скорость по hdparm -t по прежнему составляла 56 Мбайт/с (хотя куда уж больше). А вот для обоих PATA-дисков по умолчанию оказались сразу задействованы и 32-битный доступ, и DMA-режим. В результате чего измерения показали для них законные 38-39 Мбайт. Так что овчинка явно стоила выделки.