How to Obtain the U-Boot Header Information of the uImage Linux Kernel Image File Running on a BeagleBone Board

Beaglebone black board

In this article, we will show how to obtain the U-boot header information of the uImage linux kernel image file running on a beaglebone board.

The uImage file is the file that contains the linux kernel image that U-boot will boot.

There are 2 types of linux kernel images: uImage files and zImage files.

A zImage is a more basic file that simply has the compressed linux kernel image that is self-extracting.

A uImage has more in that it is composed of the zImage data along with the U-boot image header, which is composed of 64 bytes.

A uImage is seen as a more friendly file to U-boot than zImage, because it has additional U-boot header information that can be very useful.

So let's look at the U-boot header that we get when we boot our operating system on our beaglebone board.

Below is the U-boot header that we get.

U-boot header information of the uImage linux kernel file run on a beaglebone board

From the header file, we can see the name of the image, which, in the case above, is Angstrom/3.8.10/beaglebone. We can see the Image Type is, ARM Linux Kernel Image (uncompressed). We can see the data size of the kernel image is 2.8MiB. And there is more information.

The U-boot header file supplies us with this data in a relatively easy to read format, outlining some of the most important information about the kernel image.

This is what we would get if we boot up our operating system.

However, there are also ways of getting this information manually through U-boot commands.

So in order to get this through U-boot commands, without having to fully boot up the operating system, we first have to load the file into memory.

We do this through the load command.

After specifying load, we follow it with the device and the partition, along with the memory address we wish to start loading from and the specific file.

So to load the second partition from the SD card starting at memory address 0x82000000, with the file being the uImage file, we specify the following command shown below.

To load a file from a FAT based file system into memory, we use the fatload command.

For EXT file sytems, we use the load command.

Since the kernel image is located within the ROOTFS partition, we use the load command, since this is a EXT3 file system.

So we use the load command.

This is then followed by mmc 0:2

mmc 0 is the SD card.

mmc 0:2 is the second partition of the SD card, where the uImage file resides.

We then must specify the address we want to start reading from. We specify the load address specified within the uEnv.txt file for the uImage file. This address is, 0x82000000.

We then specify the file we want to load in. This is the uImage file in the boot folder of the root file system folders.

After this, if successfully loaded, the program will specify how many bytes were read and in what period of time.

We then can use the imi command followed by the memory address to print the header information for the image.

So by specifying the command below, we can get the header information for the uImage file.

This will show all the header information.

There is one more command we can use to get information about the uImage header, and this is using the md (memory display) command.

This is a bit more complex, but it allows us to get data from the uImage header.

To use this command, you specify the address after it we want to read, followed by the number of objects.

We specify 10 to get the all objects of the image header.

All of these methods are shown below.

Obtaining the U-boot header of the uImage linux kernel file run on a beaglebone board

The last method requires that you know the register map of the image header.

This register map is shown below.

typedef struct image_header {
     uint32_t ih_magic; /* Image Header Magic Number */
     uint32_t ih_hcrc; /* Image Header CRC Checksum */
     uint32_t ih_time; /* Image Creation Timestamp */
     uint32_t ih_size; /* Image Data Size */
     uint32_t ih_load; /* Data Load Address */
     uint32_t ih_ep; /* Entry Point Address */
     uint32_t ih_dcrc; /* Image Data CRC Checksum */
     uint8_t ih_os; /* Operating System */
     uint8_t ih_arch; /* CPU architecture */
     uint8_t ih_type; /* Image Type */
     uint8_t ih_comp; /* Compression Type */
     uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;

The first object is the magic number, which correlates to 56190527.

The Image Data Size would be the 4th object, which correlates to e0103d00.

This is interesting, because whwen we first loaded the uImage, the program stated that it was 4002080 bytes in total.

One thing important to note is that all of these values given by the md command are in little endian form. This means that if converted the way you're used to reading, the number in big endian for the data size is, 003d10e0.

If you convert this hex number into decimal, you get, 4002016.

4002016 bytes would be how big in size the linux kernel is.

However, remember that the uImage file comes with an additional 64 bytes for the header file. This brings the total to 4002080, which is exactly what you see in the bytes read when we initially loaded the uImage file.

So this is an alternative method to decoding the header file for the linux kernel image.

So these are ways of obtaining the U-boot header information of the uImage linux kernel image running on a beaglebone board.

Related Resources

HTML Comment Box is loading comments...