Scripts

The second section of the buildfile starts with the [+script] attribute. This attribute instructs mkifs that the specified file is a script file, a sequence of commands that you want the procnto process manager to execute when it has completed its own startup.

The script file can be external or in-line, and its name is arbitrary, though QNX usually uses some variation on .script. Multiple scripts are concatenated into one and are interpreted in the order in which they appear.

Script file syntax

Script files look just like regular shell scripts, except that:

In this example, the script file is a in-line file called .script, which contains the following:

procmgr_symlink ../../proc/boot/libc.so /usr/lib/ldqnx.so.2

devc-ser8250-abc123 -F -e -c14745600  -b115200 0xc8000000 ^2,15 &
reopen
    
display_msg Serial Driver Started

If we review the this script file, we find that the script:

  1. Creates a symbolic link to ../../proc/boot/libc.so called /usr/lib/ldqnx.so.2.
  2. Starts a serial driver (the fictional devc-ser8250-abc123) in edited mode with hardware flow control disabled at a baud rate of 115200 bps at a particular physical memory address.
  3. Issues a reopen command to redirect standard input, output, and error.
  4. Displays a message.

As mentioned in Environment variables the bootstrap file can set the _CS_PATH and _CS_LIBPATH configuration strings. You can set PATH, LD_LIBRARY_PATH, and other environment variables if the programs in your script need them.

Internal commands

Internal commands are commands that mkifs recognizes and are not loaded from the host’s filesystem. These are:

display_msg
Output the given text.
procmgr_symlink
The equivalent of ln -P (Create the link in the process manager's in-memory prefix tree.), except that ln doesn't need to be present.
reopen
Cause stdin, stdout, and stderr to be redirected to the given filename.
waitfor
Wait until a stat() on the given pathname succeeds.

Script processing

Startup scripts support foreground and background processes. Just as in the shell, specify an ampersand (&) on the command line to make the program run in the background. If you run a program in the foreground, and it doesn't exit, then the rest of the script is never executed, and the system might not become fully operational.

For a command to be run, its executable must be available when the script is executed. You can add the executable to the image, or get it from a filesystem that's started before the executable is required. Placing the executable in a filesystem reduces the size of the OS image.

Binding processes to a CPU core ([cpu=] attribute)

In the startup script, you can use the [cpu=] attribute to instruct the startup launch to bind processes to a specific the CPU core. The syntax for this attribute is like that for any “Value” attribute: [attribute=value] optional filename. Use this attribute in one of the following ways:

Bind the named program to the specified core
[cpu=zero-based core number] program name. For example:
[cpu=0] my_program
Bind all programs launched after this point to the specified core
[cpu=zero-based core number]. For example:
[cpu=1]
Allow the named program to run on any CPU core
[cpu=*] program name. For example:
[cpu=*] my_program

At boot time, if there is no processor core with the specified index, the startup displays a warning message, and launches the command with no runmask restrictions.

Note: Due to a limitation in the boot image records, this syntax allows only the specification of a single CPU and not a more generic runmask. Use the on utility to spawn a process within a fully specified runmask.

The script file on the target

The script file stored on the target isn't the same as the original specification of the script file in the buildfile. This difference is because the script file on the target is not the original ASCII text: mkifs parses the text commands in the script file and stores only the parsed output on the target.

This design minimizes the work that the process manager has to do at runtime when it starts up and processes the script file — we didn't want to have to include a complete shell interpreter in the process manager!