Описанную ниже виртуальную машину можно загрузить с Yandex диска (размер файла 9 Гбайт). Для работы с ней необходим VMPlayer, который можно загрузить с сайта www.vmware.com. Для программирования через USB понадобится утилита MFGTools, которую можно загрузить с Yandex диска. Архив также содержит собранные файлы загрузчика, ядра и файловой системы.
__________________________________________________________________
ОБНОВЛЕНИЕ от 28 февраля 2015 года
- linux-3.10.20
- u-boot 2014.01
- imx-bootlets
- buildroot-2014
Руководство пользователя к виртуальной машине.
__________________________________________________________________
Виртуальная машина о которой пойдет речь ниже предназначена для сборки загрузчика u-boot, ядра Linux и файловой системы (rootfs) для использования совместно с платами на процессоре MCIMX287 (Freescale):
- EV-iMX287
- EV-iMX287-Mini
- EV-iMX287-Micro
- EV-iMX287-NANO
- EV-iMX287-SODIMM
Также в виртуальной машине присутствует системы для сборки:
- LTIB
- Buildroot
- OpenWRT
В виртуальной машине запущены tftp сервер для возможности загрузки платы по сети и NFS сервер для организации сетевой файловой системы, которая может быть примонтирована к плате.
Внутренний загрузчик процессора iMX287 умеет грузиться со следующих источников:
- SPI Flash
- NAND Flash
- SD/MMC карта
- USB (в режиме Device)
Непременным условием загрузки является специальный формат загружаемого фала *.sb. Проще говоря, к файлу загрузчика u-boot или ядра Linux uImage добавляется заголовок, в котором находятся настройки DDR2 контроллера и подсистемы питания процессора. При считывании загружаемого файла ROM загрузчик сначала считывает заголовок и инициализирует контроллер памяти и систему питания. Из этого следует, что для систем на процессоре iMX287 использование загрузчика u-boot является необязательным. Можно создать ядро Linux в sb формате и напрямую загружать его. Далее мы рассмотрим все варианты, и с загрузчиком u-boot и без него. Для упрощения работы в системе находятся исполняемые скрипты, которые запускают основные операции по сборке.
В виртуальной машине все необходимое находится по пути /home/user/Projects:
/buildroot-2013.11 - система для сборки файловой системы (rootfs)
/linux-3.9.11 - исходники ядра версии 3.9.11
/ltib - система для сборки загрузчика u-boot-2009, ядра Linux 2.6.35 и файловой системы
/openwrt - популярная система сборки, в основном используется для сборки исходников для сетевых устройств (роутеров и т.п.)
/rootfs-buildroot - распакованная файловая система, сгенерированная с помощью buildroot, также содержит скрипты для записи на SD карту
/rootfs-debian - распакованная файловая система Debian (ARMEL версия), также содержит скрипты для записи на SD карту
/u-boot-2013.4 - исходники загрузчика u-boot
Для практических занятий потребуется плата на процессоре iMX287, компьютер с установленным VMPlayer, картридер для записи SD карт, любимая терминальная программа.
Подключаем кабель RS-232 к плате и компьютеру, подключаем сетевой кабель к роутеру или напрямую к компьютеру. Также к компьютеру подключаем картридер.
В виртуальной машине переходим в папку /home/user/Projects/u-boot-2013.4 и запускаем скрипт make_uboot_sb.sh. Результатом его сборки будет файл загрузчика u-boot в sb формате - u-boot.sb. Теперь запишем его на SD карту и попробуем загрузить плату. Как указывалось выше, в папке rootfs-buildroot находятся скрипты, которые позволяют записать на карточку u-boot, ядро и файловую систему. Для успешной записи файл загрузчика или ядра должны быть помещены в папку rootfs-buildroot/rootfs/boot под именами imx28_ivt_uboot.sb для загрузчика u-boot и imx28_ivt_linux.sb для ядра Linux.
С помощью скрипта copy_uboot_sb.sh, который находится в папке u-boot-2013.4 копируем и одновременно переименовываем файл u-boot.sb в папку rootfs-buildroot/rootfs/boot. Теперь вставляем карточку в картридер и запускаем скрипт write_uboot.sh находящийся в rootfs-buildroot. Поскольку скрипт запускается от имени суперпользователя (root) вам придется ввести пароль "123456" и ответить yes на запрос о записи на карту.
Сообщение Done! Plug the SD/MMC card into the i.MX board and power-on говорит нам о том, что процесс записи успешно завершен. Вытягиваем карточку, устанавливаем ее в плату, выбираем с помощью дип-переключателя режим загрузки с SD/MMC карты и подаем питание. Если все сделано правильно, в терминальной программе наблюдаем лог запуска загрузчика u-boot:
Нажатием любой кнопки прерываем загрузку.
В виртуальной машине переходим в папку linux-3.9.11 и запускаем скрипт make_uImage_dtb.sh. Если необходимо внести какие-то изменения в конфигурацию ядра, предварительно запускаем скрипт make_menuconfig. Скрипт make_uImage_dtb.sh запустить процесс сборки ядра и файла конфигурации imx28-evk.dtb. После успешной сборки, созданные файлы uImage и imx28-evk.dtb c помощью скрипта copy_to_tftpboot.sh (или вручную) копируем в папку tftp сервера /tftpboot. Для загрузки файлов в плату нам также потребуется выяснить адрес tftp сервера, чтобы затем прописать его в плате. В виртуальной машине выполняем команду ifconfig и смотрим IP адрес адаптера
В моем случае это 192.168.0.2.
Опять включаем плату с уже собранным u-boot, нажатием любой кнопки прерываем загрузку и вводим переменные окружения (в вашем случае IP адреса могут отличаться):
MX28EVK U-Boot > setenv serverip 192.168.0.2 (указываем IP адрес сервера) MX28EVK U-Boot > setenv ipaddr 192.168.0.115 (назначаем IP адрес нашей плате) MX28EVK U-Boot > setenv ethaddr 00:11:22:33:44:55 (придумаем плате MAC адрес) MX28EVK U-Boot > setenv bootcmd 'tftp 0x42000000 uImage; tftp 0x41000000 imx28-evk.dtb; bootm 0x42000000 - 0x41000000' (укажем командную строку, какие файлы и по какому адресу грузить) MX28EVK U-Boot > saveenv (сохраняем введенные параметры)
Нажимаем кнопку сброса или вводим команду res для перезагрузки платы. Кнопки не нажимаем, наблюдаем процесс загрузки файлов по сети и старт ядра Linux:
Сейчас процесс загрузки закончится Kernel Panic, поскольку в u-boot не указано где находится файловая система и не найдя ее ядро выведет ошибку.
Файловая система это набор программ, утилит и т.п. Для пользователя OS Windows это почти тоже самое, что находится в папке /Program Files :)
Файловую систему можно собрать используя Buildroot, LTIB, OpenWRT и кучей других подобных систем. Но мы сборку отложим на потом, а пока воспользуемся сетевой файловой системой NFS. В папке /tftpboot есть папка /rootfs (она кстати была создана с помощью Buildroot). Ее то мы и примонтируем. Для этого, нажмем кнопку сброс на плате и прервем запуск загрузки нажатием любой кнопки и введем строку аргументов:
MX28EVK U-Boot > setenv bootargs console=ttyAMA0,115200 fec_mac=00:08:02:6B:A3:1A root=/dev/nfs
nfsroot=192.168.0.2:/tftpboot/rootfs rw ip=dhcp rootwait gpmi (вместо 192.168.0.2 укажите свой адрес сервера) MX28EVK U-Boot > saveenv (сохраним переменные)
Перегружаем плату, наблюдаем процесс загрузки u-boot, загрузку файла ядра по сети
Файловая система примонтирована, вводим логин root и вы в системе.
Итак, загрузчик u-boot, ядро Linux собрано, файловая система примонтирована. Вот несколько подсказок для других случаев:
Если в папке rootfs-buildroot запустить скрипт write_uboot_rootfs.sh, то на карточку будет записан не только u-boot, но и файловая система (в раздел sdb3).
Для того чтобы ядро нашло и примонтировало файловую систему в данном случае, необходимо изменить строку аргументов в u-boot на следующую:
MX28EVK U-Boot > setenv bootargs console=ttyAMA0,115200 root=/dev/mmcblk0p3 rw rootwait ip=dhcp gpmi MX28EVK U-Boot > saveenv
Ядро uImage и файл imx28-evk.dtb можно не только загружать по сети, а также например с USB Flash Drive, в этом случае командная строка выглядит так:
MX28EVK U-Boot > setenv bootcmd 'usb start; fatload usb 0:1 0x42000000 uImage; fatload usb 0:1 0x41000000 imx28-evk.dtb; bootm 0x42000000 - 0x41000000' MX28EVK U-Boot > saveenv
или, если скопировать файлы uImage и файл imx28-evk.dtb на нашу SD карту в раздел sdb1 то можно загружать их с карты:
MX28EVK U-Boot > setenv bootcmd 'mmc dev 0; fatload mmc 0 0x42000000 uImage; fatload mmc 0 0x41000000 imx28-evk.dtb; bootm 0x42000000 - 0x41000000' MX28EVK U-Boot > saveenv
Кому-то может оказаться удобным использование стандартной файловой системы Debian. В виртуальной машине есть папка rootfs-debian, в которой находится минимальная файловая система Debian. Скрипты находящиеся в данной папке полностью аналогичны вышеописанным. Собранные вами u-boot или ядро должно быть размещено в rootfs-debian/boot, обязательно в sb формате и с именами imx28_ivt_uboot.sb или imx28_ivt_linux.sb
Задача состоит в создании файла ядра в sb формате. Результатом запуска скрипта make_uImage_dtb.sh является создание файлов uImage и imx28-evk.dtb. Но кроме этого, также создается файл zImage (linux-3.9.11/arch/arm/boot), который нам и нужен. Итак, после сборки, запускаем скрипт make_zImage_dtb.sh. Он объединит два файла (zImage и imx28-evk.dtb) в один файл zImage_dtb. Теперь запускаем скрипт make_sb_file.sh. C помощью утилиты elftosb он превратит zImage_dtb в файл imx28_ivt_linux.sb. Следующий скрипт copy_linuxsb_rootfs_buildroot.sh (или copy_linuxsb_rootfs_debian.sh) скопирует файл в нужную вам файловую систему (rootfs-buildroot/boot или rootfs-debian/boot). Записать на SD карту созданное ядро и файловую систему можно с помощью скрипта write_SD.sh
Если файловая система имеет большой размер (сотни, тысячи мегабайт) то процесс записи может занять несколько десятков минут, так что можно спокойно попить кофе. Записанную карточку вставляем в плату, далее все как и раньше. Загрузка ядра, монтирование файловой системы на карточке.
Но что делать, если файловая система должна быть в другом месте (NAND Flash, SPI Flash, NFS)? u-boot у нас нет, куда вводить строку аргументов? На самом деле, строка есть, она вписана прямо в ядре, в том самом sb заголовке. И чтобы ее изменить, нам необходимо пересобрать, так называемый imx-bootlets, который генерирует код инициализации контроллера памяти и подсистемы питания. Поскольку imx-bootlets стандартно входят в систему сборки LTIB именно там и будем его пересобирать. Путь к imx-bootlets выглядит так /ltib/rpm/BUILD/imx-bootlets-src-2.6.35.3-1.1.0. Там можно найти четыре папки:
boot_prep
linux_prep
power_prep
mach-mx28
Нас интересует папка linux_prep, в которой имеется папка cmdlines и в ней файл iMX287_EVK.txt. Именно в нем хранится строка, которую нужно изменить в любом текстовом редакторе (или F4 в mc). На самом деле там четыре строки, но править нужно первую. Дело в том, что в imx-bootlets предусмотрена возможность при старте платы, нажимаю аппаратные кнопки подключенные к плате выбрать одну из четырех строк загрузки. Поскольку на наших платах данные кнопки отключены, то используется только самая первая, верхняя строка. После правки данного файла, необходимо пересобрать imx-bootlets запустив скрипт ltib/make_imx_bootlets.sh. Скомпилированные файлы boot_prep, linux_prep, power_prep надо скопировать в папку с исходниками ядра (linux-3.9.11/tools/elf2sb) заменив находящиеся там ранее такие же файлы. После чего выполнив скрипт linux-3.9.11/make_sb_file.sh создать новый файл imx28_ivt_linux.sb с новой строкой аргументов. Процесс записи на карточку, такой же ка и раньше.
Записать ядро (imx28_ivt_linux.sb) и файловую систему в NAND Flash можно разными способами. Компания Freescale имеет утилиту MfgTool.exe для операционной системы Windows, с помощью которой можно записать ядро и файловую систему через интерфейс USB. Плата подключается к компьютеру с помощью USB кабеля (на плате обязательно в порт USB0), с помощью дип-переключателя устанавливается режим загрузки с USB (0000) и далее с помощью утилиты MfgTool.exe происходит загрузка и запись в NAND Flash (можно адаптировать и для записи в SPI Flash). В самом u-boot также имеются команды для работы с микросхемами памяти NAND Flash, SPI Flash. Ниже приведены команды для записи в микросхемы памяти в u-boot:
В u-boot-2013.4 есть встроенный скрипт для записи ядра или загрузчика в NAND Flash. Сначала необходимо задать имя файла который будем записывать в NAND Flash в переменной окружения
MX28EVK U-Boot > setenv update_nand_firmware_filename imx28_ivt_linux.sb (будем писать ядро, обязательно в sb формате!) MX28EVK U-Boot > saveenv run update_nand_firmware (эта команда загрузить по tftp файл imx28_ivt_linux.sb и запишет его в NAND Flash)
Для загрузки с NAND Flash устанавливаем дип-переключатель в положение (0010)
Для записи ядра в микросхему SPI Flash, в u-boot необходимо выполнить следующие команды:
MX28EVK U-Boot > sf probe 2 (подготавливаем SPI интерфейс) MX28EVK U-Boot > sf erase 0x0 0x800000 (стираем память) MX28EVK U-Boot > tftp 0x42000000 imx28_ivt_linux.sb (загружаем по tftp файл ) MX28EVK U-Boot > sf write 0x42000000 0x0 0x42000 (записываем в SPI Flash)
Для загрузки с SPI Flash устанавливаем дип-переключатель в положение (0100)
Удобно создать загрузочную SD карту с файловой системой, после загрузки которой будет вызываться скрипт реализующий запись ядра и файловой системы пользователя в NAND Flash. Вот пример данного скрипта (с созданием файловой системы в формате UBIFS), файл imx28_ivt_linux.sb и архив с файловой системой rootfs.tar находятся на обычной USB флешке:
mount /dev/sda1 /mnt (монтируем USB флешку) flash_eraseall /dev/mtd0 (стираем партицию 0, в ней будет находится ядро) flash_eraseall /dev/mtd1 (стираем партицию 1, в ней будет находиться файловая система) kobs-ng init /mnt/imx28_ivt_linux.sb (записываем ядро, файл с флешки, примонтированной к /mnt) ubiattach /dev/ubi_ctrl -d 0 -m 1 ubimkvol /dev/ubi0 -N rootfs0 -m mkdir -p /mnt/ubi0 mount -t ubifs ubi0_0 /mnt/ubi0 tar xf /mnt/rootfs.tar -C /mnt/ubi0 sync sync umount /mnt/ubi0
чтобы запустить меню конфигурации выполняем
make menuconfig
Выбираем пакеты которые необходимо собрать. Для запуска процесса сборки набираем
make
В результате сборки будут созданы два архива rootfs.tar и rootfs.tar.gz в папке /buildroot-2013.11/output/images. Оба они являются запакованной файловой системой. Использовать можно любой из архивов. В папке /buildroot-2013.11/output/target будет находиться распакованная файловая система.
Аналогично, чтобы запустить меню конфигурации выполняем
make menuconfig
Выбираем пакеты которые необходимо собрать. Для запуска процесса сборки набираем
make
Если в процессе сборки возникнут ошибки, можно запустить сборку с выводом дополнительной информации
make V=s
В результате сборки в папке /openwrt/staging_dir/target-arm_v5te_uClibc-0.9.33.2_eabi/root-mx28 будет находится собранная файловая система, которую можно записать на карточку (запустив скрипт /openwrt/staging_dir/target-arm_v5te_uClibc-0.9.33.2_eabi/mk_mx28_sd) или в микросхему NAND Flash.
Процесс сборки загрузчика u-boot-2009, ядра 2.6.35 и файловой системы был достаточно подробно описан в разделе Wiki. Напомним основные команды:
Все команды выполняются в папке /ltib. Запустить меня конфигурации и сборки:
./ltib -c
Создать sb файлы imx28_ivt_linux.sb и imx28_ivt_uboot.sb
./ltib -p boot_stream.spec -f
В результате сборки в папке /ltib/rootfs/boot будут созданы файлы загрузчика и ядра в sb формате imx28_ivt_linux.sb и imx28_ivt_uboot.sb. В зависимости от настроек создания файловой системы в /ltib будут находиться файлы rootfsext2.gz, rootfs.jfss2, rootfs.tar.gz представляющие собой запакованную файловую систему в разных форматах.
Использование утилиты MFG Tools для записи собранных файлов в целевую плату.
1.На плате устанавливаем режим загрузки с USB.
2.Подключаем кабель USB A-A к компьютеру и в порт USB0 платы
3.Подаем питание на плату
4.Запускаем утилиту MFG Tools
(для модуля EV-iMX287-NANO у которого нет дип переключателей для выбора режима загрузки, подключаем пинцетом контакт RE на землю и подаем питание).
В MFG Tools заходим в Options -> Configuration и щелкнув по крайнему правому столбцу выбираем что и куда записать.
Все стратегии режимов записи можно посмотреть и создать собственные в файле ucl.xml
Файлы находящиеся в \Profiles\MX28 Linux Update\OS Firmware\files\ можно заменять на собственные и записывать.
кратко о именах файлов:
...uboot_mmc - загрузчик с переменными на SD карте
...uboot_nand - загрузчик с переменными в NAND Flash
...uboot_spi - загрузчик с переменными в SPI Flash
...linux3.sb - ядро версии 3.xx (в inittab должно быть указано ttyAMA0)
...linux.sb - ядро версии 2.6.35 (в inittab должно быть указано ttyAM0)
Утилиту MFGTools с собранными файлами можно загрузить здесь.
Для хранения байт 2-5 MAC адреса предназначен регистр HW_OCOTP_CUST0. Изначально в нем находится значение 0x00000000. Байты 0-1 заполняются в борд файле значениями 00:04. Можно просто изменить значения в борд файле загрузчика или ядра. Например в борд файле ядра 3.9.11 (mach-mxs.c)
Или же, с помощью утилиты BitBurner запрограммировать их в области efuse процессора. Ниже описывается данный процесс:
С сайта Freescale загружаем саму утилиту, называется она у них IMX_OTP_TOOLS, распаковываем архив на компьютере, подключаем плату, переводим ее в режим загрузки по USB (DIPSWITCH = 0000) и запускаем саму утилиту BitBurner. В выпадающем списке слева перебираем устройства HID пока не наткнемся на плату. Разработчики утилиты не сильно напрягались, здраво рассудив, что перебрать пару десятков устройств - дело 5 минут. Вот так выглядит утилита с найденной платой.
Теперь слева, в списке регистров выбираем нужный нам HW_OCOTP_CUST0. Его значение в незапрограммированной плату равно 0x00000000. Вписываем нужный нам MAC адрес и нажимаем кнопку Write.
Крайне категорически не рекомендуется что-либо менять в других регистрах без понимания процесса. Настроек там очень много и неосторожным движением очень легко заблокировать процессор или перевести его в режим, когда он перестанет грузиться так как надо. Закрываем утилиту, выставляем нужный нам режим загрузки и запускаем плату. После загрузки ядра, командой "ifconfig -a" смотрим наши настройки сетевых интерфейсов. Из картинки видно, что интерфейс ETH0 имеет вписанный нами MAC адрес, а ETH1 имеет увеличенный на единицу.