Сборка ядра и dtb файла происходит в задании 19. Для получения полной прошивки нужно также собрать корневую файловую систему.
-
Напишем простейший init процесс, который выводит приветственное сообщение и через время завершается. Пример кода можно посмотреть в документации ядра Linux (ссылка);
#include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { printf("Hello world!\n"); sleep(20); }
-
arm-linux-gnueabihf-gcc -static init.c -o init
- соберем init процесс под ARM архитектуру, статически прилинковав libc;
Note
Для проверки свойств файла можно выполнить file ./init
.
-
echo init | cpio -o -H newc | gzip > initramfs.cpio.gz
- упакуем файл в архив; -
Положим этот архив рядом с файлом ядра и dtb файлом. Таким образом, получаем простейшую прошивку;
-
QEMU_AUDIO_DRV=none qemu-system-arm -M vexpress-a9 -kernel zImage -initrd initramfs.cpio.gz -dtb vexpress-v2p-ca9.dtb -append "console=ttyAMA0" -nographic
- запустим эмулятор с новой прошивкой:После старта увидим приветственное сообщение, выводимое init процессом:
По истечении таймера процесс init завершится и ядро упадет с ошибкой
Kernel panic
:
-
Склонируем репозитории OpenSSH, а также zlib и OpenSSL, необходимые для сборки;
-
Соберем zlib:
-
Соберем OpenSSL:
-
Выполним сборку OpenSSH:
-
./configure --prefix=$PWD/_install --disable-strip --with-zlib=$PWD/../zlib/_install --with-ssl-dir=$PWD/../openssl/_include --host=arm-linux-gnueabihf
- выполним конфигурацию под целевую платформу: -
make
- выполним сборку: -
make install
- выполним установку: -
Увидим, что файлы собрались:
-
Все получившиеся файлы будут помещены в соответствующие директории, которые получатся на следующем этапе;
-
Запуск
ssh
также будет проведен ниже.
-
-
Перейдя в директорию с BusyBox, выполним сборку под ARM:
ARCH=arm make defconfig
; -
ARCH=arm make menuconfig
- отредактируем дефолтную конфигурацию;Во вкладке Settings:
Build static binary (no shared libs)
- включить;Cross compiler prefix
указать-arm-linux-gnueabihf-
.
-
make -j <число ядер>
- выполним сборку; -
make install
- выполним установку; -
find . | cpio -o -H newc | gzip > initramfs.cpio.gz
- выполним сборку архива, перейдя в папку/_install
из корневой директории BusyBox; -
Положим этот архив рядом с файлом ядра и dtb файлом. Таким образом, получаем прошивку;
-
QEMU_AUDIO_DRV=none qemu-system-arm -M vexpress-a9 -kernel zImage -initrd initramfs.cpio.gz -dtb vexpress-v2p-ca9.dtb -append "console=ttyAMA0 rdinit=/bin/ash" -nographic
- запустим эмулятор и увидим, что теперь есть доступ к консоли. Проверим работу командecho
иssh
(предварительно была проведена настройкаssh
на платформе назначения, которая состояла в созданииroot
пользователя сUID 0
и генерации ключа с помощьюssh-keygen
):
Таким образом, обе прошивки были успешно собраны и протестированы.
-
Склонируем репозиторий по ссылке (ссылка);
-
ARCH=arm make qemu_arm_defconfig
- создадим конфигурацию; -
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j <число ядер>
- выполним сборку; -
QEMU_AUDIO_DRU=none qemu-system-arm -M virt -bios u-boot.bin -nographic
- запустим U-Boot. Так как рядом с загрузчиком ничего нет, то запустится только его терминал, где можно, к примеру, вывести переменные среды окружения (env print
) или список доступных команд (help
).
=> env print
arch=arm
baudrate=115200
board=qemu-arm
board_name=qemu-arm
boot_targets=qfw usb scsi virtio nvme dhcp
bootcmd=bootflow scan -lb
bootdelay=2
cpu=armv7
ethaddr=52:54:00:12:34:56
fdt_addr=0x40000000
fdt_high=0xffffffff
fdtcontroladdr=465ddea0
initrd_high=0xffffffff
kernel_addr_r=0x40400000
loadaddr=0x40200000
preboot=usb start
pxefile_addr_r=0x40300000
ramdisk_addr_r=0x44000000
scriptaddr=0x40200000
stderr=serial,vidconsole
stdin=serial,usbkbd
stdout=serial,vidconsole
usb_ignorelist=0x1050:*,
vendor=emulation
=> help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
blkcache - block cache diagnostics and control
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootdev - Boot devices
bootefi - Boots an EFI payload from memory
bootelf - Boot from an ELF image in memory
bootflow - Boot flows
bootm - boot application image from memory
bootmeth - Boot methods
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
bootz - boot Linux zImage image from memory
chpart - change active partition of a MTD device
cls - clear screen
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dfu - Device Firmware Upgrade
dhcp - boot image via network using DHCP/TFTP protocol
dm - Driver model low level access
echo - echo args to console
editenv - edit environment variable
eficonfig - provide menu-driven UEFI variable maintenance interface
env - environment handling commands
erase - erase FLASH memory
exit - exit script
ext2load - load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
ext4load - load binary file from a Ext4 filesystem
ext4ls - list files in a directory (default /)
ext4size - determine a file's size
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fatmkdir - create a directory
fatrm - delete a file
fatsize - determine a file's size
fatwrite - write file into a dos filesystem
fdt - flattened device tree utility commands
flinfo - print FLASH memory information
fstype - Look up a filesystem type
fstypes - List supported filesystem types
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
imxtract - extract a part of a multi-image
itest - return true/false on integer compare
lcdputs - print string on video framebuffer
ln - Create a symbolic link
load - load binary file from a filesystem
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls - list files in a directory (default /)
md - memory display
mii - MII utility commands
mm - memory modify (auto-incrementing address)
mtd - MTD utils
mtdparts - define flash/nand partitions
mw - memory write (fill)
net - NET sub-system
nm - memory modify (constant address)
nvme - NVM Express sub-system
panic - Panic with optional message
part - disk partition related commands
pci - list and access PCI Configuration Space
ping - send ICMP ECHO_REQUEST to network host
poweroff - Perform POWEROFF of the device
printenv - print environment variables
protect - enable or disable FLASH write protection
pxe - get and boot from pxe files
qfw - QEMU firmware interface
random - fill memory with random pattern
reset - Perform RESET of the CPU
run - run commands in an environment variable
save - save file to a filesystem
saveenv - save environment variables to persistent storage
scsi - SCSI sub-system
scsiboot - boot from SCSI device
setcurs - set cursor position within screen
setenv - set environment variables
setexpr - set environment variable as the result of eval expression
showvar - print local hushshell variables
size - determine a file's size
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot - load file via network using TFTP protocol
tpm - Issue a TPMv1.x command
tpm2 - Issue a TPMv2.x command
true - do nothing, successfully
usb - USB sub-system
usbboot - boot from USB device
vbe - Verified Boot for Embedded
version - print monitor, compiler and linker version
virtio - virtio block devices sub-system