Новый загрузчик для RZX-50

В заметке описывается новый загрузчик для RZX-50 на базе Linux; в первую очередь загрузчик будет интересен тем, кто пересобирает ядро для RZX-50.

Работы энтузиастов над OpenDingux для A320 привели к появлению специальной версии U-Boot, которая позволяла по желанию пользователя грузить либо заводскую прошивку либо OpenDingux с miniSD-карты (т.н. режим dualboot).

Создание чего-либо подобного для RZX-50 избавило бы от необходимости прибегать к услугам ужасного прошивальщика для WindowsXP с интерфейсом на китайском языке.

Можно конечно пойти по пути A320 и поправить U-Boot… Но есть другой путь!

Этот путь основан на использовании такой возможности ядра Linux как kexec. Суть данной возможности заключается в том, что из-под работающего ядра Linux можно запустить другое ядро Linux. Этот позволяет создавать на базе Linux загрузчики, к примеру, так появился kexec-loader.

Итак, воспользуемся kexec и организуем возможность грузить ядро не с загрузочной microSDHC-карты, а из файла на файловой системе VFAT карточки в слоте TF приставки (именно так грузится OpenDingux на A320).

Что для этого потребуется? Ядро с включённой опцией CONFIG_KEXEC и специальная user-space программа kexec. После этого остаётся только поправить имеющийся rootfs, чтобы вместо gmenu2x запускать программу kexec, которая загрузит и передаст управление ядру /media/mmcblk1p1/vmlinux.

Обращаю внимание, что kexec и U-Boot работает с образами ядра в разных форматах!

При сборке ядра получается vmlinux (обычный ELF-файл). Из vmlinux при помощи операций сжатия и приделывания соответствующего заголовка получается uImage — файл, который умеет грузить U-Boot. Как видно просто грузить из-под Linux заводскую прошивку не получится, придётся приложить некоторые усилия для того, чтобы переработать uImage обратно в ELF-файл.

Однако пользоваться загрузчиком, который тупо берёт файл с microSD-карты и запускает не слишком удобно — хотелось бы иметь возможность выбрать одно из нескольких ядер. Усовершенствуем алгоритм загрузчика: пусть, если имеется скрипт /media/mmcblk1p1/bootloader.sh, то ему передаётся управление, в противном случае загружается /media/mmcblk1p1/vmlinux. Будем называть режим работы загрузчика, при котором управление передаётся скрипту /media/mmcblk1p1/bootloader.sh, режимом разработчика.

Что поместить в /media/mmcblk1p1/bootloader.sh? Самый простой вариант — скрипт, который при помощи программы dialog реализует интерфейс с пользователем. Вот пример bootloader.sh.

Как ещё можно улучшить загрузчик?

Избавиться от отдельного файла с корневой файловой системой /media/mmcblk1p1/rootfs.ldr. Это можно сделать, включить rootfs в образ ядра, например, в виде initrd.

Уменьшить время старта. Для этого придётся отключить всё лишнее, например, вывод на экран и последовательную консоль. Дело в том, что инициализация фреймбуфера и рисование пингвина занимают какое-то время. С последовательной консолью тоже не всё просто: заводское ядро выводит в последовательный порт с самого старта ядра до старта процесса init около 3800 символов. На скорости 57600 для вывода всех этих символов надо по крайней мере 0,7 секунды.

Как пользоваться загрузчиком?

Конечно хорошо, что загрузчик позволяет отказаться от услуг адского прошивальщика Ingenic для загрузки ядра, но при необходимости проверить, как работает то или иное ядро, придётся каждый раз прибегать к выниманию microSDHC-карты из приставки, что очень неудобно. В такой ситуации гораздо лучше подключить приставку через USB как Ethernet-gadget к ПЭВМ и использовать возможности сетевого соединения. Загрузив приставку в режиме разработчика следует подключиться к ней по telnet’у, загрузить образ нового ядра Linux через сетевое соединение и запустить его. Указанные действия можно поручить специальному скрипту, который разместить, например, в /media/mmcblk1p1.

Скачать загрузчик и получить инструкции по сборке ядра из исходных текстов можно на странице Opendingux-rzx50-20120222.

На форуме имеется страница обсуждения загрузчика.

 



Добавить комментарий

Комментарии доступны через Intensedebate. Включите JavaScript.