Автор статьи: Mr.Nobody Дата: 19.03.2009
1. Автор.
Mr.Nobody
2. Ключевые слова для поиска: embedded, встроенные системы, EDB9315A-Z, EP9315, ARM, Cirrus Logic, Linux, опыт
3. Введение.
Цель статьи - как следует окунуть читателей в мир встроенных систем, познакомив с их спецификой и особенностями.
4. Первые шаги.
Итак, мной в Москве за свои "пречистые" была куплена плата EDB9315A-Z фирмы Cirrus Logic, примерно за 500$ (дорого, но что делать...) для теоретических исследований и практического (как я надеялся) использования (и время показало, что, в общем-то, не зря). Выбор был остановлен на данной плате по нескольким причинам: цена должна была быть в пределах 800$, возможность покупки в Москве частным лицом, ARM-архитектура, USB, наличие IDE разъёма для HDD, естественно сетевой интерфейс - остальное необязательно.
Другие варианты - вроде freescale - отпали по цене (дорого), omap'ы - нет IDE-разъёма для жёсткого диска, остальное стрёмно, так как неясно как обстоит дело с поддержкой железа под linux - свободного времени (и желания) заниматься оживлением чужого железа под linux совсем нет. Рассматривалась одна из наших контор, делающих подобные вещи, но она отпала быстро - попахивала совком да и похоже их только за смертью посылать можно...
Итог - плата куплена (август 2008), в коробке помимо платы было всё необходимое: блок питания, провод для подключения к com-порту, шлейф для подключения HDD, переходник для подключения 2.5" HDD (от ноутбуков) (пустячок, а приятно). На месте включили - вроде всё работает, загрузилась предустановленная WindowsCE, воткнутая usb-мышь заработала...
Приехав домой начал экспериментировать с подключением HDD - выяснилась некоторая особенность: питания от платы недостаточно для старта 3.5" жёстких дисков, из трёх HDD (8 Гб WD, 13 Гб IBM, 500 Гб Seagate) не заработал ни один. То же самое для дисков (2.5"), подключенных через USB-разъём (40 Гб Toshiba, 80 Гб Hitachi, 160 Гб Samsung). А вот через переходник для 2.5" IDE-дисков один из них раскрутился - 160 Гб Samsung, временно вынутый из ноутбука. Что ж, сойдёт для начала.
Позже докупил 2.5" 250 Гб WD (кстати, он тоже раскрутился при работе с платой) - поставил его в ноут, а вынутый 160 Гб Samsung в дальнейшем использовал с платой для экспериментов. Эксперименты показали что, похоже, питание HDD всё-таки, что называется, "на грани" - скажем, из 50 включений в 2х-3х диск не раскручивается, особенно после "холодного" старта.
Кроме того даже после успешного старта и работы в течении суток стабильно время от времени (и особенно при серьёзных нагрузках на систему) происходит hda reset, который, как я первоначально думал, вызван проседанием питания (а именно невозможностью позиционировать головки жёсткого диска), однако покупка нормального блока питания ситуацию не изменила - при этом внешняя схема rtc, которая питается от батарейки, "приказала долго жить" (их две - вторые часы rtc встроены в процессор, но после перезагрузки время сбрасывается). Почитав errata в даташитах cirrus logic'а про проблемы с dma склоняюсь к тому, что это виноваты разработчики железа :-(, хотя есть маленькая вероятность того, что реализация в ядре имеет изъян - в общем, это один единственный, но очень серьёзный минус платы.
Таким образом, для обеспечения 100% запуска hdd рекомендуется внешнее питание, хотя, похоже, есть риск вывести внешнее rtc из строя; можно также попробовать использовать CompactFlash, подключив через IDE разъём.
Да, и ещё один момент - у батарейки для часов плохой контакт - время ставится, но после выключения платы сбрасывается - я исправил это добавлением тонкой металлической шайбы под батарейкой (следует делать осторожно!). По железу - это пожалуй всё.
5. "Я еду на лыжах, а ветер мне в ...".
Ну что ж, вдоволь насмотревшись на убогое дефолтное WindowsCE подошло время снести всё что стояло по дефолту.
Нужно сказать, что на сайте сirrus'а есть много чего интересного - например, форум, где в общем-то описываются все возможные проблемы + разный софт (download утилита для прошивания NOR'а, ядра linux, кросс-компиляторы и т.д.).
Начнём двигаться от простого к сложному. Для начала я поставил redboot с помощью download-утилиты т.к. в описании присутствовал пример установки linux именно с redboot'ом. Попутно выяснилось, что у моего старого компа (с com-портом) нет возможности выставить нужную скорость - решилось следующей командой (может кому поможет):
setserial /dev/ttyS0 spd_hi
Далеё minicom и вперёд к загрузчику - для начала redboot.
У redboot'а особенность (применительно к EDB9315A) - необходимо передать параметр - стартовый адрес (в мануале это не сказано, зато есть на форуме cirrus logic'а) - без этого ядро не грузится. Кстати, redboot задействует MMU, в отличие от, скажем, u-boot'а, который работает с физическими адресами.
Что ж соберём и поставим u-boot вместо redboot'а:
make edb9315A_config
make CROSS_COMPILE=arm_v4t_le
Можно погонять тест памяти u-boot'а - вроде всё ок, только второй банк памяти не того - не видит, похоже это u-boot'кие штуки (ладно, оставим пока так, но запомним...).
Ядро надо готовить особым образом (программой mkimage - поставляется с u-boot'ом) - правда в 2.6 есть возможность сразу собирать ядро для u-boot'а - командой make uImage (mkimage должен быть в путях переменной PATH). Если делать mkimage, то нужно передать параметр -C none для того, чтобы не было двойного сжатия ядра. Есть также другой вариант - руками взять vmlinux (ELF-format) и конвертировать его в binary посредством (армовского) objcopy:
arm_linux_objcopy -O binary vmlinux vmlinux.bin
затем сжать результат gzip'ом:
gzip vmlinux.bin
и далее, использовав mkimage, получаем конечный результат:
mkimage -A arm -O linux -T kernel -C gzip -a 0xC0008000 -e 0xC0008000 -n "Linux-2.6.20.4" -d vmlinux.gz vmlinux.ub
Нужно сказать, что в самом ядре следует кое-что подправить.
В сетевом драйвере drivers/net/arm/ep93xx_eth.c:
...
int idxSts, bi;
line 947:
// Added by Mr.Nobody
int transmit_buf_len;
...
if (pQTxSts->f.txwe) {
pP->d.stats.tx_packets++;
line 979:
// Added by Mr.Nobody
pP->d.stats.rx_bytes += transmit_buf_len;
} else {
...
line 1173:
...
UINT dt;
// Added by Mr.Nobody
int receive_buf_len;
...
line 1220:
...
pP->d.stats.rx_packets++;
// Added by Mr.Nobody
pP->d.stats.rx_bytes += receive_buf_len;
if(pQRxSts->f.am == 3)
pP->d.stats.multicast++;
/*
* Mr.Nobody
* Fixed rx stats - added brackets on the next line
*/
} else {
_PRTK_SYSFAIL(("eth_isrRx(): Low Memory, Rx dropped\n"));
pP->d.stats.rx_dropped++;
}
} else {
...
Цель изменений - добавить статистику полученных/отправленных данных через сетевой интерфейс (то, что можно посмотреть напр. программой ifconfig).
В файле include/asm-arm/arch-ep93xx/hardware.h:
...
#if (defined(CONFIG_MACH_EDB9312) || defined(CONFIG_MACH_EDB9315) || defined(CONFIG_MACH_EDB9307) )
...
/*
* Mr.Nobody
* Changes for EDB9315A
*/
/*#define EP93XX_FLASH_SIZE 0x00800000*/
#define EP93XX_FLASH_SIZE 0x01000000
...
Цель изменений - чтобы размер FLASH соответствовал реальному на плате.
В файле arch/arm/mach-ep93xx/edb9315a.c:
...
// Mr.Nobody - added define for compiling w/o MTD support
#if defined(CONFIG_MTD_PHYSMAP)
#include
#endif
...
/*
* Mr.Nobody
* Changes for EDB9315A
*/
/* .end = 0x61ffffff,*/
.end = 0x60ffffff,
...
Цель изменений - чтобы имелась возможность собрать ядро без поддержки MTD и размер flash делается равный тому, что на плате.
Перед записью ядра во флеш необходимо всегда делать erase записываемой области (если нужно, то на время записи снять защиту).
В качестве rootfs можно использовать любую подходящую FS - важно чтобы ядро и rootfs совпадали по ABI - их сейчас (октябрь 2008) два: ABI и более новый EABI. В Debian это arm и armel (будет начиная с lenny) соответственно.
Я использовал Debian bootstrap как описано напр. в
Для того, чтобы заходить через minicom на плату в inittab нужно добавить:
AM0:23:respawn:/sbin/getty -L ttyAM0 57600 vt100
Важно указать правильное имя консоли (ttyAM0), правильную скорость (baud rate) и тип терминала. Имя консоли - это то, что передаётся ядру через параметр "console=".
Эта строка важна - если её не добавить в inittab, то Ctrl-C может не работать т.к. при старте консоли будет использоваться /dev/console. Кроме того, в inittab'е нужно закомментировать строку содержащую "/sbin/getty console" (если присутствует).
Всё - далее грузимся.
6. Нет предела совершенству в нашем несовершенном мире...
Загрузив linux, воткнул USB-сетевую карту (т.к. потребуется второй сетевой интерфейс - родной будет смотреть наружу, usb'ишный - внутрь). Погонял, выткнул при передаче данных по сети - ничего не упало - что ж, это радует. Если кому интересно название - D-Link Fast Ethernet USB 2.0 Adapter DUB-E100.
Установил screen, pptp-linux, inadyn, apache2, vsftpd, rtorrent, hdparm - остальное пока не требуется - будет доставляться по мере необходимости. Всё это примерно заняло 300М на диске.
При запуске всего хозяйства - при максимальной загрузке по сети internet (примерно 300кб/сек в обе стороны) загрузка CPU составила 70-80% (согласно top'у грузил в основном pptp). До этого в качестве сервера использовался ноут - ограничение по скорости доступа было такое же (т.е. "потолок" в internet тоже был примерно 300 кб/сек) при минимальном unlimited тарифе 2500 кбит/сек. Т.е. при таком трафике система "тянула" спокойно. Загрузка при транзите-forwarding'е (т.е. rtorrent запущен на ноуте, который подключён к плате) чуть выше, чем при запуске rtorrent'а на самой плате. Нужно сказать, что на плате также были задействованы достаточно навороченные правила iptables, версия ядра 2.6.20.4. Это всё - для того, чтобы примерно представлять возможности системы.
В планах - переход на armel (интересен также armeb - + эксперименты с CF.
7. Итоги: хохотали, веселились - подсчитали - прослезились...
В результате удалось создать полноценную Linux систему. В целом всё работает и работает надёжно за искючением IDE-диска. Но и эту проблему можно решить - скажем монтируя read-only, а для изменений использовать ramdisk.
8. Список использованных источников, ссылки на ресурсы в интернете.
1.
2.
3. ftp://ftp.debian.org
4.
|