From: "David L. Hawley"Subject: Re: AmigaOS and QNX... Hmmm... Tell me more... Date: 25 Nov 1998 19:17:59 GMT Mitchell Schoenbrun wrote: : Thomas Weeks wrote: : > I assume you guys have a FAQ? : You can browse around at www.qnx.com. I maintain a faq that you : can find at www.schoenbrun.com/mba. Look at http://www.qnx.com/literature/nto_sysarch/nto_sysarch.html for a good intro to Neutrino (Nto). The key aspects of all versions of QNX are that there is a small kernel which implements a handful of calls for creating a process, sending a message, handling timers and so on. Everything else is a process (thread or groups of threads in Nto). Message passing is the most interesting aspect. A file system (media or pseudo media) consists of a process which "talks" to the hardware and implements calls such as open(), close(), read(), write()... as well as defines a portion of "namespace" such as /dev/fd0 - the first floppy drive. In QNX4, if we insert a floppy with a QNX file system on it, we'd start Fsys.floppy (which creates /dev/fd0) and then do something like: mount /dev/fd0 /a which will create a prefix "/a" where we now see the floppy files. On the otherhand, if the floppy has a fat16 or fat32 file system, we'd need to run Fsys.dos which will use Fsys.floppy in block mode and present us with a directory /dos/a. The reason I used pseudo above is that I can also write a process called something like ISAMfsys which might manage a set of disk blocks (or files) as an ISAM file system. Two classic QNX4 examples of pseudo file systems are: 1. Knews - which maps a subset of the standard file system for use with news readers. The basic concept is to group all articles received in a particular news feed into 1 "real" file per day, but present a files system to the news reader which looks like 1 file per article. On a busy news group this could reduce the number of files by an order of magnitude or more. This is in /usr/free on ftp.qnx.com 2. Disk Shadow - maps 2 file systems into 1 (a poor man's RAID) opens, writes, ... of the Disk Shadow file space map into 2 opens, ... see: http://www.rtts.com.au/diskshad.html. In QNX, the device driver is a standard process. It can be debugged using printf(), trace(), or a debugger. A driver for an audio card may present several interfaces: /dev/dsp, /dev/mix, /dev/midi. A program wanting to use the device just opens it and does reads, writes, seeks, ioctls as needed. A shell (cli) might do something like: cat /home/dlh/blab.wav > /dev/dsp to play the blab file on the sound card. I suppose one could do something like cat < //2/dev/dsp > //1/dev/dsp to listen in on what's happening on node 2. OK - where does this QNX message passing come in? Look at (and I admit that my model is mostly QNX4 based) an open( "/dev/dsp", O_WRONLY ). You find that after a bit of preliminary magic (calls into Proc to find the owner of /def/dsp), the write() does a Send() to the Audio process with some info to tell Audio that a write mode open is requested. Audio will Reply() with a new file descriptor (or an error). writes() have less overhead since we know the Audio process id, and map to a Sendfd() call. Send() and Sendfd() are kernel calls which cause our process to block, and if Audio is in a Receive() state, the kernel schedules it to run and it's Receive() call returns with the data from our write call copied into it's buffers. Audio does it's stuff with the data and Reply()'s to us. The Reply() returns to a ready state. If Audio was not is a Receive() state, then we are blocked until it is. Our message is queued with any other Sends() into Audio. Audio can set itself to run at the priority of the highest priority process waiting on it to prevent priority inversion. Note that I said that the write data is copied into audio's buffers. QNX Send(), Receive(), Reply() calls pass copies of the buffers passed, not just pointers. This has several important implications: - a small bit of extra overhead (but if you hate this, pass a pointer to shared memory). - Neither process can access buffers in the other, so it's hard to trash the other process. - QNX Networking pretty much falls out. The Net process (and drivers for the specific hardware) can intercept the data and pass it to a process on an other node. In QNX4 a virtual circuit is set up to pass the Send(), Receive(), Reply() data between the processes - they don't really know that the IPC is going across the net. Note: your pointer to memory mapped data is useless in this case unless you write a memory map process which does network copies (a reasonable Nto thing to do). In QNX2 and QNX4, a lot of us the low level Send(), Receive(), Reply() calls. In Nto it's a lot easier to use the open(), read(), write() calls. It's also easier to write device drivers. If you look at the Nto kernel calls, you will see that they are a more or less orthogonal superset of the QNX4 equivalents. I think that the original idea was that Nto would slide in under the QNX4 kernel and replace it. For better or worse, a lot of the low level messages structures were "optimized", so this is going to be difficult. Both QNX4 and Nto are POSIX os's. POSIX is essentially standardized UNIX. several POSIX standards are defined including utilities, calls, and threads. The thread standard was not approved when QNX4 was written. POSIX compliance means that POSIX code, shell scripts and so on are more or less portable. -- David L. Hawley D.L. Hawley and Associates 1(503)274-2242 Software Engineer dlhawley@teleport.com