Розробка і налагодження UEFI-драйверів Intel Galileo, частина 2: готуємо плацдарм


Здрастуйте, шановні хабровчане.
Опитування першої частини показав, що тема розробки UEFI-драйверів досить цікава спільноті, тому я приступаю до написання подальших частин цього циклу. У цій мова піде про підготовку плати Intel Galileo до роботи, необхідному і бажаному залозі і, збірці і установці BSP. В результаті вийде недорога апаратна платформа, придатна для апаратної налагодження UEFI-драйверів і доступна будь-якому ентузіасту.

Вступ і відмова від відповідальності

За традицією, слід згадати, що всі наведені нижче відомості ви використовуєте на свій страх і ризик, автор не несе відповідальності за можливі втрати працездатності плати, часу, настрою та/або віри в людство. Все описане взято з відкритих джерел, список яких наведено в кінці цієї статті, і ця публікація не може вважатися порушенням NDA з мого боку.

Готуємо залізо

Сама плата
Насамперед, вам необхідно дістати якимось чином плату Intel Galileo. Неважливо, чи буде вона першого або другого покоління (з боку UEFI і вони не відрізняються нічим), головне, щоб ви змогли підключити до неї харчування і UART-конвертер (обов'язково), а також JTAG-відладчик і ISP-програматор (бажано). До мене ця плата потрапила в рамках вивчення можливостей та перспектив Quark SoC нашою компанією і була отримана безпосередньо від німецького представництва Intel. Звичайному ж людині найпростіше цю плату просто купити.

UART
Для підключення до Galileo Gen 1 по UART вам знадобиться кабель AJ-COM, який найпростіше виготовити самостійно за цією схемою:

Якщо на вашому ПК немає COM-порту, то доведеться використовувати COM-USB-конвертер, яких на ринку багато, і коштують вони недорого, так і самостійно зробити такий конвертер з PL23xx/FT232 + MAX232 великої проблеми не становить. В моєму випадку добрі люди з Intel поклали кабель AJ-COM і конвертер COM-USB на базі PL2303 в коробку разом з Galileo.
Відгуки користувачів і досвід експлуатації Galileo Gen1 призвели інженерів Intel до того, що в Gen 2 роз'єм 3,5" Stereojack і мікросхему MAX232, раніше виконувала зрушення рівнів сумісності з COM-портом, вони замінили на гребінку, сумісну з USB-TTL-кабелями виробництва FTDI і має ось таку її:

Таким чином, для підключення до порту UART на Gen 2 досить кабелю, аналогічного TTL-232R-3V3, який можна знову ж виготовити самостійно з вищезазначених PL23xx/FT232. Така заміна вигідна як для Intel (зі схеми викинули MAX232), так і для користувачів, яким тепер потрібен тільки один кабель замість двох. Більш того, майже у всіх, хто хоч трохи знайомий зі світом DIY-електроніки, конвертер USB-TTL вже є.

JTAG
Як я вже писав у попередній частині, Galileo поки залишається єдиною відомою мені платою на базі x86 CPU, на якій порт JTAG TAP доступний відразу, без необхідності підключення дорогущих конвертерів зразок Intel XDP. З одного боку, це відкриває дуже широкі можливості апаратної налагодження, а з іншого — практично для всіх випадків налагодження UEFI-драйверів цілком достатньо налагоджувальних повідомлень через UART, для яких не потрібні ні JTAG, ні додаткове ПО, тільки термінал, тільки хардкор. З іншого ж боку упускати таку можливість безблагодатно, тому знімання підключення відладчика теж варто описати.
В якості роз'єму JTAG на Galileo використовується 10-піновий коннектор з кроком 1,27 мм, до якого просто так не подключишься — дрібний, зараза. Intel пропонує використовувати ось такий перехідник на «нормальний» 20-піновий коннектор JTAG, і це хороша пропозиція, але для тих, хто вміє паяти, у мене є пропозиція трохи краще: просто припаяти п'ять проводів до промаркованим висновків на звороті роз'єму, а з іншого боку припаяти сумісний у ваших JTAG-відладчиком конектор або по BLS-наконечнику на кожен провід. З боку плати це буде виглядати приблизно ось так (прошу вибачення за неотмытый флюс):

Тепер ніякі перехідники не потрібні, і можна підключати плату до будь-якого відладчику зі списку підтримуваних OpenOCD. В Intel працездатність налагодження на Galileo перевіряли TinCanTools FLYSWATTER2 і Olimex ARM-USB-OCD-H, але обидва цих відладчика — звичайна FT2232H в красивому корпусі, тому ви можете використовувати для налагодження на Galileo будь-яку плату на чіпі FTDI серії 232 з підтримкою MPSSE. Докладніше про отладчиках і налагодження — в наступній частині.

ISP
Помилки при розробці та налагодженні UEFI-драйверів часто призводять до того, що плата перестає завантажуватися, і доводиться користуватися відновленням вмісту SPI-чіпа за допомогою recovery-образу або зовнішнього програматора. Крім того, розробка передбачає постійне оновлення прошивки, і щоразу оновлювати прошивку за допомогою штатної утиліти CapsuleApp.efi виходить довго і це моментально набридає. Саме тому є сенс підключити до Galileo програматор і шити їм. На жаль, спроби використовувати плату на FT232H спільно з утилітою flashrom ISP-програматора на цій платі у мене успіхом поки не увінчалися, і поки ця проблема не вирішена, я буду використовувати програматор Samedisk ZC2511. Intel, в свою чергу, пропонує використовувати Dediprog SF100, який теж цілком підійде. Якщо ж у вас вже є SPI-програматор, ви можете спробувати підключити його до ISP-роз'єму, знаходиться в правій верхній частині лицьового боку плати згідно нижчезазначених распиновке:


Ліричний відступ або трохи про SPI-емуляторах
насправді, ISP — це не вершина прогресу, і для професійної розробки прошивок замість SPI-програматорів використовуються SPI-емулятори, які зменшують час оновлення прошивки до 1-2 секунд. Звичайній людині вони недоступні внаслідок високої ціни (близько 500 — 700 доларів за штуку), тому зовсім вже докладно зупинятися на них я не буду. Ми використовуємо емулятор Samedisk ZC25128, здатний емулювати SPI-чіпи різних виробників ємністю до 128 Мбіт. З точки зору ОС емулятор виглядає як звичайна USB-флешка, і оновити прошивку можна простим копіюванням файлу з нею. Поки на моїй пам'яті лише один випадок (Intel CRB для Bay Trail), коли система відмовлялася завантажуватися з емулятора, так що варто визнати, що рішення має право на життя. Дивує тільки рідкість (і, в зв'язку з нею, дорожнеча) подібних пристроїв, адже зараз кожен другий мікроконтроллер має по кілька апаратних каналів SPI і виробництва емуляторів нічого не заважає.
Для сумісності з емулятором я допрацював свою плату Galileo Gen 1, замінивши SPI-чіп на спеціальний роз'єм, до якого підключається або емулятор, або SPI-чіп в ZIF-ліжечка. Виглядає це ось так:


Ось тепер, нарешті, апаратна частина готова, можна приступати до підготовки програмної.

Готуємо

Складальна платформа
Galileo існує два принципово різних набору: це BSP і Arduino Software. Перший набір необхідний для складання як UEFI-прошивки, так і пропонованої Intel в якості базової версії Yocto Linux в декількох варіантах, найпопулярнішими з яких є два — galileo-spi і galileo-full. Перший — мінімальна Linux-система, що стартує безпосередньо з SPI-чіпа і здатна виконувати Arduino-скетчі, друга вже більше схожа на нормальний Linux, але завантажувати її необхідно вже з SD-карти. З цим типом завантаження пов'язана невелика проблема: велика частина плат Gen1 вимагає оновлення прошивки для того, щоб з SD-карти запускалося хоч що-небудь, тому «з коробки» запуск вже підготовленого Intel образу неможливий.
Сумісність з Arduino у цій статті нас не цікавить, тому з всього комплекту нам знадобиться тільки архів з BSP, що називається зазвичай Board_Support_Package_Sources_for_intel_quark_vx.y.z.t.zip, в даний момент його остання версія — 1.0.1.7. Intel пропонує несамовито величезний вибір платформ для складання BSP у кількості рівно однієї штуки — Ubuntu 12.04 x64. Ви, звичайно, можете спробувати збирати з іншого дистрибутива linux'а (я пробував з Ubuntu 14.04, мінімальний образ збирається, повний — вже немає) або навіть з OSX або Windows, але мені набагато простіше встановити потрібну версію на віртуальну машину і запустити збірку з неї. Зупинятися докладно на встановлення Ubuntu я не буду, лише зазначу список пакетів, які потрібно буде встановити на кожному етапі складання BSP.

Збірка BSP
Нульовий крок
Отже, Ubuntu 12.04 x64 у вас встановлена, оновлена і завантажена, архів з останньої BSP завантажено і розпакований, для визначеності, в ~/Galileo/, у вас є з'єднання з Інтернетом і ви готові витратити трохи часу.
Перед початком складання необхідно встановити наступні пакети: build-essential gcc-multilib. Вони необхідні на всіх етапах складання. Рекомендую також для кожного кроку відкривати новий термінал в ~/Galileo/, щоб запобігти можливі конфлікти створюються на кожному кроці складальних оточень.

Збірка UEFI
Для складання UEFI потрібно встановити пакунки subversion, uuid-dev iasl. Після цього необхідно розпакувати архів Quark_EDKII_vX.Y.Z.tar.gz перейти в створену при розпакуванні директорію Quark_EDKII_vX.Y.Z і виконати в ній спочатку скрипт svn_setup.py, а потім команду svn update, яка завантажить необхідні їй для складання частини EFI Development Kit. Після закінчення завантаження необхідно виконати команду ./quarkbuild.sh -d32 GCC46 QuarkPlatfrom, яка запустить збірку налагоджувальної версії UEFI (ключ d32) за допомогою GCC 4.6 (в Ubuntu 12.04 саме такий) для платформи на базі Quark SoC (якої Galileo і є). Після закінчення складання в директорії Build/QuarkPlatfrom/DEBUG_GCC46/FV/ буде знаходитися файл QUARK.fd — це неповний образ прошивки, який знадобиться для наступної частини, а в піддиректорії Applications — утиліта CapsuleApp.efi, використовувана для оновлення прошивки з UEFI Shell, яку доведеться використовувати, якщо у вас немає програматора.

Збірка GRUB
В якості завантажувача за замовчуванням для фази BDS на цій платі Intel пропонує використовувати модифікований GRUB v1. Його не можна збирати, якщо передбачається створення навіть мінімальної складання Yocto Linux, але в нашому випадку збирати його потрібно. Знадобиться встановити пакунки gnu-efi, autoconf, libtool git. Як зазвичай, розпаковуємо архів з GRUB, переходимо в створену після розпакування директорію і виконуємо скрипт gitsetup.py, потім переходимо в підпапку work і виконуємо команди autoreconf --install, export CC4GRUB='gcc-m32-march=i586-fno-stack-protector', export GNUEFI_LIBDIR=/usr/lib32, CC="${CC4GRUB}" ./configure-quark.sh. Не поспішайте виконувати make, спочатку необхідно виправити помилку, якщо у вашій версії вона є. Справа в тому, що збирачі забули покласти в work/efi/ia32/ файл crt0-efi.S, а без нього зібрати GRUB неможливо (це startup-код), тому його потрібно завантажити (наприклад, звідси), правильно перейменувати, скопіювати в цю директорію, а потім вже з чистою совістю виконувати команду make. В результаті work/efi/ виявиться потрібний нам файл grub.efi.

Збірка мінімального образу Yocto Linux
Для складання мінімального образу ОС, який потім буде поміщений в SPI-чіп, потрібно встановити пакунки diffstat, texinfo, gawk chrpath, а якщо не виконувати попередній крок, то і git. Розпаковуємо архів meta-clanton_vX.Y.Z.tar.gz переходимо в створену папку і виконуємо скрипт setup.sh, тепер доведеться трохи почекати. Дочекавшись закінчення завантаження складальних скриптів, виконуємо команди source poky/oe-init-build-env yocto_build bitbake image-spi-galileo, після чого почнеться досить тривалий процес завантаження і складання Yocto з вихідних текстів. Для складання мінімального способу необхідно близько 2 Гб дискового простору, а складання максимально повного образу вимагає близько 35 Гб і виконується протягом майже 7 годин на моєму Core i5-2500K з 8 Гб оперативної пам'яті і SSD. Якщо раптом комусь буде цікаво — напишу про складання такого способу окрему статтю, бо там вистачає своїх підводних граблів, які тут були б зайвими. Загалом, на цьому місці пропоную відпочити і подивитися на хід складання, на який будь — гентушник ентузіаст може дивитися також довго, як на поточну воду або палаючий вогонь.

Складання всього вищевказаного в один файл
Образ ОС готовий, і можна збирати всі компоненти разом. Для цього необхідно розпакувати архіви sysimage і spi-flash-tools і перейти в директорію sysimage_vX.Y.Z/sysimage.CP-8M-debug/, в якій, крім усього іншого, є файл layout.conf. Відкрийте його в улюбленому текстовому редакторі та виправте всі шляхи та назви файлів вірні, замінивши «PLAIN/DEBUG_GCC на DEBUG_GCC46», «image-spi-clanton.cpio.lzma» на «image-spi-galileo-clanton.cpio.lzma» і додавши вашу версію до «meta-clanton» і «Quark_EDKII», після чого не забудьте зберегти зміни. Потім виконайте команду ../../spi-flash-tools_vX.Y.Z/Makefile, в результаті в директорії sysimage.CP-8M-debug будуть створені файли Flash-missingPDAT.bin, Flash-missingPDAT.cap і FVMAIN.fv. Останній використовується як recovery-образ, другий можна копіювати на microSD-карту і оновлювати прошивку вашої Galileo з допомогою CapsuleApp.efi з UEFI Shell, а для доведення першого необхідний ще один крок, останній.

Додавання Platfrom Data Flash-missingPDAT.bin
Залишився останній крок — додати залежні від платформи налаштування. Для цього необхідно перейти в директорію spi-flash-tools_vX.Y.Z/platform-data/, відкрити в улюбленому редакторі файл sample-platfrom-data.ini та виправити в ньому в розділі [Platfrom Type] значення data.value на 6 для Gen1 або 8 для Gen 2, [Mrc Params] data.value на MRC/kipsbay-fabD.v1.bin (Gen 1) або MRC/GalileoGen2.bin (Gen 2), закоментувати приклад з data.type=hex.string в тому ж розділі і змінити в розділі [MAC address 0] значення data.value на адресу, надрукований на наклейці на Ethernet-роз'єм плати, [MAC address 1] на Galileo можна не змінювати. Після цього необхідно виконати команду ./platform-data-patch.py -p sample-platfrom-data.ini-i ../../sysimage_vX.Y.Z/sysimage.CP-8M-debug/Flash-missingPDAT.bin, яка створить, нарешті, файл Flash+PlatfromData.bin, готовий до прошивці програматором.

Перевірка працездатності

Прошиваємо отриманий на попередньому кроці образ, підключаємо плату за UART до ПК, запускаємо улюблений термінал (для Windows можу порадити Puttty/Kitty або TeraTerm), підключаємося до відповідного COM-порту з налаштуваннями 115200 бод, дані — 8 біт, стоп — 1 біт, парність і контроль потоку — відключені, та підключаємо до харчування Galileo.
Якщо бачимо потік налагоджувальних повідомлень UEFI, на зразок того, що на картинці нижче — все зроблено вірно. Якщо ні — перевіряємо все ще пару раз, як мовиться, УМВР.


Висновок і подальші плани

По закінченню цієї частини статті у нас вийшла підготовлена і перевірена на працездатність апаратна платформа, яку можна успішно використовувати для налагодження самописних UEFI-драйверів, якщо інтегрувати їх зборку в образ UEFI на першому кроці. У наступній частині я спробую показати, як можна значно спростити і прискорити складальний процес, як саме здійснюється інтеграція своїх драйверів в кодову базу EDK і як здійснювати їх налагодження, використовуючи UART. Про JTAG-налагодження у Eclipse з допомогою OpenOCD і GDB планується поговорити окремо.
До першої частини, до речі, практично не було коментарів, сподіваюся, що вони будуть до цієї. Спасибі за увагу і до зустрічі в наступних частинах.

Джерела інформації

Intel Quark SoC X1000 Board Support Package (BSP) Build and Software User Guide
Intel Galileo Gen1 Schematics
Intel Galileo Gen2 Schematics
FTDI TTL to USB Serial Converter Range of Cables Datasheet
Intel Embedded Community

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.