Colibri PXA320 + Orchid + Linux
Материал из b4wiki
Содержание |
Введение
Есть у нас макет (в простонародье "Франкенштейн") и понадобилось нам поднять на нем Linux. Макет вот такой:
# Toradex Colibri PXA320 (SoM - процессор + память + немного периферии на платке SO-DIMM ) # Кит Toradex Orchid (то, куда этот SoM втыкается) # 800x600 экран OSD080TN52 с сенсорной панелью.
Приятные стороны - большая часть оборудования уже поддерживается в основной ветке ядра.
Допиливать ядро пришлось совсем чуть-чуть:
# прописать наш экран (он по параметрам отличается от экрана, поставляемого с китом) # зарегистрировать I2C (TWSI в документации на PXA320) контроллер и добавить в список I2C устройств часы реального времени M41T00. # в таблице разделов NAND убрать Read only с разделов /dev/mtd0, /dev/mtd1 и /dev/mtd2 (загрузчик, ядро и резервный разделы соответственно)
Далее можно смело собирать uImage. Изначально кит поставляется с WinCE на борту и загрузчиком E-Boot, от которых нам полезного было мало. Вместо проприетарного E-Boot было решено использовать Das U-Boot, благо к тому моменту уже существовали патчи для работы на Colibri PXA320. А для прошивки загрузчика и отладки - OpenOCD c патчами, добавляющими поддержку процессора Marvell PXA320. В качестве файловой системы можно взять rootfs от Angstrom.
Собираем OpenOCD
Исходные коды OpenOCD можно взять тут . Перед сборкой их необходимо пропатчить, чтобы OpenOCD смог работать с PXA320. Патчи лежат тут. Далее выполняем make. После завершения сборки OpenOCD готов к работе. Запускаем прямо из текущего каталога командой:
openocd -s tcl -f board/colibri_pxa320.cfg -f interface/arm-usb-ocd.cfg (пример для Olimex arm-usb-ocd адаптера).
Подключаемся к OpenOCD при помощи telnet (порт 4444 по умолчанию) и выполняем команду reset halt. Если в результате вы получите сообщение типа "target halted. Current mode: Supervisor" - все работает правильно. Если нет - проверьте подключение.
Собираем U-Boot и прошиваем его в NAND
Внимание! собирать Das U-Boot нужно при помощи gcc версии 4.2.2 или еще старше. С более новыми компиляторами U-Boot зависает. Разработчики винят в этом ошибки в gcc.
Исходные коды Das U-Boot берем из официального репозитория (git://git.denx.de/u-boot.git). Далее накладываем патчи из проекта openpxa (git://git.denx.de/u-boot.git). Выполняем make colibri_pxa320_config && make. После завершения сборки получаем u-boot.bin. Не прошивайте его в прибор!!!
Далее к этому файлу надо добавить IPL (Initial Programm Loader). Дело в том, что при загрузке с NAND процессор выполняет только первые 128kb кода, соответственно нам нужен BootROM который прочитает в память столько данных с NAND, сколько требуется для загрузки U-Boot. Для этого в проекте openpxa есть утилита OBM: копируем в папку OBM файл u-boot.bin, выполняем команду make u-boot.img и получаем готовый к прошивке загрузчик.
Для прошивки мы используем OpenOCD + Olimex arm-usb-ocd адаптер. Подключаем адаптер к плате, запускаем OpenOCD и подключаемся к нему как описано выше. Выполняем команду reset halt - после того как процессор будет остановлен - можно работать с NAND. Перед прошивкой чего либо в NAND - нужно стереть erase-block, в который мы будем записывать новые данные. Под загрузчик отводится 2 erase-block. В нашем случае 128kb+128kb. В текущей версии OpenOCD нельзя стереть несколько блоков разом - надо стирать по одному. А потом уже прошивать файл в NAND. В общем случае вся последовательность действий будет выглядеть так:
# reset halt # nand erase 0x0 0x0 0x20000 # nand erase 0x0 0x20000 0x20000 # nand write 0 /tmp/u-boot.img 0x0
Минут через 20 (!!! да, это медленный процесс.) загрузчик будет записан и можно будет перезагрузиться и увидеть в консоли его приглашение:
U-Boot 2009.11-00382-geb567b3 (Feb 04 2010 - 11:30:02)
CPU: Marvell PXA32x B2
Clock: Core: 403MHz ; Turbo: x2
[ SMC: 208MHz ; SRAM: 312MHz ; BUS: 208MHz ; DMC: 260MHz ]
DRAM: 128 MB
NAND: 1024 MiB
*** Warning - bad CRC or NAND, using default environment
In: serial
Out: serial
Err: serial
$
Ядро
Наш патч к ядру можно взять тут. Для чего он нужен:
1 Поддержка нашего экрана 800x600. 1 Регистрирует I2C (TWSI) контроллер 1 Регистрирует RTC (Real Time Clock) M41T00 1 Включена поддержка UBI и UBIFS 1 Включена поддерка Philips UCB1400 (звук + сенсорная панель) 1 Добавлен дефолтный конфиг для Colibri PXA320 + Orchid.
Я рекомендую вытянуть последнее ядро при помощи git и пропатчить его нашим патчем при помощи gim am - это самый простой способ. В качестве конфига используйте arch/arm/configs/colibri_pxa320_config.
Первая загрузка
В рамках данного примера будем работать с SD (хотя никто не мешает грузить ядро и initramfs через tftp). Для этого SD должна быть разбита так:
Device Boot Start End Blocks Id System /dev/sda1 1 69 66278 c W95 FAT32 (LBA) /dev/sda2 70 1020 913911 83 Linux
На первый раздел записываем uImage и initramfs (если нужен). На второй раздел - rootfs. Ядру передаем следующие параметры:
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 init=/linuxrc rootdelay=3
Далее загружаем с SD файлы в память:
mmc init fatload mmc 0 0x87000000 uImage bootm 0x87000000
После выполнения последней команды начнется процесс загрузки. По завершению загрузки можем приступать к записи ядра в NAND.
Запись ядра linux в NAND
flash_eraseall /dev/mtd1 nandwrite -p /dev/mtd1 uImage
После завершения последней команды раздел /dev/mtd1 будет содержать ядро.
Создание корневой файловой системы в NAND
После того, как в NAND будет записан загрузчик и ядро - нам нужна рабочая файловая система. Предположим что она у нас в архиве rootfs.tar.gz. Далее встает извечный вопрос - выбор типа файловой системы. Мы выбрали UBIFS и ничуть не жалеем. В общем случае все достаточно стандартно:
1 Форматируем раздел /dev/mtd3 в нужную нам файловую систему 2 Монтируем раздел /dev/mtd3 3 Разворачиваем на примонтированный /dev/mtd3 нашу rootfs.tar.gz 4 Отмонтируем раздел /dev/mtd3. 5 Загружаемся в нашу новую файловую систему.
Далее я опишу более подробно про UBIFS.
Предположим что поддержка UBI и UBIFS вкомпилена в ядро (или модули уже загружены). Первый шаг - стереть раздел. Для этого можно использовать flash_eraseall, но нам важно сохранить счетчики стираний. По этому мы будем пользоваться утилитой ubiformat:
ubiformat /dev/mtd3
Второй шаг - подсоединение MTD устройства к UBI. Для этого используется утилита ubiattach:
ubiattach /dev/ubi_ctrl -m 3
После этого надо создать логический том утилитой ubimkvol:
ubimkvol /dev/ubi0 -N rootfs -s 900MiB
У нас общий объем NAND - 1GB, но мы создаем том размером 900MB чтобы ubi имел необходимый запас свободных erase-block`ов, для переноса данных с неисправных блоков по мере износа NAND.
Далее - монтируем том и разворачиваем на него файловую систему:
mount -t ubifs ubi0:rootfs /mnt/ubifs tar xf rootfs.tar.gz -C /mnt/ubifs
После этого размонтируем /mnt/rootfs и перезагружаем машинку.
Теперь параметры ядра будут выглядеть следующим образом:
setenv bootargs console=ttyS0,115200 ubi.mtd=3 root=ubi0:rootfs init=/linuxrc rootfstype=ubifs
Теперь грузим с NAND ядро:
nboot 0x87000000 0 0x80000
И начинаем загружаться:
bootm 0x87000000
Информация
1 http://www.linux-mtd.infradead.org/faq/general.html
