Why did Linux use a RISC OS SWI number, when they had 24 million to choose from?
Now, Acorn weren't against looking ahead (I like to think of their software interfaces as forward-compatible, with support for likely developments looking forward many years, or even decades). One example of this was when they defined the new ARM SWI instruction, they included these bits:
Bits 20 - 23Now, Linux used to stick to this definition, using the number 9 for the OABI, but when they moved to EABI, the operating system bits were quietly dropped and SWI 0 (RISC OS's OS_WriteC - "Writes a character to all of the active output streams") was used.
These are used to identify the particular operating system that the SWI expects to be in the machine. All SWIs used under RISC OS have these bits set to zero. Under RISC iX, bit 23 is set to 1 and all other bits are set to zero.
Now, this has become a bit of a headache for me, because I'm trying to get Linux to run RISC OS programs using the ROLF compatibility library, which provides native Linux implementations for many RISC OS system calls. What I want is for the kernel to signal the application when a SWI is encountered in RISC OS code so that the ROLF routines can be executed in user space and the application (or module) can continue on its merry way.
There are a few ways to approach this:
- Check the personality of the process for each SWI executed
- Redefine the EABI to insist on SWI 0x009fxxxx as the kernel entry SWI (and treat all other SWIs as an illegal instruction or use a special signal code)
- Make OABI the standard interface
- Use a similar mechanism to the x86 emulator to generate Linux code from the RISC OS code, which won't execute any RISC OS SWIs
- Make the personality implementation more object-oriented and allow each process to determine how it should handle SWIs, Unknown instructions, data aborts, etc.
Option 2 will make some existing programs incompatible with the kernel, although not if they just use libc to make system calls, or are recompiled against a new unistd.h.
Option 3 would be a step backward for Linux (and support will probably be phased out over time). Also, it suffers from the same incompatibilities as option 2.
Option 4 will be fully compatible and would allow running of old 26-bit applications but would be much more work and probably quite a lot slower.
Option 5 would be cool, but probably too high impact.
Jan Rinze likes 1, I prefer 2, but I'll probably go with whichever produces a working solution first!