Данный опыт был проведен мной лишь после установки Debian Lenny 5.0.
Скажите, Вам когда нибудь хотелось учавствовать в разработке ядра Linux? Мало кто из пользователей линукса скажет Вам: 'А зачем мне оно надо?'. Но не у всякого хватает грамоты хотя-бы освоить как работает уже готовое ядро, даже при наличии исходников. Что же, мне тоже ее не хватает. Но несмотря на это у меня возникло желание обновить ядро. Для того что бы уже собранное ядро правильно запустить, необходимо знать как оно запускается. Но я постараюсь объяснить запуск ядра линукса в общих чертах.
Все мы (а может и не все) читали 'Руководство администратора'. Что же, заглянем туда. Часть Первая, Глава 12, страница 256, 'Построение двоичного ядра Linux' (третье издание, 2002 год). Практически ничего о работе ядра на запуске. Ничего не остается кроме как 'Сделай сам!'. Так и сделаем.
Итак начнем. Ядро я взял не самое новое на этот день - 2.6.31.3. Берем мы его с http://www.kernel.org/. Дальше в поисках ядра думаю всякий найдет дорогу. Ух-х, скопировали.
Взяли то мы его в виде linux-2.6.31.3.tar.gz. Распакуем его в /usr/src/linux-2.6.31.3.
Теперь там будут лежать исходники этого ядра.
- Ну распаковал я исходник, а дальше то что, make?
- Нет, сначала необходимо его сконфигурировать.
- А что конфигурировать-то? Ядра ведь еще нет!..
Абсолютно верно! Ядра еще нет! А конфигурировать мы будем не само ядро, а процесс его компиляции.
вводим в терминале из под root'а
# cd /usr/src/linux-2.6.31.3
Теперь пойдет процесс конфигурирования процесса компиляции ядра.
Вводим одно из
# make config -- если вы понимаете, что такое CONFIG_CGROUP_CPUACCT и подобное
# make menuconfig -- более наглядный способ консольного конфигурирования, использует библиотеку curl
# make xconfig -- графический диалог, использует библиотеки QT
# make gconfig -- графический диалог, использует библиотеки GTK
В процессе кофигурирования отмечаем, что компилировать монолитно с ядром, а что как подключаемые по требованию модули. Кое-что и вовсе нужно будет отключить. Что и как компилировать? Право ответа на это вопрос передаю читателю. Этот выбор зависит от машины, и ее назначения. Признаюсь - я оставил все по умолчанию, кроме беспроводной сети, файловых систем, и процессора.
Идем далее.
# make clean -- сейчас очистка уже не используется, но в старых ядрах еще применима и требуема.
# make bzImage -- а вот и ядрышко!!!
После этого ядро будет лежать в директории ./arch/<ваша машина>/boot и называться оно будет bzImage.
Говоря <ваша машина>, я имею ввиду ее архитектуру, например у вас процессор из серии 86-ых, Значит вам в директорию x86. Аналогично с другими процессорами.
Теперь, если вы что-то компилировали как отдельные модули, введите
# make modules
# make modules_install
Теперь в директории /lib/modules/2.6.31.3/ появились наши модули.
Ну все, кажется, можно запускать. Скопировали /usr/src/linux-2.6.31.3/arch/<ваша машина>/boot/bzImage в /boot/vmlinuz-2.6.31.3
Добавили новую запись в menu.lst или lilo.conf. Перезаписали загрузчик. Перезапустились. А ядро-то не запускается!.. Что-же делать, как-же быть?А вот как:
ядру требуется стартовый электронный диск, то же что и initrd, initial ram fs, initial ram disk.
Посмотрим на любой имеющийся файл стартового электронного диска, например /boot/initrd.img-2.6.26
Это gzip-архив. После распаковки это будет cpio-архив.
Заглянем внутрь.
И видим там директории
/bin
/conf
/etc
/lib
/lib
/sbin
/scripts
и файл init. Теперь понятно, часть жизненно необходимых модулей уже лежит в директории /lib в initrd.
Например там есть драйверы файловых систем.
- Но зачем нам нужен initrd? Разве нельзя просто запустить ядро?
- Можно!.. Только тогда все модули нужно делать монолитом с ядром. Да и в общем случае это зависит от внутренней работы ядра.
Вот как работает ядро на запуске.
Ядру кроме всяких прочих параметров передается еще и параметр с указанием местоположения initrd, а может initrd уже есть в памяти до запуска ядра, этот момент немного спорный потому, как в ядре уже должен быть какой-нибудь драйвер файловой системы.
- Что же происходит далее?
- А далее происходит монтирование _БУДУЩЕГО_ корневой директорией. и выполнение init с корневой диреткорией где уже смонтирована _БУДУЩАЯ_ корневая ФС.
- Значит, если так можно сказать, init запущен в другой ФС, и ему доступен электронный стартовый диск?
- Нет. Он запущен через chroot, что не дает ему возможности видеть дальше чем разрешено. Но вот ядро наверное видит этот initrd.
Итак мы знаем что такое initrd, знаем его назначение и примерное устройство. Как же его соорудить? Может вручную? Можно сделать и вручную, но работать он не будет, потому как... Лучше посмотрите на initrd.img и на сооруженный вами такой же initrd.my.img. Видите разницу? Местная программа gzip добавляет свой заголовок, в то время как у нормального initrd.img его либо нет, либо он другой (не могу сказать точно - по причине не знания формата gz).
В директории где откомпилировано ядро (/usr/src/linux-2.6.31.3/) есть директория ./usr/ туда и перейдем. Но вообще, мохно о не переходить.
Теперь нам нужен пакет initramfs-tools. Он содержит программу mkinitramfs.
Запустим ее из-под root'а (ее только root и имеет право запускать), в директории /usr/src/linux/2.6.31.3/usr/
# mkinitramfs -o ./../initramfs.img 2.6.31.3
Сначала указываем ключ '-o' за которым дожно следовать название выходного файла, затем - номер версии (выпуска), которому соответствуют нужные модули.
Копируем /usr/src/linux-2.6.31.3/initramfs.img в /boot/initrd.img-2.6.31.3
Добавляем его в menu.lst или lilo.conf, перезаписываем загрузчик, перезапускаемся, запускаем новое ядро. И со спокойной душой можем говорить что мы -
МегоМозг скомпилировавший ядро из исходников!