Components of an image, in order of booting

QNX Neutrino supports a wide variety of CPUs and hardware configurations. Some boards require more effort than others to embed the OS. For example, x86-based machines usually have a BIOS, which greatly simplifies your job, while ARM-based machines require that you create a complete IPL. Embedded systems can range from a tiny memory-constrained handheld computer that boots from flash, to an industrial robot that boots through a network, to a multicore system with lots of memory that boots from a hard disk.

Whatever your particular platform or configuration, the QNX System Builder helps simplify the process of building images and transferring them from your host to your target.

Note: For a complete description of OS and flash images, see the Building Embedded Systems guide.
The goal of the boot process is to get the system into a state that lets your programs run. Initially, the system might not recognize disks, memory, or other hardware, so each section of code needs to perform whatever setup is needed in order to run the subsequent section. This works as follows:
  1. The IPL initializes the hardware, makes the OS image accessible, and then jumps into it.
  2. The startup code in the OS image performs further initializations, and then loads and transfers control to the microkernel and process manager (procnto).
  3. The procnto module performs some kernel setup and then runs the boot script.
  4. The boot script executes the commands to launch the drivers and applications in your embedded system.
  5. You can now begin using your embedded system, as the OS and applications are running.


Figure 1. Typical boot order

At reset, a typical processor has only a minimal configuration that lets code be executed from a known linearly addressable device (e.g., flash, ROM). When your system first powers on, it automatically runs the IPL code at a specific address on this device; this address is called the reset vector.

IPL

When the IPL loads, the system memory usually isn't fully accessible. It's up to the IPL to configure the memory controller, but the method depends on the hardware—some boards need more initialization than others.

When the flash memory becomes accessible, the IPL scans it for the image filesystem, which contains the startup program (described in the next section). The IPL loads the startup header and startup code into RAM, and then jumps to this code.

The IPL is usually board-specific (it contains some assembly code) and is as small as possible.

Startup program

The startup program initializes the hardware by setting up interrupt controllers, cache controllers, and base timers. The program's code detects system resources such as the processor(s), and puts information about these resources into a centrally accessible area called the system page. The code can also copy and decompress the image filesystem components, if necessary. Finally, the code passes control, in virtual memory mode, to the procnto module.

The startup code is board-specific and is generally much larger than the IPL. Although a larger procnto module could do the setup, we separate the startup code so that procnto can be board-independent. After the startup code sets up the hardware, the system can reuse a part of the startup program's memory because that code won't be needed again.

Note: If you're creating your own startup variant, its name must begin with startup or the QNX System Builder perspective won't recognize it.

The procnto module

The procnto module is the core runtime component of QNX Neutrino. It consists of the microkernel, the process manager, and some initialization code that sets up the microkernel and creates the process manager threads. The procnto module is a required component of all bootable images.

The process manager handles (among other things) processes, memory, and the image filesystem. The process manager lets other processes see the image filesystem's contents. When the procnto module has started running, the OS is essentially up and running. One of the process manager's threads runs the boot script.

Several variants of procnto are available (e.g., procnto-smp for x86 multicore machines).

Note: If you're creating your own procnto variant, its name must begin with procnto- or the QNX System Builder perspective won't recognize it.

For more details, see the System Architecture Guide and the procnto entry in the Utilities Reference.

Boot script

If you want your system to load any drivers or to run any programs automatically after powering up, you must put those drivers and programs in the boot script. For example, you might make your boot script:
  • Run a devf* driver to access a flash filesystem image, and then run your programs from that flash filesystem.
  • Create adaptive partitions, run programs in them, and set their parameters, as follows:
    # Create an adaptive partition using the thread scheduler 
    # named "MyPartition" with a budget of 20%:
    sched_aps MyPartition 20 
    
    # Start qconn in the Debugging partition: 
    [sched_aps=Debugging]/usr/sbin/qconn 
    
    # Use the recommended security level for the partitions: 
    ap modify -s recommended
    

    For more information about these commands, see the Adaptive Partitioning User's Guide.

When you build your image, the boot script is converted from text to a tokenized form and saved as /proc/boot/.script. The process manager runs this tokenized script.