Опыт портирования ОС Debian GNU / Linux с расширением реального времени RTAI на процессорный модуль CM-X255
Операционная система Linux, однин из клонов Unix, в своем первоначальном виде была создана Линусом Торвальдсом 17 сентября 1991 года (дата опубликования исходных текстов в Интернете). Благодаря открытости исходных текстов система активно модернизировалась и развивалась интернет-сообществом. Сегодняшня день ОС Linux — устойчивая, надежная система, вбирающая в себя последние технологические новшества. Десятилетиями отлаживаемые (со времен создания Unix) пользовательские программы предоставляют все необходимые сервисы. Однако следует отметить, что ОС Linux разрабатывалась не для встраиваемых решений: монолитное ядро, рассчитанное на обеспечение высокого быстродействия (для серверных систем), имеет неприемлемо большое время реакции на внешние события.
RTAI — Real Time Application Interface (программный интерфейс реального времени) — основан на ядре Linux и предоставляет возможность сделать Linux полностью вытесняемым. Для получения поведения, отвечающего различным временным ограничениям, необходимо произвести изменения в ядре: в процедурах обработки прерываний и политиках планирования. Следуя этому, можно получить систему реального времени с малой задержкой и высокой предсказуемостью, размещенную внутри обычного Linux окружения (предоставляющего доступ к TCP/IP сервисам, графическим системам, системам баз данных и т. д.). RTAI предоставляет все функции ядра Linux с добавлением функций индустриальной ОС реального времени. Он представляет собой диспетчер прерываний: RTAI перехватывает прерывания от периферии и, в случае необходимости, перенаправляет их в Linux. RTAI не требует серьезной модификации ядра — используется концепция HAL (hardware abstraction layer — уровень аппаратной абстракции) для получения информации из ядра и для перехвата основных функций. Такой подход ведет к малой зависимости от ядра, что позволяет легко переносить RTAI на новые версии Linux. RTAI представляет Linux фоновой задачей, которая запускается, когда не происходит никакой активности, требующей выполненияв реальном времени (рис. 1).
В качестве аппаратной платформы был выбран модуль CM-X255 компании CompuLab Ltd. Он представляет собой компьютер класса system-on-module, включающий в себя:
- процессор Intel XScale PXA255;
- 16–64 Mбайт RAM;
- NOR Flash;
- NAND Flash;
- графический контроллер;
- три порта USB;
- пять последовательный портов;
- IrDA;
- контроллер Ethernet;
- AC’97 codec;
- и пр.
Наличие всей необходимой периферии на небольшой (66×44 мм) плате с энергопотреблением около 1 Вт делает этот модуль отличным решением при выборе аппаратной платформы для любой встраиваемой системы (рис. 2).
Для разработки под архитектуру ARM на хост-системе необходимо наличие кросскомпилятора. Он может быть скомпилирован из исходных текстов (имеются в дистрибутиве Debian, www.debian.org) или взят с сайта производителя модуля (www.compulab.co.il). При самостоятельной компиляции можно выбрать версию собираемого компилятора, библиотек, установить нужные опции при сборке. Набор для компиляции (toolchian) под ARM на сайте производителя содержит устаревшую версию компилятора, кроме того, он распространяется as is, без какой-либо технической поддержки. Поэтому при установке кросс-компилятора был сделан выбор в пользу первого варианта (подробную инструкцию по установке необходимых пакетов и их сборке смотрите на сайте проекта Debian).
Следующим этапом является создание образа ядра для целевой системы. Было выбрано ядро версии 2.4.27 как самое последнее (на момент разработки) из ветки 2.4.x, отлично зарекомендовавшей себя в предыдущих разработках. Поддержка архитектуры ARM уже присутствует в исходных текстах ядра Linux, однако для запуска на CM-X255 и для полной поддержки аппаратных ресурсов модуля (главным образом NOR и NAND Flash) необходимо установить патч от производителя (CompuLab). Патч от CompuLab предназначен не для оригинального ядра, а для уже модифицированного, поэтому перед его применением необходимо наложить патчи vrs и pxa (их версии «заданы» в названии файла). Например, для патча diff-2.4.26-vrs1-pxa3-armcore необходимо взять ядро 2.4.26, наложить на него соответствующие «промежуточные» патчи (vrs1 и pxa3), и лишь потом — этот патч.
Частой проблемой при таком подходе (создании своего образа ядра вместо использования готового) становится несовпадение версий накладываемых патчей. В этом случае необходимо наложить патч «вручную», реализовав требуемые изменения в другом фрагменте кода. Изменения, которые не удалось произвести утилите, сохраняются (в исходном формате) в файле с расширением .rej (rejected) для каждого файла, который «постигла неудача» (например, для fs.c будет создан файл fs.c.rej). После наложения всех патчей нужно в конфигурационном файле ядра включить поддержку необходимой периферии (командой make menuconfig в директории ядра) и собрать образ командой:
После этого надо создать образ корневой файловой системы, который будет содержать все требуемые утилиты, конфигурационные файлы, файлы устройств и пр. — все то, что необходимо для функционирования ОС. Ради удобства доступа образ целесообразно создать в файле, а уже потом монтировать этот файл.
Эта команда создает файл размером 64 Мбайт, состоящий из одних нулей. Объем создаваемого файла должен быть таким, чтобы его можно было загрузить в NAND Flash на модуле. В общем случае он должен быть немного меньше размера Flash-памяти (на случай наличия плохих блоков).
Теперь надо создать в этом файле файловую систему:
Файловая система extended 3 была выбрана в качестве корневой из-за ее устойчивости к сбоям при внезапном отключении питания (ext3 — журналируемая файловая система). Теперь этот образ может быть подключен с помощью команды mount:
Опция loop команды mount позволяет монтировать обычные файлы (а не только блочные устройства).
При наполнении файловой системы за основу была взята так называемая base system дистрибутива Debian. Она представляет собой набор пакетов утилит, необходимых для функционирования системы.
Этот набор команд распаковывает пакеты из базовой системы в указанную директорию (/mnt/rootfs).
Для реализации необходимой функциональности (возможность доступа по сети к системе) следует добавить пакеты netkitbase, ftpd, telnetd. Для этого применялась следующая последовательность команд (для каждого пакета):
Команда ar распаковывает deb-пакет, извлекая файлы control.tgz и data.tgz. Файл control.tgz содержит установочные и конфигурационные скрипты пакета. Они выполняются при автоматической установке (apt-get) и в нашем случае не нужны (разве что как справочная информация по настройке). Команда tar распаковывает содержимое файла data.tgz в директорию, на которую смонтирован образ файловой системы. Архив data.tgz содержит полные пути к файлам, поэтому для «установки» надо просто распаковать его.
В результате были установлены следующие пакеты:
- ftpd_0.17-13;
- netkit-inetd_0.10-9;
- telnetd_0.17-18woody2;
- net-tools_1.60-4;
- netkit-ping_0.10-9;
- nvi_1.79-20;
- tcpd_7.6-9;
- libwrap0_7.6-9;
- netbase_4.07.
Процедура компиляции и установки модулей RTAI принципиально не отличается от случая «обычной» конфигурации.
Завершающий этап — настройка поставленных пакетов и установка полученных образов в целевую систему.
Для удобства работы с полученной системой надо обеспечить возможность доступа к ней по последовательному порту (по нему происходит общение с программой-загрузчиком модуля). Для этого необходимо запустить при загрузке процесс getty, передав ему в качестве параметра имя нужного порта (getty обеспечит пользователю возможность входа в систему). Канонический способ — использовать программу init. Для этого необходимо в файл /еtc/inittab добавить следующую строку:
Для обеспечения работы сервисов ftp и telnet надо сделать так, чтобы процесс inetd (inet superserver, запускающий необходимую программу, например, telnetd, при запросе этого сервиса по сети — при появлении пакета на порту 23) стартовал при загрузке системы:
Кроме того, важно включить в его конфигурационном файле необходимые сервисы:
Для установки полученных образов фирма-производитель предлагает использовать ARMMON— встроенную в модуль программу-монитор. С помощью этой программы можно загрузить образы через последовательный порт, USB, либо сеть Ethernet по протоколу tftp. Последний вариант наиболее прост и быстр (как по времени, необходимому для настройки программ на хост-системе, так и по времени загрузки). Для поддержки протокола tftp на хост-системе надо настроить tftp-сервер — в конфигурационном файле /etc/inetd.conf надо добавить строку:
и перезапустить inetd командой:
Теперь следует запустить программу-терминал на хост-системе и включить процессорный модуль. После включения в терминале должно появиться приглашение командной строки загрузчика:
Для загрузки образа ядра по сети в оперативную память используется команда (192.168.0.2 — IP-адрес хост-системы):
Для записи образа ядра в NOR flash:
Для форматирования NAND-памяти и записи в нее образа корневой файловой системы необходимо проделать следующее:
Теперь для загрузки полученной ОС необходимо дать команду:
В результате была получена система, построенная на базе ОС Debian GNU/Linux «Sarge» при помощи компилятора gcc-3.4.3. Она занимает 24 Мбайт (NAND flash) и 1,1 Мбайт (ядро) на NOR flash . Время реакции системы на прерывание от внешнего устройства (по тестам RTAI kern/latency) составляет 2 мкс.