Разработка для Embedded Linux на ARM девайсе
Материал из Bryansk Linux Users Group.
Содержание |
Вступление
В настоящее время я (Arceny) изучаю Embedded Linux и разработку для него на устройстве Сириус-терминал, которое представляет собой одноплатный компьютер для промышленных и встраиваемых применений на базе микрочипа CirrusLogic EP9315 с архитектурой ARM9 и частотой 200мгц, 64мб RAM и 8мб ROM. Здесь я по мере изучения вопроса буду размещать материалы, которые, надеюсь, пригодятся сообществу. Так как мне не удалось найти сколь-бы то ни было доступной документации, собранной в одном месте, на русском языке.
В мои первоначальные задачи входит научиться разрабатывать приложения на Qt под этот устройство.
Первоначальный запуск
Настройка платы
Плата, которая попала мне в руки, была настроена до меня. Для изучения процесса первоначальной настройки рекомендую обратиться к документу http://groups.google.com/group/tion_sbc/web/work_plata.doc [5], в котором подробнейшим образом описан весь процесс. Единственный минус - настройка описана приментительно к host-компьютеру под Windows, однако особой роли это не играет.
Запуск
Для работы с последовательной консолью я использую GTKTerm V. 0.99.5:
# apt-get install gtkterm
Загрузку образа ядра и диска я осуществлял с хост машины по ethernet с помощью tftp сервера. Установим и настроим его:
# apt-get install tftpd-hpa # dpkg-reconfigure tftpd-hpa
Выбираем "no" и непринуждённо запускаем:
# in.tftpd -l -s /dir/with/images
Где /dir/with/images - директория, в которой будут лежать образы.
Теперь надо сконфигурировать redboot на загрузку по tftp, набрав fconfig в консоли загрузчика. Моя конфигурация выглядит так:
RedBoot> fconfig -l Run script at boot: true Boot script: .. load -r -v -b 0x800000 -m tftp -h 192.168.1.2 /ramdisk.gz .. load -r -v -b 0x80000 -m tftp -h 192.168.1.2 /zImage .. exec -r 0x800000 -s 11360698 -c "root=/dev/ram console=ttyAM0" Boot script timeout (1000ms resolution): 2 Use BOOTP for network configuration: true Default server IP address: 0.0.0.0 Set eth0 network hardware address [MAC]: true eth0 network hardware address [MAC]: 0x0E:0x00:0x00:0xEA:0x18:0xF0 GDB connection port: 9000 Force console for special debug messages: false Network debug at boot time: false
Здесь 11360698 - размер в байтах образа ramdisk.gz, который вместе с zImage лежит в папке указанной для tftp (можно указывать больший размер. это даже удобнее, если пересобираешь образ по нескольку раз). IP адрес плата получает по DHCP.
Embedded Linux
На диске вместе с устройством поставлялся довольно старый дистрибутив от Cirrus Logic с ядром 2.4 или 2.6.8. Поэтому было принято решение опробовать более новую версию, которая была скачана с http://arm.cirrus.com/files/linux/releases/linux-2.6/ обоих версий (1.0.0 и 1.0.3) для платы 9312 (linux_1-0-x-9312.tar.bz2). Первая - с 2.6.17.14, вторая - с 2.6.20.4 ядром. Загрузилась почему-то только версия 1.0.0, с чем связано - не знаю. 1.0.0 с ядром от 1.0.3 грузится, но на экране присутствует пиксельный шум, в виде зеленых и красных точек - очевидно, недоработка или ошибка в драйвере фреймбуфера ядра. Так как готовый дистрибутив слишком "жирный" для моих целей, было принято решение о сборке собственного образа.
Сборка собственного образа
В мои цели входит сборка минимального образа, который можно разместить прямо в 8ми-мегабайтном ROM для автономной быстрой загрузки. Очевидно, что готовый дистрибутив в этот размер не помещается, и имеет на борту лишний груз - в первую очередь среду Opie, а так же не имеет нужной мне библиотеки gettext (для мультиязычных приложений). Самым большим компонентом в моём образе будет библиотека Qt, приложение, написанное на которой, и будет автоматически стартовать в полноэкранном режиме.
Сразу предупреждаю, что скачать придётся не одну сотню метров, поэтому позаботиться о хорошем канале в интернет стоит заранее. Итак, скачиваем и распаковываем исходники последней версии Crater'a (именно так называется дистрибутив от Cirrus Logic):
$ cd ~ $ wget http://arm.cirrus.com/files/linux/releases/linux-2.6/1.0.3/linux_1-0-3-src.tar.bz2 $ tar xvf linux_1-0-3-src.tar.bz2
Теперь нам нужен кросскомпилятор linux-gcc и elf-gcc (нужен только для загрузчика, сборка его не обязательна). Я взял последний GCC 4.1.1. Скачиваем, распаковываем:
$ wget http://arm.cirrus.com/files/tools/arm-linux-gcc-4.1.1-920t.tar.bz2 $ wget http://arm.cirrus.com/files/tools/arm-elf-gcc-3.2.1-full.tar.bz2 # tar xvf arm-linux-gcc-4.1.1-920t.tar.bz2 -C / # tar xvf arm-elf-gcc-3.2.1-full.tar.bz2 -C /
Теперь запускаем процедуру конфигурирования образа, выкидываем ненужные, выбираем нужные пакеты. Я выбрал 17е ядро, по причинам, описанным выше. Архитектуру везде выставил 9312. Возможно нужно 9315, но при загрузке платы пишется именно про 12, хотя чип - 15й. В разделе "Bootloader Options" конфигуратора можно снять все галки, если redboot.rom уже имеется, и его пересборка не требуется. Тогда архив elf-gcc не нужен. Опция "Enable locale/gettext/i18n support" для uClibc приводило к прерыванию сборки образа. Никакие ухищрения не помогли. Возможно, решение будет найдено. Не забываем при выходе сохранить конфигурацию.
$ cd linux-crater_1-0-3 && make menuconfig
Даём команду make. Все нужные исходники будут скачиваться в папку linux-crater_1-0-3/dl автоматически. Среди них такие огромные архивы, как ядро (39 мб), Qt и проч. Будьте терпеливы.
Могут иметь место ошибки компиляции. Внимательно читайте ошибки, если самостоятельно найти решение проблемы не удаётся - обращайтесь к поиску на http://arm.cirrus.com/forum/ . У меня останов произошёл на файле linux-crater_1-0-3/build/makedevs/makedevs.c, для которого был включен режим компилятора -Wall (рассматривать warning'и как ошибки). Make файл править не стал, подправил код, закомментировав строки 427,429-432,434-436. Видимо связано с тем, что дистрибутив тестировался на GCC 3.4, а не 4.1.1, возможно что-то другое.
В общем, после успешного выполнения, мы получим zImage и ramdisk.gz в linux-crater_1-0-3/images/9312, которые теперь можно загрузить в девайс и делать с ними всё что угодно. Однако предварительно кое-что нужно модифицировать.
Сборка собственного ядра
Если по каким-то причинам ядро в стандартной конфигурации не подходит, необходимо его переконфигурировать и пересобрать. Я это сделал чтобы уменьшить размер итогового образа и отключить поддержку ненужных устройств и как следствие получить большую скорость загрузки и меньшее потребление памяти.
Запускаем, находясь в директории linux-crater_1-0-3:
make ep=9312 linux-config
Запустится конфигуратор ядра. Отключаем поддержку ненужных устройств, включаем необходимое. Я отключил поддержку Wireless, Sound, IRDA, PPP, включил более быструю реализацию soft-fpu. С hardware-fpu ещё предстоит разобраться. По выходе сохраняем конфиг и сборка начинается. По её окончании мы получим новый файл zImage. У меня его размер - 1454128 байт.
Модификация образа
Полученный образ необходимо модифицировать, например для отключения dhcp и присвоения статического адреса.
Монтируем:
$ gzip -d -c ramdisk.gz > ramdisk # mkdir /mnt/root # mount -o loop ramdisk /mnt/root
Теперь можно просто править файлы в /mnt/root.
Если мы будем загружать образ прямо в память, а не использовать Compact Flash, образ надо опять сжать:
# cd / && umount /mnt/root $ gzip -9 -c ramdisk > ramdisk.gz
Размещениe образа в ROM
Для загрузки во флешь диска и ядра форматируем флешь (если требуется):
fis init -f
Грузим ядро:
load -r -v -b 0x80000 -m tftp -h 192.168.1.2 /zImage
Шьем его во флешь, где 1454128 - размер ядра в байтах:
fis create -b 0x80000 -l 1454128 zImage
Грузим образ:
load -r -v -b 0x800000 -m tftp -h 192.168.1.2 /ramdisk.gz
Шьем, где 4155062 - размер образа в байтах:
fis create -b 0x800000 -l 4155062 ramdisk.gz
Для запуска выполняем (вручную или через скрипт):
fis load -b 0x80000 zImage fis load -b 0x800000 ramdisk.gz exec -r 0x800000 -s 4155062 -b 0x80000 -l 1454128 -c "root=/dev/ram console=ttyAM0"
где
- после -r идет начальный адрес в ОЗУ файла ramdisk,
- после -s длина файла ramdisk в ОЗУ,
- после -b начальный адрес файла ядра zImage в ОЗУ,
- после -l длина файла ядра zImage в ОЗУ.
- после -с в двойных кавычках идут параметры запуска ОС.
За дополнительной информацией обратитесь к [5].
CompactFlash для удобной работы
Если мы внесем какое-либо изменение в файловую систему устройства при загрузке с ramdisk эти изменения будут утеряны при следующей перезагрузке. Поэтому для тестирования и отладки было принято решение использовать IDE жёсткий диск или флешку, как корневую файловую систему (раздел). После того, как вся разработка и отладка будет завершена, можно будет собрать ramdisk снова.
Мы выбрали простой CompactFlash-IDE переходник, питание которого было подключено на разъём x12 (5В) платы. CompactFlash (CF) карточку следует отформатировать на "большом" компьютере и записать на неё необходимые файлы. Используем дешевый картридер. У меня CF увиделась как /dev/sde. Итак, удаляем все разделы и создаём новый, на всю флешку, и присваиваем ему статус BOOT:
# cfdisk /dev/sde
Выбираем [WRITE], а затем [QUIT]. Теперь создаём раздел ext2:
# mkfs.ext2 /dev/sde1
Так как ramddisk мы монтировали в разделе "Модификация образа", копируем его содержимое:
# mkdir /mnt/cf # mount /dev/sde1 /mnt/cf # cp -Ra /mnt/root/* /mnt/cf # umount /mnt/cf
Вытаскиваем CF, и вставляем в наш девайс. Теперь необходимость грузить ramdisk отпадает. Ядру следует только указать на новое расположение root (корня) файловой системы. Редактируем загрузочный скрипт, вот его новый вид:
fis load -b 0x80000 zImage exec -b 0x80000 -l 1629256 -c "root=/dev/hda1 console=ttyAM0"
Ещё одно преимущество такого подхода - больший доступный приложениям объём RAM, за счёт отсутствия необходимости расположения файловой системы целиком в памяти. Загружаем систему и пробуем включить DMA а так же протестируем скорость чтения из кеша диска и с его поверхности:
# hdparm -u 1 /dev/hda # hdparm -Tt /dev/hda
Кроссразработка
Первым делом необходимо настроить все необходимые компиляторы и toolchain'ы для сборки программ на хост машине. С hello world проблем не возникнет, а вот если используются какие-либо shared библиотеки, придётся повозиться...
Hello World
Qt Hello World
Ссылки
Здесь ссылки на хорошие документы по сабжу
- Официальная страница Сириус-терминал
- Сайт Cirrus Logic, на котором можно скачать компиляторы, тулчайны, исходники, дистрибутивы, ядра
- Форум (на английском) на официальном сайте Cirrus
- Русскоязычная группа обсуждения девайса
- Работа с платой, установка загрузчика redboot и его настройка (doc, 376 кб)

