Разработка для 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 для удобной работы

cfdisk /dev/sde
cfdisk /dev/sde

Если мы внесем какое-либо изменение в файловую систему устройства при загрузке с 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

Ссылки

Здесь ссылки на хорошие документы по сабжу

  1. Официальная страница Сириус-терминал
  2. Сайт Cirrus Logic, на котором можно скачать компиляторы, тулчайны, исходники, дистрибутивы, ядра
  3. Форум (на английском) на официальном сайте Cirrus
  4. Русскоязычная группа обсуждения девайса
  5. Работа с платой, установка загрузчика redboot и его настройка (doc, 376 кб)
Личные инструменты