Development and debugging of UEFI drivers on Intel Galileo, part 2: preparing a bridgehead

  • Tutorial

Hello, dear Khabrovites.
The survey in the first part showed that the topic of developing UEFI drivers is quite interesting for the community, so I will begin to write further parts of this series. This article will focus on preparing the Intel Galileo board for work, the necessary and desirable hardware and software, and the assembly and installation of BSP . The result is an inexpensive hardware platform suitable for hardware debugging of UEFI drivers and accessible to any enthusiast.

Entry and disclaimer

By tradition, it should be mentioned that you use all of the information below at your own peril and risk, the author is not responsible for possible loss of board performance, time, mood and / or faith in humanity. Everything described is drawn from open sources, a list of which is given at the end of this article, and this publication cannot be considered a violation of the NDA on my part.

Cooking Iron

The board itself
First things first, you need to get the Intel Galileo board somehow. It does not matter whether it will be the first or second generation (from the UEFI and the software side they are no different), the main thing is that you can connect power to it and a UART converter (required), as well as a JTAG debugger and ISP programmer (preferably) . This board came to me as part of studying the capabilities and prospects of Quark SoC by our company and was received directly from the German Intel representative office. For an ordinary person, the easiest way is to simply buy this board.

To connect to Galileo Gen 1 via UART, you need an AJ-COM cable, which is easiest to make yourself according to this scheme:

If your PC does not have a COM port, you will have to use a COM-USB converter, which are many on the market, and they cost It’s inexpensive, and it’s not a big problem to make such a converter from PL23xx / FT232 + MAX232 yourself. In my case, the good people from Intel put an AJ-COM cable and a PL2303 COM-USB converter in a box with Galileo.
User reviews and operating experience of Galileo Gen1 led Intel engineers to replace the 3.5 ”Stereojack connector and the MAX232 chip, which previously shifted compatibility levels with a COM port, and replaced it with a comb compatible with USB-TTL production cables FTDI and having here such a pinout:

Thus, to connect to the Gen 2 UART port, a cable similar to the TTL-232R-3V3 is enough , which again can be made independently from the aforementioned PL23xx / FT232. Such a replacement is beneficial both for Intel (MAX232 was thrown out of the circuit) and for users who now need only one cable instead of two. Moreover, almost everyone who is even a little familiar with the world of DIY electronics already has a USB-TTL converter.

As I wrote in the previous part, Galileo remains the only x86-based CPU board known to me on which the JTAG TAP port is available immediately, without the need to connect expensive converters like Intel XDP. On the one hand, this opens up very broad possibilities for hardware debugging, and on the other hand, for almost all cases of debugging UEFI drivers, debugging messages via UART are quite enough, for which neither JTAG nor additional software are needed, only the terminal, only hardcore. On the other hand, this opportunity is missed without grace, so the debugger connection removal is also worth describing.
As a JTAG connector on Galileo, a 10-pin connector with a pitch of 1.27 mm is used, which you just can’t connect to - a small, contagious one. Intel suggests using such an adapterto the “normal” 20-pin JTAG connector, and this is a good offer, but for those who can solder, I have a better suggestion: just solder the five wires to the marked terminals on the back of the connector, and on the other hand solder the compatible one in your JTAG - debugger connector or BLS-tip on each wire. From the side of the board, it will look something like this (I apologize for the unwashed flux):

Now no adapters are needed, and you can connect the board to any debugger from the list of supported OpenOCDs. At Intel, debugging performance on Galileo was tested with TinCanTools FLYSWATTER2 and Olimex ARM-USB-OCD-H, but both of these debuggers are an ordinary FT2232H in a beautiful package, so you can use any board on the FTDI chip of the 232 series with MPSSE support for debugging on Galileo. Learn more about debuggers and debugging in one of the following parts.

Errors in the development and debugging of UEFI drivers often lead to the fact that the board stops loading, and you have to use the recovery of the contents of the SPI chip using a recovery image or an external programmer. In addition, the development implies a constant update of the firmware, and each time updating the firmware using the standard CapsuleApp.efi utility takes a long time and it immediately bothers. That is why it makes sense to connect the programmer to Galileo and sew it. Unfortunately, attempts to use the FT232H board together with the flashrom utility as an ISP programmer on this board have not been successful so far, and until this problem is solved, I will use the Samedisk ZC2511 programmer . Intel, in turn, suggests usingDediprog SF100 , which is also quite suitable. If you already have an SPI programmer, you can try connecting it to the ISP connector located in the upper right part of the front side of the board according to the pinout below:

Lyrical digression or a little about SPI emulators
In fact, ISP is not the pinnacle of progress, and for professional firmware development, instead of SPI-programmers, SPI-emulators are used, which reduce the firmware update time to 1-2 seconds. They are unavailable to an ordinary person due to the high price (about 500-700 dollars apiece), so I will not dwell on them in detail. We use the Samedisk ZC25128 emulatorcapable of emulating SPI chips of various manufacturers with a capacity of up to 128 Mbps. From the point of view of the OS, the emulator looks like an ordinary USB flash drive, and you can update the firmware by simply copying the file with it. So far, in my memory there is only one case (Intel CRB for Bay Trail), when the system refused to boot from the emulator, so it’s worth recognizing that the solution has the right to life. Only the rarity (and, in connection with it, the high cost) of such devices is surprising, because now every second microcontroller has several SPI hardware channels and nothing prevents the production of emulators.
For compatibility with the emulator, I modified my Galileo Gen 1 board, replacing the SPI chip with a special connector, which connects either the emulator or the SPI chip in the ZIF bed. It looks like this:

Now, finally, the hardware is ready, and you can begin to prepare the software.

Cooking software

Assembly platform
There are two fundamentally different sets of software for Galileo: these are BSP and Arduino Software. The first set is necessary for assembling both UEFI firmware and Intel's proposed base version of Yocto Linux in several versions, the most popular of which are two - galileo-spi and galileo-full. The first is a minimal Linux system that starts directly from the SPI chip and is capable of performing Arduino sketches, the second is more like normal Linux, but you must load it from the SD card. There is a small problem with this type of boot: most of the Gen1 boards require a firmware update in order to start anything from the SD card, so starting an Intel-prepared image out of the box is impossible.
Compatibility with Arduino in this article does not interest us, therefore, fromof the whole software package, we only need an archive with BSP, usually called Board_Support_Package_Sources_for_Intel_Quark_vX.YZTzip , at the moment its latest version is Intel offers a frantically huge selection of platforms for building BSP in the amount of exactly one thing - Ubuntu 12.04 x64. Of course, you can try building from another Linux distribution (I tried from Ubuntu 14.04, the minimal image is being built, the full one is gone) or even from OSX or Windows, but it’s much easier for me to install the version you need on the virtual machine and run the build from her. I will not dwell on installing Ubuntu in detail, I will only indicate a list of packages that will need to be installed at each stage of BSP assembly.

BSP assembly
Zero step
So, Ubuntu 12.04 x64 is installed, updated and downloaded, the archive from the last BSP has been downloaded and unpacked, for definiteness, in ~ / Galileo /, you have an Internet connection and you are ready to spend some time.
Before you begin building, you must install the following packages: build-essential and gcc-multilib . They are necessary at all stages of assembly. I also recommend that for each step, open a new terminal in ~ / Galileo / to prevent possible conflicts of the assembly environments created at each step.

UEFI build
To build UEFI, you need to install the subversion , uuid-dev, and iasl packages . After that, you need to unzip the Quark_EDKII_vX.YZtar.gz archive, go to the Quark_EDKII_vX.YZ directory created during unpacking and run the script in it first , and then the svn update command , which will download the EFI Development Kit parts that it needs to build. After the download is complete, you must run the command ./ -d32 GCC46 QuarkPlatfrom, which will start assembling the debug version of UEFI (d32 key) using GCC 4.6 (in Ubuntu 12.04 it is) for a platform based on Quark SoC (which Galileo is). After the assembly is completed, the QUARK.fd file will be located in the Build / QuarkPlatfrom / DEBUG_GCC46 / FV / directory - this is an incomplete image of the firmware, which will be needed in the next part, and in the Applications subdirectory is the CapsuleApp.efi utility used to update the firmware from UEFI Shell, which will have to be used if you do not have a programmer.

Assembly grub
As a default bootloader for the BDS phase on this board, Intel suggests using a fairly modified GRUB v1. It can be omitted if it is supposed to create even a minimal build of Yocto Linux, but in our case it needs to be assembled. You will need to install the gnu-efi , autoconf , libtool, and git packages . As usual, we unpack the archive with GRUB, go to the directory created after unpacking and execute the script , then go to the work subdirectory and run the commands autoreconf --install , export CC4GRUB = 'gcc -m32 -march = i586 -fno-stack- protector ' , export GNUEFI_LIBDIR = / usr / lib32 ,CC = "$ {CC4GRUB}" ./ . Take your time to make , first you need to fix the error, if your version has it. The fact is that the collectors forgot to put the crt0-efi.S file in work / efi / ia32 /, but without it it is impossible to compile GRUB (this is a startup code), so you need to download it (for example, from here ), rename it correctly, copy it to the above directory, and then with a clear conscience execute the make command . As a result, the grub.efi file we need is in work / efi /.

Building a minimal image of Yocto Linux
To build a minimal OS image, which will then be placed in the SPI chip, you need to install diffstat , texinfo , gawk and chrpath packages , and if you do not follow the previous step, then git . Unpack the meta-clanton_vX.YZtar.gz archive, go to the created folder and execute the script , now you have to wait a bit. After waiting for the assembly scripts to load, execute the source poky / oe-init-build-env yocto_build and bitbake image-spi-galileo commands, after which a rather lengthy process of loading and building Yocto from the sources will begin. To build a minimal image, you need about 2 GB of disk space, and building the most complete image requires about 35 GB and takes about 7 hours on my Core i5-2500K with 8 GB of RAM and SSD. If suddenly someone is interested, I’ll write a separate article about the assembly of such an image, because there are enough of their underwater rakes, which would be superfluous here. In general, at this place I propose to relax and look at the assembly process, which any enthusiast gentushnik can watch for as long as flowing water or a burning fire.

Assembling all of the above into a single file
The OS image is ready, and you can assemble all the components together. To do this, you need to unpack the sysimage and spi-flash-tools archives and go to the sysimage_vX.YZ / sysimage.CP-8M-debug / directory, which, in addition to everything else, has a layout.conf file. Open it in your favorite text editor and correct all the paths and file names with the correct ones, replacing “PLAIN / DEBUG_GCC” with “DEBUG_GCC46”, “image-spi-clanton.cpio.lzma” with “image-spi-galileo-clanton.cpio. lzma "and adding the correct version number to" meta-clanton "and" Quark_EDKII ", then remember to save the changes. Then run the command ../../spi-flash-tools_vX.YZ/Makefile, as a result, the files Flash-missingPDAT.bin, Flash-missingPDAT.cap and FVMAIN.fv will be created in the sysimage.CP-8M-debug directory. The latter is used as a recovery image, the second can be copied to a microSD card and the firmware of your Galileo can be updated using CapsuleApp.efi from UEFI Shell, and to finish the first one more step is required, the last one.

Adding Platfrom Data to Flash-missingPDAT.bin
The last step left is to add platform-specific settings. To do this, go to the spi-flash-tools_vX.YZ / platform-data / directory, open the sample-platfrom-data.ini file in your favorite editor and fix the data.value value in it in the [Platfrom Type] section to 6 for Gen1 or 8 for Gen 2, in [Mrc Params] data.value on MRC / kipsbay-fabD.v1.bin (Gen 1) or MRC / GalileoGen2.bin (Gen 2), comment out the example with data.type = hex.string in that in the same section and change in the [MAC address 0] section the data.value value to the address printed on the label on the Ethernet connector of the board, [MAC address 1] can not be changed to Galileo. After that, run the command ./ ​​-p sample-platfrom-data.ini -i ../../sysimage_vX.YZ/sysimage.CP-8M-debug/Flash-missingPDAT.bin, which will finally create the Flash + PlatfromData.bin file, ready for firmware by the programmer.

Health Check

We flash the image obtained in the previous step, connect the board via UART to the PC, launch our favorite terminal (for Windows I can recommend Putty / Kitty or TeraTerm), connect to the corresponding COM port with 115200 baud settings, data - 8 bits, stop - 1 bit, parity and flow control are disabled, and we connect power to Galileo.
If we see a stream of UEFI debugging messages, like the one in the picture below, everything is done correctly. If not, we’ll recheck a couple of times, as they say, UIA .

Conclusion and Future Plans

At the end of this part of the article, we got a prepared and tested hardware platform that can be successfully used to debug self-written UEFI drivers if you integrate their assembly into the UEFI image in the first step. In the next part I will try to show how you can significantly simplify and speed up the assembly process, how exactly the integration of their drivers into the EDK code base is carried out and how to debug them using UART. We are planning to talk about JTAG debugging in Eclipse using OpenOCD and GDB separately.
By the way, there were practically no comments on the first part, I hope they will be on this one. Thank you and see you in the following parts.

Sources of information

Intel Quark SoC X1000 Board Support Package (BSP) Build and Software User Guide
Source Level Debug using OpenOCD / GDB / Eclipse on Intel Quark SoC X1000
Intel Galileo Gen1 Schematics
Intel Galileo Gen2 Schematics
FTDI TTL to USB Serial Converter Range of Cables Datasheet
Intel Embedded Community

Also popular now: