Пост

Linux From Scratch. Введение

Мне понадобился минимальный Linux, который бы удовлетворял следующим требованиям:

  • Максимально оптимизированная система;
  • Возможность полностью контролировать компоненты системы;
  • Иметь полный контроль над системой в целом.

Поэтому я принял решение собрать LFS.
Опыт сборки уже был, примерно год назад я собирал LFS, а потом и BLFS, правда BLFS я не дособрал.
Сборка LFS у меня еще работает и осталась, но хочется собрать все по новой и сделать дополнительные заметки по сборке.

Сам по себе мануал по сборке LFS написан очень подробно и хорошо, поэтому переписывать его целиком не вижу смысла, но основные проблемы с которыми я буду сталкиваться я постараюсь описать подробно, а также все дополнительные настройки и “ковыряние” в исходиках разных пакетов.

Требования к хост-системе

Основной раздел из мануала

По требованиям к системе, на которой будет собираться LFS - требуется как минимум 4 ядра и 8GB оперативной памяти. Это оправданные рекомендации, в целом чем больше тем лучше, потому что собираться это все дело даже на 4 ядрах будет довольно таки долго…

Я буду собирать всё на физической машине со следующими характеристиками:

OSKernelCPURAMStorage
Fedora Linux 396.5.6-300.fc39.x86_64AMD Ryzen 9 5950X128 GBSSD на 240G

Требования к софту на хост-системе

Версии софта на моей хост-системе:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
OK:    Coreutils 9.3    >= 7.0
OK:    Bash      5.2.15 >= 3.2
OK:    Binutils  2.40   >= 2.13.1
OK:    Bison     3.8.2  >= 2.7
OK:    Diffutils 3.10   >= 2.8.1
OK:    Findutils 4.9.0  >= 4.2.31
OK:    Gawk      5.2.2  >= 4.0.1
OK:    GCC       13.2.1 >= 5.1
OK:    GCC (C++) 13.2.1 >= 5.1
OK:    Grep      3.11   >= 2.5.1a
OK:    Gzip      1.12   >= 1.3.12
OK:    M4        1.4.19 >= 1.4.10
OK:    Make      4.4.1  >= 4.0
OK:    Patch     2.7.6  >= 2.5.4
OK:    Perl      5.38.0 >= 5.8.8
OK:    Python    3.12.0 >= 3.4
OK:    Sed       4.8    >= 4.1.5
OK:    Tar       1.35   >= 1.22
OK:    Texinfo   7.0.3  >= 5.0
OK:    Xz        5.4.4  >= 5.0.0
OK:    Linux Kernel 6.5.6 >= 4.14
OK:    Linux Kernel supports UNIX 98 PTY
Aliases:
OK:    awk  is GNU
ERROR: yacc is NOT Bison
OK:    sh   is Bash
Compiler check:
OK:    g++ works

Скрипт для проверки, находится ниже по тексту Основного раздела из мануала

Есть одна ошибка: ERROR: yacc is NOT Bison.
Так как Bison является заменой YACC, нужно сделать враппер, который будет запускать YACC из Bison.

Из man bison:

1
2
-y, --yacc
       emulate POSIX Yacc

Файл нужно создать в переменных $PATH. Я разместил скрипт в /usr/bin.
Оригинальный YACC переименовал: mv /usr/bin/yacc /usr/bin/yacc_orig

Враппер /usr/bin/yacc:

1
2
3
4
5
6
7
8
#!/usr/bin/env bash
BISON=$(which /usr/bin/bison)
if [ -z "$BISON" ]; then
	echo "bison not found"
	exit -1
fi

$BISON -y "$@"

И не забываем сделать chmod +x /usr/bin/yacc.

После добавления враппера, ошибка должна уйти:

1
2
[spybull@fedora ~]$ bash version-check.sh  | grep yacc
OK:    yacc is Bison

Требования к разметке диска

Основной раздел из мануала

Я буду использовать весь диск целиком под систему. Общий объем которого составляет 240GB.

Схема разметки

PartitionFilesystemSizeMount PointDescription
/dev/sda1fat32600 MB/boot/efiСистемный раздел EFI
/dev/sda2ext41 GB/bootРаздел для хранения ядра, initramfs и т.д
/dev/sda3отсутсвуетвсё что осталосьотсутсвуетРаздел под LVM

Схема разметки LVM

pvvglvfssize
/dev/sda3lfsrootext415 GB
/dev/sda3lfsswapswap4 GB
/dev/sda3lfshomeext420 GB

Этого достаточно, остальное место можно оставить свободным и в будущем расширить или добавить отдельные тома LVM.

Подготовка диска под систему

Для создания таблицы разделов буду использовать parted.
Заходим в утилиту parted /dev/sda и далее идет список команд, которые использовались для создания разделов:

Разметка диска с помощью parted

1
2
3
4
5
6
7
unit MiB
mklabel gpt
mkpart primary fat32 1MiB 600MiB
mkpart primary ext4 601MiB 1625MiB
mkpart primary 1625MiB 100%
set 1 boot on
set 3 lvm on

Для удобства я выбрал юниты MiB. Эти единицы удобнее использовать, потому что MB = 1000/MiB = 1024

Настройка LVM

1
2
3
4
5
pvcreate /dev/sda3
vgcreate lfs /dev/sda3
lvcreate -L15G -n root lfs
lvcreate -L4G -n swap lfs
lvcreate -L20G -n home lfs

Создание файловых систем

1
2
3
4
5
mkfs.vfat /dev/sda1
mkfs.ext4 /dev/sda2
mkfs.ext4 /dev/lfs/root
mkswap /dev/lfs/swap
mkfs.xfs /dev/lfs/home

Ранее при сборке LFS я использовал xfs для / и точно помню, что версия файловой системы, которая использовалась для форматирования диска на основной системе не совпадала с версией xfs в LFS. Я думаю что эта проблема может возникнуть и с любой другой файловой системой, поэтому лучше заранее проверить версии и изменения в пакетах которыми вы форматируете разделы на хосте, и версии файловых систем которыми вы будете пользоваться в LFS.

Монтирование разделов

В качестве точки монтирования делаем /mnt/lfs аналогично как написано в мануале. Заводим переменную LFS для удобства работы.

1
2
export LFS=/mnt/lfs
mkdir -p $LFS

Создаем директории и монтируем наши рабочие разделы, не забываем, что у нас LVM, поэтому монтируем корень из LVM в первую очередь:

1
2
mount /dev/lfs/root $LFS
mkdir -p $LFS/{boot,home}

Выглядит это так:

1
2
3
4
tree $LFS
/mnt/lfs
├── boot
└── home

Монтирование boot и home разделов

1
2
mount /dev/lfs/home $LFS/home/
mount /dev/sda2 $LFS/boot

Монтирование efi раздела

1
2
mkdir $LFS/boot/efi
mount /dev/sda1 $LFS/boot/efi/

Включаем swap

1
swapon /dev/lfs/swap

Swap должен стать активным:

1
2
3
4
[root@fedora ~]# swapon -s
Filename				Type		Size		Used		Priority
/dev/zram0                              partition	8388604		0		100
/dev/dm-6                               partition	4194300		0		-2

Результат создания и монтирования разделов

1
2
3
4
5
6
7
8
9
10
11
12
[root@fedora ~]# df -Th | grep lfs
/dev/mapper/lfs-root        ext4       15G  496M   14G   4% /mnt/lfs
/dev/sda2                   ext4      974M  268K  906M   1% /mnt/lfs/boot
/dev/sda1                   vfat      598M  4.0K  598M   1% /mnt/lfs/boot/efi
/dev/mapper/lfs-home        xfs        20G  175M   20G   1% /mnt/lfs/home


[root@fedora ~]# tree $LFS
/mnt/lfs
├── boot
│   └── efi
└── home

Пакеты и патчи

Основной раздел из мануала

Создаем директорию sources

1
mkdir $LFS/sources

Для сборки базовой системы требуется набор пакетов и патчей, которые нужно скачать. LFS предоставляет URL лист с нужными версиями пакетов и патчей. Данный список мы и возьмем отсюда wget-list-sysv.
Также скачаем файл с хэшсуммами для проверки.

1
2
wget https://www.linuxfromscratch.org/lfs/view/stable/wget-list-sysv
wget https://www.linuxfromscratch.org/lfs/view/stable/md5sums --directory-prefix=$LFS/sources

Выкачиваем пакеты

1
wget --input-file=wget-list-sysv --continue --directory-prefix=$LFS/sources

После скачивания проверяем совпадает ли количество пакетов в файле с количеством скачанного

1
2
3
4
[root@fedora ~]# cat wget-list-sysv | wc -l
93
[root@fedora ~]# ls -1 $LFS/sources | grep -v md5 | wc -l
93

Проверка хэш сумм

1
2
3
pushd $LFS/sources/
[root@fedora sources]# md5sum -c md5sums  | grep -iwv ok
[root@fedora sources]# 

Вывод должен быть пустым

Необходимо сделать владельца и группу root для всех файлов:

1
chown root:root $LFS/sources/*

Окончательные настройки

Создание структуры директорий

Основной раздел из мануала

Берем скрипт из документации и просто исполняем его:

1
2
3
4
5
6
7
8
9
mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}

for i in bin lib sbin; do
  ln -sv usr/$i $LFS/$i
done

case $(uname -m) in
  x86_64) mkdir -pv $LFS/lib64 ;;
esac

Создаем еще одну директорию для кросс-компилятора:

1
mkdir -pv $LFS/tools

Добавляем LFS пользователя

Основной раздел из мануала

1
2
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs

Задаем пароль для пользователя:

1
passwd lfs

Выдаем права на директории:

1
2
3
4
chown -v lfs $LFS/{usr{,/*},lib,var,etc,bin,sbin,tools}
case $(uname -m) in
  x86_64) chown -v lfs $LFS/lib64 ;;
esac

Логинимся:

1
su - lfs

Настройка окружения

Основной раздел из мануала

Создаем .bash_profile:

1
2
3
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

Добавляем список необходимых переменных в .bashrc:

1
2
3
4
5
6
7
8
9
10
11
12
cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
EOF

Разница .bash_profile и .bashrc заключается в том, что при входе в систему читается .bash_profile один раз, а .bashrc - читается каждый раз, когда создается новый терминал. Соответсвенно внесенные изменения в .bashrc можно применить сразу, создав новое окно терминала.

Перечитываем вручную .bash_profile

1
source ~/.bash_profile

Полезные ссылки

  1. LFS
  2. BLFS
  3. OSDev
  4. Gentoo Handbook
Авторский пост защищен лицензией CC BY 4.0 .

© spybull. Некоторые права защищены.

Использует тему Chirpy для Jekyll

Популярные теги