I’ve been workin’ on the WebKit all the live long day …

WebKit for Neutrino 6.4.0 that is

Lots has gone on since my last post on SRR.  After finishing up my parental leave last year  I decided that after working at QNX for nearly 10 years it was time for a change and took on a role at Crank Software.

We’re doing a lot of interesting things at Crank, mostly to do with graphics and improving the way people integrate graphical content into their embedded products. 

Crank is doing a lot of work with customers who base their user interface designs on what Apple’s iPhone and iTouchcan do, but want to do it on systems with less powerful CPU’s, smaller memory capacity and less capable graphics engines.

Oh yeah … and for those devices that are network connected they also want to run WebKit, the engine under Apple’s Safari web browser

As part of addressing these needs (better, faster, smaller) Crank has ported WebKit to QNX Neutrino, and since web browsers and graphical applications go hand in hand these days, we plan to provide assistance and support on this technology. 

If you are keen, you can try out an advance pre-release version of the WebKit engine by downloading it from  http://www.cranksoftware.com/pre-release/.

This is a snapshot of our development from a month ago after we got the initial port running and passing the basic browser tests, lots of improvements have been made since then and we’ll update it when we hit a good stability point.

Our initial ports run on both Neutrino 6.3.2 and 6.4.0.  We currently have Photon microGUI versions and expect to have an AGTDK based version out in the coming weeks.

The development on WebKit is very active, with lots of work going on in all areas from user interface to scalability to scripting performance.  Getting the initial port up and running wasn’t a trivial amount of work, and we hope to work with the WebKit developers to back port our changes. 

In the mean time, if you run Neutrino and wanted to be like all the other cool kids out there running WebKit go check out the pre-release and let us know how it works for you! 


QNX 6.4.0 loves ARM v6

One of the really cool things about 6.4.0 is the support for ARM v6 chips.

You may recall that ARM v5 chips have a somewhat icky cache implementation, resulting in an unfortunate limititation in the virtual address range per process, and also a limitation in the number of processes in the system.  It’s all described here, if you are interested.

The really cool news is that the v6 architecture doesn’t have this problem (it has a physically tagged cache), and thus the limitation has been removed (read all about it here!).

Not only that, but the gcc 4.2.4 compiler is much better for ARM, resulting in much better code generation.

QNX 6.4.0 now also supports the Vector Floating Point unit – which can make a big difference – read about it here.

Last but not least, the ARM kernel and Image Filesystem are now mapped with large 1Mb pages.  This really boosts the performance of kernel calls – since we are using way fewer TLBs.

The fact that 6.4.0 supports large pages is also important for userland programs, especially on ARM – I’ll get into that in another post.


QNX 6.4.0 – go get it!

This is why we’ve been so quiet of late – a LOT of work has gone into QNX 6.4.0 – the first full release of the OS in … well, it’s been a while!

I’ll be posting about some of the new features in 6.4.0 – but how about first you go and download it!


Daddy, the network is down…

The gateway of my home network, is not one of those “broadband router”. Instead, it’s an old Pentium 200Hz machine in my basement, running, of cause, QNX. Why am I doing this? I think it’s one of those “because I can” thing. Since I compiled my own TCPIP stack, I can really know every detail of the packets in and out of my gateway. Another reason is, of cause, I like to “live on the edge”.

Yes, it’s really “bleeding edge”, though a lot of benifit and fun of running the HEAD branch stack, one of the disadvantage is, while in it’s early stage, the stack “crashes”. The good thing is I have the core dump I could look at, but the bad thing is, that’s also when my kids started shutting at me.

Those of you who had been managed a home network, would really understand how stressful this is. :) Fortunatly, soon my kids find out the “engineering way” to fix the problem. They went down to the basement, press the little reset button on the old Pentinum, give it a couple of minutes, and wola, everything comes back.

This works well for a while, but one day while I was at home along, the stack on gateway gone again. I have to get out of my comfort couch, went down to the basement and reset it myself. I said to myself, “why can’t I just write a program to resetart the network if it’s crashed”, after all, QNX is all about Micro Kernel and Modular System, isn’t it?

That’s where my “sockmon” program cames from. Once started, it will keeps on monitoring if TCPIP stack is still running, if it disappered, “sockmon” will try to execute a shell script you gave it on command line, to re-start the network. If the restart somehow failed after some try, then it will just reboot the system.

You may wonder “how do you know if TCPIP stack is there or not”? Well, QNX resource manager have builtin notification to all connected clients if their server disappeared. So all you need is to establish a connection to the tcpip stack (by call socket()), and setup to waitfor the notification events.

I have include the source here, the “notification” thing above is true for ALL resource manager (unless the manager is written in such way that turned off this feature), so you can easilly extended my program to any resource manager. Just give it a config file to read about which resource manager (what namespace you care) to watch out, and what to do (which script to execute) if the manager went away.

I will leave this for reader exercise, but if you did that, you would realiz you just got yourself a simple, basic, HA program.


#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <process.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <sys/procmgr.h>
#include <sys/sysmgr.h>
#include <sys/neutrino.h>
#include <sys/socket.h>

int main(int argc, char **argv)
        char *script;
        int sd, chid, fcount;
        struct _pulse pulse;

        if (argc < 2) {
                fprintf(stderr, “sockmon <re-start script>\n”);
                return -1;

        script = argv[1];
        if (access(script, X_OK) != 0) {
                fprintf(stderr, “access(‘%s’): %s\n”, script, strerror(errno));
                return -1;

        /* creat a channel for accept COIDDEATH pulse */
        if ((chid = ChannelCreate(_NTO_CHF_COID_DISCONNECT)) == -1) {
                return -1;

        /* don’t care about the child */
        signal(SIGCHLD, SIG_IGN);

#ifdef NDEBUG
        if (procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE) == -1) {
                return -1;

        openlog(“sockmon”, LOG_PID, LOG_DAEMON);

        for (;;)
                fcount = 0;

                /* connect to tcpip to monitoring, give it 30 seconds, if still can’t
                 * connect, reboot the system
                while ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
                        if (++fcount >= 6) {
                                syslog(LOG_ERR, “Can’t connect to socket after 3 minutes, reboot…”
                                spawnl(P_NOWAIT, “/bin/slay”, “slay”, “-f”, “syslogd”, NULL);
                                return 0;
                        syslog(LOG_INFO, “Connect to Socket failed: %m”);

                syslog(LOG_INFO, “Connected to Network, start monitoring…”);
                if (MsgReceivePulse(chid, &pulse, sizeof(pulse), NULL) == -1) {
                        syslog(LOG_ERR, “MsgReceivePulse(): %m”);
                        return -1;

                if (pulse.code != _PULSE_CODE_COIDDEATH) {
                        syslog(LOG_ERR, “MsgReceivePulse(): %m”);
                        return -1;

                if (pulse.value.sival_int != sd) {
                        syslog(LOG_ERR, “COIDDEATH pulse for %d\n”, pulse.value);

                syslog(LOG_INFO, “Network gone, restarting…”);
                spawnl(P_WAIT, “/bin/ksh”, “/bin/ksh”, script, NULL);

        return 0;


It’s time to OD

At long last, the dtrace project at Foundry27 is public. It’s really still in the formative stages, but if you want to download the source and hack around a bit, or even just laugh at the dirty hacks, feel free!

I’m slowing working on a more thorough port, but the prototype is a nice forum to play around in.

Have fun…