The script file
The second section of the buildfile starts with the [+script] attribute. This attribute informs mkifs that the specified file is a script file, which is a sequence of commands that you want the kernel and process manager to execute when it has completed its own startup.
The script file can be external or inline, 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, but have the following differences:
You can use modifiers and attributes to control different aspects of command execution or environment. For example, you can use the
[cpu=0]
modifier to bind a particular process to CPU 0.When you specify a modifier on a separate line, it applies to all subsequent commands. When you specify one on the same line as a command, it applies to that command only.
For a description of all available modifiers, see
Script files
in the mkifs documentation.- Some commands are internal (e.g.,
reopen /dev/con1
); seeInternal commands
below. - The script file's contents are parsed by mkifs before being placed into the image.
.script
, which
contains the following: .script={
procmgr_symlink ../../proc/boot/ldqnx-64.so.2 /usr/lib/ldqnx-64.so.2
....
devc-ser8250-abc123 -F -e -c14745600 -b115200 0xc8000000 ^2,15 &
reopen /dev/ser1 5.0
display_msg Serial Driver Started
}
If we review this file, we find that the script:
- Creates a symbolic link in the process manager's in-memory prefix tree.
- 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.
- Issues a reopen command to redirect standard input, output, and error.
- 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
- display_msg [message]
- Output the given message, followed by a newline.
- procmgr_symlink src_path link_path
- 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 [ device_path [ wait_time ] ]
- Redirect standard input, standard output, and standard error to the specified device. Also
suspend the interpretation of the script file for the specified amount
of time until a stat() on the specified device path
succeeds. The default is /dev/console.Note:The wait_time value specifies the maximum number of seconds to wait for the device to appear. Include a decimal character to specify tenths of a second. The default is 5.0 seconds.Writing to /dev/text causes the kernel to output the data to its debug device (typically unbuffered serial port output). At least one core is occupied with transferring this data. Due to the slow speeds of serial ports, this transfer adds latency.
- waitfor pathname [wait_time]
- Wait until a stat() on the given pathname succeeds. The wait_time value can include one decimal digit to specify tenths of a second. The default is 5.0 seconds.
Script processing
Buildfile scripts support foreground and background processes. Just as in the shell, you can 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)
You can use the [cpu=]
attribute to instruct the process manager
to bind processes to a specific CPU core. The syntax for this attribute is like that of any
value
attribute: [attribute=value] 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
- Bind all programs launched after this point to the specified core
[cpu=zero-based core number]
- Allow the named program to run on any core
[cpu=*] program name
At boot time, if there is no CPU core with the specified index, the process manager displays a warning message and launches the program with no runmask restrictions (i.e., no restrictions about which cores it may run on).
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!