Загрузка ядра и фс из юбут.
Юбут после исполнения должен передать управление ядру линукс, которое в свую очередь после загрузки должно подмонтировать корневую файловую систему.
За то где распологается ядро линункс и корневая файловая система отвечают такие переменные юбута как 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;'