Making Multiple Images

What's a multiple image?

When you use mkifs to build an OS filesystem, you can specify that executables will either execute in place (normally in flash) or be copied to RAM and executed there (see "Notes on XIP versus copy," in the mkifs entry in Utilities Reference).

But what if you want some executables to run from flash and others from RAM? That's what multiple images are used for.

Multiple image file systems are typically used in execute-in-place (XIP) systems to separate executables that must run directly from flash (to conserve RAM) and those that should be copied and then executed from RAM (for performance).

How do you create a multiple image?

Simply put, you create two separate images and then stitch them together.

Overview

This is what the OS image will look like:

OS Structure

The boot image file system will be run from RAM to improve performance and the XIP image file system will be run from flash to conserve RAM.

Each of the three sections must begin at a memory page boundary (typically 4KB). The IPL code will execute the OS in the first image. Once running, the OS will then automatically mount both the boot and XIP image file systems.


Note: If you prefer to run the process manager XIP and other executables from RAM, You can adapt the following procedures by altering the build scripts so that code from the boot image is used in place and code from the second image is copied into RAM.

Generating An XIP Image File System

Here's a typical XIP build script:

# Specify the search path, otherwise defaults to x86
[search=/shle/bin:/shle/usr/bin:/shle/sbin:/shle/usr/sbin:/shle/lib:/shle/lib/dll:/shle/usr/lib]

# Where the xip files will be mounted at boot time
[prefix=/xip]   

# Libraries to include
[data=copy code=uip]
libc.so

# Windows mkifs needs to be reminded of permissions
[perms=+x]
 
[+raw data=copy code=uip]
slay
devc-sersci
esh
ls
pidin
slogger
sloginfo

Unlike the build script for a bootable OS image, the XIP script does not have a boot section, nor does it have a boot script. Running mkifs on the above script with verbose output gives the following output:

$ mkifs -v xip.build /tmp/xip.ifs
Offset   Size    Entry   Ramoff Target=Host
       0     5c     ----      --- Image-header
      5c    1b8     ----      --- Image-directory
    1000  53000    2dd4a      --- xip/libc.so.2=/shle/lib/libc.so
    ----    ---     ----      --- xip/libc.so=libc.so.2
   54000   85ac     ----      --- xip/pidin=/shle/bin/pidin
   5c5ac   83f0     ----      --- xip/devc-sersci=/shle/sbin/devc-sersci
   6499c   5344     ----      --- xip/ls=/shle/bin/ls
   69ce0   3568     ----      --- xip/esh=/shle/bin/esh
   6d248   2aa8     ----      --- xip/slay=/shle/bin/slay
   6fcf0   2598     ----      --- xip/slogger=/shle/usr/sbin/slogger
   72288   1b90     ----      --- xip/sloginfo=/shle/bin/sloginfo
   73e18      4     ----      --- Image-trailer

Note that the first entry is the image file system header rather than the startup code normally found in a bootable image.

From the output, we can see that the image file system occupies 0x73e1c bytes; rounding this up to the next memory page boundary (we'll assume 4KB pages), we get 0x74000 bytes. We will need this information later to mount the image.

Generating A Bootable OS Image

A bootable OS image can be generated as described in mkifs in the Utilities Reference and in Making an OS Image in Building Embedded Systems.

When running the mkifs utility, use the verbose option to obtain the starting memory address of the bootable OS image and the starting address of the XIP image file system.

Let's look at a typical build file:

[image=0x8c007000]
[virtual=shle,binary] .bootstrap = {
        startup-aspen -Dscif..57600 -v
        PATH=/proc/boot:/xip LD_LIBRARY_PATH=/proc/boot:/xip procnto -vv
}

[+script] .script = {
        # Start the serial driver
        devc-sersci -t8 -e -b57600 scif sci &
        reopen
        display_msg Welcome to Neutrino on a ASPEN board .. with multiple image support!

        TERM=qansi
        PATH=/proc/boot:/xip
        LD_LIBRARY_PATH=/proc/boot:/xip
        slogger &

        # Start a session
        [+session] PATH=/proc/boot:/xip esh &
}

# Set up the console
[type=link] /dev/console=/dev/ser1
[type=link] /tmp=/dev/shmem

[type=link] /usr/lib/ldqnx.so.2=/xip/libc.so

Here is the verbose output from mkifs:

Offset   Size    Entry   Ramoff Target=Host
8c007000    100     ----      --- Startup-header
8c007100   8008 8c0086a4      --- /tmp/DAA570595
8c00f108     5c     ----      --- Image-header
8c00f164    160     ----      --- Image-directory
    ----    ---     ----      --- usr/lib/ldqnx.so.2=/xip/libc.so
    ----    ---     ----      --- tmp=/dev/shmem
    ----    ---     ----      --- dev/console=/dev/ser1
8c00f2c4    150     ----      --- proc/boot/.script=/tmp/CAA570595
8c010000  46000 8c02c058      --- proc/boot/procnto=/tmp/EAA570595
8c056000      4     ----      --- Image-trailer

From the first line of the mkifs output, we can see that the bootable image will be loaded into physical memory address 0x8c007000. From the last line of the output we can see that the image ends at the physical memory address 0x8c056004 (the extra 4 bytes is for the size field).

If we round the end address up to the next memory page boundary (we'll assume 4KB pages), the XIP image should begin at physical address 0x8c057000.

Generating A Combined IPL, Boot, and XIP Image

From the information gathered above, we will create the following combined OS image:

Combined Image

The start address for the boot image will be offset by 4KB for the IPL and size.

First, we must edit the startup line in the build script for the boot image to:

startup-aspen -Dscif..57600 -M0x51000,0x74000,2 -v

The new line registers the memory occupied by the XIP image as type 2 (MEMTYPE_IMAGEFSYS) so that the OS will automatically mount the extra image file system.


Note: Notice that the memory address is relative to the beginning of the IPL (0x8c058000 - 0x8c007000 = 0x51000).

After rebuilding the boot image with mkifs, ensure that none of the offsets have changed (this will only happen near the 4KB page boundaries). Otherwise, you will have to edit the new addresses in the build script one more time.

Now, we can use the mkimage utility to join the two images and insert the necessary padding:

mkimage -b4k -o boot_xip.ifs boot.ifs xip.ifs

Finally, we prepend the IPL code:

cat ipl boot_xip.ifs > ipl_boot_xip.img

The resulting image is now ready to be loaded into the target system's flash array.


Note: If the flash writing software requires the image to be in a special format, refer to mkrec in the Utilities Reference to find out how to do the conversion.

See also

mkifs, mkimage, and mkrec in the Utilities Reference.

Making an OS Image in Building Embedded Systems.