QNX Developer Support
![]() |
![]() |
![]() |
![]() |
Controlling How Neutrino Starts
This chapter includes:
- What happens when you boot?
- Loading a Neutrino image
- diskboot
- .diskroot
- /etc/system/sysinit
- Device enumeration
- /etc/rc.d/rc.sysinit
- rc.local
- tinit
- Troubleshooting
What exactly happens when you start up your system depends on the hardware; this chapter gives a general description.
![]() |
You need to log in as root in order to change any of the files that the system runs when it starts up. |
What happens when you boot?
When you boot your system, the CPU is reset, and it executes whatever is at its reset vector. This is usually a BIOS on x86 boxes, but on other platforms it might be a ROM monitor, or it might be a direct jump into some IPL code for that board. After a ROM monitor runs, it generally jumps to the IPL, and a BIOS might do this as well -- or it might jump directly to the start of the OS image.

Booting a Neutrino system.
The IPL copies the boot image into memory and jumps to the startup. The startup code initializes the hardware, fills the system page with information about the hardware, loads callout routines that the kernel uses for interacting with the hardware, and then loads and starts the microkernel and process manager, procnto (which, starting with release 6.3.0, also manages named semaphores). IPL and startup for a board are generally part of a Board Support Package (BSP) for a particular board.
After procnto has completed its initialization, it runs the commands supplied in the boot script, which might start further customization of the runtime environment either through a shell script or through some program written in C, C++, or a combination of the two.
On a non-x86 disk-booted system, that's pretty well how it happens: most customization is done in the boot script or in a shell script that it calls. For more details, see Making an OS Image in Building Embedded Systems.
For an x86 BIOS boot, this becomes more complex:

Booting a Neutrino system with an x86 BIOS.
After gaining control, the BIOS configures the hardware, and then it scans for BIOS extension signatures (0x55AA). It calls each BIOS extension (e.g. a network card with a boot ROM or hard disk controller) until one of them boots the system. If none of the BIOS extensions boots the system, the BIOS presents some (usually strange) failure message.
For the network boot case, the boot ROM (usually bootp) downloads an image from a server, copies it into memory, then jumps to the start of the image. The boot image generally needs to run a network stack, and starts some sort of network filesystem to retrieve or access additional programs and files.
You can use the mkifs utility to create the OS image. For a sample buildfile for this sort of image, see the Examples appendix.
For a disk-based boot of a Neutrino desktop system, the process of booting, and especially system initialization, is more complex. After the BIOS has chosen to boot from the disk, the primary boot loader (sometimes called the partition loader) is called. This loader is "OS-agnostic;" it can load any OS. The one installed by Neutrino installations displays the message:
Press F1-F4 to select drive or select partition 1,2,3? 1
After a short timeout, it boots whatever OS system is in the partition prompted for. This loader is /boot/sys/ipl-diskpc1. You can write a loader onto a disk by using dloader.
Loading a Neutrino image
When you choose a QNX partition, the secondary boot loader (sometimes called the OS loader) starts. This loader is Neutrino-specific and resides on the QNX partition. It displays the message:
Hit Esc for .altboot
If you let it time out, the loader loads the operating system image file from /.boot; if you press Escape, the loader gets the image from /.altboot instead. As the loader reads the image, it prints a series of periods. If an error occurs, the loader prints one of the following characters, and the boot process halts:
- S
- No OS signature was found.
- D or ?
- An error occurred reading the disk.
The only difference between the default installed images is that /.boot uses DMA for accessing the EIDE controller, while /.altboot doesn't.
You can find the buildfiles for these images in /boot/build:
- qnxbasedma.build for .boot (see the Examples appendix)
- qnxbase.build for .altboot
You can't rename, unlink, or delete /.boot and /.altboot, although you can change the contents or copy another file to these files. For example, these commands don't work:
mv /.altboot oldaltboot mv newboot /.altboot
but these do:
cp /.altboot oldaltboot cp newboot /.altboot
![]() |
If you modify your boot image, it's a good idea to copy your working image from /.boot to /.altboot, then put your new image in /.boot. That way, if you make a mistake, you can press Escape when you next boot, and you'll have a working image for recovery. |
diskboot
The buildfile for the default .boot image, qnxbasedma.build, includes these lines:
[+script] startup-script = {
# To save memory make everyone use the libc in the boot image!
# For speed (less symbolic lookups) we point to libc.so.2 instead
# of libc.so
procmgr_symlink ../../proc/boot/libc.so.2 /usr/lib/ldqnx.so.2
# Default user programs to priority 10, other scheduler (pri=10o)
# Tell "diskboot" this is a hard disk boot (-b1)
# Tell "diskboot" to use DMA on IDE drives (-D1)
# Start 4 text consoles buy passing "-n4" to "devc-con" (-o)
# By adding "-e" Linux ext2 filesystem will be mounted as well.
[pri=10o] PATH=/proc/boot diskboot -b1 -D1 -odevc-con,-n4
}
This script starts the system by running diskboot, a program that's used on disk-based systems to boot Neutrino. For the entire qnxbasedma.build file, see the Examples appendix.
![]() |
When diskboot starts, it prompts:
Press the space bar to input boot options...
Most of these options are for debugging purposes. The diskboot program looks for a Neutrino partition to mount, then runs a series of script files to initialize the system:

Initialization done by diskboot.
The main script for initializing the system is /etc/system/sysinit; you usually keep local system initialization files in the /etc/rc.d directory. For example, if you want to run extra commands at startup on a node, say to mount an NFS drive, you might create a script file named rc.local, make sure it's executable, and put it in the /etc/rc.d directory. For more information, see the description of rc.local later in this chapter.
Here's what diskboot does:
- It starts the system logger, slogger. Applications use slogger to log their system messages; you can use sloginfo to view this log.
- Next, diskboot runs seedres to read the PnP BIOS and fill procnto's resource database.
- Then, diskboot starts pci-bios to support the PCI BIOS.
- After that, diskboot starts
devb-eide
or other disk drivers.

If you want to pass any options to devb-eide or other drivers, pass them to diskboot in your buildfile.
- Next, diskboot looks for filesystems (i.e. partitions and CDs)
to mount, which it does by partition type. It recognizes:
- CD-ROMs
- types 1,4,6,11,12,14: DOS
- type 131: Ext2 if the -e option is passed to diskboot
- type 77,78,79: QNX 4 -- 77 and 78 indicate secondary partitions
These are mounted as /fs/cdx for CD-ROMs, and /fs/hdx-type-y, where x is a disk number (e.g. /fs/cd0, /fs/hd1), and y is added for uniqueness as it counts upwards. For example, the second DOS partition on hard drive 1 would be /fs/hd1-dos-2.
By default, one QNX 4 partition is mounted as / instead. This is controlled by looking for a .diskroot file on each QNX 4 partition. If only one such partition has a .diskroot file specifying a mountpoint of /, that partition is unmounted as /fs/hdx-type-y and is then mounted as /; if more than one is found, then diskboot prompts you to select one.
The .diskroot file is usually empty, but it can contain some commands. For more information, see below.
- Optionally, diskboot runs the fat embedded shell, fesh.
- Next, diskboot starts the console driver, devc-con.
- Finally, diskboot runs the main system-initialization script, /etc/system/sysinit.
.diskroot
The diskboot program uses the .diskroot file to determine which QNX 4 partition to mount as /. The .diskroot file can be one of:
- a 0-length file. This is the default, which requests a mountpoint of /.
- a one-line file that specifies the requested mountpoint.
For example:
/home
The line must not start with a number sign (#) or contain an equals sign (=). The diskboot program ignores any leading and trailing whitespace.
- a multiple-line configuration file.
In this case, it must contain a mountpoint specification, and can contain
additional specifications.
All specifications are of the form:
token = value
The diskboot program ignores any whitespace at the start and end of the line, and on either side of the equals sign.
The recognized tokens are:
- mount or mountpt
- Where to mount this partition.
For example:
mount = /home
- opt or options
- Mount options, either specifically for this mountpoint, or generic.
Use commas (not spaces) to separate the options.
For example:
options = ro,noexec
For more information, see the documentation for mount and specific drivers in the Utilities Reference, and mount() and mount_parse_generic_args() in the Neutrino Library Reference.
- desc or description
- The diskboot program recognizes and parses these tokens, but it currently ignores the information.
- type
- The diskboot program recognizes the strings qnx4, ext2, and dos, but currently ignores this token. It determine the type based on partition numbers, as described for diskboot, above.
/etc/system/sysinit
The /etc/system/sysinit file is a script that starts up the main system services. In order to edit this file, you must log in as root.
![]() |
Before you change the sysinit script, make a backup copy of the latest working version. If you need to create the script, remember to make it executable before you use it (see chmod in the Utilities Reference). |
The sysinit script does the following:
- It starts slogger, if it isn't yet running.
- The script starts the pipe manager, pipe. This manager lets you pass the output from one command as input to another; for more information, see "Redirecting input and output" in Using the Command Line.
- Next, sysinit starts
mqueue,
which manages message queues, using the "traditional"
implementation.
If you want to use the alternate implementation of message queues that
uses asynchronous messaging, you need to start the
mq
server.
For more information, see the Utilities Reference.

Starting with release 6.3.0, procnto* manages named semaphores, which mqueue used to do (and still does, if it detects that procnto isn't doing so).
- If this is the first time you've rebooted after installing the OS, sysinit runs /etc/rc.d/rc.setup-once, which creates various directories and swap files.
- Next, sysinit sets the _CS_TIMEZONE configuration string to the value stored in /etc/TIMEZONE. If this file doesn't exist, sysinit sets the time zone to be UTC, or Coordinated Universal Time (formerly Greenwich Mean Time). For more information, see "Setting the time zone" in Configuring Your Environment.
- If /etc/rc.d/rc.rtc exists and is executable,
sysinit runs it to set up the realtime clock.
We recommend that you set the hardware clock to UTC time and use the _CS_TIMEZONE configuration string or the TZ environment variable to specify your time zone. The system displays and interprets local times and automatically determines when daylight saving time starts and ends.
This means that you can have dial-up users in different time zones on the same computer, and they can all see the correct current local time. It also helps when transmitting data from time zone to time zone. You stamp the data with the UTC time stamp, and all of the computers involved should have an easy time comparing time stamps in one time zone to time stamps in another.
Some operating systems, such as Windows, set the hardware clock to local time. If you install Windows and Neutrino on the same machine, you should set the hardware clock to local time by executing the following command as root and putting it into /etc/rc.d/rc.rtc:
rtc -l hw
If you're using Photon, you can just uncheck The hardware clock uses UTC/GMT in phlocale; if you do that, the program creates a rc.rtc file for you that contains the above command.
- After setting up the clock, sysinit
sets the HOSTNAME environment variable to be the name of
the host system.
It gets this name from the
hostname
command, or from /etc/HOSTNAME if that doesn't succeed.

A hostname can consist only of letters, numbers, and hyphens, and must not start or end with a hyphen. For more information, see RFC 952.
- Then, sysinit runs /etc/rc.d/rc.devices to enumerate your system's devices (see "Device enumeration," below). This starts io-net as well as various other drivers, depending on the hardware detected.
- If /etc/system/config/useqnet exists and io-net is running, sysinit initializes Neutrino native networking (see the Using Qnet for Transparent Distributed Processing chapter in this guide, and npm-qnet.so in the Utilities Reference).
- Next, sysinit runs the system-initialization script, /etc/rc.d/rc.sysinit (see below).
- If that fails, sysinit tries to become a sh or, if that fails, a fesh, so that you at least have a shell if all else fails.
Device enumeration
Neutrino uses a device enumerator manager process, enum-devices, to detect all known hardware devices on the system and to start the appropriate drivers. It's called by the /etc/rc.d/rc.devices script, which /etc/system/sysinit invokes.
The enum-devices manager uses a series of configuration files to specify actions to take when the system detects specific hardware devices. After it reads the configuration file(s), enum-devices queries its various enumerators to discover what devices are on the system. It then matches these devices against the device IDs listed in the configuration files. If the device matches, the action clauses associated with the device are executed. You can find the enumerator configuration files in the /etc/system/enum directory.
Here's some sample code from a configuration file:
device(pci, ven=2222, dev=1111)
uniq(sernum, devc-ser, 1)
driver(devc-ser8250, "-u$(sernum) $(ioport1),$(irq)" )
This code directs the enumerator to do the following when it detects device 1111 from vender 2222:
- Set sernum to the next unique serial device number, starting at 1.
- Start the devc-ser8250 driver with the provided options (the device enumerator sets the ioport and irq variables).
To detect new hardware or specify any additional options, you can extend the enumerator configuration files in the following ways:
- an oem file or directory
- an overrides file or directory
- a host-specific set of enumeration files
as described below.
The enumerator reads and concatenates the contents of all configuration files under the chosen directory before it starts processing.
For details on the different command-line options and a description of the syntax for the configuration files, see enum-devices in the Utilities Reference.
oem file or directory
If you're an OEM, and you've written any device drivers, create an oem file or directory under /etc/system/enum to contain the definitions for the devices.
overrides file or directory
If you need to set up devices or options that are specific to your particular system configuration, create an overrides file or directory under /etc/system/enum. The enumerator includes the overrides file or directory last and adds any definitions in it to the set that enum-devices works with. If the overrides file has something that a previously included file also has, the later definition wins.
For example:
- If you want to stop a particular device from running, or
change how it starts, create a /etc/system/enum/overrides
file and add a device(...) entry for the device:
device(pci, ven=1234, dev=2000) device(pci, ven=1234, dev=2001) requires( $(IONET_CMD), ) uniq(netnum, devn-en, 0) mount(-Tio-net /lib/dll/devn-pcnet.so, "/dev/io-net/en$(netnum)") device(pci, ven=1234, dev=2002) device(pci, ven=1234, dev=2003)The first block of this code specifies to do the following if the enumerator detects devices 2000 and 2001 from vendor 1234:
- If io-net isn't running, start it. IONET_CMD is a macro, defined in /etc/system/enum/include/net, that specifies the default io-net command line.
- Set netnum to the next unique network interface device number, starting at 0.
- Mount the PCNET driver into io-net.
The second block of code tells the enumerator to do nothing if it detects devices 2002 or 2003 from vendor 1234.

When you add device entries to prevent devices from being enumerated, make sure that there aren't any action clauses after them. Any group of actions clauses found after any single or set of device entries is used for those devices. Place these device entries at the end of your overrides configuration file.
- If you want to change the way the enumerator starts TCP/IP, you have
to override the definition of the basic io-net command that's
defined in /etc/systems/enum/include/net.
By default, the command is:
io-net -ptcpip
If you want to enable IPSec, add this code to your overrides file:
all set(IONET_CMD, io-net -ptcpip ipsec)
Host-specific enumerators
To further customize the enumerators for your system configuration, you can create a /etc/host_cfg/$HOSTNAME/system/enum directory. If this directory structure exists, the rc.devices script tells the enumerators to read configuration files from it instead of from /etc/system/enum.
![]() |
Even if you have a /etc/host_cfg/$HOSTNAME/system/enum directory, the enumerator looks for an oem directory and overrides file under /etc/system/enum. |
An easy way to set up the directory is to copy the /etc/system/enum directory (including all its subdirectories) to your /etc/host_cfg/$HOSTNAME/system directory and then start customizing.
/etc/rc.d/rc.sysinit
The /etc/system/sysinit script runs /etc/rc.d/rc.sysinit to do local initialization of your system.

Initialization done by /etc/rc.d/rc.sysinit.
The rc.sysinit script does the following:
- It starts a secure random-number generator, random, to provide random numbers for use in encryption and so on.
- If the /var/dumps directory exists, rc.sysinit starts the dumper utility to capture (in /var/dumps) dumps of processes that terminate abnormally.
- If /etc/host_cfg/$HOSTNAME/rc.d/rc.local exists and is executable, rc.sysinit runs it. Otherwise, if /etc/rc.d/rc.local exists and is executable, rc.sysinit runs it. There isn't a default version of this file; you must create it if you want to use it. For more information, see "rc.local," below.
- Finally, rc.sysinit runs tinit. By default, the system starts Photon, but if you create a file called /etc/system/config/nophoton, then rc.sysinit tells tinit to use text mode. For more information, see "tinit," below.
rc.local
As described above, rc.sysinit runs /etc/host_cfg/$HOSTNAME/rc.d/rc.local or /etc/rc.d/rc.local, if the file exists and is executable.
You can use the rc.local file to customize your startup by:
- starting additional programs
- mounting libraries for processes that are already running
You can also use rc.local to slay running processes and restart them with different options, but this is a heavy-handed approach. Instead of doing this, modify the device enumeration to start the processes with the correct options. For more information, see "Device enumeration," earlier in this chapter.
For example, you can:
- run an NFS or CIFS client to mount a remote filesystem
- start inetd, to allow users on other machines to access your machine (see TCP/IP Networking)
- start lpd or a specific instance of spooler -- or both -- to support printing (see Printing)
- arrange to bypass the login prompt when booting into Photon, by
adding this:
/usr/photon/bin/Photon -l '/usr/photon/bin/phlogin -O -Uuser:password'Note that you have to put your password as plain text in your rc.local, but presumably you aren't concerned with security if you want to bypass the login prompt.
The -O option to phlogin brings you back to text mode when you terminate your Photon session; without the -O, pressing Ctrl-Shift-Alt-Backspace simply logs you in again.
Alternatively, you can set up a user's .profile to start Photon (with the ph command), and then add this command to your rc.local file:
login -f user_nameFor more information, see login in the Utilities Reference.
Don't use the rc.local file to to set up environment variables, because there's another shell that starts after this script is run, so any environment variable that you set in this file disappears by the time you get a chance to log in.
![]() |
After you've created rc.local, make
sure that you set the executable bit on the file with the command:
chmod +x rc.local |
tinit
The tinit program initializes the terminal, as follows:
- If the -p option is specified, tinit starts Photon.
- Otherwise, tinit looks at /etc/config/ttys and runs login or shells, based on the contents of the file.
For more information, including a description of /etc/config/ttys, see tinit in the Utilities Reference.
Troubleshooting
Here are some problems you might encounter while customizing how your system starts up:
- The applications I put in rc.local don't run.
- Check the following:
- Make sure that the file is executable; use the
chmod
command to correct this, if necessary:
chmod +x /etc/rc.d/rc.local
- Make sure that the executable is in a directory that's included in the PATH environment variable as it's defined when the system executes /etc/rc.d/rc.local.
- Make sure that the file is executable; use the
chmod
command to correct this, if necessary:
- I messed up my rc.local file, and now I can't boot.
- You can:
- Boot from CD and correct your rc.local file.
Or:
- Boot your system into "debug shell" mode:
press Space during booting up, then press F5 to start
the debug shell.
Once you're in the debug shell ( fesh), enter the exit command, then wait for the second shell prompt. Type this command:
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
You can then correct your rc.local, or move it out of the way so that you can boot without it:
cd /etc/rc.d cp rc.local rc.local.bad rm rc.local
- Boot from CD and correct your rc.local file.
![]() |
![]() |
![]() |
![]() |

![[Previous]](prev.gif)
![[Contents]](contents.gif)
![[Index]](keyword_index.gif)
![[Next]](next.gif)
