mketfs

Updated: April 19, 2023

Build an embedded transaction filesystem (QNX)

Syntax:

mketfs [option...]* [buildfile] [directory] [outputfile]

mkxfs -t etfs [option...]* [buildfile] [directory] [outputfile]

Runs on:

Linux, Mac, Microsoft Windows

Options:

-?
(QNX Neutrino 7.0 or later) Display some help information.
-D
Treat undeclared intermediate directories as errors. If there's a target filesystem entry of /x/y, and /x has never occurred explicitly in the buildfile, the input directory, or as a child of a recursively included directory, then /x is considered an undeclared intermediate directory.
-d
Display warnings for undeclared intermediate directories.
-l inputline
(“el”) Process inputline before interpretation of the buildfile begins. Input lines given to mketfs should be quoted to prevent interpretation by the shell (as mketfs input lines often contain spaces). Multiple -l options are processed in the order specified. No default.
-n[n...]
Don't use timestamps in the files. Using the -n option permits identical images in binary format. Specifying additional -n options strips all time information from files.
-p patchfile
Apply patching instructions from this file (see Patch files,” below).
-r rootdir

This option doesn't immediately affect where mketfs searches for host files; it only adds standard search paths under rootdir to the MKIFS_PATH environment variable. Because this variable isn't used as the default value for the search attribute (unlike with mkifs), you must do the following to make mketfs behave like mkifs when searching for files:

  1. Add the line [search=${MKIFS_PATH}] near the beginning of your buildfile. For more information, see the search attribute and the MKIFS_PATH description.
  2. Set the PROCESSOR and PROCESSOR_BASE environment variables based on the target platform.

Then, when searching for files, mketfs will search the default paths used for storing binaries within the rootdir directory before searching the default paths within ${QNX_TARGET}.

You can define multiple -r options; each adds a set of paths to search for files. For an explanation of how multiple -r options are handled, see the mkifs -r option.

-v[v..]
Operate verbosely. Specifying additional -v options increases verbosity. Default is quiet operation.

Description:

The mketfs utility reads a text buildfile describing an embedded transaction filesystem (ETFS) and produces a binary image file containing the ETFS as a sequence of transactions. You can copy this file to flash at a later stage, using etfsctl.

Note: Don't confuse this command with mkifs, which builds an OS image filesystem, or mkefs, which builds an embedded filesystem.

You specify the input and output on the command line:

buildfile
The filename of the buildfile that describes the contents of the embedded filesystem; use - to specify standard input (the default).
directory
The root of a directory hierarchy to be appended to the file list specified in buildfile (if any). The default is no directory.
outputfile
The filename of the image file containing the ETFS; use - to specify standard output (the default). Note that you can specify the outputfile only if you specified a buildfile.

If you don't specify either a buildfile or a directory, a buildfile is expected as input from standard input. The output is always an image file; if you don't specify outputfile, image-file data will be produced on standard output.

The mketfs utility generates a list of clusters, which are sized to match the hardware (1024, 2048, or 4096 bytes). Each cluster has a header of type struct etfs_trans, which is a fixed 16 bytes. So the actual size of the image file is the size of the input data (rounded up to a multiple of the cluster size) plus 16 bytes times the number of clusters. When etfsctl writes to the filesystem, it removes the etfs_trans structure. As the devio layer is putting the cluster into hardware, it generates a new, BSP-specific structure to hold the same information as was in the etfs_trans.

License checking

The mketfs utility checks for a valid QNX license key before performing any operation. If the license check fails, the utility stops running and displays a diagnostic message. A license check may fail if the license key is expired, missing, or not currently activated, or if the key doesn’t contain the permissions needed to run the utility.

Buildfiles

The buildfile uses the same grammar as the mkifs command, but supports different attributes.

The buildfile is basically just a list of files that you want to be included in the ETFS image file when it's built by mketfs. As well as the files to be included, you can specify various attributes that are used to set parameters of the filesystem and the files in it. For example, you can specify the maximum size of the filesystem, or the user and group IDs of the individual files.

Note:

You can't use a backslash (\) to break long lines into smaller pieces.

You can use forward slashes (/) as directory delimiters in mketfs buildfiles, even on Windows. It is strongly recommended to do so, because backslashes may adversely affect the functionality of your buildfile.

In a buildfile, a pound sign (#) indicates a comment; anything between it and the end of the line is ignored. There must be a space between a buildfile command and the pound sign.

Each line is in the form:

[attributes] file_specification

where the attributes (with the enclosing square brackets) and the file specification are both optional.

You can use an attribute:
  • on the same line as a filename, in which case the attribute modifies only that file. In this example, the attribute modifies only file A:
    [attribute] A
    B
    C
    
  • on a line by itself, in which case the attribute modifies all subsequent files. In this example, the attribute modifies files A, B, and C:
    [attribute]
    A
    B
    C
    

Attributes provide information about the file following the attribute. They're enclosed in square brackets; when combining attributes (e.g., to specify both the user ID and the group ID), enclose both attribute tokens in the same pair of square brackets. For example:

# correct way
[uid=5 gid=5] filename

# incorrect way
[uid=5] [gid=5] filename

There are two types of attributes:

boolean attributes
Those prefixed with a plus (“+”) or minus (“-”) sign.
value attributes
Those ending with an equals sign (“=”) followed by a value. Don't put any spaces around the equals sign.

A question mark (?) before an attribute makes the setting conditional. The attribute is set only if it hasn't already been set. For example, ?+bigendian sets the +bigendian attribute only if +bigendian or -bigendian hasn't been specified.

The file_specification that follows the attributes takes one of these forms:

path

The file is copied from the host to the location in the image defined by the prefix attribute. If path starts with a slash (“/”) on a Linux or Mac development host, or a disk volume label (i.e., drive letter and a colon) followed by a backslash (“\”) on a Windows host, the path is absolute and mketfs looks for the file at that exact host location. (On Windows, any path starting with a backslash but no disk label is absolute within the disk volume of the current directory (e.g., the C: drive) but not across all volumes. To make the path completely absolute, the disk label must be given.)

If path contains a slash or backslash character that's not at the start, the path is relative and mketfs tries to resolve it relative to the current working directory (CWD). If path does not contain a directory separator or the file could not be found relative to the CWD, mketfs tries to resolve it relative to all directories given in the search attribute, in succession.

target_path=host_path
The specified file or contents of the specified directory are fetched from the host filesystem and placed into the image at the specified target location. The search for the host_path file or directory contents proceeds in the same way as it does with the first file specification form, meaning it depends on whether the path is absolute or relative (see the previous paragraph for details).
target_path={contents}
An inline definition. The contents of the file are listed within the buildfile itself, enclosed in braces ({ }); the file doesn't exist on the host system anywhere. The contents of the inline file can't be on the same line as the opening or closing brace.
Note: The mketfs utility doesn't parse the contents of an inline file for anything but the closing brace. For example, mketfs doesn't interpret a pound sign (#) in an inline file as the beginning of a comment. The syntax of the inline file depends on what it's used for on the target system.

Closing braces (}) and backslashes (\) in an inline file must be escaped with a backslash.

You can enclose a filename in double quotes ("") if it includes spaces or unusual characters.

Attributes

The mketfs command supports the following attributes:

Note: You should explicitly specify the cluster_size, block_size and num_blocks attributes as appropriate for your flash device to ensure that the image produced is fully compatible with your specific device.
Note: An OR-bar indicates that either the first element or the second element must be present, but not both (e.g. +|- bigendian means either +bigendian or -bigendian, but not +-bigendian).

bigendian attribute (boolean)

+|-bigendian

Set the byte order for the embedded filesystem to either big (via +bigendian) or little (via -bigendian) endian. The default is little endian.

block_size attribute

block_size=bsize

Set the block size for the ETFS. The block size depends on what memory device you have in your target hardware. The default block size is 16 KB.

cd attribute

cd=pathname

Set the current working directory to the specified pathname before attempting to open the host file. Default is the directory from which mketfs was invoked.

You can specify variables in the attribute's value. For information on how they're expanded (i.e., evaluated to a value used in their place), see the mkxfs section on processing variables.

In the pathname, you can use forward slashes (/) as directory delimiters, even on Windows. It is strongly recommended to do so, because backslashes may adversely affect the functionality of your buildfile.

cksum attribute

cksum=number

Specify the expected checksum (as calculated by the cksum utility) of the file that the attribute applies to. If you specify this attribute, mketfs calculates the checksum of the host file imported into the image and compares it to the expected value; if a mismatch is detected, the program terminates with an error.

cluster_size attribute

cluster_size=csize

Set the cluster size for the ETFS. The cluster size depends on what memory device you have in your target hardware. The default cluster size is 1 KB.

dperms attribute

dperms=dperms_spec

Set the access permissions of the directory. The dperms_spec can be one of the following:

The default dperms_spec is *.

Note: When running on a Windows host, mketfs might guess at the permissions, so you should use the dperms attribute to specify them explicitly. You might also have to use the uid and gid attributes to set the ownership correctly.

drop attribute

drop=[pattern[|pattern]...]

(QNX Neutrino 7.1 or later) Specify patterns of file names that you want to ignore when recursively importing host directories. Each pattern is a simple filename wildcard pattern that can include the following meta-characters:

?
Match exactly one arbitrary character.
*
Match zero or more arbitrary characters.
\
Treat the next character literally.

For example:

[drop=*.sym] bin
[drop=*.a|*.dll] lib

Note the following:

Specifying the drop attribute without a pattern turns off exclusion in subsequent directories (unless you specify another drop attribute).

dupignore attribute

+|-dupignore

Specify whether mketfs should ignore duplicate file entries. When buildfiles are defined from templates by external tools, or when the content is split across multiple files that are then combined with the include attribute, there might be multiple entries defining the same target path. Enabling this attribute (+dupignore) allows you to continue using your buildfile structures when you can't change some parts of the image specification and might have to handle duplicate file entries.

If this attribute is undefined for a file entry, the default value is disabled (-dupignore).

If a file entry is found to have the same target path as another, already parsed entry, then:
  • if both entries have -dupignore (either because it's explicitly set or the default value is used), mketfs reports an error and exits
  • if only one of the entries has +dupignore, mketfs ignores it and includes the other entry in building the image
  • if both entries have +dupignore, the entry defined earlier in the buildfile is included and the entry defined latter is ignored

When an entry is ignored, mketfs reports it if the verbosity level is greater than one (e.g., if -vv is used).

For file entries to be considered duplicates, the target path is the only thing that must match. Other attributes that affect files, such as uid, gid, and perms can differ, but the dupignore settings in effect for any entries containing a given target path determine which entry gets included in the image. It's up to the buildfile writer or systems integrator who generates the target image to ensure that what's included at a given target path has all the appropriate attribute settings.

You can use this attribute to override any default file entry for a particular target path. Suppose you generate a buildfile by using a utility such as mkqnximage, which enables dupignore globally at the beginning of the buildfile. You can manually specify an entry for the target path of interest with this attribute disabled, as follows:
[-dupignore] sshd = path/to/sshd
Because it's only this sshd entry that doesn't allow duplicates, this file will be taken irrespective of where it's listed in the buildfile.
This attribute is handy also if you're using an existing buildfile that defines dupignore for specific files but not globally, and you want to prepend some entries to its files list (e.g., to keep all the entries you manually added in one place, for readability). Suppose the file enables this attribute, and defines others, for a particular target path:
[+dupignore, uid=0] xyz = /etc/abc
If you want to leave the existing content intact but use a different host file with different ownership settings for the same target path, you can add the following entry early in the buildfile, above the existing files list:
[+dupignore, uid=1] xyz = /vars/def
Because both entries for the target path xyz have dupignore enabled, the earlier entry is included in the image. In this case, the file will be the one taken from the host location of /vars/def and its uid will be 1.

In this last example, the two host files specified for the common target location are not identical, but again, the target path is the only thing that determines whether their entries are duplicates.

filter attribute

filter=filter_spec

Run the host file through the filter program specified, presenting the host file data as standard input to the program and using the standard output from the program as the data to be placed into the embedded filesystem. Default is no filter.

You can specify a filter_spec of none. This is useful if you need to override a global filter specification.

[+|-followlink]

Whether to resolve any symbolic links and include the target files or directories instead of the links.

If you specify +followlink (enable the attribute), whenever an item taken from the host filesystem is a symbolic link, mketfs follows the link and includes its target. If you omit the attribute, this is the default behavior.

If you specify -followlink (disable it):

gid attribute

gid=id_spec

Set the group ID number for the file. The value of this attribute may be either a number or an asterisk (*). If it's an asterisk, the group ID is taken from the host file; for an inline file, the group ID is the group of the user running mketfs. The default value for this attribute is *.

include attribute (boolean)

+|-include

(QNX Neutrino 7.1 or later) Include files as part of the buildfile being processed. You can apply this attribute to a single file:

[+include] buildfile_path

or as a global attribute:

[+include]
buildfile_path_1
buildfile_path_2
...
buildfile_path_n
[-include]

You can specify variables in the attribute's value. For information on how they're expanded (i.e., evaluated to a value used in their place), see the mkxfs section on processing variables.

Each buildfile_path can be an absolute or a relative path. If buildfile_path starts with a slash (“/”) on a Linux or Mac development host, or a disk volume label followed by a backslash (“\”) on a Windows host, it's absolute and mketfs searches for the file in that exact host location. For more details on specifying absolute paths, see the buildfile path description above.

If the path starts with another character sequence, it's a relative path, and mketfs searches the following directories (in this order):

Note that you can't use the target=host notation for the paths.

If an include file can't be found, the result depends on the optional attribute. If +optional is set, the missing file is skipped; otherwise, mketfs terminates with an error.

Buildfiles are processed top-down, and buildfile inclusion happens in place: when an include attribute is found, the included buildfile is loaded and processed; when processing is completed, mketfs returns to the including buildfile.

You can nest buildfile inclusions, but any circular inclusion is treated as an error. For example, the inclusion hierarchy A(B(D),C(E,F)) is valid, but A(A) and A(B(C(B))) aren't. If you include a buildfile more than once (which could easily happen with nested include files), the repeated inclusion is ignored, and mketfs issues a diagnostic message.

Note: The top buildfile together with its included buildfiles effectively form one large “buildfile stream” that's processed as a single buildfile would be. This means that all attribute settings in effect before an inclusion remain in effect inside the included files, and everything set in an included file is carried over into the parent buildfile.

The default is -include, which causes files (if found) to be added to the filesystem, not to the buildfile.

mountperms attribute

mountperms=perms_spec

Set the access permissions for mountpoints. The perms_spec can be one of the following:

The default perms_spec is “0775”.

mtime attribute

mtime=time_spec

Set the timestamps of the files or directories to the specified time. The time_spec must be either:

Timestamps specified with the mtime attribute aren't affected by the -n option.

num_blocks attribute

num_blocks=num_blocks[,num_pad]

You must use this attribute to specify the number of blocks in the flash device (num_blocks). You can also use it to specify the minimum number of blocks in the image file (num_pad). If you specify num_pad, then the image file is padded out to that number of blocks; otherwise the image file is padded to num_blocks blocks.

To keep the image as small as possible (for faster programming of the NAND part), set num_blocks to the appropriate number and set num_pad to 0. Doing this will correctly set the size of the .counts file (an array of the blocks showing the read and erase counts), so that wear-leveling will be done.

optional attribute (boolean)

+|-optional

If this attribute is enabled and the host file can't be found, output a warning and continue building the embedded filesystem. If it's disabled and the host file can't be found, output an error message and exit. The default setting is enabled.

This attribute applies only to those items explicitly included in the buildfile.

Note: If you specify [+optional] and [+followlink] (or don't specify one or both of them and use their default setting) and a broken symbolic link is implicitly included from a directory, mketfs returns an error and exits. This is because when followlink is enabled, symbolic links should never be imported into the image.

perms attribute

perms=perms_spec

Set the access permissions of the file. The perms_spec can be one of the following:

The default perms_spec is *.

Note: When running on a Windows host, mketfs can't get the setuid (“set user ID”) or setgid (“set group ID”) permissions from the file, and it might guess at the read, write, and execute permissions, so you should use the perms attribute to specify the permissions explicitly. You might also have to use the uid and gid attributes to set the ownership correctly. To determine whether or not a utility needs to have the setuid or setgid permission set, see its entry in the Utilities Reference.

prefix attribute

prefix=prefix_spec

Set the prefix on the target file names. The default is the empty string.

You can specify variables in the attribute's value. For information on how they're expanded (i.e., evaluated to a value used in their place), see the mkxfs section on processing variables.

In the prefix path, you can use forward slashes (/) as directory delimiters, even on Windows. It is strongly recommended to do so, because backslashes may adversely affect the functionality of your buildfile.

search=path:path:…

This attribute specifies that mketfs should search for the file in the named path locations on the host system. The search directory portion of the host file name isn't included in the name that's stored in the ETFS. The default setting is empty, meaning only the current working directory will be searched for the host files. To make mketfs include the directories named in the MKIFS_PATH variable in the host locations that it searches, see the -r rootdir explanation above.

You can specify variables in the attribute's value. For information on how they're expanded (i.e., evaluated to a value used in their place), see the mkxfs section on processing variables.

Note:

To ensure that your search paths work without modification on all supported host OSs, you can use:

  • forward slashes (“/”), which are now recognized by Windows as well as Linux and macOS; it is strongly recommended to use forward slashes as directory delimiters, because backslashes may adversely affect the functionality of your buildfile
  • the PFS environment variable instead of “;” or “:” to separate multiple paths in path lists (see PFS under “Environment variables:” below)

sha256 attribute

sha256=hex_string

Specify the expected SHA256 hash of the file that the attribute applies to. If you specify this attribute, mketfs calculates the SHA256 hash of the host file imported into the image and compares it to the expected value; if a mismatch is detected, the program terminates with an error. You must specify the expected hash as a string of 64 hexadecimal digits, without a prefix or any delimiters. For example, instead of specifying 0xaa,0xbb,0xcc,..., specify aabbcc....

type attribute

type=file_type

Sets the type of the files being created in the ETFS. Allowable types are:

Note: Specifying [type=dir] tells mketfs to make the named file a directory; you don't need to specify the type when you're copying the contents of a directory. For example, this command:
[type=dir]/usr/bin=/usr/nto/x86_64/bin

creates an empty directory named /usr/bin, with the same owner and permissions as for the host directory. To recursively copy /usr/nto/x86_64/bin to /usr/bin, you just need to specify:

/usr/bin=/usr/nto/x86_64/bin

uid attribute

uid=id_spec

Set the user ID number for the file. The value of this attribute may be either a number or an asterisk (*). If it's an asterisk, the user ID is taken from the host file; for an inline file, the user ID is the user running mketfs. The default value for this attribute is *.

Patch files

Patch files let you override the user ID, group ID, and permissions of certain files, depending on their location and filename pattern. Patches are applied after all files have been collected (from the buildfile and/or the specified directory). Consequently, patch files can override settings specified in the buildfile.

Patch files must contain only lines of the form:

#comment

or:

type:path:pattern:uid:gid:perms

In comment lines, # must be the very first character. The entire line is regarded as a comment and is ignored.

The type is either d or f, optionally followed by r. Type d patches are applied only to directories, and type f patches are applied only to files. An r indicates that the patch should be applied recursively within path; without r, the patch is applied to path only.

The pattern is a filename pattern that specifies which files to apply the patch to. The uid and gid must be decimal numbers, while perms must be an octal number (see chmod). Note that it isn't possible to set only the user ID, group ID, or permissions; for each match, all three are affected.

Examples:

Here's a sample buildfile, my_etfs.bld:

# A sample buildfile for mketfs

[cluster_size=1k block_size=64k num_blocks=240]
/home/jgarvey/nto_flash

In this example, we've specified a cluster_size of 1 KB, a block_size of 64 KB and a total device size of 240 blocks (which is the default configuration of fs-etfs-ram). The files and subdirectories from the /home/jgarvey/nto_flash directory on the host system are to be recursively copied into the root directory of the ETFS.

To create an ETFS image file using the above buildfile, invoke mketfs as follows:

mketfs my_etfs.bld my_image.etfs

This creates the my_image.etfs file containing the ETFS filesystem, which can then be copied to the target sstem as follows:

etfsctl -d /dev/etfs2 -S -e -w my_image.etfs -c

Environment variables:

PFS
Specifies the Path Field Separator (PFS). The mketfs utility automatically sets this variable to the character used to separate paths in path lists. That is, mketfs sets the variable to “;” on a Windows host and to “:” on a Linux or macOS host.

To keep buildfiles host OS-independent, use this environment variable instead of the OS-specific characters; for example, instead of writing:

[search=/a/b:/x/y/z]

write:

[search=/a/b${PFS}/x/y/z]

The mketfs utility will set the environment variable to the path separator appropriate for the host platform.

Exit status:

0
Successful completion.
1
An error occurred.