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
Личные инструменты
Пространства имён

Варианты
Действия
разработки
технологии
разное
Инструменты