Журнал LinuxFormat - перейти на главную

LXF89:Hardcore Linux

Материал из Linuxformat
Перейти к: навигация, поиск

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

Содержание

Ядро: Создай себе свое!

Говорят, что звания линуксоида достоин только тот, кто лично собирал ядро. Вы готовы взяться за гуж? Нейл Ботвик покажет, как это сделать.


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

Но что дает вам собственное ядро помимо законной гордости? Вот список возможных ответов:

  • Компактный объем. Ядра, входящие в дистрибутивы, обычно поддерживают массу лишнего оборудования, о котором вы, возможно, сроду не слышали.
  • Дополнительные функции или драйвера. Закон Мэрфи гласит: несмотря на предыдущее утверждение, в этой массе не найдется только одного драйвера – для вашего только что купленного устройства.
  • Ядро новее поставляемого с вашим дистрибутивом. Вам хочется собрать его для поддержки нового оборудования, усиления безопасности – или просто потому, что душа просит.
  • Заплатки на ядро. Существуют заплатки, пока не включенные в основную ветку ядра; некоторым из них там и не бывать. Если вы хотите насладиться каким-нибудь Reiser4, придется подлатать исходный код и скомпилировать ядро самим.

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

Для этого урока я воспользуюсь Mandriva Linux 2007, однако сам процесс одинаков для всех дистрибутивов. Мы будем работать только с ядрами серии 2.6; ядра серии 2.4 имеют некоторые отличия, но те, кто все еще работает с ними и ни разу не собирал ядро из исходных текстов, вряд ли когда-нибудь решат сделать это.

Обращение к истокам

Приступить к делу мы сможем не раньше, чем установим исходные тексты ядра. Для начала, воспользуемся исходными текстами, соответствующими вашему наличному ядру: ведь это готовая рабочая конфигурация, и ее можно принять за отправную точку. С помощью менеджера пакетов вашего дистрибутива установите нужные пакеты. Имя пакета варьируется от дистрибутива к дистрибутиву, но обычно оно выглядит как kernel-source или linux-source. В Mandriva 2007 ядро находится в пакете kernel-2.6.17.5mdv-1-1mdv2007.0, оно уже установлено, а исходные тексты – в пакете kernel-source-2.6.17.5mdv-1-1mdv2007.0, их надо будет установить из Центра Управления. Номер версии текущего ядра вам выведет команда uname -r.

Также понадобится установить компилятор и сопутствующие инструменты; установка GCC должна обеспечить установку всех остальных пакетов. Некоторые дистрибутивы имеют группы пакетов для разработки; если у вас стоит Ubuntu, то установка пакета build-essentials, подтянет другие пакеты в виде зависимостей.

Обычно исходные тексты Linux располагаются в каталоге /usr/src/linux-номер-версии, на который ссылается /usr/src/linux. Если ваш дистрибутив не создал ссылку, сделайте это сами, командами

cd /usr/src
ln -s linux-2.6.xyz linux

Так как мы используем существующую настройку как отправную точку, то должны убедиться, что в /usr/src/linux есть копия файла настройки. Файл называется .config; если его там нет, возможно, он в каталоге /boot или в пакете linux headers. Команда locate .config поможет его найти; скопируйте его в /usr/src/linux.


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

cd /usr/src/linux
make menuconfig
(thumbnail)
Графический интерфейс на Ncurses скучноват, зато функционален и не требует X.

Теперь вы находитесь в инструменте настройки, использующем библиотеку Ncurses. Не пожалейте времени на осмотр и попробуйте различные варианты (перемещаясь с помощью курсорных клавиш). При выходе вас спросят, хотите ли вы сохранить настройку ядра; пока вы не ответили Да, ваши эксперименты ни на что не влияют. Большинство предлагаемых опций довольно очевидны. Любой пункт, оканчивающийся на --->, содержит подменю, куда вы можете войти, нажав Enter. Exit фактически переводит вас на уровень выше, и настоящий выход возможен только с самого верхнего уровня. Вместо Exit можно использовать клавишу Esc.

Обычно выбранные пункты могут иметь одну из трех отметок: *, M или ничего. * означает, что данный пункт будет встроен в ядро, M – что он будет скомпилирован как подгружаемый модуль ядра, а «ничего» означает, что опция отключена. Вы можете выбирать данные состояния с помощью клавиш Y, M и N соответственно, или переключаться между состояниями клавишей пробела. Еще одна клавиша, которая вам пригодится (особенно на первых порах) – ?, она выводит подсказку о текущем пункте.

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

Обрезка дерева ядра

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


Перейдите в раздел Device Drivers > Network Device Support > Ethernet (10 или 100Mbit) – увидите список всех драйверов сетевых карт, установленных в вашем ядре. Нужны вам, скорее всего, один или два, так что снимите «галочки» с остальных, которые не относятся к вашим устройствам. В случае затруднения команда lsmod покажет вам, какие модули загружены в данный момент, а файл помощи каждой опции поможет вам узнать имя модуля. Повторите этот процесс для разделов Ethernet (1000Mbit) и беспроводной сети [wireless LAN]. С удалением поддержки отсутствующих звуковых и видео карт торопиться не надо, этим мы займемся позже. Нажимайте Exit, пока не появится предложение сохранить файл настройки ядра – ответьте согласием.

Теперь пора скомпилировать и установить ваше новое ядро:

make all modules_install install

Сюда включены три шага: компиляция нового ядра и всех его модулей, установка модулей в /lib/modules/версия-ядра и, наконец, установка ядра в /boot. Прежде чем делать что-либо, проверьте, что загрузчик правильно настроен: на новое или на старое ядро. В /boot вы увидите, что make install поместил туда новое ядро.

В некоторых дистрибутивах make install способна на большее. Например, дистрибутивы на основе Debian, а также Gentoo и те, что используют скрипт Debian installkernel, создают еще и символьную ссылку: для нового ядра на vmlinuz, а для предыдущего на vmlinuz.old. Другие, как Mandriva, только копируют ядро и сопутствующие файлы. Чтобы поменьше печатать, я написал короткий скрипт для установки ссылок в таких дистрибутивах:

#!/bin/bash
cd /boot
NEW_KERNEL=$(ls -1rt vmlinuz-* | tail -n 1)
OLD_KERNEL=$(readlink vmlinuz)
NEW_VERSION=${NEW_KERNEL##vmlinuz-}
OLD_VERSION=${OLD_KERNEL##vmlinuz-}
for F in config System.map vmlinuz; do
    [ -f "${F}-${NEW_VERSION}" ] && ln -sf ${F}-${NEW_VERSION} ${F}
    [ -f "${F}-${OLD_VERSION}" ] && ln -sf ${F}-${OLD_VERSION} ${F}.old
done
[ -f "initrd-${NEW_VERSION}.img" ] && ln -sf initrd-${NEW_VERSION}.img initrd.img
[ -f "initrd-${OLD_VERSION}.img" ] && ln -sf initrd-${OLD_VERSION}.img initrd.img.old
 
[ -x /sbin/lilo ] && /sbin/lilo -v

Если вы отредактируете настройку загрузчика, вставив ссылки на vmlinuz и vmlinuz.old, то всегда сможете загрузить любое из ядер. При использовании Grub потребуется привести /boot/grub/menu.lst к следующему виду:

title Latest kernel
kernel /vmlinuz root=абв... и другие опции загрузки
title Previous kernel
kernel /vmlinuz.old root=абв... другие опции загрузки

Если вы используете Lilo, то должны сделать аналогичные изменения в настройке и не забыть запустить Lilo после установки нового ядра. Скрипт Debian installscript и скрипт, приведенный выше, позаботятся об этом за вас.

Осторожно, ловушки!

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


Есть пара ловушек для неосмотрительных, которые не позволяют системе загрузиться. При выборе файловой системы проверьте, что файловая система, используемая корневым разделом, встроена в ядро, а не является его модулем (подробности см. во врезке Драйверы: модули или встроенные?). Также проверьте, что вы включили поддержку вашего чипсета IDE, SATA или SCSI; они тоже должны быть встроены. Ядра, входящие в дистрибутивы, вполне могут компилировать критические участки кода как модули, потому что загружают их с загрузочного диска (initrd), размещаемого в оперативной памяти [ramdisk]. Ваш дистрибутив, возможно, использует файл initrd из /boot – его необходимо указать в настройках загрузчика.

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

При сборке сугубо личного ядра нужды в этом нет – все необходимые драйверы умещаются в ядре (у вас ведь только один контроллер диска и одна файловая система), а оставшиеся 99% опций можно выкинуть. Единственно, когда вам может понадобиться initrd при использовании самодельного ядра – это если вы захотите поумничать: управлять файловой системой через LVM или выводить чудо-экран во время загрузки системы.

(thumbnail)
Можете взять графический инструмент настройки, например, Make Xconfig.

Вернемся к нашей задаче. В этот раз мы использовали make menuconfig для настройки ядра. Преимущество этого способа в том, что он не использует X, поэтому вы можете использовать его даже удаленно через SSH. Но если вы предпочитаете графику, то существует парочка графических оболочек: Make xconfig и Make gconfig. Первая использует оболочку на основе Qt, вторая – на основе GTK. Они предоставляют многопанельный интерфейс, в котором одна панель отображает описание для текущей опции – полезно, когда вы просматриваете ядро в поисках того, что можете сделать. Альтернатива Qt также содержит опцию поиска, но она не так полезна, как в menuconfig, которая показывает вам, где расположена опция и что еще вам необходимо включить. Вы можете выбрать из трех альтернатив. Тяжело выбрать фаворита, поэтому попробуйте их все.

А вдруг вы решите взять исходные тексты ядра из других источников? Хороший вопрос. Пусть, например, поддержка вашего оборудования появилась только в последнем релиз-кандидате. Вы скачиваете архив исходных текстов ядра с http://www.kernel.org (пререлизы находятся в http://www.kernel.org/pub/linux/kernel/v2.6/testing), распаковываете его в /usr/src, меняете символьную ссылку linux способом, описанным выше, и копируете файл .config вашего предыдущего ядра в этот каталог.

Теперь вы понимаете, почему мы начали с исходных текстов вашего существующего ядра. Хотя вы и работаете с другой версией, большинство настроек следует сохранить. А если понадобятся новые настройки, как их найти и отрегулировать? Для этого существуют специальные средства. Сначала перейдите с помощью cd в /usr/src/linux и наберите

make oldconfig

Команда пройдется по вашему файлу настройки и предъявит вам все новые, еще не настроенные опции. Как обычно, для каждой опции вас попросят выбрать Y/M/N/?. Если сомневаетесь, жмите ?, и все о ней узнаете. Проделав все это, можете набрать make menuconfig/xconfig и подкорректировать параметры, а потом уж наберите make all modules_install install; ядро скомпилируется и установится как и ранее.

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

Латаем ядро

Мы уже почти закончили: по-моему, я рассказал о большинстве доводов для сборки своего ядра: уменьшение объема, включение новых возможностей и использование нового ядра. А как насчет заплаток на ядро? Да не убегайте, вернитесь! Не так все сложно. Предположим, что вы скачали нужную заплатку на ваше ядро, ну хоть Reiser4 для ядра 2.6.18.3 – поставьте ее следующим образом:

cd /usr/src/linux
gunzip reiser4-for-2.6.18-3.patch.gz
patch -p1 <reiser4-for-2.6.18-3.patch

Здесь подразумевается, что заплатки сжаты с помощью gzip (обычный вариант); ну, а если они сжаты с помощью bzip2, используйте bunzip2. Вы можете пропустить этап распаковки, если замените последние две строчки на эту (для заплатки, упакованной с помощью bzip2, используйте bzcat):

zcat reiser4-for-2.6.18-3.patch.gz | patch -p1

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

Применив заплатку, запустите make menuconfig/xconfig/oldconfig чтобы установить новые опции, затем запустите make all modules_install install. Если заплатка не срабатывает, вам может помочь изменение значения параметра -p. Взгляните в начало файла-заплатки: вы увидите нечто похожее на

--- linux-2.6.18.orig/arch/i386/lib/usercopy.c
+++ linux-2.6.18/arch/i386/lib/usercopy.c


Здесь указано имя файла, который будет изменен, а также сами изменения. Имя файла прописано относительно текущего каталога. Опция -p для патча определяет число ведущих каталогов (строго говоря, число слэшей) для удаления. Мы уже находимся в каталоге linux-2.6.18, поэтому -p1 удаляет эту часть пути и ищет файл arch/i386/lib/usercopy.c. Если бы мы были в каталоге /usr/src, нам понадобилось бы использовать опцию -p0, но в нашей конфигурации она не работает, потому что исходный каталог называется linux-2.6.18.3, а не linux-2.6.18. Применение заплатки из каталога /usr/src/linux обычно является наиболее безопасным выбором.

Все это может показаться ерундой, но при установке заплаток подбор верного значения -p часто оказывается сложнее всего прочего. Однако есть опция --dry-run, с которой вы можете начать. Она просто проверяет, корректно ли наложатся заплатки, не внося никаких изменений.

Одну заплатку наложить на ядро таким способом довольно просто. А вот в случае их множества могут возникнуть проблемы, так как разные заплатки могут менять одни и те же файлы. Тогда все зависит от порядка их наложения. Множество заплаток порождает множество опций. Можете посидеть в Google, или почитать рассылку Linux Kernel Mailing List, или придумать еще что-нибудь, чтобы заставить заплатки работать совместно. А можете применить коллекцию заплаток. Такие коллекции добавляют множество возможностей и расширений одной командой patch, и их довольно много: от уважаемых и стабильных до крайне рисковых. В первой группе прочно обосновался набор заплаток mm.

ММ, заплатки!

Набор заплаток mm подготовлен Эндрю Мортоном [Andrew Morton], хранителем ядра серии 2.6. Набор доступен на сайте http://www.kernel.org, и официальнее, чем он, неофициальному набору и быть нельзя. Он содержит заплатки, которые могут быть внесены в официальную ветку ядра 2.6 в будущем, но пока считаются недостаточно протестированными для повсеместного применения. В наборе mm изменено более 3 850 файлов (из почти 21 000 файлов, входящих в ядро) – можете представить, сколько работы потребуется для применения заплаток по отдельности.

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

cd /usr/src/linux-2.16.19-rc6
bzcat /path/to/2.6.19-rc6-mm1 | patch -p1

Затем настройте, исследуйте новые опции, скомпилируйте и установите. Теперь вы гордый владелец крутого, «пропатченного» ядра. Как видите, ничего страшного – но не обязательно этого рассказывать восхищенным новичкам Linux!


Персональные инструменты
купить
подписаться
Яндекс.Метрика