Ядро Linux
Это сердце ОС. Первоначальный выпуск 0.01 был выпущен 17 сентября 1991 года. Самый крупный проект с открытым исходным кодом в мире. Написан на C с расширениями GCC и ASM (AT&T). Скомпилированное ядро - файл vmlinux (в формате объектного файла ELF, COFF или a.out)
Ядро имеет монолитную архитектуру с загружаемыми во время выполнения модулями (modular monolithic). Все части ядра находятся в одном адресном пространстве. Все драйверы устройств работают в пространстве ядра.
Требования ядра:
- ЦП с MMU (блок управления памятью)
- Достаточный ОЗУ (2 мб+);
- Минимальные возможности ввода-вывода со средствами отладки (например, последовательный порт)
- Ядро должно иметь возможность загружать корневую файловую систему из какого-либо постоянного хранилища или получать к ней доступ по сети
Ядро и его исходники здесь: kernel.org
Хорошая статья на тему сборки linux.
Конфигурация ядра в файле .config. Для генерации файла требуется скачать исходники и выполнить make config. Если конфигурация уже была (например, вы ранее строили ОС и нужно обновить) можно использовать make oldconfig для интерактивного обновления файла конфигурации или make olddefconfig для автоматического применения "дефолтных" значений ко всем новым полям.
Также существуют графические варианты кофигурации:
make menuconfig- псевдографическийинтерфейс в консоли.make xconfig(for Qt),make gconfig(for GTK) - графическое окно.
В готовой конфигурации можно переключать опции двумя способами:
scripts/config, например:scripts/config --disable SYSTEM_TRUSTED_KEYS- рекомендованый способ. Есть множество ключей.sed, например:sed -i 's/^CONFIG_TC=y/# CONFIG_TC is not set/' .config
Для реализации меню, инструкций и конфигурации используется Kconfig.
Текущая конфигурация ядра может быть найдена тут:
/proc/config.gz
/boot/config
/boot/config-$(uname -r)
Что находится в .config
CONFIG_RUNTIME_TESTING_MENU=y – опция выбрана
# CONFIG_TEST_USER_COPY is not set – опция не выбрана
CONFIG_TEST_BPF=m – опция выбрана и добавляется в виде модуля ядра
Выполнение задания
Собрать новое ядро с rt-patch, установить и запустить операционную систему с новым ядром Linux с наложенным rt-patch Сравните результаты работы теста cycletest для обычного ядра и ядра с rt-patch
C версии 6.12 патч rt-patch не требуется, достаточно включить PREEMPT_RT.
Ядро собирается на самой ОС, запуск и отладка - в QEMU (может потребоваться доустановить sudo apt install qemu-system-x86).
Пример с патчем приведен для v6.6.127 (longterm).
Выполняем скачивание исходников (включая rt-tests для cyclictest) (busybox сразу распаковываем):
mkdir build
KERNEL_VERSION=v6.6.127
git clone --branch $KERNEL_VERSION --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git build/linux-$KERNEL_VERSION
BUSYBOX_VER="1.37.0"
wget -q https://busybox.net/downloads/busybox-$BUSYBOX_VER.tar.bz2
mkdir -p build/busybox-$BUSYBOX_VER
tar xjf busybox-$BUSYBOX_VER.tar.bz2 -C build/
cd build
git clone https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
Собираем все из исходников. В первую очередь - busybox:
cd busybox-1.37.0
make defconfig
make -j$(nproc) CONFIG_STATIC=y
file busybox
make CONFIG_STATIC=y CONFIG_PREFIX=../rootfs install
cd ..
Создаем файловую структуру будущей ОС и init script:
mkdir -p rootfs/{bin,sbin,etc,proc,sys,dev,run,tmp,var}
mkdir -p rootfs/usr/{bin,sbin}
cat > rootfs/init << 'EOF'
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs tmpfs /run
mount -t tmpfs tmpfs /tmp
mkdir -p /dev/shm
mount -t tmpfs shm /dev/shm
mdev -s
if [ -c /dev/fb0 ]; then
TTY=/dev/tty1
else
TTY=/dev/ttyS0
fi
# Очистка и приветсвие
echo 0 > /proc/sys/kernel/printk
printf "\033c" > $TTY
cat << INNER > $TTY
===============================
Minimal Linux by Vlad Ryabchevsky
Kernel: $(uname -r)
Time: $(date)
===============================
INNER
# Запускаем shell
exec setsid sh -c "exec sh <'$TTY' >'$TTY' 2>'$TTY'"
EOF
chmod +x rootfs/init
Сбока и копирование cyclictest
cd rt-tests
make clean
make CFLAGS="-static -O2 -D_GNU_SOURCE" LDFLAGS="-static -lnuma -lpthread -lrt" cyclictest
cp cyclictest ../rootfs/usr/bin/
chmod +x ../rootfs/usr/bin/cyclictest
cd ..
Нужно больше приложений? Не вопрос! - качайте их исходники и собирайте. С другой стороны, не проще ли тогда взять тот же ubuntu?
Теперь создается rootfs-образ:
cd rootfs
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
cd ..
Дальше - сборка ядра linux:
cd linux-$KERNEL_VERSION
make tinyconfig
./scripts/config \
-e 64BIT \
-e PCI \
-e PCI_HOST_GENERIC \
-e TTY \
-e BLK_DEV_INITRD \
-e SERIAL_8250 \
-e SERIAL_8250_CONSOLE \
-e BINFMT_ELF \
-e BINFMT_MISC \
-e BINFMT_SCRIPT \
-e DEVTMPFS \
-e DEVTMPFS_MOUNT \
-e TMPFS \
-e PRINTK \
-e EARLY_PRINTK \
-e PROC_FS \
-e SYSFS \
--set-str INITRAMFS_SOURCE "../rootfs.cpio.gz" \
-e RD_GZIP \
-e INITRAMFS_COMPRESSION_GZIP \
-e EFI \
-e EFI_STUB \
-e FB \
-e FB_EFI \
-e FRAMEBUFFER_CONSOLE
make olddefconfig
make -j$(nproc)
ls -lh arch/x86/boot/bzImage
Если небыло ошибок, то запускаем ВМ:
qemu-system-x86_64 -m 2G -kernel linux-$KERNEL_VERSION/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -machine pc -cpu qemu64 -append "console=ttyS0 init=/bin/busybox" -nographic
cyclictest -t 1 -i 200 -l 1000 -p 80
Результат БЕЗ патча:
~ # cyclictest -t 1 -i 200 -l 1000 -p 80
WARN: stat /dev/cpu_dma_latency failed: No such file or directory
WARN: High resolution timers not available
policy: fifo: loadavg: 0.00 0.00 0.00 1/17 28
T: 0 ( 28) P:80 I:200 C: 1000 Min: 2592 Act: 3819 Avg: 3852 Max: 4289
Далее, скачиваем необходимый rt-patch
wget https://www.kernel.org/pub/linux/kernel/projects/rt/6.6/patch-6.6.127-rt69.patch.xz
xz -dk patch-6.6.127-rt69.patch.xz
cd linux-$KERNEL_VERSION
make clean
patch -p1 < ../patch-6.6.127-rt69.patch
Возвращаемся к шагу конфигурирования ядра, перед сборкой открываем make menuconfig и включаем General setup -> Preemption Model -> Fully Preemptible Kernel
Аналогично запускаем и видим:
~ # cyclictest -t 1 -i 200 -l 1000 -p 80
WARN: stat /dev/cpu_dma_latency failed: No such file or directory
WARN: High resolution timers not available
policy: fifo: loadavg: 0.32 0.07 0.02 1/30 41
T: 0 ( 41) P:80 I:200 C: 999 Min: 3288 Act: 3955 Avg: 3919 Max: 7292