Building a BlackBerry QNX 7 Desktop

BlackBerry QNX officially released version 7 of its Software Development Platform (SDP) last month. This release is the first to support 64-bit architectures, including x86-64 and aarch64. It also brings with it new features and over two years stability fixes.

As is the case for any release of an operating system that is not backwards-compatible with an earlier version, we were faced with the problem of a lack of content for SDP 7. Yes, the code has been thoroughly tested in the lab on a variety of boards and yes, Alpha and Beta versions of the release have been used by our partners to bring up new versions of their systems. Nevertheless, it was felt that a crucial part was missing in the test cycle, that of eating one’s own dog food.

BlackBerry QNX is an embedded operating system targeting applications in the automotive, general embedded, and medical markets. However, it is not your garden-variety embedded OS: QNX is a full-blown, UNIX-like, POSIX-compliant operating system with all of the features you would expect of a desktop or sever-class OS. Compatibility with other systems means that, at least in theory, porting various open source projects to SDP 7 should be a relatively easy task. And so, while there is no official support in this release for a desktop environment, there is nothing precluding someone from building such a system. With that in mind, I set myself the task of building a BlackBerry QNX 7 desktop.

The hardware consists of an ASRock IMB-151 mini ITX board, with a 4-core Intel Celeron processor. We used this board in the early development stage of the x86-64 architecture, and so had a few lying around. I bought a nice small case to house it and, despite it being advertised as a fanless board, attached a big fan to the top of the case, just to be on the safe side. Not a very clean job but hey, I’m a software developer.

IMG_20170403_093142

It is interesting to note that in order to measure the effect of the fan on the board I had to read a machine-specific register, which can only be done in Ring 0. It seems like an odd architectural decision to require the highest privilege level just to tell how hot is the CPU.

The standard board-support package for x86-64 works well on this board, so installing SDP 7 on it was straight-forward. Installation involves booting the board from a USB stick which was flashed with an Image File System (IFS) containing the necessary tools (shell, PCI server, disk driver, file system, network stack, and daemons) to create a QNX6 file system on the board’s flash drive and copy over the necessary binaries. Once done, the IFS itself is copied to the flash drive and the USB stick is no longer required.

Working Hard

As I use computers primarily for software development, my first step was to create a development environment. Typically, development for embedded systems is done on a different machine (the host) than the one on which the embedded software runs (the target). There are two main reasons for host-side development (also known as cross-compilation):

  1. Embedded environments typically do not support self-hosted build tools
  2. The target hardware is often considerably less powerful than a modern desktop

As was mentioned earlier, BlackBerry QNX is not your typical embedded system, and our tools team provided me with the GNU tool chain (compiler, linker, debugger) built to run on an SDP 7 system. And while the target I chose is certainly not as fast as my T440s laptop, it is more than adequate for most compilation tasks. That said, some of the porting efforts described below were still done in a cross-compilation environment, as even software that is itself portable does not always use a portable build system.

Software development requires code to be written. The version of vi shipped with SDP 7 may be sufficient for editing /etc/resolv.conf, but it is a far cry from a modern editor. The first project I tackled was therefore Vim 7.4.

(Disclaimer: I do most of my development work on Emacs. However, Emacs requires Gtk+. Porting Gtk+ to SDP 7 is left as an exercise to the reader.)

Porting Vim proved to be a somewhat harder task than might have been expected. Self-hosted building was unsuccessful as the configuration script insisted on using GNU Grep, even though any Grep implementation should have been sufficient (note that this is not a requirement of Vim itself, only of the build). Cross-compiling Vim is not very well documented, and many of the configuration steps do not work in such an environment. Reading through the configuration script yielded the following, somewhat unwieldy, command line:

# vim_cv_memmove_handles_overlap=yes vim_cv_stat_ignores_slash=yes vim_cv_getcwd_broken=no vim_cv_toupper_broken=no vim_cv_terminfo=yes vim_cv_tty_group=world ./configure --build=x86_64-pc-linux-gnu --host x86_64-pc-nto-qnx7.0.0 --with-tlib=ncurses

(Given the amount of effort involved in cross-compiling Vim, it would have probably been easier to port GNU Grep and other build dependencies to SDP 7.)

Vim was now ready to be compiled. The only obstacle I ran into at this stage was a legacy QNX-specific function in the Vim code, which is no longer applicable and had to be removed. Other than that compilation went smoothly. I copied the binary and the supporting files to the target and now had a working, modern, vi clone.

The next project was Subversion, which is needed for OS development at QNX. Building SVN is not hard, but it does require a few other libraries, namely APR, APR Util and libserf. The latter uses Scons as its build system and, for some reason, insists on building with the ‘-std=c89’ compiler option, which I had to remove.

Tool chain, editor, source control. Ready for work.

Having Fun

Some of us get very excited at the sight of a C program being compiled and linked into an executable. The masses, however, need their entertainment.

If you search the web for open-source games, you will notice that many of them use the Simple DirectMedia Layer (SDL) library. Given that observation, I decided to try and port this library (version 2.0.5) next. Porting SDL, however, goes beyond building the code, as the library depends on OS-specific implementation of its API for graphics (2D and 3D), audio and input devices. The task proved much easier than I had anticipated, though. Most of SDL’s graphics functions correspond to native functions in Screen, the QNX compositing window manager. For audio, I found that SDL already had code for QNX, albeit with a crippling bug. Nevertheless, once spotted, the bug was very easy to fix. The SDL mixer, TTF and image libraries followed, but with the main library already ported these were easy to build.

Armed with a port of SDL 2 I went hunting for some games to try. I found a couple of clones of well-known old-time games that worked very well. Unfortunately, while the games themselves are open-sourced, the ones which they clone are not, so no screenshots for those.

This activity only took a couple of days. My kids had a blast bossing around certain plumbers who shall go unnamed.

A Qt Little Thing

SDP 7 comes with a port of Qt, version 5.6.2. In theory, it should be trivial to port Qt applications. The problem is that the QNX plugin for Qt is very embedded-oriented, designed for full-screen applications with either touch or keyboard input. I wrote a naive clipboard library (which in hindsight should have been written as a resource manager) to satisfy desktop applications. One major annoyance is the placement of drop-down menus. Qt treats all pop-up menus as top-level windows and uses absolute coordinates to position them on the screen. QNX Screen, however, does not allow non-privileged applications to position windows with absolute coordinates. This is not a problem for embedded applications, as these typically do not use traditional menu bars, but is quite a limitation for a desktop environment. I have yet to find a solution to this problem and would love to hear from any Qt experts out there.

Having Qt allowed me to port one of my favourite applications, SpeedCrunch. It was a simple matter of running ‘qmake’ followed by ‘make’. Next, I ported the QTermWidget library so that I could have terminal windows.

Putting It All Together

I now had an arsenal of useful (and less than useful) applications at my disposal, but still not a true desktop environment. Each application could only be launched separately, in full screen mode.

As mentioned earlier, SDP 7 does not target the desktop market. Nevertheless, it comes with the necessary building blocks to create a desktop manager, including a compositing window manager, USB and HID stacks for handling input devices, and libraries for drawing images and rendering fonts. (As a side note, using the PNG, font-config and freetype libraries directly rather than via a high-level toolkit was quite educating.)

The desktop manager does the following:

  1. Draws frames (title bars and borders) around windows
  2. Positions windows (x, y and z axes)
  3. Allows a window to be moved around by dragging its title bar
  4. Handles the title bar buttons (drawing alternative images when a button is clicked and taking the appropriate action for that window)

A few weekends later (sorry, kids) I had my desktop manager. It is written in C++, and currently uses less than 2500 lines of code (and over a thousand lines of comments – credit goes to my brother in law, Noam Dror, who taught me the importance of documenting code many years ago). The window decorations are less than stellar (damn it, Jim, I’m a kernel developer, not a UI designer!), but the whole thing looks quite reasonable. A launcher bar written in Qt and a background image of QNX’s home town complete the scene.

QNX_SDP-x86_64-2017-04-02-08-15-43

This activity has been a challenge, dealing with many different subsystems and code from a variety of sources. It has also been very satisfying – after years of kernel development, I had forgotten the thrill of writing code that does things you can actually see. Most importantly, it provided for a great way to follow the old maxim: “always eat your own dog food before you serve it to others”, canine or human.

48 thoughts on “Building a BlackBerry QNX 7 Desktop

  1. QNX 6.5.x SDP already had a full desktop environment for development, and was much easier to boot and install natively.. but they removed the “Neutrino host” .ISO’s.

    As for porting software, there was already pkgsrc for QNX, but I guess you didn’t notice..

    http://community.qnx.com/sf/projects/pkgsrc/
    https://www.pkgsrc.org/

    IMHO They went downhill when they closed up the foundry27 source again after Blackberry and removed the Hobbyist licensing, but this is coming from someone who has used QNX and was a fan since using QNX2 in highschool on the Unisys/Burroughs computers. Betrayed.

    Liked by 1 person

    • I’m not sure why makes you so angry. Photon died because it was not commercially viable, Both display technology and internal architecture have changed considerably since Photon was introduced. Bringing it back requires a lot of work for something that, again, has no market.
      And I am very much aware of pkgsrc.

      Like

      • I just miss my Canadian QNX, not angry.. just sad. It certainly could have been commercially viable, but QNX decided not to pursue the desktop market in the 90’s. Remember the QNX4 demo floppy?

        Liked by 2 people

      • What a strange and ugly mantra “Photon died”? So many QNX customers world wide even I know which use Photon. Even Linux didn’t drop X Window yet. But leave this strange decision on the Blackberry. I see that QNX loses the customers and markets. Dropped CPU platforms, Photon, hobby license. It makes me sad.

        But that I want to say. Photon’s not dead!

        Like

      • If it has no market, then why were QNX reps asking me if I could port it for a legacy customer of theirs? You don’t have to tell me why this will never happen, I already know. A very small concern that I’ve done work for, for a decade left QNX because Photon was not available on 7. That very small concern, the US Postal service, probably larger than any US corporation.

        Like

  2. Pingback: 1 – Building a BlackBerry QNX 7 Desktop

    • Can’t do it as long as KDE depends on X Windows. However, Wayland sounds like a promising development, as it may be feasible to port the protocol to use QNX Screen (instead of Wayland’s own compositing window manager).

      Liked by 1 person

  3. Hey nice job.

    Are you planning to continue porting other apps and frameworks?
    It would also be nice to provide a VM image for other to try it out.

    Cheers from austria 🙂
    Matthias

    Like

  4. Is there a source-code release still available (there used to be some sort of a license for students IIRC, but i couldn’t get to it on the site). ?

    Like

  5. > The window decorations are less than stellar (damn it, Jim, I’m a kernel developer, not a UI designer!), but the whole thing looks quite reasonable.

    I hate this kind of lazy mindset which btw is very common among devs, Yes you aren’t a UI designer however you must have some sort of aesthetic in you that tell you this looks like it’s something that came out in the 90s, and this looks sleek and modern, in the end if you can’t design something yourself copy some ideas from elsewhere. (r/unixporn)

    Like

  6. Too bad the whole Gateway-Amiga-QNX thing never went anywhere.. I still have the QNX floppy demo and show it to people once in a while. Looks like I’ll have to keep running ol’ AmigaOS 3.x for a few more decades 🙂

    Like

  7. Reading all this through my Passport. It’s good to know QNX can still be used to power up a desktop, just like it was used to power my cell phone.

    Like

  8. During my last days at QNX I used the Asus J1900 ITX board and it booted QNX 6.4 with Photon fine. When I tried 6.6 .. only the Qt demo from one of my former FAE colleagues worked. Good to know that Qt is the way to go .. I now have an Asrock J3710 ITX to play with.

    Like

  9. That’s strange. Did they remove Qt support from QDP 7.0?
    I was able to create a Qt project in Momentix, but when I try to build the project on the target VM it says “No Qt install available for this target”

    Did I miss something?

    Like

  10. Hey Elad! This looks great. I am new to building QNX7 boot disks, what are the steps to get the IFS build onto the USB drive to start (and how to configure what tools are installed?)

    Like

    • The BSP for the specific board you are targeting should have instructions on how to get an initial image on removable media. Once you have that you will need to get a QNX6 file system on whatever you end up using as permanent storage.
      I realize the response is vague, but it really depends on the board.

      Like

      • Thank you! One more question. I am attempting to build with screenwm with the licensed version of QNX 7.1 SDP with the libraries listed as requirements, but I don’t have any cairo headers. Am I missing a library that needs to be installed? I have everything I have access to with my license installed.

        Like

      • Thank you! One more question. I am attempting to build with screenwm with the licensed version of QNX 7.1 SDP with the libraries listed as requirements, but I don’t have any cairo headers. Am I missing a library that needs to be installed? I have everything I have access to with my license installed.

        Like

      • I built that from source. Pixman first and then Cairo. You don’t have to use Cairo, but then you are stuck with my original ugly window decorations.

        Like

Leave a comment