![]() |
![]() |
![]() |
![]() |
This appendix covers the following:
Before you attempt to configure Photon to run on your embedded system, we recommend that you use the information provided in this appendix to construct a trial embedded Photon environment on a normal PC.
At the end of the appendix, we've included sample files that you can use. If your PC doesn't have a standard keyboard, msoft mouse, or a video card supported by the drivers used in these examples, you'll have to modify the examples so that they'll work in your environment.
When you run Photon in a desktop environment, you simply type ph, a script that does all the work for you. This script:
Once Photon is started, you run the applications you want using either the window manager or desktop manager.
In an embedded environment, you'll need to perform all these steps yourself manually. This has many benefits, because it lets you predefine the minimum files needed for your system and exactly how each driver/application will start.
Here's an outline of the steps required to boot directly into Photon with your application(s) running.
Each of these steps requires certain files to be installed in your target system. By predetermining exactly what graphics hardware you have and what fonts your application needs, you can keep the number of files (and required disk space) to an absolute minimum.
We'll go through all the steps in detail and discuss the files needed for each step. At the end of this process, you should know exactly what Photon files you'll need to run your embedded application.
The PHOTON_PATH environment variable is intended to hold the base directory of the Photon installation. By default, this directory is /usr/photon. This location is expected to hold at least the following subdirectories:
You should set the PHOTON_PATH environment variable:
export PHOTON_PATH=/usr/photon
If you don't need to pass any command-line arguments to the Photon server, it can be started as follows:
Photon &
![]() |
If your embedded environment is touchscreen or pen-based, you can adjust the
input values for pointer events by specifying the -D, -R,
and -U options. For example, to prevent random changes
in position because the size of a finger press is larger than a pixel,
specify the -U option.
For more information, see Photon in the QNX Neutrino Utilities Reference. |
The server must be located in the current PATH and the path must be defined before running the command. In QNX Neutrino, this path is /usr/photon/bin. For example:
export PATH=:/bin:/usr/bin:/usr/photon/bin
![]() |
If your boot image is too large because you've included Photon or other
executables, you can mount a filesystem, wait for it to appear, and then
load the executables from a filesystem at boot time.
For more information, see
mkifs
in the QNX Neutrino Utilities Reference.
If you do include any of the Photon executables in your boot image, you must also include /usr/photon/bin in MKIFS_PATH. |
/usr/photon/bin/Photon
Normally in a desktop environment, you use the inputtrap utility to automatically generate the correct command line and to invoke the appropriate devi-* driver. For example:
kbd fd -d/dev/kbd msoft
You typically run inputtrap because you don't know in advance what the appropriate command line should be.
In an embedded system, the input devices are often found at unusual locations, are incapable of PnP identification, or are simply not supported by an existing devi-* driver. In addition, the inputtrap utility tends to be quite large and would only waste precious storage and memory in a constrained environment. For these reasons, you typically specify the command line to the devi-* driver manually. (You can temporarily install inputtrap and use it to generate the correct command line.)
You can customize the input drivers by using the Input Driver Development Kit (Input DDK). For example, you can change the size of the memory footprint, or you can create a custom module to support new devices.
The appropriate devi- driver in /usr/photon/bin
When building an embedded system, you need to make several decisions about the level of font support, including which fonts you need, and whether or not you need scalable fonts.
The first step is to decide which fonts you need:
Check the browser's configuration to see which fonts are expected, and use those fonts, modifying the configuration to reflect what you have installed, or use the fontmap file to map them at runtime.
You can map, or substitute, font names by using the fontmap file, or the Mappings section of the fontadmin utility. For more information, see the QNX Neutrino Utilities Reference.
You can configure the fonts on the embedded system itself, but it's easier to use the development system to configure the fonts for the embedded system and assemble the font data and configuration files in the appropriate Embedded File System (EFS) build image directory.
For example, suppose the root directory of this image is /usr/EKit/bsp/board/build/root (the real pathname depends on your development environment).
Change your current directory to be the root of your build subdirectory:
export EKIT_DIR=/usr/EKit/bsp/board/build/root cd /usr/EKit/bsp/board/build/root
Then create a font subdirectory for your embedded system. For example:
mkdir -p my_dir/font_repository
Copy the necessary font files into the build image framework for collection by mkefs:
cp font_filename my_dir/font_repository (repeat for each font) cp /usr/photon/font_repository/font* my_dir/font_repository cp /usr/photon/font_repository/phfont.ini my_dir/font_repository mkfontdir -i $EKIT_DIR/my_dir/fontdir \ -d $EKIT_DIR/my_dir/font_repository # NOTE: mkfontdir requires a full path
This example creates an initial configuration, updates the font configuration files, and copies any font files into the specified target directory.
To change mappings, invoke fontadmin:
fontadmin -c my_dir/font_repository -d my_dir/font_repository
If your startup script invokes a specific font server (e.g. phfontphf or phfontFA), you don't benefit from the preprocessing of the fontopt file by the phfont utility; you must manually pass each option contained in that file on the command line.
You can test the font setup prior to building the embedded image by restarting your desktop font server, pointing it at the new configuration (invoke phfont with the -d option to specify the font subdirectory from the build image). To revert to the original setup, just run:
phfont &
If you know in advance what capabilities of the font server you need (scalable PFR via phfontpfr, or simple bitmap support via phfontphf), then you can start the appropriate server directly:
/usr/photon/bin/phfontphf &
If the font files aren't in the local image, you need to specify the directory containing these files and the configuration, by using the -d command-line option (to either phfont, or the real servers phfontphf, phfontpfr, and so on):
/usr/photon/bin/phfontphf -d /fs/hd1-qnx4/my_dir/font_repository
Also, if my_dir isn't the same as $PHOTON_PATH on the embedded system, the -d option must point to the correct location.
The available servers are in /usr/photon/bin, and include:
Normally in a desktop environment, you use the Photon crttrap program -- it can determine your display hardware and set up a configuration file for your hardware, where you can pick your desired graphics mode and resolution.
In an embedded environment, this information should be predetermined. The process of switching into graphics mode and starting the graphics driver should be done manually by specifying the commands directly, without the use of convenience tools like trappers and display-configuration applications.
In many embedded environments, the Video BIOS isn't present because of cost considerations. The Video BIOS is responsible for initializing the video controller chip, and any other setup required by the video subsystem, as today's graphic controllers often need elaborate setup before they can even be used in VGA mode.
On the desktop, the BIOS POST code calls into the Video BIOS and the controller is set up at this time. When the modeswitcher is invoked, the video controller is in an initialized state, so the modeswitcher doesn't need to know how to set up the controller. To add to this, many of the desktop modeswitchers use the kernel's virtual 8086 support to execute code in the Video BIOS to perform the mode switch. Virtual 8086 support is available only on x86 platforms.
In the embedded system that doesn't use a BIOS, the job of setting up the video controller falls to either the IPL code (init_hw2) or the modeswitcher. If the system will be used in only one mode, then the IPL code usually is modified to set up the video controller. If more than one mode is to be supported, a special modeswitcher that can completely set up the controller without using the resources in the Video BIOS is used.
There are several ways that you can have the card switched into graphics mode:
mov ah, 0 ; set mode mov al, 12h ; mode 0x12: 640x480, 16 colors int 10h
If you're going to switch modes using the graphics driver DLL, chances are you're going to use a driver supplied either by QNX Software Systems or by a third party.
However, if you want the write your own mode-switching code, you will probably find the Graphics Driver Development Kit useful.
![]() |
Currently, all the drivers that we ship require a Video BIOS in order to run correctly. Some drivers make calls to the video BIOS to switch video modes. These drivers only work on x86 systems. Other drivers rely on the fact that the hardware was already initialized (e.g. at boot time by the BIOS, boot ROM, or IPL) while others (e.g. devg-banshee.so) are able to initialize the hardware themselves, but require information that's stored in the BIOS ROM. If there's no Video BIOS on your target system, you'll probably need a custom graphics driver. |
The Photon graphics subsystem is started by running io-graphics.
Here are some sample invocations:
io-graphics -g640x480x8 -dldevg-vga.so -P/usr/photon/palette/vga4.pal io-graphics -g1024x768x16 -dldevg-vesabios.so io-graphics -g1024x768x16 -dldevg-rage.so -d0x1002,0x4755 -I0
Here's what the options mean:
For more information about io-graphics, see the QNX Neutrino Utilities Reference.
This step is optional if only a single application is used, or if your embedded system doesn't require the services provided by the window manager.
At this time, the only known unsupported feature is that multiple Ph_WM_CLOSE messages to a non-responding app will not raise a SIGHUP on that process (until support for a channel-"netkill"-style operation is added to the kernel).
The workspace configuration file ($HOME/.ph/wm/wm.cfg) and may be modified dynamically using the pwmopts. Alternatively, non-default options may be set with command-line options or through the PHWMOPTS environment variable.
The personalized PWM menu ($HOME/.photon/wm/wm.menu), if used, may pose a problem if commands are given as absolute pathnames (unqualified command names should be portable across systems, provided that the PHOTON_PATH environment variable is consistent). The standard PWM menu invokes all commands from $PHOTON_PATH/bin. For embedded systems, note that you can disable this menu completely by using the -W option to pwm.
/usr/photon/bin/pwm
If your application is a single executable and doesn't require the window manager, then you can link your application static -- you won't need the Photon shared library.
If you need the window manager or have more than one Photon program running, then it's best to use the Photon shared library.
Your application files.
If your application needs the Photon shared library:
/usr/photon/lib/libph.so
The following are observations that some customers have encountered when moving Photon to an embedded system.
By default, mkifs strips Photon resource names from executable files. To prevent this, specify the +raw attribute for all Photon applications.
The following flash filesystem properties will affect how you configure Photon:
$(ABOBJ) $(MYOBJ) $(LD) $(LDFLAGS) $(ABOBJ) $(MYOBJ) -M -o mine usemsg mine ../Usemsg phabbind mine $(ABMOD)
to:
$(ABOBJ) $(MYOBJ) $(LD) $(LDFLAGS) $(ABOBJ) $(MYOBJ) -M -o mine usemsg mine ../Usemsg phabbind mine.res $(ABMOD)
You'll also need to export the AB_RESOVRD path variable if the resource records aren't in the same directory as the executables. This avoids searching the directory containing the executables.
![]() |
The config file routines aren't compatible with the flash filesystem. |
Many embedded systems lack components that are typical on a desktop machine. Here are a few items to watch for.
Here are some miscellaneous considerations:
Photon -D1000 &
Let's look at the steps involved in embedding Photon for use on an embedded device.
Our goal is to build a Photon system with the following minimal capabilities:
Embedding Photon requires analyzing a number of things:
The first step involves looking at a full system. Run Photon on your PC.
Look at the output of the pidin arg command. Here's the output on a Gateway Laptop, cropped to show only the Photon-specific components:
pidin ar pid Arguments 3620894 Photon 3665951 fontsleuth -d /usr/photon/font_repository 3727406 pwm 3657775 /usr/photon/bin/phfontFA -d /usr/photon/font_repository -j -s 300k 3698736 io-graphics -g1024x768x32 -dldevg-rage.so -I0 -d0x1002,0x4c42 3715121 devi-hirun kbd fd -d/dev/kbd ps2 kb -2 3772466 shelf 3809331 bkgdmgr 3809332 wmswitch 3809336 Xphoton -once 3809337 gtwm
We need only a few of the programs:
The others are completely optional for most embedded systems:
Save the argument list for your system in a file. We'll need that output later.
On our system we want only the following components:
Look at the output of the pidin mem command:
1048603 1 /photon/bin/Photon 10r RECEIVE 64K 120K 8192(516K)* ldqnx.so.1 @b0300000 300K 12K 1302557 1 usr/photon/bin/pwm 10o RECEIVE 116K 56K 8192(516K)* ldqnx.so.1 @b0300000 300K 12K libph.so.1 @b034e000 1220K 48K libphrender.so.1 @b048b000 232K 8192 1085470 1 hoton/bin/phfontFA 12r RECEIVE 284K 880K 12K(516K)* ldqnx.so.1 @b0300000 300K 12K /dev/mem @40100000 ( 0) 32K 1122335 1 io-graphics 12r REPLY 144K 148K 8192(516K)* ldqnx.so.1 @b0300000 300K 12K libph.so.1 @b034e000 1220K 48K libphrender.so.1 @b048b000 232K 8192 devg-rage.so @b04c7000 24K 4096 libffb.so.1 @b04ce000 28K 4096 libdisputil.so.1 @b04d6000 24K 4096 /dev/mem @40100000 ( 0) 32K /dev/mem @40108000 ( 0) 4096 /dev/mem @40109000 ( 4000) 64K /dev/mem @40119000 ( 0) 8192K /dev/mem @40919000 (fd7ff000) 4096 /dev/mem @4091a000 ( 0) 2304K 1138720 1 o/x86/o/devi-hirun 15o RECEIVE 52K 24K 8192(516K)* 1138720 2 o/x86/o/devi-hirun 10o REPLY 52K 24K 4096(132K) 1138720 3 o/x86/o/devi-hirun 12o SIGWAITINFO 52K 24K 4096(132K) 1138720 4 o/x86/o/devi-hirun 15o RECEIVE 52K 24K 4096(132K) ldqnx.so.1 @b0300000 300K 12K libph.so.1 @b034e000 1220K 48K libphrender.so.1 @b048b000 232K 8192
This listing tells us every library that we need available to the embedded system. The laptop has a Rage video chipset (devg-rage.so).
So we need the following libraries (at least):
Now let's look at fonts. Sometimes an application expects a specific font, and codes directly to that font. If this is the case, you need to explicitly include every font that your application needs. If you standardize on a certain family/style of fonts or if you don't necessarily care what exact font you have (as long as the size is okay), then you can cut down on the number of fonts and use one font to replace several other families of fonts. For example, Times can be used as a replacement for Helvetica and Courier.
Now's a good time to create a play area on your system to begin testing the embedded system.
Create a subdirectory called /phembed off the root of your system. Within that directory, create these subdirectories:
Now back to the fonts. In our example we wish to use the primasansbts TrueType font for almost everything. We'll use a pcterm fixed-width font for our (optional) pterm terminal windows. We also want to use a mouse occasionally, so we'll include the phcursor.phf file.
Here are the files we need:
-rw-rw-r-- 1 root root 707 Nov 29 15:20 fontdir -rw-rw-r-- 1 root root 104 Mar 20 2000 fontext -rw-rw-r-- 1 root root 697 Nov 29 15:19 fontmap -rw-rw-r-- 1 root root 12393 Mar 20 2000 pcterm12.phf -rw-rw-r-- 1 root root 12905 Mar 20 2000 pcterm14.phf -rw-rw-r-- 1 root root 17437 Mar 20 2000 pcterm20.phf -rw-rw-r-- 1 root root 2868 Mar 20 2000 phcursor.phf -rw-rw-r-- 1 root root 75784 Mar 20 2000 tt2001m_.ttf -rw-rw-r-- 1 root root 77924 Mar 20 2000 tt2002m_.ttf -rw-rw-r-- 1 root root 71200 Mar 20 2000 tt2003m_.ttf -rw-rw-r-- 1 root root 82452 Mar 20 2000 tt2004m_.ttf -rw-rw-r-- 1 root root 56156 Mar 20 2000 tt2009m_.ttf -rw-rw-r-- 1 root root 58748 Mar 20 2000 tt2011m_.ttf
Copy these files from /usr/photon/font_repository to /phembed/font_repository, then change directories to /phembed/font_repository.
We want to modify the fontdir, fontmap, and fontext files to reflect the fonts and mappings we want for our embedded system.
Here's the modified fontdir file:
; ; fontdir config file, Tue Jan 18 15:34:42 2000 ; phcursor,.phf,Photon Cursor,0,,E900-E921,Np,32x32,3K primasansbts,0@tt2001m_.ttf,PrimaSans BT,0,,0020-F002,MIp,133x129,75K primasansbtsi,0@tt2002m_.ttf,PrimaSans BT,0,I,0020-F002,MIp,134x129,77K primasansbtsb,0@tt2003m_.ttf,PrimaSans BT,0,B,0020-F002,MIp,143x130,70K primasansbtsbi,0@tt2004m_.ttf,PrimaSans BT,0,BI,0020-F002,MIp,145x129,81K primasansmonobts,0@tt2009m_.ttf,PrimaSansMono BT,0,,0020-F002,MIf,60x129,55K primasansmonobtsb,0@tt2011m_.ttf,PrimaSansMono BT,0,B,0020-F002,MIf,60x130,58K pcterm12,.phf,PC Terminal,12,,0000-00FF,Nf,6x12,13K pcterm14,.phf,PC Terminal,14,,0000-00FF,Nf,8x14,13K pcterm20,.phf,PC Terminal,20,,0000-00FF,Nf,10x19,18K
As you can see from the above list:
The pcterm12/14/20 fonts are for our pterm sessions, and phcursor is for all the mouse cursor images.
Here's the modified fontmap file:
; ; fontmap config file, Tue Jan 18 15:34:42 2000 ; BalloonFont = primasansbts FixedFont = primasansmonobts HeadingFont = primasansbts MenuFont = primasansbts MessageFont = primasansbts TextFont = primasansbts TitleFont = primasansbts Helvetica = primasansbts Verdana = primasansbts monospace = primasansmonobts sans-serif = primasansbts serif = primasansbts web = primasansbts arial = primasansbts term = pcterm geneva = primasansbts monaco = primasansbts ny = primasansbts courier = primasansmonobts dutch = primasansbts swiss = primasansbts times = primasansbts wingbats = primasansbts helv = primasansbts ncen = primasansbts time = primasansbts ? = primasansmonobts
You can compress this file further by mapping any undefined fonts to the ? font. This depends on which fonts you want to be fixed-width, and which you want to be proportional.
Here's the modified fontext file:
; ; fontext config file, Mon Dec 13 15:36:21 1999 ; +normal = primasansbts, primasansmonobts, phcursor
There are several font servers available:
Unless you explicitly need .pfr support for legacy reasons, we recommend that you use phfontFF.
Now let's put all the pieces we need in place, and build a simple script that will start our embedded Photon.
You should have already created the following directories:
Copy the required binaries to /phembed/bin:
cp /usr/photon/bin/Photon /phembed/bin cp /usr/photon/bin/phfontFF /phembed/bin cp /usr/photon/bin/io-graphics /phembed/bin cp /usr/photon/bin/devi-hirun /phembed/bin cp /usr/photon/bin/pwm /phembed/bin
Copy the required libraries to /phembed/lib:
cp /usr/lib/libph.so.1 /phembed/lib cp /usr/lib/libphrender.so.1 /phembed/lib cp /usr/lib/libffb.so.1 /phembed/lib cp /usr/lib/libdisputil.so.1 /phembed/lib cp /lib/dll/devg-rage.so /phembed/lib
There is one other library we might need. If you want to run PhAB-generated applications that require libAp.so.1, you also need that library. We recommend making it available:
cp /lib/libAp.so.1 /phembed/lib
We also want to create links in the /phembed/lib directory. This is required so that applications that look for .so instead of .so.1 still work correctly. Do the following:
cd /phembed/lib ln -s libAp.so.1 libAp.so ln -s libph.so.1 libph.so ln -s libphrender.so.1 libphrender.so ln -s libffb.so.1 libffb.so ln -s libdisputil.so.1 libdisputil.so
Now we can look at the graphics driver. In the example above, we're running the devg-rage.so driver with options of:
dldevg-rage.so -I0 -d0x1002,0x4c42
(We saw this in the output of pidin arg.)
If you have a different graphics driver, you should copy it to /phembed/lib.
Now we can look again at the fonts. You should have a /phembed/font_repository directory filled with the .ttf files that you want, and containing modified fontmap, fontdir, and fontext files as described above.
We should now have all the pieces we need in order to try out our embedded Photon system. The easiest way to try this out is to use a second machine connected to the first one over a telnet or a null-modem serial cable.
If you use a null-modem cable, you can start a shell on your terminal machine by typing on -t/dev/ser1 ksh on the QNX Neutrino machine. A shell prompt (#) should appear on your terminal if the baud rate and flow control on the serial ports match. We assume that you have this connection running and that you have a shell prompt available on a terminal of some kind that's connected to your QNX Neutrino machine.
It's useful to have a shell script to start Photon. Here's a shell script that starts Photon using the above example:
export PHOTON_PATH=/phembed export LD_LIBRARY_PATH=/phembed/lib:/lib cd /phembed/bin ./Photon & on -w /dev/photon -W10 ./phfontFF -d /phembed/font_repository -c 20K -j -s 50K -F 10 -S 50 & on -w /dev/phfont -W10 ./io-graphics -g1024x768x32 -dldevg-rage.so -I0 -d0x1002,0x4c42 & /usr/photon/bin/phcalc -x100 -y100 & /usr/photon/bin/phcalc -x300 -y100 &
Copy this shell script to a file called /phembed/ph-start and make the shell script executable (chmod a+x ph-start).
Note the following about the above script:
We use the on command to halt the script until the requested device name is available. For more information, see the QNX Neutrino Utilities Reference.
If all has gone well, you should be able to (from your terminal) run the ph-start script and have Photon appear, with two calculator windows side by side on the screen. Be sure to exit any current Photon sessions before running the ph-start script.
Some other handy tips for debugging your embedded Photon system:
pwm &
For example, on our embedded system, the following line starts the devi driver:
/usr/photon/bin/devi-hirun kbd fd -d/dev/kbd ps2 kb -2 &
We can run this command directly from the shell prompt on the terminal and we should automatically see a mouse pointer appear, and also have keyboard use.
On a truly embedded system, you may not have the /dev/kbd device presented to you, so you will want to look at the documentation for the devi-* family of drivers. For example, if you have just a PS2 port:
devi-hirun kbd kb ps2 kb -2
/usr/photon/bin/pterm &
And then exit the terminal window later.
![]() |
![]() |
![]() |
![]() |