Linux from scratch kernel

What is Linux From Scratch?

Linux From Scratch (LFS) is a project that provides you with step-by-step instructions for building your own customized Linux system entirely from source.

Why would I want an LFS system?

Many wonder why they should go through the hassle of building a Linux system from scratch when they could just download an existing Linux distribution. However, there are several benefits of building LFS. Consider the following:

LFS teaches people how a Linux system works internally
Building LFS teaches you about all that makes Linux tick, how things work together and depend on each other. And most importantly, how to customize it to your own tastes and needs.

Building LFS produces a very compact Linux system
When you install a regular distribution, you often end up installing a lot of programs that you would probably never use. They’re just sitting there taking up (precious) disk space. It’s not hard to get an LFS system installed under 100 MB. Does that still sound like a lot? A few of us have been working on creating a very small embedded LFS system. We installed a system that was just enough to run the Apache web server; total disk space usage was approximately 8 MB. With further stripping, that can be brought down to 5 MB or less. Try that with a regular distribution.

LFS is extremely flexible
Building LFS could be compared to a finished house. LFS will give you the skeleton of a house, but it’s up to you to install plumbing, electrical outlets, kitchen, bath, wallpaper, etc. You have the ability to turn it into whatever type of system you need it to be, customized completely for you.

LFS offers you added security
You will compile the entire system from source, thus allowing you to audit everything, if you wish to do so, and apply all the security patches you want or need to apply. You don’t have to wait for someone else to provide a new binary package that (hopefully) fixes a security hole. Often, you never truly know whether a security hole is fixed or not unless you do it yourself.

What can I do with my LFS system?

A by-the-book LFS system is fairly minimal, but is designed to provide a strong base on which you can add any packages you want. See the BLFS project for a selection of commonly used packages.

Who’s who:

  • Project Creator: Gerard Beekmans
  • Managing Editor: Bruce Dubbs
  • Editor: Ken Moffat
  • Editor: Pierre Labastie
  • Editor: DJ Lucas
  • Editor: Douglas R. Reno
  • Editor: Thomas Trepl
  • Editor: Tim Tassonis
  • Editor: Xi Ruoyao
  • Plus numerous people who contribute to the book and its side projects.

© 1998-2021 Gerard Beekmans. Website design by Jeremy Huntwork & Matthew Burgess.

Источник

Как собрать ядро Linux с нуля

Обновл. 18 Июн 2021 |

Ядро Linux является основой дистрибутивов Linux. Оно связывает аппаратное и программное обеспечение компьютера, а также отвечает за распределение доступных ресурсов.

Если вы хотите отключить несколько опций и драйверов или попробовать экспериментальные исправления, то вам необходимо будет собрать ядро вручную. В этой статье вы узнаете, как с нуля самостоятельно скомпилировать и установить ядро Linux.

Сборка ядра Linux

Процесс сборки ядра Linux состоит из семи простых шагов. Однако для выполнения этой процедуры вам потребуется значительное количество времени (зависящее от характеристик вашего компьютера).

Примечание: Для сборки ядра Linux я выделил следующие ресурсы:

виртуальная машина — VMware Workstation 15 Pro (15.5.6);

дистрибутив — Debian Linux (ветка Testing);

ресурсы — 2 ядра CPU (Ryzen 5 1600 AF), 2GB RAM, HDD;

время компиляции — 3+ часа.

После этого я попробовал собрать ядро еще раз, перенеся образ виртуальной машины на NVMe SSD A-Data XPG SX8200 Pro (1TB), а также увеличив количество доступных для виртуальной машины ядер CPU до 6, а RAM — до 4GB. В таком варианте время компиляции составило около 1.5 часов.

Шаг №1: Загрузка исходного кода

Откройте сайт kernel.org и найдите архив с исходными кодами самой свежей версии ядра (Latest Release).

Читайте также:  Ярлык удаленного доступа windows 10

Примечание: Не пугайтесь, если версия ядра на сайте kernel.org не совпадает с той, которую я использовал на данном уроке. Все рассмотренные шаги/команды работоспособны, просто вам придется заменить цифры в версии ядра на свои.

Затем откройте терминал и с помощью команды wget скачайте архив с исходным кодом ядра Linux:

Шаг №2: Распаковка архива с исходным кодом

Распакуем архив, применив команду tar :

$ tar xvf linux-5.12.10.tar.xz

Шаг №3: Установка необходимых пакетов

Нам потребуются дополнительные утилиты, с помощью которых мы произведем компиляцию и установку ядра. Для этого выполните следующую команду:

Пользователям Debian/Ubuntu/Linux Mint:

$ sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

Данная команда установит следующие пакеты:

Пакет Описание
git Утилита, помогающая отслеживать изменения в файлах исходного кода. А в случае какой-либо ошибки, эти изменения можно будет откатить.
fakeroot Позволяет запускать команду в среде, имитирующей привилегии root.
build-essential Набор различных утилит для компиляции программ (компиляторы gcc, g++ и пр.).
ncurses-dev Библиотека, предоставляющая API для программирования текстовых терминалов.
xz-utils Утилита для работы с архивами в .xz-формате.
libssl-dev Библиотека для разработки и поддержки протоколов шифрования SSL и TLS.
bc (Basic Calculator) Интерактивный интерпретатор, позволяющий выполнять скрипты с различными математическими выражениями.
flex (Fast Lexical Analyzer Generator) Утилита генерации программ, которые могут распознавать в тексте шаблоны.
libelf-dev Библиотека, используемая для работы с ELF-файлами (исполняемые файлы, файлы объектного кода и дампы ядра).
bison Создает из набора правил программу анализа структуры текстовых файлов.

Пользователям CentOS/RHEL/Scientific Linux:

$ sudo yum group install «Development Tools»

$ sudo yum groupinstall «Development Tools»

Также необходимо установить дополнительные пакеты:

$ sudo yum install ncurses-devel bison flex elfutils-libelf-devel openssl-devel

Пользователям Fedora:

$ sudo dnf group install «Development Tools»
$ sudo dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel

Шаг №4: Конфигурирование ядра

Исходный код ядра Linux уже содержит стандартный файл конфигурации с набором различных настроек. Однако вы можете сами изменить его в соответствии с вашими потребностями.

Для этого перейдите с помощью команды cd в каталог linux-5.12.10:

Скопируйте существующий файл конфигурации с помощью команды cp :

$ sudo cp -v /boot/config-$(uname -r) .config

Чтобы внести изменения в файл конфигурации, выполните команду make :

Данная команда запускает несколько сценариев, которые далее откроют перед вами меню конфигурации:

Меню конфигурации включает в себя такие параметры, как:

Firmware Drivers — настройка прошивки/драйверов для различных устройств;

Virtualization — настройки виртуализации;

File systems — настройки различных файловых систем;

Для навигации по меню применяются стрелки на клавиатуре. Пункт H elp > поможет вам узнать больше о различных параметрах. Когда вы закончите вносить изменения, выберите пункт S ave > , а затем выйдите из меню с помощью пункта E xit > .

Примечание: Изменение настроек некоторых параметров может привести к тому, что в вашем новом ядре будет отсутствовать поддержка жизненно важных для системы функций. Если вы не уверены, что нужно изменить, то оставьте заданные по умолчанию настройки.

Примечание: Если вы использовали вариант с копированием файла конфигурации, то перед переходом к следующему шагу, откройте этот файл и проверьте, что параметр CONFIG_SYSTEM_TRUSTED_KEYS у вас определен так же, как указано на следующем скриншоте:

В противном случае вы можете получить ошибку:

make[4]: *** No rule to make target ‘debian/certs/test-signing-certs.pem’, needed by ‘certs/x509_certificate_list’. Stop.
make[4]: *** Waiting for unfinished jobs.

Шаг №5: Сборка ядра

Для старта сборки ядра выполните следующую команду:

Процесс сборки и компиляции ядра Linux занимает довольно продолжительное время.

Во время этого процесса в терминале будут перечисляться все выбранные компоненты ядра Linux: компонент управления памятью, компонент управления процессами, драйверы аппаратных устройств, драйверы файловых систем, драйверы сетевых карт и пр.

Затем нужно будет установить модули с помощью следующей команды:

$ sudo make modules_install

Осталось произвести установку нового ядра. Для этого необходимо выполнить:

$ sudo make install

Шаг №6: Обновление загрузчика

Загрузчик GRUB — это первая программа, которая запускается при включении системы.

Пользователям Debian/Ubuntu/Linux Mint:

Команда make install автоматически обновит загрузчик.

Для того, чтобы обновить загрузчик вручную, вам необходимо сначала обновить initramfs до новой версии ядра:

$ sudo update-initramfs -c -k 5.12.10

Затем обновить загрузчик GRUB с помощью следующей команды:

Пользователям CentOS/RHEL/Scientific Linux :

$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
$ sudo grubby —set-default /boot/vmlinuz-5.6.9

Вы можете подтвердить детали с помощью следующих команд:

grubby —info=ALL | more
grubby —default-index
grubby —default-kernel

Шаг №7: Перезагрузка системы

После выполнения вышеописанных действий перезагрузите свой компьютер. Когда система загрузится, проверьте версию используемого ядра с помощью следующей команды:

Как видите, теперь в системе установлено собранное нами ядро Linux-5.12.10.

Поделиться в социальных сетях:

Источник

Делаем из Linux From Scratch свой универсальный дистрибутив

Так уж случилось, что пару лет назад по долгу службы на команду разработчиков, к которой я отношусь, свалилась неожиданная задача — разработка системы управления оборудованием (в этом-то как-раз неожиданности нет, ибо направление разработок такое) с управляющим PC под Linux.
Разработки линуксовой части велись (да и ведутся) под Ubuntu, в среде Code::Blocks. Но, как показала практика, для качественной работы нужно что-то гораздо более легкое с гарантированным временем отклика. Для работы было достаточно консоли, так как задачи организации пользовательского интерфейса решались на подключаемом по TCP/IP удаленном компьютере.
Тогда и пришла идея использовать дистрибутив Linux собственной сборки, чем (сборкой дистрибутива), собственно, в свободное время я и занялся. Выбор пал на LFS. Про то что такое LFS уже неоднократно писали даже на Хабре, я же опишу решение нескольких дополнительных (кроме простенького Linux’а) задач, вставших передо мной в нашем конкретном случае.
Поначалу такая задача была одна — использовать real-time ядро.
Однако дальше, когда идея USB-флешки с дистрибутивом, пришлась всем по душе, то появились задачи размножения флешек и запуска системы на различных компьютерах (тестовых стендов много, имея свою флешку суешь в карман и иди к любому). Вот тут и появились проблемы — LFS не обладает 100% переносимостью с одного компьютера на другой. Для ее адаптации к конкретному компьютеру нужно править некоторые скрипты, что в условиях команды вчерашних Windows-кодеров проблематично (на виртуалку с Ubuntu некоторые пересели, но консоль и скрипты — это беда). Размножение системы также требует повторения некоторых манипуляций, проделываемых в процессе сборки (тот же GRUB установить).

Читайте также:  Астра линукс настройка сканера

Естественно, решение всех задач есть на просторах интернета, но, думаю, сбор некоторой информации в одном месте никому не помешает.
Итак, конкретные задачи были следующие…

1. Использование ядра Linux с real-time патчем

Это была одна из самых легких задач. Процесс сборки прошел по книге LFS с единственным исключением — вместо штатного для книги ядра было взято 2.6.33.9 и RT-патч для него. Везде, где происходили манипуляции с ядром (установка Linux Headers и ядра непосредственно), работаем с нашей пропатченной версией.
Также не лишним будет сказать, что дистрибутив собирался без подключения swap-раздела (2Гб ОЗУ это в нашем случае — выше крыши, наличие swap не желательно по причине его негативного влияния на гарантированное время отклика, да и для флешки он крайне губителен) и представлял собой один единственный раздел ext2fs.

2. Автоматический вход в систему (в условиях разработки безопасность нам не важна, да и систему пускаем под рутом по ряду причин)

Идея автоматического входа была взята отсюда.
Был создан файл autologin.c следующего содержания:

Далее файл был скомпилирован командой:

gcc autologin.c -o /usr/local/sbin/autologin

Далее было решено, что двух консолей с автоматическим входом хватит (одна для запуска системы, другая для всего остального, если понадобится).
В файле /etc/inittab строчки:

1:2345:respawn:/sbin/agetty tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600

были заменены на:

1:2345:respawn:/sbin/agetty -n -l /usr/local/sbin/autologin tty1 9600
2:2345:respawn:/sbin/agetty -n -l /usr/local/sbin/autologin tty2 9600

После этого никаких проблем с автоматическим входом не было, поэтому никаких дополнительных манипуляций со скриптами не было.

3. Отвязывание системы от порядка подключения дисков

У разных BIOS свои заморочки. Одни, например, считают, что первым является тот диск, с которого мы загружаемся. В этом случае наша флешка будет sda. Другие считают, что сначала должны идти жесткие диски, а потом другие устройства. В этом случае наша флешка будет иметь имя sdb, sdc и так далее.
В результате, то система не может загрузиться с диска, которого нет, то корневой каталог не может быть смонтирован по той причине, что в /etc/fstab указан не тот диск.
Все решается либо исправлением /boot/grub/grub.cfg и /etc/fstab под конкретную машину или использованием для загрузки и монтирования не имени диска (sda, sdb и т. д.), а UUID файловой системы, который для данной файловой системы на флешке будет уникален и, что самое главное — постоянен.
Проблема в том, что GRUB работать с UUID умеет, а ядро — нет, то есть напрямую монтировать корневую систему по UUID (не зная имени устройства) невозможно. Это не баг, а следствие идейных соображений Линуса Торвальдса, поэтому на такую возможность и в будущем надеяться не стоит. Тем не менее пути обхода есть — это initramfs.
Initramfs — временная файловая система, помогающая в загрузке и монтировании файловых систем настоящей системы.
В стандартную сборку LFS initramfs не входит, поэтому для ее построения воспользуемся рекомендациями из Gentoo Wiki и некоторыми собственными соображениями (вариант из Gentoo Wiki без изменений в моем случае проблему с именами дисков не решил, да и не заработал толком).
Для создания простейшей initramfs системы, монтирующей нашу основную по UUID нужна простейшая командная оболочка (shell) и скрипт init. Полный набор утилит командной строки достаточно громоздок для initramfs, поэтому часто для этой цели применяется busybox, который при скромных размерах и требованиях реализует некоторые, наиболее часто используемые утилиты.
Забираем последнюю версию busybox:

Читайте также:  Не удается инициализировать установщик службы windows search

Распаковываем и конфигурируем:

tar jxf busybox-1.18.4.tar.bz2
cd busybox-1.18.4
make menuconfig

Конфигурирование производится при помощи меню (наподобие ядра Linux). В принципе, стандартной конфигурации хватает для наших нужд, но, на всякий случай, стоит проверить, что подключены следующие возможности:
Support for devfs — поддержка devfs для работы с /dev.
Build Busybox as a static library (no shared libraries) — статическая компоновка, чтобы не тянуть за собой кучу so-библиотек.
Support version 2.6.x Linux kernels — поддержка ядер линейки 2.6.
А также поддержка функциональности утилит: sh, cat, cut, findfs, mount, umount, sleep, echo, switch_root.

Теперь собираем дерево каталогов нашей файловой системы:

mkdir /usr/src/initramfs
cd /usr/src/initramfs
mkdir -p bin lib dev etc mnt/root proc root sbin sys
cp -a /dev/ /usr/src/initramfs/dev/

Копируем busybox и создаем линки на утилиты:

cp /sources/busybox-1.18.4/busybox ./bin/
cd bin
ln -s busybox sh
ln -s busybox cat
ln -s busybox cut
ln -s busybox findfs
ln -s busybox mount
ln -s busybox umount
ln -s busybox sleep
ln -s busybox switch_root
cd ..

Осталось написать скрипт init:

Делаем наш скрипт исполняемым:

chmod +x /usr/src/initramfs/init

Собираем нашу временную файловую систему в архив:

cd /usr/src/initramfs
find . -print0 | cpio —null -ov —format=newc | gzip -9 > /boot/initrd.img-2.6.33-rt31

Обратим внимание на имя файла — оно должно соответствовать имени ядра (это нужно, чтобы GRUB его правильно подцепил). То есть, если ядро имеет имя vmlinux-2.6.33-rt31, то initramfs должен иметь имя initrd.img-2.6.33-rt31.

Теперь при выполнении grub-mkconfig GRUB обнаружит initramfs, а также включит в конфигурацию UUID корневой системы. Для проверки можно поправить /boot/grub/grub.cfg руками. Например конфигурацию:

menuentry «Linux 2.6.33-rt31» —class gnu-linux —class gnu —class os <
insmod ext2
set root='(hd0,1)’
search —no-floppy —fs-uuid —set 47029df8-8567-417d-b813-eedfe1ff8b0f
linux /boot/vmlinux-2.6.33-rt31 root=/dev/sda1 ro
>

menuentry «Linux 2.6.33-rt31» —class gnu-linux —class gnu —class os <
insmod ext2
set root='(hd0,1)’
search —no-floppy —fs-uuid —set 47029df8-8567-417d-b813-eedfe1ff8b0f
linux /boot/vmlinux-2.6.33-rt31 root=UUID=47029df8-8567-417d-b813-eedfe1ff8b0f ro
initrd /boot/initrd.img-2.6.33-rt31
>

UUID файловой системы можно узнать так (например, для /dev/sdb1):

blkid -p -o udev /dev/sdb1

Осталось поправить /etc/fstab, заменив строчку:

/dev/sda1 / ext2 defaults 1 1

UUID= 47029df8-8567-417d-b813-eedfe1ff8b0f / ext2 defaults 1 1

Также следует заметить, что для всех манипуляций выше необходимо, чтобы в ядре была включена поддержка devtmpfs (CONFIG_DEVTMPFS=y) и initramfs (CONFIG_BLK_DEV_INITRD=y).

4. Отвязывание системы от сетевой карты

Если в компьютере установлено более одной сетевой платы, то при параллельной загрузке модулей ядра не гарантируется постоянное назначение имен этим платам. Например, есть две платы. Плата_1 имеет имя интерфейса в системе eth0, Плата_2 — eth1. При очередной перезагрузке может получиться так, что Плата_1 станет eth1, а Плата_2 — eth0.
С этой целью в LFS производится привязка имени к конкретной плате. При загрузке на другом компьютере очень велика вероятность, что сеть не поднимется.
В моем конкретном случае плата на всех компьютерах одна и IP — статический (связь только с терминальным компьютером напрямую).
Поднятие сетевого интерфейса в LFS осуществляется скриптом /etc/rc.d/init.d/network. Допишем скрипт так, чтобы каждый раз при загрузке генерировался конфигурационный файл /etc/udev/rules.d/70-persistent-net.rules и при завершении работы этот файл удалялся. Подозреваю, что есть метод проще, но найденный метод заработал, а копаться в принципах работы Udev времени и особого желания на момент сборки системы не было.
В начало раздела start команды case добавляем:

А в конец секции stop (непосредственно перед ;;) добавляем:

Теперь при загрузке на любой системе имя сетевого интерфейса будет eth0 (кроме самых экзотических случаев) и сеть будет подниматься. Разумеется, каталог /etc/sysconfig/network-devices/ifconfig.eth0 с файлом ipv4 должен существовать. Содержимое этого файла описано в книге LFS.

5. Написание скрипта, производящего инсталляцию LFS на любую флешку

Осталось последнее — сделать архив системы и скрипт, который будет ее устанавливать на произвольный носитель.
Загружаемся в другой системе (не с флешки), монтируем флешку, например в /mnt/usb-os. Архивируем содержимое:

cd /mnt/usb-os
tar -cvjf

Пишем скрипт для установки install_usb-os.sh. В качестве параметра скрипт принимает имя устройства, на котором необходимо развернуть систему (например /dev/sdb). Скрипт сам создаст необходимый раздел и файловую систему (/dev/sdb1, если указано имя /dev/sdb), распакует архив и установит GRUB.

Запускаться он должен с правами root и, на самом деле, очень опасен.
В случае неверного указания имени устройства могут быть уничтожены все данные на рабочем диске!

Источник

Оцените статью