mkqnximage

QNX SDP8.0Utilities ReferenceUtilities

Generate a QNX OS virtual machine image

Syntax:

mkqnximage --type=vmware|vbox|qemu [--arch=x86_64 | aarch64le]
           [--assumed-ip=ip-address] [--build] [--clean]
           [--config=file[:file]...] [--defaults [=option]]
           [--extra-dirs=none|directory_list] [--getip]
           [--graphics [= yes | no ]] [--help [=option|brief]]
           [--hostname=hostname][--options]
           [--policy=none|path] [--repos=dir[:dir]...]
           [--run [= options | -h ]] [--stop]
           [--wipe]

Runs on:

Linux, Microsoft Windows

Options:

For additional options not described here, use --help and --options.

--arch = x86_64 | aarch64le

Specify the architecture to build for.

The default value is x86_64. For VMWare and VirtualBox, only x86_64 is supported.

--assumed-ip=ip-address

Use the specified IP address instead of trying to resolve it. Specify none to select the normal resolution process (for more information, go to the description for --getip).

--build

Force a rebuild of the system image.

--clean
Force a clean build of the system image.

Because mkqnximage sometimes uses files from previous builds instead of regenerating them (for efficiency), rebuilding with --clean can be a helpful troubleshooting step.

--config=file[:file]...
If you have a set of options that you use frequently, you can save them in a file. If you have multiple configuration files, use a colon (:) to separate the filenames. For example, to specify the files set1 and set2:
mkqnximage --config=set1:set2
--defaults[=option]
Revert the specified option to its default value, or omit option to revert all options to their default values.
--extra-dirs=none | directory_list
Specify additional directories to search for mkqnximage options and other files. Specify none to use only the standard mkqnximage and local directories.
--getip
Get the IP address of the QNX OS system image in this directory.

This option waits for the system image to be up and running before it returns a value.

If you are creating an image for a physical target, resolving the IP address relies on multicast DNS and --getip doesn't work if your host machine is not in the same subnet as the target. To work around this issue, determine the IP address by other means (e.g., run ifconfig on the console) and use --assumed-ip to provide it to mkqnximage.
--help [= option | brief ]
  • --help — Display detailed descriptions of all options.
  • --help=brief — Display a brief description of all options.

  • --help=option — Display detailed information about the specified option.
--hostname=hostname
Specify the name of the virtual machine. Because VMware and VirtualBox list virtual machines by hostname, this option can make it easier to identify a machine in those environments.

You can use this option to specify a different name. For example:

mkqnximage --type=vmware --run --hostname=qnx
--options
Display the options that are currently used when you run mkqnximage.
--repos=dir[:dir]...
Specify the search path used by mkifs and mkqnx6fsimg to locate files specified in the build files. Use a colon (:) or semi-colon (;) to separate the directories that mkifs and mkqnx6fsimg search.

For example, use the following command to search both $QNX_TARGET and ~/qnx/stage for files to include:

mkqnximage --repos='$QNX_TARGET:~/qnx/stage' 
The following command also searches both $QNX_TARGET and ~/qnx/stage, but prefers files in ~/qnx/stage:
mkqnximage --repos='~/qnx/stage:$QNX_TARGET' 
--run [=options | -h]
  • --run — Run the system image in the current directory.
  • --run=-h — Run the system image in the current directory in headless mode. The system image runs in the background without displaying anything on the screen.

--ssh-ident=path
Set the path to an ssh identity file, which allows you to log in as root to a virtual machine using ssh without specifying a password.
--stop
Stop any running system image.
--type = vmware | vbox | qemu
A directory can only contain one system image, but you can rebuild it for a different virtualization environment at any time, by rerunning with a different --type option. Whatever options you specified for the original environment are preserved.
--wipe
Stop the image if it is running, unregister it from any virtualization environments where it is registered (if possible), and delete the local and output directories.

Description:

The mkqnximage utility is a QNX OS virtual machine image generator. It can generate images to run in the following virtualization environments:

  • VMware — A hosted hypervisor.
  • VirtualBox — A free and open-source hosted hypervisor for x86 virtualization.

  • QEMU (Quick EMUlator) — A free and open-source emulator.

You can configure various options for the generated images, including the target CPU architecture. Currently, only the following combinations of host OS, VM platform, and target CPU architecture are supported:

Virtualization Technology Host OS QNX Guest CPU Architecture
VMware Windows x86-64
VirtualBox Windows x86-64
QEMU Ubuntu x86-64, AArch64
Note:
Currently, graphics is only available for VMware images.

There is no limit to the number of QNX OS images you can create, but each one has to be in a different directory.

For information on creating an image on real hardware, see the BSP documentation for your board.

Preparing the virtualization environment:

VirtualBox network interface requirements

If this is the first time using VirtualBox, make sure it has a network interface before you run mkqnximage. To create a network, select the Network settings from Tools from the left pane and then click on the Create icon. Also, you have to enable DHCP.

Setting environment variables for Microsoft Windows

To use mkqnximage on Microsoft Windows from a cmd window, first locate and run the file qnxsdp-env.bat from the base directory of a QNX Software Center installation.

Building, running, and managing QNX system images:

Getting information about options

The mkqnximage utility supports more options than the ones listed above. To display the complete set of options with a brief description of each, run the following command:

mkqnximage --help=brief

For detailed information about a specific option, specify an option name instead of brief. Specify --help by itself to display all options with full descriptions.

Image directory

Whenever you run mkqnximage, it operates on the image in the current directory, whether you are building or running an image or getting its IP address.

In most cases, when you create a new system image, you start with an empty directory.

When mkqnximage first builds an image, it creates the following directories:

local
Contains information about how the target was built and any local customizations.
output
Contains the actual system image and buildfiles used to generate it. If you delete this directory, you can regenerate the image by running mkqnximage.

The output/build directory contains the build files and startup scripts that mkqnximage generates. You can edit these files and scripts as a quick way to try things out and diagnose problems. However, be aware that the contents of the output/build directory is regenerated when you run mkqnximage with updated options.

Running and stopping system images

Use --run to start the image in the current directory and --stop to stop it.

If you are using VMware Workstation Player, you cannot use mkqnximage to start and stop images. Instead, open the file local/vmware_files/vmware.vmx.

You can combine other options with --run. If the options are different than the ones you used to build the image, mkqnximage rebuilds the image before it runs it; otherwise, it just runs it. If needed, you can use --build to force a rebuild of the system image when you run it. For example, you can force a rebuild to pick up changed versions of files.

Connecting to an image

The --getip option outputs the IP address of the system image if it is currently running. You can then use ssh to log in.

You can use scp and sftp to transfer files to and from the virtual machine.

Images built by mkqnximage include the users root, qnxuser, and user1 to user6. The password for each user is the same as the username.

Changing build options

When you run mkqnximage, the options you specify are preserved in local/options. To make changes, run mkqnximage and specify just the options you want to change. Use --options to display the current set of preserved options.

Use the following command to revert a single option to its default value:

mkqnximage --defaults=option

To revert all options to their default values, specify --default on its own.

Image filesystems

The filesystems on images built by mkqnximage are organized to achieve the best results for an embedded system rather than the traditional UNIX layout. No filesystem (other than possibly the IFS) is mounted at /. Instead, an image has the following filesystems:

  • A system partition that in some cases is made read-only. It is mounted at /system and contains binaries and read-only configuration files.
  • A data partition mounted at /data that is always read-write.

Deleting an image

When you no longer need the system image, use --wipe to unregister it from any virtualization environments where it is registered (if the environment allows it), and delete the local and output directories.

The mkqnximage utility cannot remove a virtual machine from VMware. The --wipe option frees all disk space used by the image, but the virtual machine in VMware’s Virtual Machine Library has to be deleted manually.

Both VMware and VirtualBox allow you to delete virtual machines including all associated files. While this action prevents the image from being run, because all the options are preserved, you can restore it by simply re-running mkqnximage.

Customizing an image

You can add content to files generated by mkqnximage as well as add new files to the image, which allows you to, for example, start new services on boot.

To make these changes, you edit 'snippet' files in the local/snippets directory. The most commonly used files are created for you, and you can create more as needed.

Each snippet file name has a prefix that determines what it does and a suffix that makes its name unique. Although the suffix is usually .custom, you can use a different value. For example, to add files to the system partition, you edit the file local/snippets/system_files.custom, and to add files to the IFS, you edit local/snippets/ ifs_files.custom.

The format of a snippet file depends on the file. For a snippet file that adds files to the system, the format must be in mkifs buildfile format for the IFS or mkqnx6fsimg buildfile format for the other two filesystems. The mkqnximage utility recognizes the following snippet file prefixes:

File prefix Description
ifs_files Includes additional files in the IFS. Uses the mkifs buildfile format.
system_files Includes additional files in the system partition. Uses the mkqnx6fsimg buildfile format.
data_files Includes additional files in the data partition. Uses the mkqnx6fsimg buildfile format.
ifs_env Used mainly for creating procmgr symlinks and setting environment variables at the beginning of the IFS startup script. These files must use the format defined for script files by mkifs.
ifs_start Commands used for starting the system. These commands include security policy loading if appropriate and execution of the startup script or SLM depending on the method used for starting the system. These files must use the format defined for script files by mkifs.
post_start Included in post_startup.sh, a shell script run at the end of startup.sh and by the SLM configuration file. It should contain commands that ksh can handle.
slm Included in the SLM configuration file.
profile Included in target system's /system/etc/profile, which is the file run when a user logs in to set up their environment. It should contain commands that ksh can handle.
passwd_file, shadow_file, group_file Include content in the passwd, shadow and group files. The format of these files must match that used by /etc/passwd, /etc/shadow, and /etc/group.
definitions Insert into the start of all preprocessed files to define preprocessor symbols.
options Define special options. This file is formatted as one or more bash variable assignments. Setting the variable PROC_OPTIONS appends the value of this variable to the procnto command line options.

To include your own files in an image, either provide full paths to the files or use --repos to specify the paths to search.

Configuration files

If you have sets of options that you use frequently, you can save their values in a file and apply them using --config. The files are treated as bash scripts that are sourced by mkqnximage and are expected to set one or more variables to indicate new values for options. For example, a file contains the following line:
OPT_SECURE_PROCFS='yes'

When you load the file using --config, the effect is the equivalent to specifying --secure-procfs=yes.

The current settings of all options in this format are in the file local/options. If you set the environment variable MKQNXIMAGE_CONFIG to a path to this type of file, mkqnximage uses the file to provide the initial configuration whenever it creates a new system image.

Because the configuration file is a bash script, it can do more than set variables. For example, it can set the --hostname option based on the name of the current directory.

Image security

The mkqnximage utility is intended to provide, among other things, a method for demonstrating QNX OS security features. However, it is deliberately not secure because making it secure would make it less suitable for its primary role as an easy-to-use platform for experimentation. Although it provides a good way to learn about security features, for security reasons, it should not be emulated too closely in a real system. The following characteristics are some of ways that it is insecure:
  • It provides console access running a root shell.
  • It uses password and ssh public key authentication.
  • It uses deliberately obvious passwords.
  • sshd permits root logins.
  • When QNX Trusted Disk is used, the private key is kept unprotected in a local host directory.
  • It does not use any form of secure boot.
  • It runs the qconn service.

Generating images for physical targets:

The mkqnximage utility creates the disk partition files differently when building for a physical target. This difference is to support the use of large SD cards without paying the cost of writing this much data, as well as the ability to update individual partitions.

To support individual updates, mkqnximage makes partitions on the SD cards a fixed size, specified by the --part-sizes option. The partition files that contain the filesystems for the system and data partitions are made just big enough to hold their initial contents. The partition files are copied to their respective partitions on the SD card and, in the case of Power-Safe filesystems, expanded on first boot.

Because the partitions are a fixed size, individual ones can be updated without affecting the others. This update can be done either by writing the SD card on the host system or via an over-the-air update to a running system.

For writing the SD card, mkqnximage provides two options:

  • Create a complete image file. It is shrunk and takes advantage of filesystem expansion. You are responsible for copying the image file to the SD card.
  • Have mkqnximage write to the SD card directly.

The second method is slightly more flexible because it allows mkqnximage to update just the data partition without affecting the boot or system, while the first results in an image file that can be, for example, stored for later use or sent to someone else.

Setting the partition size

For physical targets, instead of using options such as --sys-size to determine filesystem sizes, you use the --part-sizes option to set the partition sizes of the boot, system, and data partitions. For example, the following option and values set the sizes of the boot and system partitions to 50 and 200 MB, respectively. The data partition is sized to take the remaining space to a maximum of 60 GB:

--part-sizes=50:200

You can also set an explicit size for the data partition, which is useful if you want either a partition that is smaller than the default size (and leave some unused space on the SD card) or an image that's bigger than 60GB.

For example, the following option and values make the data partition 20 GB in size (or the space remaining, whichever is smaller):

--part-sizes=50:200:20000

Copying to an SD card

To update an SD card, use the --copy-dest and --copy options.

Like most mkqnximage options, --copy-dest is persistent and can often be set once and left unchanged, assuming the path to the SD card remains fixed. If you set --copy-dest to none (the default) mkqnximage creates the complete image file for the system. For virtual images, leave it at the default. Alternatively, to make mkqnximage write to the card directly, set it to the path to the SD card.

The --copy option updates the system image with the latest partition files. Its value indicates which partition or partitions to update:

  • all—update the entire image
  • b—update the boot partition
  • s—update the system partition
  • d—update the data partition

You can update selective partitions. For example, the following command updates only the boot and system partitions:

mkqnximage --copy=bs

When --copy-dest is set to none, mkqnximage does not write to the SD card directly but instead creates an image file in the output directory whenever a build is done. This image file then needs to be transferred to the SD card using the dd utility or some similar method.

To do a partial update, you can use the --copy option to create image files with a different set of partitions. The set of partitions used for the most recent --copy option are used as the default for future copying and builds. However, if --copy-dest is none, copying one partition also copies all the partitions that come before it on the SD card. You can't, for example, update only the data partition.

Over-the-air updates

The --update option allows you to update a target via the network. These over-the-air updates change entire partitions rather than individual files. The --update option uses the same values as --copy, and like --copy it allows you to select which of the target's partitions to update.

You can combine --update with other options, such as --build, to rebuild before updating.

The update performs a few basic tasks. If there are regenerated partition files, mkqximage copies them to /dev/shmem, the devb-* driver is slayed and restarted, and the partition files are copied on top of the actual partitions. If something goes wrong, it might be necessary to reinitialise the SD card using --copy.

Note:

Currently, you can't use an update to change partition sizes.

The --update option depends on the IP address that mkqnximage obtains via --getip, or that you provide via --assumed-ip. For more information, go to Options.

Setting up permissions to allow you to write to your SD card

When you use --copy, mkqnximage requires write access to the device file that represents the SD card. In most cases, you don't have this since you typically read and write to the mounted filesystem, not the raw device that underlies it.

You can change permissions to this path before you run mkqnximage, but this task has to done repeatedly because the permissions are reset each time you insert a card.

On Linux this issue can be fixed using udev rules. These rules are evaluated whenever you insert a card and can, among other things, update permissions.

To use udev rules, you must first identify the device that represents your SD card. This device is something such as /dev/mmcblk0 or /dev/sdb. It can vary depending on whether you are inserting the SD card directly into your computer or using a USB card reader.

If your SD card currently has a filesystem on it that gets mounted when you insert it, you can run the mount command to identify the mount point (probably under /media) and the required device. For example:

$ mount | grep /media
/dev/mmcblk0p1 on /media/myusername/664D-014C type vfat (rw,nosuid,nod . . .

In this case, the required device is /dev/mmcblk0 (which is /dev/mmcblk0p1 with p1 removed).

You can verify that you have the proper path because the path appears when you insert it and not after you remove it. If the SD card does not get mounted, try paths such as /dev/sda, /dev/sdb, and /dev/mmcblk0 and see of their existence changes as you insert and remove the card.

Note:

Make sure that you identify the correct path—you don't want to overwrite your hard disk by mistake!

After you identify the right path, add a simple udev rule for it by creating a file in /etc/udev/rules.d. You can use almost any name, but it must end in .rules (e.g., 99-cardreader.rules). Its content should be something like the following line:

KERNEL=="mmcblk0", ACTION=="add", MODE="0666"

where the KERNEL value is the path that you identified earlier with /dev omitted. The MODE="0666" item indicates that read/write access should be given to everyone.

If you want to set up rules for multiple paths, your rules file can have multiple lines.

In some cases, changes to you udev rules file may not be detected. Use the following command to fix this issue:

sudo udevadm control @o --reload-rules

You can have more sophisticated matching rules by adding various ATTRS tags to the rules. For example:

KERNEL=="sda", ACTION=="add", ATTRS{vendor}=="Kingston", ATTRS{model}=="UHSII uSD Reader", MODE="0666"

To get the possible attributes, run:

udevadm info -a -n /dev/sda

where /dev/sda is whatever is appropriate in your case. This command provides a whole lot of information identifying your device. Pick the attributes that suit your needs.

Setting the time server

Because some targets (e.g., Raspberry Pi) don't include a real-time clock, you need to set their time on boot, via NTP. The default NTP server, pool.ntp.org, may not be accessible from your network. Use the --time-servers option to select an available server. For example:

--time-servers=<ntp_server>

Building an image that can boot on a Raspberry Pi:

Use the following mkqnximage options to build a Raspberry Pi image and write it to an SD card:

mkqnximage --extra-dirs=+rasppi --type=rasppi [--copy-dest=...] --part-sizes=... --repos=...
--extra-dirs=+rasppi

The Raspberry Pi configuration is kept separate. This option makes the rasppi type accessible.

--type=rasppi

Requires --extra-dirs=+rasppi.

--copy-dest=...

(Optional) The path to the device used to access your SD card. When you use the mkqnximage --copy option, the parts of the image that you specify are written here. Can be set to none (the default). For more information, go to "Copying to an SD card."

--part-sizes=...

Two or three colon-separated numbers that specify the size of the boot, system, and data partitions, respectively, in megabytes. The sizes are fixed to allow you to update them selectively.

If only two numbers are specified, the data partition fills the remainder of the SD card, up to 64 GB. If you want a data partition that's larger than 64 GB, specify its size. The size of the data partition is reduced if it doesn't fit on the card.

--repos=...

Specify the locations of additional files needed to build the image. In most cases, you need to specify QNX_TARGET and the directory that contains the firmware.

You can put some of the configuration in a file and load it with the mkqnximage --config option. For example, the file rpi_config has the following content:

OPT_REPOS='$FIRMWARE:$QNX_STAGE_nto:$QNX_TARGET'
OPT_COPY_DEST='/dev/rdisk4'
OPT_PART_SIZES='70:500'

Then, use the following command to build the image using rpi_config:

mkqnximage --extra-dirs=+rasppi --type=rasppi --config=rpi_config

As always, you only need to specify all these options once—the image can be rebuilt different ways without specifying them again.

Note that the example also expects that you have set the environment variable FIRMWARE, which indicates where to find the firmware for the Raspberry Pi (discussed in the next section).

Raspberry Pi firmware blobs

A number of firmware blobs have to be included in the boot partition. You can obtain the latest versions from https://github.com/raspberrypi/firmware. For example:

wget https://github.com/raspberrypi/firmware/raw/master/boot/bcm2711-rpi-4-b.dtb
wget https://github.com/raspberrypi/firmware/raw/master/boot/start4.elf
wget https://github.com/raspberrypi/firmware/raw/master/boot/fixup4.dat

WiFi support requires firmware blobs that can be obtained from https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git. For example:

wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/cypress/cyfmac43455-sdio.bin
wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/cypress/cyfmac43455-sdio.clm_blob
wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/brcm/brcmfmac43455-sdio.raspberrypi,4-model-b.txt

To use these firmware files, fetch them, and then add the containing directory as an additional repository directory via the --repos option.

Configuring WiFi

To connect your Raspberry Pi to a WiFi network, add the relevant network configuration to local/snippets/wifi.custom and rebuild the image.

The contents of local/snippets/wifi.custom is included as part of the /data/var/etc/settings/wpa_supplicant.conf file on the target.

Copying a Raspberry Pi image to an SD Card

If you've set --copy-dest, after you build the image, you use the --copy option to copy it to an unmounted SD card. For example:

mkqnximage --copy=all

This command writes all partition files to the location specified with --copy-dest.

Initially, the entire image must be updated, but subsequently you can copy only selected partitions. For example, the following command updates only the boot (b) and system (s) partitions:

mkqnximage --copy=bs

After the system is booted, subsequent updates can be done over the network using --update instead of --copy. For more information, go to "Over-the-air updates."

If you did not set --copy-dest (or set it to none), you need to write the system image (output/system-image*.img) to the SD card yourself.

Locating the Raspberry Pi

As with virtual machine images, if the Raspberry Pi is booted, you can use the following command to determine its IP address:

mkqnximage --getip

Troubleshooting:

If the --getip option fails to return an address, it most likely means that the virtual machine is not running or failed to boot. If have this issue when the machine is running, you should check the console for indications of an error.

If a system fails to boot, check first that you've chosen a virtualization environment that is available on your system. The mkqnximage utility reports the target type after it builds the image.

In some cases, the source of problems might be that some files are not generated as they should be after one or more local changes or QNX packages are updated. To ensure this is not the case, rebuild with --clean or delete the output directory.

If you are running a QEMU image in headless mode, the console output is redirected to output/qemu.out. For VMware and VirtualBox, you can find the output from the commands used to start the virtual machine in .log files in the output directory.

If you get a build failure, a likely reason is changes you've made to one or more customization files. Any line numbers reported by mkifs or mkqnx6fsimg refer to files in the output/build.

Page updated: