Appendix: Examples

This appendix includes examples of the following:

Buildfile for an NFS-mounting target

Here's a sample buildfile for an NFS-mounting target.


Note: In a real buildfile, you can't use a backslash (\) to break a long line into shorter pieces, but we've done that here, just to make the buildfile easier to read.

###########################################################################
##
## QNX Neutrino 6.x on the fictitious ABC123 board
##
###########################################################################
##
## SUPPORTED DEVICES:
##
## SERIAL:  RS-232 ports UART0 and UART1
## PCI:     4 PCI slots
## NETWORK: AMD 79C973
## FLASH:   4MB Intel Strata Flash
## USB:     UHCI USB Host Controller
##
##  - For detailed instructions on the default example configuration for
##    these devices see the "CONFIGURING ON-BOARD SUPPORTED HARDWARE"
##    section below the build script section, or refer to the BSP docs.
##  - Tip: Each sub-section which relates to a particular device is marked
##         with its tag (ex. SERIAL). You can use the search features of
##         your editor to quickly find and add or remove support for
##         these devices.
##
###########################################################################
##
## NOTES:
##
###########################################################################

###########################################################################
## START OF BUILD SCRIPT 
###########################################################################

[image=0x800a0000]
[virtual=armle,srec] .bootstrap = {
###########################################################################
## default frequency for 4kc is 80MHz; adjust -f parameter for different 
## frequencies
###########################################################################
    startup-abc123 -f 80000000 -v
    PATH=:/proc/boot procnto-32 -v 
}

[+script] .script = {
    procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2

    display_msg Welcome to QNX Neutrino 6.x on the ABC123 board

    #######################################################################
    ## SERIAL driver
    #######################################################################
    devc-ser8250 -e -c1843200 -b38400 0x180003f8,0x80020004 \
0x180002f8,0x80020003 &
    waitfor /dev/ser1
    reopen /dev/ser1

    slogger &
    pipe &

    #######################################################################
    ## PCI server
    #######################################################################
    display_msg Starting PCI server...

    pci-abc123 &
    waitfor /dev/pci 4
    
    #######################################################################
    ## FLASH driver
    #######################################################################
    # display_msg Starting flash driver...
    #
    # devf-abc123 &
    
    #######################################################################
    ## NETWORK driver
    ##  - substitute your IP address for 1.2.3.4
    #######################################################################
    display_msg Starting on-board ethernet with the v6 TCP/IP stack...
     
    io-pkt-v6-hc -dpcnet
    waitfor /dev/io-net/en0 4
    ifconfig en0 1.2.3.4

    #######################################################################
    ## REMOTE_DEBUG (gdb or Momentics)
    ##  - refer to the help documentation for the gdb, qconn and the IDE
    ##    for more information on remote debugging
    ##  - the commands shown require that NETWORK be enabled too
    #######################################################################
    # devc-pty &
    # waitfor /dev/ptyp0 4
    # qconn port=8000



    #######################################################################
    ## USB driver
    #######################################################################
    # display_msg Starting USB driver...
    #
    # io-usb -duhci &
    # waitfor /dev/io-usb/io-usb 4
    
    #######################################################################
    ## These env variables are inherited by all the programs which follow
    #######################################################################
    SYSNAME=nto
    TERM=qansi
    PATH=:/proc/boot:/bin:/sbin:/usr/bin:/usr/sbin
    LD_LIBRARY_PATH=:/proc/boot:/lib:/usr/lib:/lib/dll

    #######################################################################
    ## NFS_REMOTE_FILESYSTEM
    ##  - This section is dependent on the NETWORK driver
    ##  - Don't forget to properly configure and run the nfsd daemon on the
    ##    remote file server.
    ##  - substitute the hostname or IP address of your NFS server for
    ##    nfs_server. The server must be exporting
    ##    "/usr/qnx630/target/qnx6/armle".
    #######################################################################
    display_msg Mounting NFS filesystem...
     
    waitfor /dev/socket 4
    fs-nfs3 nfs_server:/usr/qnx630/target/qnx6/armle /mnt

    [+session] ksh &
}

[type=link] /bin/sh=/proc/boot/ksh
[type=link] /dev/console=/dev/ser1
[type=link] /tmp=/dev/shmem

###########################################################################
## uncomment for NFS_REMOTE_FILESYSTEM
###########################################################################
[type=link] /bin=/mnt/bin
[type=link] /sbin=/mnt/sbin
[type=link] /usr/bin=/mnt/usr/bin
[type=link] /usr/sbin=/mnt/usr/sbin
[type=link] /lib=/mnt/lib
[type=link] /usr/lib=/mnt/usr/lib
[type=link] /etc=/mnt/etc

libc.so.2
libc.so
libm.so

###########################################################################
## uncomment for NETWORK driver
###########################################################################
devn-pcnet.so
libsocket.so

###########################################################################
## uncomment for USB driver
###########################################################################
# devu-uhci.so
# libusbdi.so

[data=c]
devc-ser8250

###########################################################################
## uncomment for REMOTE_DEBUG (gdb or Momentics)
###########################################################################
# devc-pty
# qconn

###########################################################################
## uncomment for PCI server
###########################################################################
pci-abc123
pci

###########################################################################
## uncomment for FLASH driver
###########################################################################
# devf-abc123
# flashctl

###########################################################################
## uncomment for NETWORK driver
###########################################################################
io-pkt-v6-hc
ifconfig
nicinfo
netstat 
ping

###########################################################################
## uncomment for USB driver
###########################################################################
# io-usb
# usb

###########################################################################
## uncomment for NFS_REMOTE_FILESYSTEM
###########################################################################
fs-nfs3

###########################################################################
## general commands
###########################################################################
ls
ksh
pipe
pidin
uname
slogger
sloginfo
slay

###########################################################################
## END OF BUILD SCRIPT
###########################################################################

qnxbasedma.build

Here's the buildfile for .boot on an x86 platform, qnxbasedma.build:


Note: In a real buildfile, you can't use a backslash (\) to break a long line into shorter pieces, but we've done that here, just to make the buildfile easier to read.

#
# The buildfile for QNX Neutrino booting on a PC
#
[virtual=x86,bios +compress] boot = {
	# Reserve 64 KB of video memory to handle multiple video cards.
	startup-bios -s64k

	# PATH is the *safe* path for executables
    #    (confstr(_CS_PATH...))
	# LD_LIBRARY_PATH is the *safe* path for libraries
    #    (confstr(_CS_LIBPATH)) i.e. This is the path searched
    #    for libs in setuid/setgid executables.
	PATH=/proc/boot:/bin:/usr/bin:/opt/bin \
LD_LIBRARY_PATH=/proc/boot:/lib:/usr/lib:/lib/dll:/opt/lib \
procnto-instr
}

[+script] startup-script = {
	# To save memory, make everyone use the libc in the boot
    # image! For speed (fewer symbolic lookups), we point to
    # libc.so.3 instead of libc.so.
	procmgr_symlink ../../proc/boot/libc.so.3 /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" 
    # and "devc-con-hid" (-o).
	# By adding "-e", the Linux ext2 filesystem will be mounted
    # as well.
	[pri=10o] PATH=/proc/boot diskboot -b1 -D1 \
-odevc-con,-n4 -odevc-con-hid,-n4
}

# Include the current libc.so. It will be created as a real
# file using its internal SONAME, with libc.so being a
# symlink to it. The symlink will point to the last libc.so.*,
# so if an earlier libc is needed (e.g. libc.so.2), add it
# before libc.so.

libc.so.2
libc.so
libhiddi.so
libusbdi.so

# Include all the files for the default filesystems
libcam.so
io-blk.so
cam-disk.so
fs-qnx4.so
fs-dos.so
fs-ext2.so
cam-cdrom.so
fs-udf.so

# USB for console driver
devu-ehci.so
devu-ohci.so
devu-uhci.so
devh-usb.so
devh-ps2ser.so

# These programs need to be run only once from the boot image.
# "data=uip" will waste less memory as the RAM from the boot
# image will be used directly without making a copy of the data
# (i.e. as the default "data=cpy" does). When they have been
# run once, they will be unlinked from /proc/boot.
[data=copy]
seedres
pci-bios
devb-eide
devb-amd
devb-aha2
devb-aha4
devb-aha7
devb-aha8
devb-adpu320
devb-ncr8
devb-umass
devb-ahci
devb-mvSata
umass-enum
umass-enum.cfg
io-usb
io-hid
diskboot
slogger
fesh
devc-con
devc-con-hid

For more information about buildfiles (including some other samples), see Building Embedded Systems.

Buildfile that doesn't use diskboot

This buildfile is for an OS image that starts up without using diskboot.


Note: In a real buildfile, you can't use a backslash (\) to break a long line into shorter pieces, but we've done that here, just to make the buildfile easier to read.

#
# The build file for QNX Neutrino booting on a PC
#
[virtual=x86,bios +compress] boot = {
    startup-bios -s64k
    PATH=/proc/boot:/bin:/usr/bin LD_LIBRARY_PATH=/proc/boot:\
/lib:/usr/lib:/lib/dll procnto-smp
}

[+script] startup-script = {
    display_msg "  "
    display_msg "QNX Neutrino 6.3.0 inside!"
    display_msg "  "
    procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2

    display_msg "---> Starting PCI Services"
    seedres
    pci-bios
    waitfor /dev/pci

    display_msg "---> Starting Console Manager"
    devc-con -n8
    waitfor /dev/con1
    reopen /dev/con1

    display_msg "---> Starting EIDE Driver"
    devb-eide blk cache=64M,auto=partition,vnode=2000,ncache=2000,\
noatime,commit=low dos exe=all
    waitfor /dev/hd0
    waitfor /dev/hd1

    # Mount one QNX 4 filesystem as /, and another as /home.
    # Also, mount a DOS partition and the CD drive.

    mount /dev/hd0t79 /
    mount /dev/hd1t78 /home
    mount -tdos /dev/hd1t12 /fs/hd1-dos
    mount -tcd /dev/cd0 /fs/cd0
    
    display_msg "---> Starting /etc/system/sysinit"
    ksh -c /etc/system/sysinit
}

libc.so.2
libc.so
libcam.so
io-blk.so
cam-disk.so
fs-qnx4.so
fs-dos.so
fs-ext2.so
cam-cdrom.so
fs-cd.so

[data=c]
seedres
pci-bios
devb-eide
slogger
ksh
devc-con
mount

.profile

When you create a new user account, the user's initial .profile is copied from /etc/skel/.profile (see Managing User Accounts). Here's what's in that file:

# default .profile
if test "$(tty)" != "not a tty"; then
echo 'edit the file .profile if you want to change your environment.'
echo 'To start the Photon windowing environment, type "ph".'
fi

This profile runs the tty utility to get the name of the terminal that's open as standard input. If there is a terminal, .profile simply displays a couple of helpful hints.

You might want to set some environment variables:

EDITOR
The path to your favorite editor (the default is vi).
ENV
The name of the profile that ksh should run whenever you start a shell.

The code for these changes could look like this:

export EDITOR=/usr/local/bin/jed
export ENV=$HOME/.kshrc

.kshrc

Here's an example of a profile that ksh runs if you set the ENV environment variable as described above for .profile:

alias rm="rm -i"
alias ll="ls -l"
export PS1='$(pwd) $ '

This profile does the following:

Configuration files for spooler

This section includes the configuration files to use for remote printing, using lpr, SAMBA, and NCFTP.

Using lpr

PNPCMD=POSTSCRIPT

#----------------------------------------------------------------------
#
# The following macros are expanded for each filter command line
# $d - Device
# $m - PnP manufacture/model id
# $n - Printer name
# $s - Spooldir name
# $$ - A real $
#
#----------------------------------------------------------------------

FileVersion             =   2
#   printer_name is the name that you specified in the /etc/printcap file.
Filter                  =   ps:$d:lpr -Pprinter_name
Filter                  =   phs:ps:phs-to-ps

Supported Resolution    =   300 * 300,
                            600 * 600,
                            1200 * 1200

Supported PaperSize     =   8500 * 11000 : Letter,
                            8500 * 14000 : Legal

Supported Orientation   =   0 : Portrait,
                            1 : Landscape

Supported Intensity     =   0   : Min,
                            100 : Max

Supported InkType       =   1 : "B&W",
                            3 : "Color (CMY)",
                            4 : "Color (CMYK)"

Resolution              =   600 * 600
PaperSize               =   8500 * 11000 : Letter
Orientation             =   0 : Portrait
Intensity               =   50
InkType                 =   4 : "Color (CMYK)"
NonPrintable            =   500:Left, 500:Top, 500:Right, 500:Bottom

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_850DDE
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 8500;CLS:PRINTER;CMD:POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_25A854
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 2500C;CLS:PRINTER;CMD:PCL,MLC,PML,POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

Using NCFTP

PNPCMD=POSTSCRIPT

#----------------------------------------------------------------------
#
# The following macros are expanded for each filter command line
# $d - Device
# $m - PnP manufacture/model id
# $n - Printer name
# $s - Spooldir name
# $$ - A real $
#
#----------------------------------------------------------------------

FileVersion             =   2
#   x.x.x.x is the IP address of the printer
#   prt0 is the port used on the printer (in this case, port zero).
Filter                  =   ps:$d:ncftpput -V -E x.x.x.x /prt0
Filter                  =   phs:ps:phs-to-ps

Supported Resolution    =   300 * 300,
                            600 * 600,
                            1200 * 1200

Supported PaperSize     =   8500 * 11000 : Letter,
                            8500 * 14000 : Legal

Supported Orientation   =   0 : Portrait,
                            1 : Landscape

Supported Intensity     =   0   : Min,
                            100 : Max

Supported InkType       =   1 : "B&W",
                            3 : "Color (CMY)",
                            4 : "Color (CMYK)"

Resolution              =   600 * 600
PaperSize               =   8500 * 11000 : Letter
Orientation             =   0 : Portrait
Intensity               =   50
InkType                 =   4 : "Color (CMYK)"
NonPrintable            =   500:Left, 500:Top, 500:Right, 500:Bottom

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_850DDE
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 8500;CLS:PRINTER;CMD:POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_25A854
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 2500C;CLS:PRINTER;CMD:PCL,MLC,PML,POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

Using SAMBA

PNPCMD=POSTSCRIPT

#----------------------------------------------------------------------
#
# The following macros are expanded for each filter command line
# $d - Device
# $m - PnP manufacture/model id
# $n - Printer name
# $s - Spooldir name
# $$ - A real $
#
#----------------------------------------------------------------------

FileVersion             =   2

# You need to have an environment variable, DEVICE_URI, set for smbspool
# to access the SAMBA shared printer. 
#
# Form for smb command used with smbspool which is set in DEVICE_URI
#     No Username and password required:
#         - DEVICE_URI = "smb://server/printer"
#         - DEVICE_URI = "smb://workgroup/server/printer"
#     Username and password required:
#         - DEVICE_URI = "smb://username:password@server/printer"
#         - DEVICE_URI = "smb://username:password@workgroup/server/printer"
#
#     Where     username = SAMBA username
#               password = SAMBA password
#               workgroup = SAMBA workgroup   
#               server  = SAMBA server name
#               printer = SAMBA shared printer name
#
# Use of DEVICE_URI environment variable allows you to set this entry for
# the smbspool to automatically look for it when it isn't included in the
# command line.
#

Filter                  =   ps:$d:smbspool 1 NULL none 1 1  
Filter                  =   phs:ps:phs-to-ps

Supported Resolution    =   300 * 300,
                            600 * 600,
                            1200 * 1200

Supported PaperSize     =   8500 * 11000 : Letter,
                            8500 * 14000 : Legal

Supported Orientation   =   0 : Portrait,
                            1 : Landscape

Supported Intensity     =   0   : Min,
                            100 : Max

Supported InkType       =   1 : "B&W",
                            3 : "Color (CMY)",
                            4 : "Color (CMYK)"

Resolution              =   600 * 600
PaperSize               =   8500 * 11000 : Letter
Orientation             =   0 : Portrait
Intensity               =   50
InkType                 =   4 : "Color (CMYK)"
NonPrintable            =   500:Left, 500:Top, 500:Right, 500:Bottom

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_850DDE
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 8500;CLS:PRINTER;CMD:POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

if PNPID=HEWLETT-PACKARDHP_25A854
PNPSTR=MFG:HEWLETT-PACKARD;MDL:HP 2500C;CLS:PRINTER;CMD:PCL,MLC,PML,POSTSCRIPT;

Supported PaperSize     =    8500 * 11000 : Letter,
                             8500 * 14000 : Legal,
                             7250 * 10500 : Exec,
                            11000 * 17000 : B,
                             8262 * 11692 : A4,
                             5846 *  8262 : A5,
                             7000 *  9875 : B5,
                            11692 * 16524 : A3

#----------------------------------------------------------------------

PPP with CHAP authentication between two Neutrino boxes

The following script starts the Point-to-Point Protocol daemon, pppd, with a chat script, waits for the modem to ring, answers it, and starts PPP services with CHAP (Challenge-Handshake Authentication Protocol) authentication. After PPP services have terminated, or an error on modem answer occurs, it restarts and waits for the next call:

#!/bin/sh

SERIAL_PORT=$1
DEFAULT_SERIAL_PORT=/dev/ser1
PPPD="/usr/sbin/pppd"
DO_CHAT="chat -v ABORT BUSY ABORT CARRIER ABORT ERROR \
 TIMEOUT 32000000 RING ATA TIMEOUT 60 CONNECT \d\d\d"
STTY="/bin/stty"
ECHO="/bin/echo"
LOCAL_IP=10.99.99.1
REMOTE_IP=10.99.99.2

if [ "$SERIAL_PORT" == "" ]; then
    SERIAL_PORT=$DEFAULT_SERIAL_PORT
fi

#do some initialization
$STTY +sane +raw < $SERIAL_PORT

while [ true ]; do
    $ECHO "Waiting on modem $SERIAL_PORT..."
    $ECHO "Starting PPP services..."    
    $PPPD connect "$DO_CHAT" debug nodetach auth +chap \
$LOCAL_IP:$REMOTE_IP $SERIAL_PORT
done;

The TIMEOUT is 32000000 because it's a long period of time before the timeout takes effect; chat doesn't allow an infinite wait. The /etc/ppp/chap-secrets is as follows:

# Client  Server  Secret    Addresses allowed
##############################################################
*  *  "password" *

You can also extend the chat script that answers the modem to be a little more robust with specific events that should restart the answering service other than the events given. You might want to add other features as well.

Here's the buildfile used to set up a machine to allow telnet connections (to log in for shell access) and tftp access (for file transfer) over PPP:

[virtual=x86,bios +compress] .bootstrap = {
    startup-bios -K8250.2f8^0.57600.1843200.16 -v
    PATH=/proc/boot procnto -vvv
}
[+script] startup-script = {
    seedres 
    pci-bios &
    waitfor /dev/pci
    # Start 1 keyboard console
    devc-con -n8 &
    # Start serial A driver
    waitfor /dev/con1
    reopen /dev/con1
    devc-ser8250 -e -b38400
    waitfor /dev/ser1
    pipe
    touch /tmp/syslog
    syslogd
    devc-pty
    io-pkt-v4 -ppppmgr
    waitfor /dev/io-net/ip_ppp
    inetd &

    display_msg "[Shell]"
    [+session] PATH=/bin:/proc/boot /bin/sh &
}

# Make /tmp point to the shared memory area...
[type=link] /tmp=/dev/shmem

# Programs require the runtime linker (ldqnx.so) to be at
# a fixed location
[type=link] /usr/lib/ldqnx.so.2=/proc/boot/libc.so
[type=link] /bin/sh=/bin/ksh

# We use the "c" shared lib (which also contains the
# runtime linker)
libc.so
libsocket.so

# The files above this line can be shared by multiple
# processes
[data=c]
devc-con
devc-ser8250
devc-pty
pci-bios
seedres
pipe
io-pkt-v4
/bin/echo=echo
/bin/stty=stty
tail
pci
chat
ifconfig
ping
syslogd
touch
./modem_ans_ppp.sh

#Services (telnetd etc) config
inetd
/usr/sbin/telnetd=telnetd
/usr/sbin/tftpd=tftpd
/usr/sbin/pppd=pppd
/bin/login=login
/bin/ksh=ksh

/etc/ppp/chap-secrets = {
# Client    Server     Secret     Addrs
#########################################
*           *           "password"  *
}
/etc/syslog.conf = {
*.*     /tmp/syslog
}

# Inetd config Files
/etc/services= /etc/services
/etc/protocols= /etc/protocols
/etc/termcap= /etc/termcap
/etc/passwd= /etc/passwd
/etc/default/login= /etc/default/login
/etc/resolv.conf= /etc/resolv.conf
/etc/nsswitch.conf= /etc/nsswitch.conf
/etc/shadow = /etc/shadow

/etc/inetd.conf = {
telnet      stream  tcp nowait  root    /usr/sbin/telnetd   in.telnetd
tftp        dgram   udp wait    root    /usr/sbin/tftpd     in.tftpd
}

/etc/hosts = {
127.1   localhost.localdomain   localhost
10.99.99.1  server  server
10.99.99.2  client  client
}

Note: To build the image using this buildfile, you'll need to be root, because it takes a copy of /etc/passwd and /etc/shadow (which make passwords easy to remember) but you can also put your own version of them into the buildfile as inline files.

Using two computers with modems, you can have one automatically answer, establish PPP services, and authenticate. You can then telnet and tftp to the server from a client. Use these client pppd parameters (in addition to the same chap-secrets file):

pppd connect "chat -v -f/tmp/dial_modem" auth +chap /dev/ser3

but use the appropriate serial port for the client-side modem instead of /dev/ser3. Make sure you use the full path to your modem script. The chat script, dial_modem, is fairly simple:

ABORT 'NO CARRIER'
ABORT 'ERROR'
ABORT 'BUSY'

'' ATDTxxxxxxx
CONNECT ''