Существует множество причин по которым необходимо собрать свой дистрибутив Linux и столько же причин этого не делать, но зачастую перед вами будет стоять выбор - собирать или искать дистрибутив подходящий под ваши нужды и наплевать на оптимальность.
С выходом RaspberryPI 3 а теперь ещё и RaspberryPI 4 с ARM x64 процессорами, люди столкнулись с тем что отсутствуют x64 дистрибутивы под новую платформу, в свою очередь RPI зарекомендовал себя как вполне стабильная система для применения в ответсвеных конструкциях и учитывая цену он очень вкусно выглядит на фоне различных специализированных платформ.
На сколько оправдано использование x64 на RaspberryPi и остальных, вопрос открытый и каждый решает сам.
В моём случае, необходимо перетащить софт скомпилированный под aarch64, на базе очень специфической железки, за которую хотят очень много денег, а выходит из строя она до безобразия часто :)
Сразу создадим окружение для работы
mkdir -p buildroot/{sources,release,build,toolchain}
cd buildroot
dirs -c
Загружаем исходные коды и всё остальное что понадобится нам
Основное ядро для RaspberryPi на данный момент - 4.19.y а также 5.3.y.
При клонировании репозитория с ядром, укажите желаемую версию:-b rpi-4.19.y
- 4.19 (linux kernel 4.19.81)-b rpi-5.3.y
- 5.3 (linux kernel 5.3.8)
pushd sources
wget https://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz
wget https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.xz
# rootfs arch linux aarch64
wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
# official linux kernel for rpi
git clone https://github.com/raspberrypi/linux.git rpi-kernel --depth=1 -b rpi-4.19.y
# armstubs
git clone https://github.com/raspberrypi/tools.git rpi-tools --depth=1
# vendor firmware
git clone https://github.com/RPi-Distro/firmware-nonfree --depth=1
# /boot/overlays ... etc.
git clone https://github.com/raspberrypi/firmware --depth=1
# extract gcc and binutils
tar -xpJf binutils-2.33.1.tar.xz
tar -xpf gcc-9.2.0.tar.gz
popd
Общий объём “исходников” примерно 4GB, так что учитывайте это, если у вас ограничен трафик или низкая скорость соединения.
Для удобства зададим переменные
export ROOT=`pwd`
export SOURCES=${ROOT}/sources
export BUILD=${ROOT}/build
export RELEASE=${ROOT}/release
export TOOLCHAIN=${ROOT}/toolchain
export PATH=$PATH:$TOOLCHAIN/bin
Собираем binutils
mkdir ${BUILD}/binutils
pushd ${BUILD}/binutils
${SOURCES}/binutils-2.33.1/configure \
--prefix="$TOOLCHAIN" \
--target=aarch64-linux-gnu \
--disable-nls
make -j4
make install
popd
Собираем gcc
mkdir ${BUILD}/gcc
pushd ${BUILD}/gcc
${SOURCES}/gcc-9.2.0/configure \
--prefix="$TOOLCHAIN" \
--target=aarch64-linux-gnu \
--with-newlib \
--without-headers \
--disable-nls \
--disable-shared \
--disable-threads \
--disable-libssp \
--disable-decimal-float \
--disable-libquadmath \
--disable-libvtv \
--disable-libgomp \
--disable-libatomic \
--enable-languages=c
make all-gcc -j4
make install-gcc
popd
В систему необходимо доставить следующие пакеты bc bison flex
В зависимости от того для какого Raspberry Pi вы собираете ядро, необходимо указать соответственный конфигурационный файл:bcm2711_defconfig
– Raspberry Pi 4bcmrpi3_defconfig
– Raspberry Pi 3
pushd ${SOURCES}/rpi-kernel
make -j4 O=${BUILD}/rpi-kernel/ \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
bcm2711_defconfig # <-- Указать необходимый вам!
make -j4 O=${BUILD}/rpi-kernel/ \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu-
export KERNEL_VERSION=`cat ${BUILD}/rpi-kernel/include/generated/utsrelease.h | sed -e 's/.*"\(.*\)".*/\1/'`
make -j4 O=${BUILD}/rpi-kernel/ \
DEPMOD=echo \
MODLIB=${RELEASE}/rpi-kernel/lib/modules/${KERNEL_VERSION} \
INSTALL_FW_PATH=${RELEASE}/rpi-kernel/lib/firmware \
modules_install
make -j4 O=${BUILD}/rpi-kernel/ \
ARCH=arm64 \
INSTALL_HDR_PATH=${RELEASE}/rpi-kernel/usr \
headers_install
depmod --basedir ${RELEASE}/rpi-kernel "${KERNEL_VERSION}"
echo ${KERNEL_VERSION} > ${RELEASE}/rpi-kernel/version
popd
Ядро и всё прилагающееся будет сохранено в release/rpi-kernel
, этот каталог можно заархивировать и спрятать на будущее, но немного позже :)
/boot
Собираем в кучу всё необходимое для каталога /boot
.
У нас остался не собранным bootstub
, исправим
pushd ${SOURCES}/rpi-tools/armstubs
make armstub8-gic.bin
popd
И окончательно комплектуем - kernel, bootstub, overlays, bootloader, ThreadX, device tree, etc.
mkdir ${RELEASE}/boot
cp ${SOURCES}/rpi-tools/armstubs/armstub8-gic.bin ${RELEASE}/boot/
cp -arf ${SOURCES}/firmware/boot/overlays ${RELEASE}/boot/
cp -arf ${SOURCES}/firmware/boot/*.dat ${RELEASE}/boot/
cp -arf ${SOURCES}/firmware/boot/*.elf ${RELEASE}/boot/
cp -arf ${SOURCES}/firmware/boot/*.bin ${RELEASE}/boot/
cp -arf ${BUILD}/rpi-kernel/arch/arm64/boot/dts/broadcom/*.dtb ${RELEASE}/boot/
cp -arf ${BUILD}/rpi-kernel/arch/arm64/boot/Image ${RELEASE}/boot/kernel8.img
# cmdline.txt & config.txt
cat > ${RELEASE}/boot/config.txt <<- EOM
initramfs initramfs-linux.img followkernel
armstub=armstub8-gic.bin
enable_gic=1
arm_64bit=1
EOM
echo -n "root=/dev/mmcblk0p2 rw rootwait console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop logo.nologo vt.global_cursor_default=1 audit=0 quiet" > ${RELEASE}/boot/cmdline.txt
Также рекомендую сохранить скомпилированное ядро где-нибудь, я предпочитаю каталог с модулями ядра rootfs/lib/modules/KERNEL_VERSION/
- при сборке, скомпилированное ядро остаётся в каталоге /build/rpi-kernel/arch/arm64/boot/
.
cp -arf ${BUILD}/rpi-kernel/arch/arm64/boot/Image \
${RELEASE}/rpi-kernel/lib/modules/${KERNEL_VERSION}/Image
rootfs
Arch Linux ARM x64На этом этапе, все операции производятся с правами root
пользователя!
Распаковываем rootfs
Arch Linux, и сразу подчищаем лишнее, подчищать не обязательно если в дальнейшем вы собираетесь донастраивать систему в chroot
окружении (Об этом в предыдущей статье), в этом случае, в chroot
необходимо будет удалить пакеты linux-aarch64, linux-firmware, linux-api-headers – pacman -Rdd linux-aarch64 linux-firmware linux-api-headers
# !!! USER ROOT !!!
sudo su root
Password: ******
export ROOT=`pwd`
export SOURCES=${ROOT}/sources
export RELEASE=${ROOT}/release
export KERNEL_VERSION=`cat ${RELEASE}/rpi-kernel/version`
export ROOTFS=${RELEASE}/archlinux-aarch64-${KERNEL_VERSION}-rootfs
pushd ${RELEASE}
mkdir ${ROOTFS}
tar -xpf ${SOURCES}/ArchLinuxARM-aarch64-latest.tar.gz -C ${ROOTFS}
rm -rf ${ROOTFS}/boot/*
rm -rf ${ROOTFS}/lib/modules/*
rm -rf ${ROOTFS}/lib/firmware/*
rm -rf ${ROOTFS}/usr/include/{asm,asm-generic,drm,linux,misc,mtd,rdma,scsi,sound,video,xen}
rm -rf ${ROOTFS}/var/lib/pacman/local/linux-aarch64*
rm -rf ${ROOTFS}/var/lib/pacman/local/linux-firmware*
rm -rf ${ROOTFS}/var/lib/pacman/local/linux-api-headers*
popd
Копируем новое ядро, библиотеки, firmware
# ! use root user
cp -arf ${RELEASE}/boot/* ${ROOTFS}/boot/
cp -arf ${RELEASE}/rpi-kernel/lib/* ${ROOTFS}/lib/
cp -arf ${RELEASE}/rpi-kernel/usr/include/* ${ROOTFS}/usr/include/
cp -arf ${SOURCES}/firmware-nonfree/* ${ROOTFS}/lib/firmware/
chown -R root:root ${ROOTFS}/boot/* ${ROOTFS}/lib//modules/* \
${ROOTFS}/usr/include/* ${ROOTFS}/lib/firmware/*
# fix kernel version in mkinitcpio preset
sed -i 's|^ALL_kver.*|ALL_kver="'${KERNEL_VERSION}'"|g' ${ROOTFS}/etc/mkinitcpio.d/linux-aarch64.preset
# fstab
cat > ${ROOTFS}/etc/fstab <<- EOM
# <file system> <dir> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,noatime,nodiratime 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime,nodiratime 0 1
EOM
С этого момента ваш Arch Linux полностью готов, rootfs
можно скопировать на SD карту и загрузить Raspberry Pi, донастроить уже по месту или использовать chroot
для настройки.
Доступ к chroot
для arm x64 из под x86_64 описан в предыдущей статье, подготовка SD карты в офф. документации.
5й пункт документации заменить на
sudo su
cp release/archlinux-aarch64-rootfs/* /MOUNT_POINT_ROOT/
Упаковать дистрибутив в архив - рекомендую именно в архив а не городить образ, инсталяция занимает гараздо меньше времени чем dd
образа.
# !!! USE ROOT !!!
pushd ${ROOTFS}
tar -cvpzf ${RELEASE}/archlinux-aarch64-${KERNEL_VERSION}.tar.gz --one-file-system ./
popd
--one-file-system
- на случай если забыли отмонтировать dev
,proc
etc.