Загрузка ядра и фс из юбут.

Юбут после исполнения должен передать управление ядру линукс, которое в свую очередь после загрузки должно подмонтировать корневую файловую систему.

За то где распологается ядро линункс и корневая файловая система отвечают такие переменные юбута как bootargs и bootcmd.

Обычно в готовых устройствах образ ядра линукс в формате uImage и образ ФС распологаются на флешке.

Тогда для варианта загрузки с nand-flash и использования ubifs, переменные юбута будут иметь следующий вид:

set bootargs 'console=ttyS0,115200 ubi.mtd=2 root=ubi0:rootfsU rootfstype=ubifs init=/etc/preinit'
set bootcmd 'nand read.e $(loadaddr) kernel; bootm $(loadaddr)'

Пример скрипта для формирования ubi образа:

#!/bin/sh

mkfs.ubifs -q -r $WORKING_DIR/openWrtSMV628/build_dir/target-arm_v5te_uClibc-0.9.33.2_eabi/root-smv628 -m 2048 -e 129024 -c
2047 -o ubifs.img
ubinize -o /home/dima/Tftpboot/mrv/brd6282/ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg

Для варианта с nor-flash и файловой системы в формате jffs2 переменные юбут выглядят так:

set bootargs 'console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=jffs2 loglevel=7 init=/etc/preinit'
set bootcmd 'bootm 0xf8100000'

Пример скрипта для формирования jffs2 образа:

#!/bin/sh

$WORKING_DIR/openWrtSMV628/build_dir/host/mtd-utils-1.4.5/mkfs.jffs2 \
 -x lzma rtime --squash -e0x40000 \
 -d $WORKING_DIR/openWrtSMV628/build_dir/target-arm_v5te_uClibc-0.9.33.2_eabi/root-smv628 \
 -o /home/dima/Tftpboot/mrv/brd6282/rootfs.jffs2

Еще одним вариантом загрузки может быть когда файловая система распологается на внешней usb-флешке.

set bootargs 'console=ttyS0,115200 root=/dev/sda1 rootwait rw loglevel=8 init=/etc/preinit'

При этом здесь важно наличие параметра rootwait, который полволяет дождаться момента инициализации usb-флешки ядром линукс.

Очень часто, когда проект находится в стадии отладке и регулярная прошивка устройства отнимает кучу времени, то можно использовать загрузку по сети с использованием протокола tftp:

set bootargs 'console=ttyS0,115200 root=/dev/ram rw loglevel=8 init=/etc/preinit'
set bootcmd 'set ethact egiga0; tf $(loadaddr) mrv/brd6282/uImage;tf 0x3000000 mrv/brd6282/ramdisk.img;bootm $(loadaddr) 0x3000000'

При этом файловая система представлена в образе рамдиска.

Для создания рамдиска из дерева ФС можно использовать следующий скрипт(где RFS это файловая система):

#!/bin/sh

rm -f /tmp/ramdisk.img
rm -f /tmp/ramdisk.img.gz
rm -f /tmp/ramdisk_with_title.img

RDSIZE=220000
BLKSIZE=1024

dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE

mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE

sudo mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop

sudo cp -R ./RFS/* /mnt/initrd

sudo umount /mnt/initrd
gzip -9 /tmp/ramdisk.img

mkimage -A arm -C none -O linux -T ramdisk -a 0x0000000 -e 0x0000000 -n LinuxRamDisk -d /tmp/ramdisk.img.gz /tmp/ramdisk_with_title.img
cp /tmp/ramdisk_with_title.img /home/dima/Tftpboot/mrv/brd6282/ramdisk.img

Рамдиск может распологаться и на флешке. Тогда переменные будут выглядеть так:

set bootargs 'console=ttyS0,115200 root=/dev/ram rw loglevel=8 init=/etc/preinit'
set bootcmd 'nand read.e $(loadaddr) kernel; nand read.e 0x3000000 0x00600000 0x300000;bootm $(loadaddr) 0x3000000'

Также возможно комбинирование. Например ядро по tftp, фс с флешки:

set bootargs 'console=ttyS0,115200 ubi.mtd=2 root=ubi0:rootfsU rootfstype=ubifs init=/etc/preinit'
set bootcmd 'set ethact egiga1; tf $(loadaddr) mrv/brd6282/uImage; bootm $(loadaddr)'

Когда размер файловой системы мегабайты,или десятки мегабайт то загрузка по тфтп является удобным, но если размер фс сотни мегабайт то и сама загрузка будет не быстрой и оперативаная память должна позволять вмещать такие размеры. Для этого случая можно использовать загрузку с использованием NFS:

setenv bootargs 'console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.10:/home/dima/Nfsboot/fsl ip=192.168.1.100:192.168.1.10:192.168.1.10:255.255.255.0::eth0: loglevel=7'
setenv bootcmd 'tf 1000000 mrv/brd6282/uImage; bootm 1000000'

В данном примере ядро загружается через tftp, а фс подмонтируется через nfs.

Еще один пример использования альтернативного способа загрузки. Мне он был полезен когда есть устройство, для которого у меня не было исходников юбута и по этой причине не хотелось вносить изменения в заводские переменные юбута.
Для этого создаются временные переменные и устройство загружается через вызов команды: run new_boot

set newBootArgs 'set bootargs console=ttyS0,115200 root=/dev/ram rw loglevel=8 init=/etc/preinit'
set newBootCmd 'set ethact egiga1;tf $(loadaddr) mrv/brd6282/uImage;tf 0x3000000 mrv/brd6282/ramdisk.img;bootm $(loadaddr) 0x3000000'
set new_boot 'run newBootArgs; run newBootCmd;'