понедельник, 11 апреля 2011 г.

Компилируем ядро Linux в Ubuntu


Итак, для начала разберемся что такое ядро и с чем его едят.


А что же такое - ядро?
К этому вопросу следует подходить со всей ответственностью, поэтому обратимся к материалу википедии.

Linux — ядро операционной системы, соответствующее стандартам POSIX. Разработка была начата финским студентом Линусом Торвальдсом в 1991 году.
В основном код написан на Си с некоторыми расширениями gcc и на ассемблере (с использованием AT&T-синтаксиса GNU Assembler).


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


А что собираемся делать?

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

А где взять исходники ядра и какие они бывают?

На самом деле есть много разных вариаций ядра - с патчами для ubuntu, с патчами для gentoo и еще всякие разные. В моем посте я буду рассматривать так называемые "ванильные" ядра. Это ядра, взятые непосредственно с сайта kernel.org. Эти ядра находятся в таком состоянии, в каком их непосредственно оставили разработчики: то есть без всяких патчей и прочих плюшек.


Ну и ваша цель - зайти на kernel.org и скачать последнюю стабильную версию ядра. На данный момент это версия 2.6.37




Я готов! Терминал открыт! Погнали!

Сразу предупрежу, работать мы будем в папке /usr/src. В консоли лучше сразу перейти туда и с помощью wget скачать исходники.
  1. Качаем исходники ядра:

    sudo apt-get install wget
    cd /usr/src
    sudo wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.37.tar.bz2
  2. Итак, для начала вам понадобятся пакеты для компиляции и сборки ядра в пакет .deb

    sudo apt-get install fakeroot build-essential libc6-dev gcc binutils-dev
  3. Далее для удобства я посоветую вам сидеть под рутом. Только никому ни слова! И никаких лишний телодвижений! ;)

    sudo -s
  4. Итак, теперь работаем под рутом. И в папке /usr/src. Распакуем наш архив:

    tar xvf linux-2.6.37.tar.bz2
  5. Теперь в появилась папка /usr/src/linux-2.6.37. Далее перейдем в нее:

    cd /usr/src/linux-2.6.37
  6. Скопируем старый конфиг в папку с исходниками, только с именем .config
    тут уже понадобится пораскинуть мозгами и выбрать конфиг последнего ядра (ну или не последнего, как больше нравится)
    Конфиги лежат в папке /boot и имеют имя вида config-2.6.xx-xx-generic (например, config-2.6.35-25-generic). Чтобы посмотреть какие конфиги ядра лежат, выполните следующую команду:

    ls /boot | grep config

    Выбираете самый последний и копируете в папку с исходниками (покажу на примере со своим конфигом, не забудьте поменять циферки):

    cp /boot/config-2.6.35-25-generic .config
  7. Далее нужно как-то назвать свое ядро:

    gedit Makefile

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

    EXTRAVERSION = -tratata
  8. А теперь самое интересное! Начинаем компиляцию:

    make-kpkg -j%number% --initrd --revision=0.01 kernel_image kernel_headers

    Жирным я выделил версию ядра, которую вы можете сами поменять на какую захочется. Главное - это число. А так же %number%, который надо изменить на число = числу ядер + 1

    И еще один момент. Вам будет предложено дофига вопросов какие фичи подключить. На данный момент тыкайте Enter - будут выбраны значения по умолчанию. Я вот вообще зажал его и не отпускал пока не кончились вопросы :D
  9. После того, как вы отдохнули и попили чайку (ну и ядро, конечно же, собралось), необходимо перейти в директорию /usr/src и увидеть там два готовых deb-пакета. Ну и поставить их :)

    cd ..
    dpkg -i *.deb
  10. Ну а дальше осталось только уйти в ребут и загрузиться из нового ядра :) 
 Теперь отдельно поговорим о конфигурировании ядра.

Вообще, для начала, определимся, что вообще значит "сконфигурировать ядро".
Как известно, исходники ядра содержат в себе массу компонентов, которые пользователь может выбирать. Цель единственная - получить работающее, грамотно сконфигурированное ядро. Ну и, так уж вышло, вам требуется только выбрать как тот или иной компонент будет участвовать в системе. Он может вообще не присутствовать, может быть вшитым в ядро, либо (если это возможно) работать в качестве модуля.
Утилит не так уж и много, всего 5 (безусловно, если и еще, но это не входит в данный пост).
  1. make config
  2. make oldconfig
  3. make menuconfig
  4. make xconfig
  5. make gconfig
Для удобства опущу make.
Config задает стопицот вопросов. На мой взгляд, это не очень удобно. :)

Oldconfig делает простую вещь - смотрит на .config и задает кучу вопросов по поводу новых фич в ядре.

Menuconfig - консольная утилита с горячим клавишами и текстовыми кнопками :)
Что бы menuconfig заработал - необходимо поставить libncurses5-dev

sudo apt-get install libncurses5-dev


Xconfig - по функционалу ровно такой же как menuconfig. Только имеет графический интерфейс. На мой взгляд, это самый удобный вариант, потому что эта утилита разбита на 3 части: дерево, список опций, и описание выделенной опции. Очевидно, что удобно никуда не тыкаясь, читать нужную информацию.
Чтобы xconfig заработал, надо установить следующие библиотеки:
sudo apt-get install libqt3-headers libqt3-mt-dev

Как вы видите, это библиотеки qt3. Есть возможность использовать qt4, но я не знаю что нужно ставить, да и не сильно интересно. Все-таки порой приятно вспомнить 2008 год, когда я впервые с ядром возился :)
Gconfig - вроде бы то же, что и xconfig, но почему-то он мне в свое время не понравился. Да и лень искать все либы для него. Если кто-нибудь в комментариях выскажется в его пользу и расскажет, что и где брать, чтобы заработало, я с удовольствием внесу исправления :)
Предлагаю вам выбирать между xconfig и menuconfig. И всем советую не забывать сохраняться по завершении настройки. 
Определимся с очисткой исходников от собранного ранее
Все-таки иногда приходится одно и тоже ядро пересобирать несколько раз. Чтобы не возникало ошибок при повторной компиляции нужно чистить объектные файлы, которые уже были созданы. Конечно, с одной стороны может показаться, что созданные ранее объектные файлы помогут быстрее собрать новую конфигурацию ядра по очевидным причинам. Но все порой возникают неприятные ошибки, которые устранялись только чисткой.
Для этого случая есть 2 утилиты:
  1. make-kpkg clean
  2. make mrproper
make-kpkg clean - приятная утилита, которая рекурсивно по папкам стирает весь хлам. Заметьте, конфиг ваш она не тронет!
make mrproper - судя по моим наблюдениям, делает тоже, что и make-kpkg clean + стирает .confi
 Вводим и вперед
  make xconfig (например)

И начинаете настраивать.
Если вы уже собирали ядро, но мусор не почистили, то я советую заранее сделать

make-kpkg clean