tag:blogger.com,1999:blog-334140022024-02-28T15:29:39.491+01:00ROLF - An alternative GUI for LinuxROLF is a GUI framework using the framebuffer device on Linux to provide a look and feel similar to that of the RISC OS operating system.
The RISC OS GUI is largely unchanged in concept since the late 1980's, not because of any lack of development, but because it just worked.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.comBlogger54125tag:blogger.com,1999:blog-33414002.post-84743259866697473632013-09-08T11:01:00.000+02:002013-09-08T11:01:23.000+02:00LiveSD card nearly readyI've been working on getting a bootable SD card working for the last couple of weeks, and it is getting close to release.<br />
<br />
It is based on <a href="http://www.linuxfromscratch.org/" target="_blank">Linux From Scratch</a>, specifically the automated version jhalfs-2.3.2, and the latest LFS book on SVN. LFS is a book describing how to generate a minimal Linux distribution from source code and goes through several stages to avoid dependencies on the build operating system (in my case Knoppix 7.2). <a href="http://www.linuxfromscratch.org/alfs/" target="_blank">JHALFS</a> automates that process by reading the book for you and generating scripts and makefiles to perform all of the work described in the book. It's a really good idea to go through the book manually a couple of times first, if you want to learn what it's all about, but eventually you'll want to automate it as I did in the construct-live-cd part of the <a href="http://sourceforge.net/p/ro-lf/code/255/tree/" target="_blank">ROLF repository on sourceforge</a>. JHALFS, however, moves with the times (my scripts generate linux-2.6.30.7, but LFS is on linux-3.10.10).<br />
<br />
Moving with the times is not without its own problems, however.<br />
<br />
Somewhere between binutils-2.22/linux-2.6.30.7 and binutils-2.23.2/linux-3.10.10, there seems to have come a change which meant that all my ROLF programs would fail on startup. More strangely still, ldd and gdb would report the problem as follows:<br />
<br />
<blockquote class="tr_bq">
<b>ldd: exited with unknown exit code (139)</b></blockquote>
and<br />
<blockquote class="tr_bq">
<b>(gdb) start<br />Temporary breakpoint 1 at 0x8000383<br />Starting program: /tmp/x/x1 <br /><br />Program received signal SIGSEGV, Segmentation fault.<br />0xb7fdfa24 in dl_main () from /lib/ld-linux.so.2</b></blockquote>
I had the same problem many years ago, but this time, I'm writing it down!<br />
<br />
The culprit is a link option I have to use to avoid the loader putting native code or data where RISC OS programs expect to have ROM or RAM mapped:<br />
<blockquote class="tr_bq">
<pre>-Wl,--section-start,.interp<span class="o">=</span>0x10000100</pre>
</blockquote>
I have never come across an option that tells the linker to avoid a certain area of memory for the program to use, so this is the best I could come up with. ".interp" seemed to be the first section located in memory, and all other sections would follow on, so, initially, I tried <br />
<blockquote class="tr_bq">
<pre>-Wl,--section-start,.interp<span class="o">=</span>0x10000000</pre>
</blockquote>
...with the result that I got similar problems as above. Adding 256 bytes to the address, however made it go away and for a long time, I was happy....<br />
<br />
It turns out that adding another 256 bytes makes it go away again. If anyone can tell me why this happens, I'd be very interested to know!<br />
<br />
<br />Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com2tag:blogger.com,1999:blog-33414002.post-13692382820070034322012-10-31T14:34:00.003+01:002012-10-31T20:00:56.542+01:00bind: Address family not supported by protocolTrying to get ROLF running on a Raspberry Pi, I installed Debian Wheezy, but then found that my vnc server version of ROLF doesn't start up.<br />
<br />
I've boiled the problem down to a minimal program that works fine on 2.6.32.6, but not on "Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux" or "Linux Microknoppix 3.4.9 #34 SMP PREEMPT Fri Aug 17 06:30:04 CEST 2012 i686 GNU/Linux", so presumably there's a change in a major version. All I have to do is find out what it is...<br />
<br />
<b>Update: </b>It seems someone turned on the "check for idiot programmers" flag in the kernel; fix: <b>addr.sin_family = AF_INET;</b><br />
<br />
<pre>#include <sys/types.h>
#include <sys socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main()
{
int vnc_server;
int port = 2008;
struct sockaddr_in addr = { 0 };
addr.sin_family = htons( AF_INET );
addr.sin_port = htons( port );
if (-1 == (vnc_server = socket( AF_INET, SOCK_STREAM, 0 )))
perror( "socket" );
if (0 != bind( vnc_server, (struct sockaddr*) &addr, sizeof( addr ) ))
perror( "bind" );
return 0;
}
<sys 0="0" addr.sin_family="htons(" addr.sin_port="htons(" addr="addr" af_inet="af_inet" amp="amp" bind="bind" gt="gt" if="if" in.h="in.h" include="include" int="int" lt="lt" main="main" nbsp="nbsp" netinet="netinet" perror="perror" port="port" pre="pre" return="return" sizeof="sizeof" sock_stream="sock_stream" sockaddr="sockaddr" sockaddr_in="sockaddr_in" socket.h="socket.h" socket="socket" struct="struct" tcp.h="tcp.h" vnc_server="vnc_server"></sys></pre>
Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-22440547308951710442012-07-17T12:41:00.000+02:002012-07-21T14:55:32.411+02:00Better timingsSince my last post, I've had a look at the ARM-on-ARM emulator with a view to improving the speed.<br />
<br />
Using gprof, I found that:<br />
<ol>
<li>The image translation from RISC OS Sprite to screen mode was unoptimised (i.e. making two unoptimised function calls per pixel). This, I improved, but it only made a small overall difference since it occurs after the rendering work is done in the emulator.</li>
<li>gprof is useless for following what's going on in the emulator generated code.</li>
</ol>
Building the emulator to dump the state after every emulated instruction, then with a bit of fiddling with grep, sed, sort and uniq, meant that I could find the instructions most used by the renderer (about 10000 times each rendering the ACORN file). I noticed that one branch condition (actually, the case where a conditional branch instruction is <b>not</b> taken) always did a lot of work (hash table lookup, etc.) but that the existing branch fixup code could be used to improve it.<br />
<br />
With that six or seven line code change, the situation is now that the BeagleBoard renders the celtic_knot3 file in a little over 37s, down from 85s.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVItP7MpTVVaaItJHwfTBosU8aOX7uhSlR7Zs7FuSPluiMteJ0gRvH_rUnBFgvzcDN8ayDM-lGQ_jPmSf6FRVTYtL49A0bt60ObUsXkdBCvJrlgX9dAm2akG4CVKvvd5IIJy4F/s1600/BranchFixup.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVItP7MpTVVaaItJHwfTBosU8aOX7uhSlR7Zs7FuSPluiMteJ0gRvH_rUnBFgvzcDN8ayDM-lGQ_jPmSf6FRVTYtL49A0bt60ObUsXkdBCvJrlgX9dAm2akG4CVKvvd5IIJy4F/s400/BranchFixup.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">x86 PC: 14s, Beagle Board: 37s</td></tr>
</tbody></table>
My RISC PC is not cooperating at the moment, but the same file takes about 55s to render on its 200MHz StrongARM.<br />
<br />
The branch fixup code currently avoids having to clear the code cache by calling the fixup code using LDR pc, [pc, #...], having stored the code address in a scratch register. That way, only the word loaded by that instruction has to be changed to point to the generated code instead of the fixup routine, and the next time the instruction is reached, the fixup routine will be bypassed (although the setup for the call remains).<br />
<br />
Further possible improvements to be tried:<br />
<ol>
<li>Modify the first instruction of the fixed up code to be a proper branch to the address, as well as the current change; if the code falls out of the code cache by itself, the next time the code is run it will be quicker.</li>
<li>Clear the ARM code cache explicitly, so that the faster code will be called straight away. This may be slower, due to the overhead of a system call the first time the branch occurs.</li>
</ol>
The ARM-on-ARM emulator code is available on the SourceForge ROLF project site, at: <a href="http://ro-lf.svn.sourceforge.net/viewvc/ro-lf/ROLF/rolf/Libs/Compatibility/arm_arm_emulator.c?view=log">http://ro-lf.svn.sourceforge.net/viewvc/ro-lf/ROLF/rolf/Libs/Compatibility/arm_arm_emulator.c?view=log</a><br />
<br />
If you compile with -DSTANDALONE, it will create an executable that takes the name of a file that should contain ARM instructions, and run them (only really useful with gdb, to see what's going on).<br />
<br />
The handling of unaligned memory accesses is still incorrect (except on my custom kernel, which fixes up the accesses in the old fashioned way).<br />
<br />
Update: <a href="http://ro-lf.svn.sourceforge.net/viewvc/ro-lf/ROLF/rolf/Libs/Compatibility?view=tar">http://ro-lf.svn.sourceforge.net/viewvc/ro-lf/ROLF/rolf/Libs/Compatibility?view=tar</a> downloads the whole ROLF compatibility library, including the include files and disassembly code. (I can't check this at the moment, but...) The following should generate an executable on an ARM system:<br />
<br />
<pre>tar xf ro-lf-Compatibility.tar.gz
cd Libs/Compatibility/ # Possibly other subdirectory
touch config.h # Usually generated by the ROLF configure routine
gcc -o standalone_emulator arm_arm_emulator.c arm_d*.c -DARCH_ARM -DSTANDALONE -DDISASSEMBLE -Iincludes -I.</pre>
<br />Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com2tag:blogger.com,1999:blog-33414002.post-68874239639167200652012-07-05T16:28:00.000+02:002012-07-06T11:13:52.095+02:00AWRender on BeagleBoard, with timingsThe AWRender module is now working under ROLF on the BeagleBoard.<br />
<br />
It's a long story, but it looks like the problem wasn't with unaligned accesses after all (the newest module version doesn't do any), as I'd thought.<br />
<br />
The symptoms were twofold: Viewer crashed as soon as it tried to open an ArtWorks image with a problem in the dynamic linker, and the !AWRender BASIC program displayed just a small part of the image (and showed unaligned accesses occuring).<br />
<br />
It wasn't until I built from svn sources on the x86 platform again that I noticed that the BASIC program generated exactly the same (wrong) output. The implication was that the problem was (a) independent of the emulator and (b) previously fixed, but lost (the program had previously be working, as can be seen from screenshots on this blog). This started me looking at the Viewer problem, and I eventually noticed that ARMLinux locates executables at 0x8000 (same as RISC OS), rather than up above the 128MB boundary. A build explicitly locating the executable in the same area resulted in properly displayed images (although, strangely, the celtic knot 3 image appears lighter on the BB than on the x86 PC, when both viewed via tightvnc on the same monitor).<br />
<br />
This is what Linux's 'uname -a' and /proc/cpuinfo tells me about both systems:<br />
<br />
BeagleBoard:<br />
<br />
<pre>Linux (none) 2.6.39.1 #10 SMP Wed Jun 13 21:00:36 CEST 2012 armv7l GNU/Linux
Processor : ARMv7 Processor rev 3 (v7l)
processor : 0
BogoMIPS : 490.52
Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x1
CPU part : 0xc08
CPU revision : 3
Hardware : OMAP3 Beagle Board
Revision : 0020
Serial : 0000000000000000
</pre>
<br />
<br />
PC:<br />
<pre>Linux Microknoppix 2.6.32.6 #8 SMP PREEMPT Thu Jan 28 10:51:16 CET 2010 i686 GNU/Linux
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 107
model name : AMD Athlon(tm) Dual Core Processor 5050e
stepping : 2
cpu MHz : 2593.613
cache size : 512 KB
bogomips : 5189.36</pre>
<br />
The same for core 1 (the emulator is single threaded, so that the second core will make minimal difference to rendering speed).<br />
<br />
The AMD processor appears to be over ten times faster (BogoMIPS) than the BB's ARM.<br />
<br />
The test I'm using is to display <a href="http://www.simon-smith.org/graphics/celtic_knots.html">celtic_knot3</a>, a file of 355812 bytes. The rendering time is in the tens of seconds, displayed in the titlebar of the Viewer window, so the file access time (in the millseconds) is of no consequence.<br />
<br />
The initial times I'm getting are:<br />
<br />
BeagleBoard 85s, PC 15s (to the nearest second).<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixIdZQ7HQ87F2vEjqz2DkwYBd8mYWm6SsEzKlsOFTTBBCNqo5wKu3RdqiarLYLAptEfjAv6TQhwOPjZi4lABhXHD8sRbkOeK5OoLTCw5cGYcH_gysDn8GnaNQ7cFDr9fjF-to6/s1600/Speed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixIdZQ7HQ87F2vEjqz2DkwYBd8mYWm6SsEzKlsOFTTBBCNqo5wKu3RdqiarLYLAptEfjAv6TQhwOPjZi4lABhXHD8sRbkOeK5OoLTCw5cGYcH_gysDn8GnaNQ7cFDr9fjF-to6/s320/Speed.png" width="320" /></a></div>
<br />
This is disappointing; the (200MHz) RISC PC manages it in 55s (see <a href="http://ro-lookandfeel.blogspot.de/2010/05/emulator-speedups.html">here</a>).Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-91537294636335433652012-06-01T20:42:00.000+02:002012-06-01T20:42:24.986+02:00Mounting an NFS filesystem requires the loopback interface to be upOver the last few weeks, I've been using flash drives connected to my BeagleBoard to store files for compilation; the MMC card I use for the root filesystem is too small for compiling MPlayer. Unfortunately, the flash drive stopped working, and I can't seem to recover a single byte of what was on it.<br />
<br />
So, I decided to mount an NFS partition instead, but most of the commands I tried after running rpcbind (the portmapper) hung until they timed out. What I finally worked out is that the loopback interface has to be up ("ifconfig lo up") for them to work.<br />
<br />
If I was trying to mount an NFS partition as my root partition, I would probably take the approach I used for the x86 live CD, which was to have a compressed minimal root filesystem as part of the kernel image (look into CONFIG_BLK_DEV_INITRD, CONFIG_INITRAMFS_SOURCE, etc.), which was able to bring up the appropriate interfaces (reading environment variables set in the uEnv.txt file for the NFS server, etc.).<br />
<br />Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-26233170343611389372012-02-07T09:59:00.001+01:002012-02-07T15:37:29.288+01:00Programming ROLF windowsIn changing the Viewer application over from the old (furniture.h) Wimp interface to the new (composite_window.h) version, it occurred to me that I hadn't done any documentation for the way it works. I'll try to remedy that here.<br />
<br />
<u>Background</u><br />
<br />
The ROLF Wimp has always treated a window as a rectangle controlled by the applications with a set of (usually smaller) rectangles, called hotspots, which respond to user input events according to a set of flags (report drags, clicks, activations, etc.). Windows may be opaque (obscuring any windows lower than them on the stack) or translucent (not completely obscuring them).<br />
<br />
Initially, the hotspots were defined to be non-overlapping, but that can add a lot of complexity to the application, so the definition was changed so that the last hotspot in the set (now a list, since the order of definition is important) matching a given coordinate is the one that may report the event.<br />
<br />
The Wimp behaviour has been fixed for some years, now. I need to add one more function, to return the current keyboard modifier flags (shift key states, etc.) for the filer to use, and to fix a bug in translucent window redrawing.<br />
<br />
A window may also be marked as "transient", indicating that it should be informed before an active user input event (i.e. a click, not simple pointer movement) is sent to another process. This enables the implementation of pop-up menus.<br />
<br />
<u>Original API (furniture.h)</u><br />
<br />
The original API, defined in furniture.h, wasn't very flexible, and shouldn't be used any more. It allowed an application to request window sizes according to the required size of the application drawn area of a window, which was good, but failed to provide the flexibility to do more "interesting" things, like sharing the horisontal scroll bar area with a status bar. Also, the user input events went through a single set of application provided routines, that had to distinguish between window types and made it difficult to provide standard window types (like a save window).<br />
<br />
<br />
The new (and probably final) window API provides a C object-oriented interface where the application provides a pointer to a structure containing function pointers to the API which uses that pointer as the first parameter to those functions.<br />
<br />
<u>New Window API (window.h)</u><br />
<br />
I spent some considerable time considering various approaches to defining how your application's windows should be laid out by the library, either with North, South, East, West, or a spiral of rectangles out from a central rectangle, etc., until I realised that it would be more work to define any but the most simple windows in that sort of way than to simply write a couple of routines per window type that would fill in the hotspot information for the library, given the window dimensions.<br />
<br />
The API now invisibly, routes user events to the appropriate window's routines, which allows standard window types to be implemented without affecting the application code past the initial window creation.<br />
<br />
<u>Composite Windows</u><br />
<br />
The composite window API is a layer above the windows.h interface which makes the definition of non-overlapping rectangular areas, frames, of the window easier. This, in turn, allows libraries to provide standard window furniture features such as scroll bars and sizer icons.<br />
<br />
Each frame provides a similar set of routines to those used in the window.h interface and a composite_window creating application will provide similar routines that the library can ask to provide information about the whereabouts of each frame.<br />
<br />
There are some assumptions that can be made by application (and library) authors regarding these routines, namely:<br />
<ul><li>Only one user event will occur at a time (there's only one pointer)</li>
<li>Only one window (per process) will be being redrawn at a time</li>
</ul>This means that, say, the titlebar implementation can provide a single shared frame structure pointer, plus a routine to set up what it should display when it is drawn.<br />
<br />
<u>Drawing Windows</u><br />
<br />
ROLF applications should be written with the assumption that the Wimp will handle acceleration of window redraws compatible with the system the application is running on. In general, applications should aim to use as little memory as possiblem and let the Wimp worry about buffering.<br />
<br />
As an example, on a small-memory device with shared framebuffer memory, the Wimp will probably request the application draws directly to the framebuffer; in a large-memory device, the Wimp may allocate memory for the content of each window and combine them automatically, perhaps with DMA to a separate graphics card, so that the application will never be asked to perform a redraw because of window repositioning. The aim is to converge on an intermediate solution that notices details like how frequently a window's content changes, how quickly redraws complete, etc. and buffers the most processor intensive windows, automatically. (This doesn't happen yet, though.)<br />
<br />
ROLF's drawing mechanism is based around an Image library, with a few essential types/interfaces:<br />
<ul><li>SourceImage (things you can render to a DestinationImage)</li>
<li>DestinationImage (things you can render SourceImage things to)</li>
<li>Bitmap (providing both of the above interfaces) </li>
<li>Rectangle</li>
<li>ScreenRectangle (Rectangles with short (16-bit) values - it's sufficient for a 3m square display at 300dpi)</li>
<li>rgba16 (The standard colour format, with 16-bits for each of RGB and Alpha)</li>
</ul>One of the main aims of the library is to minimise the amount an application has to know about how images are encoded, conversion and optimisation will be provided within the library.<br />
<br />
All Images (Source or Destination) represent a rectangular area, not necessarily with a (0, 0) origin.<br />
<br />
[ To be continued ]Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-10267310891426891172012-02-03T19:02:00.002+01:002012-02-04T20:13:04.062+01:00NetSurf on ROLFI thought it was time to update NetSurf on ROLF, so I have.<br />
<br />
Revision 191 should build on a clean system.<br />
<br />
Most annoying features:<br />
<ul><li>Can't type a URL into the URL bar</li>
<li>Menu in a window exits the application</li>
<li>Double-clicking an html file doesn't start the program [Fixed in rev. 192]</li>
<li>Scroll bars don't update properly </li>
</ul>Still, it should give an idea of what's possible.<br />
<br />
I've done something to the filer that means the NetSurf icon shows up OK, but none of the others do, any more. [Update: That was just a libpng version mismatch, which also showed up as lots of NoMemory messages from NetSurf.]Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-24420255728083406542011-12-07T10:16:00.000+01:002011-12-07T10:16:10.111+01:00Beagle Board booting moving to another blogIt seems what I'm doing now mirrors the goings on back in July at this site <a href="http://www.embedded-bits.co.uk/category/beagleboard/">this</a> site, which is written in a much better style.<br />
<br />
I'm intending to continue working on this until I have a complete OS on the BeagleBoard. I'll be talking about that on my <a href="http://somethinglikeeiffel.blogspot.com/">Something Like Eiffel</a> blog, since it's going to be designed around the same language features that I've been thinking about there.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com10tag:blogger.com,1999:blog-33414002.post-32624630364430778512011-11-24T21:40:00.000+01:002011-11-24T21:40:43.969+01:00Booting Beagleboard by BBC BASICThe RPC is the only machine I have left with a serial port (well, except the BBC Micro that's coming up to its 30th birthday next year, and it can't quite manage 115200 baud).<br />
<br />
Below is a very short BBC BASIC program that assembles some code and uploads it to the BB internal memory. You have to hold down the USR button on powerup/reset to get it to talk. (The slowest part in development was noticing out that the initial boot sequence uses 8E1 protocol, and not the 8N1 that the x-loader and u-boot and linux do.)<br />
<br />
I wanted to get into the boot process as early as possible without continuously re-flashing the NAND ROM, and also avoiding plugging an SD card into the somewhat worn out socket.<br />
<br />
Brunel OS is an idea I've been thinking about for years, with a concept based on an Eiffel inspired language that handles multi-threading by simply only alowing one thread at a time access to any object and allowing threads to pass through multiple memory maps (somewhat different to the process model of other operating systems I've had experience of).<br />
<br />
So, an example of loading a very small program into internal RAM of the BeagleBoard from a Risc PC:<br />
<br />
<pre>SYS"OS_SerialOp", 0, &106, &fffffe00
SYS"OS_SerialOp", 1, %011000
SYS"OS_SerialOp", 5, 18
SYS"OS_SerialOp", 6, 18
PROCassemble
REM Receive ASIC ID (and ignore it, for the time being)
FOR R%=1 TO 58
REPEAT
SYS"OS_SerialOp", 4 TO ,J%;F%
UNTIL (F% AND 2) = 0
PRINT RIGHT$( "0"+STR$~J%, 2 );
NEXT
PRINT "Sending boot command"
PROCput( 2 )
PROCput( 0 )
PROCput( 3 )
PROCput( &f0 )
PRINT "Boot command sent"
DIM B% 4
!B%=P%-code%
PROCput( B%?0 )
PROCput( B%?1 )
PROCput( B%?2 )
PROCput( B%?3 )
PRINT "Length sent ";!B%
T%=0
FOR Q%=code% TO P%
SYS"OS_SerialOp", 4 TO ,J%;F%
IF (F% AND 2) = 0 THEN
PROCshow( J% )
ENDIF
PROCput( ?Q% )
T%+=1
NEXT
PRINT "Transmission finished "; T%; " bytes"
REM Kind of terminal (one way, at the moment)
REPEAT
REPEAT
SYS"OS_SerialOp", 4 TO ,J%;F%
UNTIL (F% AND 2) = 0
PROCshow( J% )
UNTIL 0
END
DEF PROCput( C% )
REPEAT
SYS"OS_SerialOp", 3, C% TO ; F%
UNTIL (F% AND 2) = 0
ENDPROC
DEF PROCshow( C% )
R%+=1
IF C%>31 OR C%=10 OR C%=13 THEN
VDU C%
ELSE
PRINT "<";~C%;">"
ENDIF
ENDPROC
DEF PROCassemble
DIM code% 1000
FOR I%=0 TO 1
P%=code%
[OPT 3*I%
MOV r9, #&49000000
ORR r9, r9, #&00020000
ADR r1, welcome
.write_loop
LDRB r2, [r1], #1
CMP r2, #0
STRNEB r2, [r9] ;This can overflow the buffer, but it's not important yet
BNE write_loop
.loop
B loop
.welcome
EQUS "Welcome to Brunel OS 0.0.0-1"+CHR$10+CHR$13
EQUB 0
ALIGN
]
NEXT
ENDPROC
</pre><br />
Output:<br />
<pre>04010501343007561302010012150100000000000000000000000000000000000000001415010000000000000000000000000000000000000000Sending boot command
Boot command sent
Length sent 64
Transmission finished 65 bytes
Welcome to Brunel OS 0.0.0-1
</pre>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-58825004467724838862011-11-04T19:33:00.001+01:002011-11-04T19:35:26.084+01:00Alignment and modern ARM processorsBack when RISC OS was in its heyday, and the ARM processor was new, reading or writing a word at a non-word aligned address didn't cause an exception or cause two memory words to be read (and half discarded); instead it would read the word at (address & ~3) (i.e. the word containing the byte addressed) and load it into the register, rotated so that the addressed byte was the least significant byte in the register (IIRC).<br />
<br />
ARM Architecture Reference Manual:<br />
<br />
<blockquote class="tr_bq">load single word ARM instructions are architecturally defined to rotate right the word-aligned data transferred by a non word-aligned address one, two or three bytes depending on the value of the two least significant address bits.</blockquote><br />
Modern ARM processors, when faced with this case, can trigger an alignment exception, allowing the OS to fixup the instruction to behave in the (admittedly more high-level-language-friendly) way of reading the four bytes starting at the address and treating them as a single word); some hardware can even perform the fixup automatically.<br />
<br />
Unfortunately, that means that some RISC OS (read: old) code breaks.<br />
<br />
There are two Linux features that appear to have a bearing on the problem:<br />
<ol><li>/proc/cpu/alignment (allows you to set whether an alignment exception should be fixed up or a SIGBUS sent to the process). Unfortunately, that has at least two problems; firstly, it's system-wide, and so may cause other programs to break, secondly, it doesn't register unaligned LDRs (probably because the hardware performs the fixup).</li>
<li>The prctl has the following values defined in linux/prctl.h: PR_SET_UNALIGN and PR_GET_UNALIGN, and the possible values: PR_UNALIGN_NOPRINT (for silent fixup) and PR_UNALIGN_SIGBUS (to signal the exception to the process for fixing up). This is a per-process feature but, unfortunately, these values are not implemented in the ARM kernel.</li>
</ol>Ideally, I think I'd like to use the prctl approach and have a third value to set the system to, PR_UNALIGN_ARM_TRADITIONAL, which would simply work the way ARM processors used to. How practical that is remains to be seen (especially in the presence of multi-core processors; the behaviour has to be settable on a per-core basis).Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-83651110702059932652011-11-02T19:15:00.004+01:002011-11-02T23:41:56.784+01:00ARM Emulation on ARM - progressThe emulation approach I talked about in my last post is working well enough that most BASIC seems to work well (and the missing parts are probably due to omissions in the ROLF libraries, not down to the emulator code). !Edit (from a RISC OS 4.02 ROM image) starts up, brings up an IconBar icon and opens a window (whose text can be read, provided it's not in system font), but for some reason the characters typed each get put on a new line!<br />
<br />
There are still some bugs to be ironed out, and the (unoptimised) speed is less than I'd hoped. Actually it's about 100 times slower than my 200MHz RiscPC!<br />
<br />
Still, I have several features that still need implementing, such as a hash table for cache searching, fixing up jumps to non-local code so that the second and subsequent jumps make no search, compiling the library with gcc optimisation on (which made a surprisingly large difference on the x86 ARM emulator) and, if all else fails, reorganising the instruction identification mechanism to be more efficient.<br />
<br />
Update 19:39. Implemented a simple three instruction hash, for a better than 10x speedup. Now only 10 times slower than the 15 year old machine!<br />
<br />
Update 19:55. -O4 optimisation gives a 30% speedup (a test that used to take 167cs, now takes 115cs), although that's probably more about turning off some debug than anything else.<br />
<br />
Update 00:21. One fixup approach takes the time down to 78cs (for 1 million times around a FOR...NEXT loop).<br />
Initially, I thought I'd have to clear the cache (which involves a system call, plus whatever the OS does) for each fixup, but I realised that I could use LDR pc, [pc,...] to load the destination address using the data cache, (where the destination address would initially be the fixup routine and later the actual code address). I might try some other approaches in the morning. (I just noticed some debug output still in there, so I deleted it and... the time went UP to 106cs. I'm going to bed.)Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-15963839386346403212011-10-06T15:23:00.000+02:002011-10-06T15:23:59.574+02:00ARM Emulation on ARMROLF has a compatibility layer intended to allow execution of RISC OS applications. On x86 platforms, this includes an emulator for the ARM instruction set. Recent experience with trying to simply use the ARM processor on ARM platforms ended in <a href="http://ro-lookandfeel.blogspot.com/2011/07/minor-hitch-running-risc-os-code-on.html">failure</a>. I'm trying a different approach to work around that problem, which should also remove the need for Linux kernel changes and allowing the execution of both 32-bit and 26-bit programs.<br />
<br />
The emulator interface will be the same as the emulator on the emulator that generates x86 code, but takes a different approach to code generation due to the similarity of emulated and host processors.<br />
<br />
Basically, code generated by the emulator is isolated from the Linux code by a code fragment that stores and replaces Linux register values with the emulator's register values on entry and does the opposite on exit. Most instructions can then simply be copied verbatim from the emulated code to the generated code. Since the emulator generated code needs some workspace to deal with, four registers have been reserved and instructions that use the reserved registers will be modified and supplemented with code to load and/or store the stored register's values into reserved registers.<br />
<br />
For example:<br />
<br />
<pre>ADD r1, r4, #17</pre><br />
Would be copied, but<br />
<br />
<pre>ADD r8, r9, r10 LSL#2</pre><br />
needs to be replaced with something like<br />
<br />
<pre>LDR r8, [r11, #40] ; Load arm_emulator_regs[10] into r8
LDR r9, [r11, #36] ; Load arm_emulator_regs[9] into r9
ADD r8, r9, r8 LSL#2 ; The original instruction with the register fields replaced
STR r8, [r11, #32] ; Store r8 into arm_emulator_regs[8]
</pre><br />
Use of r15, the program counter, will also be recognised by the emulator and code generated to emulate either the 26-bit or 32-bit PC, depending on the current mode.<br />
<br />
The reserved registers chosen are r8-r11, since:<br />
<ol><li>They appear to be the least used registers in the RISC OS 4.02 ROM</li>
<li>They are in a block of four, aligned on a four register boundary, which allows instructions using them to be identified by checking the top two bits of the register number (0b10xx) </li>
<li>Four is the smallest number of registers that this can work with, considering instructions like ADD r11, r10, r9, LSL r8 need three registers to hold the "input" values (we can re-use one of them as the destination register) and one more register (r11) to store a pointer to the emulator's registers in memory (plus the stored caller's registers and the emulator's PSR).</li>
</ol>Condition flags are also a breeze compared with emulating them in x86 machine code, and conditional execution of instructions pretty much takes care of itself, except when the instruction sets the flags and the emulator still has to emit code to store the value of a reserved register.<br />
<br />
For example:<br />
<pre>ADDEQ r8, #1
</pre><br />
Can't simply do this:<br />
<pre>LDREQ r8, [r11, #32]
ADDEQS r8, #1
STREQ r8, [r11, #32]
</pre><br />
because the final instruction will execute on the conditions set by the preceeding instruction.<br />
<br />
So, in cases where the instruction condition is not AL, and a reserved register may be modified by the instruction, the generated code will have to be more like this:<br />
<br />
<pre>ADDNE pc, pc, #offset
LDR r8, [r11, #32]
ADDS r8, #1
STR r8, [r11, #32]
</pre><br />
I'll have to experiment to see if it's more efficient to implement all conditional instructions with a opposite-condition hop over unconditional instructions or copying the emulated instruction's condition to each of the generated instructions. I suspect that the hop approach will be easier to implement and also faster at generating code, so that's what I'll try initially.<br />
<br />
Two details that have cropped up in the implementation so far are that:<br />
<ol><li>The generated code needs to be written to a writable, executable area of memory, so not a global variable but an anonymous mmap'd area (or possibly a global variable declared specially, perhaps in an assembler file?)</li>
<li>The ARM instruction cache needs clearing after generating code. Linux provides a call: __clear_cache( void *begin, void *end ) - begin is inclusive, end is exclusive.</li>
</ol>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com3tag:blogger.com,1999:blog-33414002.post-83481249930865182502011-09-04T18:55:00.002+02:002011-09-09T16:09:10.453+02:00What now?I've been having a look at what's working and what's not (on x86 systems).<br />
<br />
The basic ROLF functionality is largely there, with some minor bugs (buttons appearing pressed when they aren't any more, etc.) It's largely unchanged, although it's easier to produce different Wimps for different display types (currently xlib, vnc and the original frame buffer are supported, I expect others, like SDL, would be fairly simple to implement). XLib needs to be able to support mouse movement outside the screen area (probably by including an offset to the X mouse position to ensure the mouse limit is always within the window area). Framebuffer needs autorepeat of keypresses to be implemented; the Terminal application is a bit of a pain to use without that. The only adjustment to the Wimp protocol still to be made is to allow an application to request the current state of the modifier keys, specifically for shift-activating application directories in the Filer.<br />
<br />
From the point of view of RISC OS programs, support is patchy. For example, the ArtWorks renderer seems to work quite well, both using the AWRender module from the ROLF-native Viewer application as well as !AWViewer, a complete RISC OS application (given a RO4 ROM image to provide various modules).<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgawepeK1p4FA1UeG-fomy2mAJmqG6-NQB789NwZEZZ46rFyVsscrxWgOxWfmqYmiasZsfCmkEa_rJdg8tyvwk59uvPh4Gi7ePpj3_HaxOue_OGLmej16w-4GlI_R-QXvF0aqvg/s1600/ArtWorksExamples.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="240" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgawepeK1p4FA1UeG-fomy2mAJmqG6-NQB789NwZEZZ46rFyVsscrxWgOxWfmqYmiasZsfCmkEa_rJdg8tyvwk59uvPh4Gi7ePpj3_HaxOue_OGLmej16w-4GlI_R-QXvF0aqvg/s320/ArtWorksExamples.png" /></a></div><br />
On the other hand, of the ROM applications from RO4, none of them show their proper application icons <b>[fixed]</b> and only Edit gets to the point where it does anything useful. Draw drops out after adding an icon to the iconbar. Help requires the toolbox, which I've not included in the list of modules loaded by default. None of the others bother the scorer at all.<br />
<br />
NetSurf needs tidying up and possibly merging with the NetSurf sources. It would be nice if ArtWorks files could be displayed, using AWRender, and even videos using mplayer. At the moment, none of the menu items work, you can't type in a URL, etc.<br />
<br />
The MPlayer application hasn't changed in a long time, some videos appear in diagonal stripes, like the horizontal hold is broken; perhaps they have an unusual width or height? The one I just looked at has a width of 930, which isn't divisible by eight... [<b>fixed</b> - the stride passed in to the draw_slice routine was greater than needed for the width, my mistake]<br />
<br />
I have no idea if GTK still compiles, let alone does anything useful.<br />
<br />
Brandy 1.0.19 has a patch that may still work, but I tend to use the RO BASIC interpreter, because it's got an assembler built in (needed for AWViewer to run). I seem to recall that 1.0.20 needed quite a different patch approach, but I can't remember the details.<br />
<br />
I think I'll have a go at the Filer, first, it's been a long time since I looked at it.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-22996959170962767202011-07-09T16:56:00.000+02:002011-07-09T16:56:18.024+02:00A minor hitch running RISC OS code on ARMLinuxUpdate to an <a href="http://ro-lookandfeel.blogspot.com/2011/05/building-on-angstrom-on-beagleboard.html">earlier post</a> about running RISC OS applications on ARMLinux.<br />
<br />
Here's the thing: RISC OS modules, libraries and, occasionally, even applications switch merrily between USR and SVC mode at will. There's even a system call, OS_EnterOS, which exits with your application running in SVC mode, no questions asked.<br />
<br />
The problem is that at least one instruction to return to user mode (MSR CPSR_c, r1) is still a legal instruction <i>in</i> user mode (i.e. its execution isn't flagged as an exception), so ROLF can't detect that it should switch the "banked" registers it emulates.<br />
<br />
One solution might be to jump to the code while in SVC mode but, even if that works, there would be a hole in the Linux security model big enough to fly a fleet of A380s through.<br />
<br />
Bother.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-15369757494999444702011-06-15T09:47:00.003+02:002011-06-15T09:49:53.000+02:00Why does the language version being used affect standard semantics?<pre>knoppix@Microknoppix:/tmp$ cat x.c
#include <signal.h>
siginfo_t info;
knoppix@Microknoppix:/tmp$ gcc x.c -c
knoppix@Microknoppix:/tmp$ gcc x.c -c <span style="background-color: yellow;">-std=c99</span>
x.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'info'
knoppix@Microknoppix:/tmp$ </pre><br />
Hmpf.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com2tag:blogger.com,1999:blog-33414002.post-46586239557640965392011-06-11T17:14:00.002+02:002011-06-28T08:19:56.447+02:00Root filesystem for Beagleboard on MMC cardUpdate: There is of course the rootwait kernel parameter, which is better. (I'll leave the rest in case someone else searches for the same symtoms.)<br />
<br />
<br />
Just in case someone else has the same problem, I've had a frustrating few days trying to get my own kernel to start up with the root filesystem on /dev/mmcblk0p2.<br />
<br />
I based my kernel on the config found <a href="http://rcn-ee.net/deb/squeeze/v2.6.39.1-x1/defconfig">here</a>, and based my boot.scr file on the one supplied with the Debian Net Install generates with "mk_mmc.sh --uboot beagle_bx".<br />
<br />
No matter which kernel I tried, or boot.scr options I could find, I kept getting a kernel panic whenever I tried to use root=/dev/mmcblk0p2 (rather than an initfd):<br />
<br />
<blockquote>[ 4.075317] regulator_init_complete: VDAC: incomplete constraints, leaving on<br />
[ 4.083404] md: Waiting for all devices to be available before autodetect<br />
[ 4.090637] md: If you don't use raid, use raid=noautodetect<br />
[ 4.097534] md: Autodetecting RAID arrays.<br />
[ 4.101928] md: Scanned 0 and added 0 devices.<br />
[ 4.106628] md: autorun ...<br />
[ 4.109558] md: ... autorun DONE.<br />
[ 4.113159] Root-NFS: no NFS server address<br />
[ 4.117614] VFS: Unable to mount root fs via NFS, trying floppy.<br />
[ 4.124816] VFS: Cannot open root device "mmcblk0p2" or unknown-block(2,0)<br />
[ 4.132141] Please append a correct "root=" boot option; here are the available partitions:<br />
[ 4.140991] 1f00 512 mtdblock0 (driver?)<br />
[ 4.146362] 1f01 1920 mtdblock1 (driver?)<br />
[ 4.151672] 1f02 128 mtdblock2 (driver?)<br />
[ 4.157012] 1f03 4096 mtdblock3 (driver?)<br />
[ 4.162384] 1f04 255488 mtdblock4 (driver?)<br />
[ 4.167724] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)<br />
[ 4.176483] [<c0069384>] (unwind_backtrace+0x0/0xf8) from [<c0615f38>] (panic+0x5c/0x190)<br />
[ 4.185150] [<c0615f38>] (panic+0x5c/0x190) from [<c0008f88>] (mount_block_root+0x160/0x214)<br />
[ 4.194061] [<c0008f88>] (mount_block_root+0x160/0x214) from [<c00091d4>] (mount_root+0xa8/0xc4)<br />
[ 4.203338] [<c00091d4>] (mount_root+0xa8/0xc4) from [<c000934c>] (prepare_namespace+0x15c/0x1c0)<br />
[ 4.212707] [<c000934c>] (prepare_namespace+0x15c/0x1c0) from [<c0008c30>] (kernel_init+0x150/0x194)<br />
[ 4.222381] [<c0008c30>] (kernel_init+0x150/0x194) from [<c00635f4>] (kernel_thread_exit+0x0/0x8)</c00635f4></c0008c30></c0008c30></c000934c></c000934c></c00091d4></c00091d4></c0008f88></c0008f88></c0615f38></c0615f38></c0069384></blockquote><br />
The solution turns out to be dead simple (but I couldn't find a reference to it on the web): the rootdelay kernel parameter gives the kernel time to detect the MMC card before trying to mount it.<br />
<br />
Now, if I can just work out how to stop Debian's "Detecting Network Hardware" stopping the installation process in its tracks, I'll be a happy man...Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-22669537578124983282011-06-03T19:55:00.000+02:002011-06-03T19:55:38.161+02:00Why did Linux use a RISC OS SWI number, when they had 24 million to choose from?The EABI syscall interface for Linux on ARM processors uses the SWI (SoftWare Interrupt instruction) number zero as its way into supervisor mode and the kernel. Unfortunately, that instruction has been in use for more than twenty years by the operating system used by the originators of the ARM, Acorn's RISC OS.<br />
<br />
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:<br />
<br />
<blockquote>Bits 20 - 23<br />
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.</blockquote>Now, 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.<br />
<br />
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.<br />
<br />
There are a few ways to approach this:<br />
<ol><li>Check the personality of the process for each SWI executed</li>
<li>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)</li>
<li>Make OABI the standard interface </li>
<li>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</li>
<li>Make the personality implementation more object-oriented and allow each process to determine how it should handle SWIs, Unknown instructions, data aborts, etc. </li>
</ol>Option 1 will work, but will slow down all system calls even more than just moving back to OABI.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
Option 5 would be cool, but probably too high impact.<br />
<br />
Jan Rinze likes 1, I prefer 2, but I'll probably go with whichever produces a working solution first!Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-21507589972349268252011-05-22T00:37:00.002+02:002011-05-24T16:37:13.068+02:00Building on Angstrom on a BeagleBoardUpdate: Anonymous says all I needed to do was: <b>opkg install task-native-sdk</b>, thanks!<br />
<br />
These are some quick notes that I intend to update when I have (a) time, and/or (b) a working build.<br />
<br />
Tha Angstrom distribution doesn't include a native toolchain (it's meant to be light-weight, so that's OK). It does, however, mean you need to use the opkg package manager <i>a lot</i>.<br />
<br />
First try:<br />
"opkg install gcc"... This works.<br />
"gcc x.c"... command not found - what?<br />
<br />
<div style="margin: 0px;">"opkg install gcc-symlinks"... Ah! gcc now exists!</div><div style="margin: 0px;"><br />
</div><div style="margin: 0px;">Here's part of today's bash history:</div><div style="margin: 0px;"></div><div style="margin: 0px;"> 87 opkg install gcc</div><div style="margin: 0px;"> 88 opkg install gcc</div><div style="margin: 0px;"> 93 opkg install binutils binutils-symlinks cpp cpp-symlinks </div><div style="margin: 0px;"> 95 opkg install libc-6</div><div style="margin: 0px;"> 96 opkg install libc6-dev</div><div style="margin: 0px;"> 107 opkg install libmagic</div><div style="margin: 0px;"> 109 opkg install libmagic-dev</div><div style="margin: 0px;"> 110 opkg install file</div><div style="margin: 0px;"> 111 opkg install file-dev</div><div style="margin: 0px;"> 115 opkg install ccache</div><div style="margin: 0px;"> 117 opkg install install</div><div style="margin: 0px;"> 118 opkg install libtool-symlink</div><div style="margin: 0px;"> 119 opkg install libtool-symlinks</div><div style="margin: 0px;"> 121 opkg install coreutils</div><div style="margin: 0px;"> 128 opkg install freetype2-dev</div><div style="margin: 0px;"> 129 opkg install freetype-dbg</div><div style="margin: 0px;"> 131 opkg install freetype-dbg</div><div style="margin: 0px;"> 147 opkg install libjpeg-dev</div><div style="margin: 0px;"> 148 opkg install libpng-dev</div><div style="margin: 0px;"> 152 opkg install pkg-config</div><div style="margin: 0px;"> 154 opkg install pkg-config</div><div style="margin: 0px;"> 174 opkg install eval</div><div style="margin: 0px;"> 195 opkg install bash</div><div style="margin: 0px;"> 215 opkg install stl</div><div style="margin: 0px;"> 218 opkg install c++</div><div style="margin: 0px;"> 221 opkg install g++ g++-symlinks</div><div style="margin: 0px;"> 223 opkg install libstdc++-dev</div><div><br />
</div><br />
<div>Some worked, some didn't. But I think the combination of all of them has given me enough programs and libraries to build ROLF without RISC OS compatibility.</div><div><br />
</div><div>I also had to set up these symbolic links for libraries:</div><div><div><br />
</div><div>ln -s libfreetype.so.6 /usr/lib/libfreetype.so</div><div>ln -s /lib/libgcc_s.so.1 /lib/libgcc_s.so</div></div><div><br />
</div><div>As the applications were supposed to be linked, there was a problem with libtool; the generated static libraries contained only the text "! < a r c h ><arch>" (without the spaces), which turned out to be because the /bin/sh link was to /bin/busybox, not /bin/bash (which was already installed). For search engines: there were several lines like: "eval: 1: libtool_args+=: not found".</arch></div><div><br />
</div><div>ln -sf bash /bin/sh</div><div><br />
</div><div>I've noticed you can get a tarball of rolf code using the following URL (which means you don't have to install SVN to build it):</div><div><br />
</div><div>http://ro-lf.svn.sourceforge.net/viewvc/ro-lf/ROLF/rolf/?view=tar</div><div><br />
</div><div>The code needs modifying to get it to build, including removing the agp specific code and also the compatibility library, for the time being. The signal handlers in the compatibiity code need modifying to cope with ARM registers, rather than x86. Also, run_arm_code, and similar routines should be replacable with a simple jump to the code - a kernel patch by Jan Rinze will provide a signal on non-Linux system calls, allowing the compatibilty library to handle RISC OS system calls in-process.</div><div><br />
</div><div>I'm really hoping we can get this to work!</div><div><br />
</div>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com4tag:blogger.com,1999:blog-33414002.post-42853761941343746912011-01-27T19:08:00.000+01:002011-01-27T19:08:30.105+01:00Building on and for Knoppix IIUpdated with some corrections from <a href="http://ro-lookandfeel.blogspot.com/2010_05_01_archive.html">last time</a>.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSUV23TocG7WJJzVoEQVOMgvw8MfhsmVvnasUC7BgsNnjqKVqlxCK_v0pMNWBu1GBjJOPI-mkNy1URuoy4yBk8rJy09XB72T3nXYySzj3UwtJ-R14ayneJW7nZxPNN1e-bv85W/s1600/Screenshot.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5476751033902693426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSUV23TocG7WJJzVoEQVOMgvw8MfhsmVvnasUC7BgsNnjqKVqlxCK_v0pMNWBu1GBjJOPI-mkNy1URuoy4yBk8rJy09XB72T3nXYySzj3UwtJ-R14ayneJW7nZxPNN1e-bv85W/s320/Screenshot.png" style="cursor: pointer; display: block; height: 256px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
The Knoppix Live CD (http://knopper.net/knoppix/) is an excellent way to try out Linux on any PC with a CD-ROM drive. It won't store anything on your PC (unless you ask it to) and doesn't mess up any existing installations of Linux or Windows.<br />
<br />
In this article, I'm going to describe how to build ROLF to run on Linux assuming a PC booted from an unmodified Knoppix 6.2 CD.<br />
<br />
When done, you should have a working ROLF desktop being displayed in a window, able to run a few native ROLF programs and even some RISC OS programs, in a limited way. Simply by copying the directory into which you've installed ROLF to some permanent storage (a hard disc or a memory stick, for example), you can use the build again without having to go through the steps I describe.<br />
<br />
<span style="font-weight: bold;">Set up a build environment</span><br />
<br />
Knoppix, unfortunately, doesn't include all the tools needed to build ROLF, so we have to get them from Debian first. (If your Linux system already includes these tools, you can obviously skip this step.)<br />
<br />
First, get the full list of packages that are available:<br />
<br />
<span style="font-style: italic;">sudo apt-get update</span><br />
<br />
Then update the compiler to include the C++ compiler, needed to build the Server part of ROLF (the libraries are all plain C, but to build them, you need libtool).<br />
<br />
<span style="font-style: italic;">sudo apt-get install build-essentials</span><br />
<span style="font-style: italic;">sudo apt-get install subversion</span><br />
<span style="font-style: italic;">sudo apt-get install libtool</span><br />
<span style="font-style: italic;">sudo apt-get install pkg-config</span><br />
<br />
After that has been done, the compiler will still refuse to compile C++ programs because it can't find cc1plus, for some reason. The simplest way to fix that is to add the path to the (just installed) cc1plus file installed to the PATH environment variable.<br />
<br />
<span style="font-style: italic;">export PATH=$PATH:$(dirname $(find /usr/ -name cc1plus 2>/dev/null | head -n 1))</span><br />
<br />
Now, to get the source code:<br />
<br />
<span style="font-style: italic;">svn co https://ro-lf.svn.sourceforge.net/svnroot/ro-lf/ROLF/rolf</span><br />
<br />
(If you don't expect to make any changes to the code, you can instead use:<br />
<span style="font-style: italic;">svn export https://ro-lf.svn.sourceforge.net/svnroot/ro-lf</span>/ROLF/rolf)<br />
<br />
Change directory into the downloaded code and run configure (not as complicated as a normal configure script):<br />
<br />
<span style="font-style: italic;">cd rolf</span><br />
<span style="font-style: italic;">./configure --appsdir=$(pwd)/Apps --prefix=$(pwd) --tarballs=$(pwd)/tarballs/</span><br />
<br />
Knoppix (or Debian) have all their shared libraries taged by their version number; to make the files linkable, we need to do this:<br />
<br />
<span style="font-style: italic;">mkdir lib<br />
ln -s /usr/lib/libz.so.1 lib/libz.so<br />
ln -s /usr/lib/libjpeg.so.62 lib/libjpeg.so<br />
ln -s /usr/lib/libpng12.so.0 lib/libpng.so<br />
ln -s /usr/lib/libfreetype.so.6 lib/libfreetype.so<br />
ln -s /usr/lib/libstdc++.so.6 lib/libstdc++.so<br />
ln -s /usr/lib/libmagic.so.1 lib/libmagic.so<br />
</span><br />
<br />
Similarly, the build requires a set of include files [This bit needs an update!]<br />
<br />
Specifically, the files needed are:<br />
<br />
From zlib:<br />
zlib.h, zconf.h<br />
<br />
From libpng:<br />
png.h, pngconf.h<br />
<br />
From file:<br />
magic.h<br />
<br />
From libjpeg<br />
jpeglib.h, jmorecfg.h, jconfig.h<br />
<br />
From freetype 2:<br />
./ft2build.h<br />
./freetype/internal/internal.h<br />
./freetype/fttypes.h<br />
./freetype/ftsystem.h<br />
./freetype/ftmoderr.h<br />
./freetype/ftimage.h<br />
./freetype/fterrors.h<br />
./freetype/fterrdef.h<br />
./freetype/freetype.h<br />
./freetype/config<br />
./freetype/config/ftheader.h<br />
./freetype/config/ftconfig.h<br />
./freetype/config/ftstdlib.h<br />
./freetype/config/ftoption.h<br />
<br />
Update the config.mak file created by configure to point at the libraries and includes:<br />
<span style="font-style: italic;"><br />
sed -i 's/CFLAGS.*$/& -L$(CFGDIR)\/lib/' config.mak<br />
sed -i 's/CFLAGS.*$/& -I$(CFGDIR)\/my_includes/' config.mak<br />
</span><br />
<br />
Now you should be able to build ROLF:<br />
<br />
<span style="font-style: italic;">make</span><br />
<br />
Assuming all goes well with the build, the next step is to collect the resources needed in one place.<br />
<br />
You will need:<br />
<ul><li>Fonts (at least FreeSerif.ttf; the default font)<br />
</li>
<li>Tool and Icon sprites (I use Chris Wraight's Steel theme, from here: http://www.lym.iconbar.com/downloads/steel.zip)<br />
</li>
<li>A mimemap.txt file (if you're going to use RISC OS software)<br />
</li>
<li>and a !Boot file, to load them all (like the one below)<br />
</li>
</ul>Create a resources directory with subdirectories:<br />
<span style="font-style: italic;"> mkdir -p Resources/fonts/{FreeSerif,FreeSans,FreeMono}</span><br />
<span style="font-style: italic;">ln -s /usr/share/file/ Resources/ </span><br />
<span style="font-style: italic;">cd Resources/fonts </span><br />
<span style="font-style: italic;">for i in *; do for f in $( find /KNOPPIX/ -name $i*.ttf ); do ln -s $f $i/ ; done ; done 2>/dev/null</span><br />
<span style="font-style: italic;"># This one is needed for the Terminal application: </span><br />
<span style="font-style: italic;">cp `find /KNOPPIX/ -name default8x16.psf* 2> /dev/null` .</span><br />
<span style="font-style: italic;"> cd .. # Resources</span><br />
<span style="font-style: italic;">unzip <pathto>steel.zip</pathto></span><br />
<span style="font-style: italic;"><pathto>cd ..</pathto></span><br />
<span style="font-style: italic;"><pathto>cat > \!Boot <<"EOF"</pathto></span><br />
<span style="font-style: italic;"><pathto> IconSprites $ROLF_RESOURCES/Steel/Tools </pathto></span><br />
<span style="font-style: italic;"><pathto>IconSprites $ROLF_RESOURCES/Steel/Icons </pathto></span><br />
<span style="font-style: italic;"><pathto>LoadPointer $ROLF_RESOURCES/Steel/Icons ptr_default 0 21</pathto></span><br />
<span style="font-style: italic;"><pathto> LoadPointer $ROLF_RESOURCES/Steel/Icons ptr_double 0 21</pathto></span><br />
<span style="font-style: italic;"><pathto> # Match up icons with the appropriate mime types </pathto></span><br />
<span style="font-style: italic;"><pathto>if [ -f $ROLF_RESOURCES/mimemap.txt ] ; then ( grep -v ^# $ROLF_RESOURCES/mimemap.txt | tr -s '\t' | cut -f 1,3 | sort -k 2 | sed 's/\(.*\)\t\(.*\)$/IconSprite file_\2 "file_\1"/' | sh ) ; fi </pathto></span><br />
<span style="font-style: italic;"><pathto># Load applications </pathto></span><br />
<span style="font-style: italic;"><pathto>IconBar </pathto></span><br />
<span style="font-style: italic;"><pathto>Filer Icon $(dirname $0)/Apps 50 romapps Apps</pathto></span><br />
<span style="font-style: italic;"><pathto> Filer Icon /tmp 40 ramfs ramfs </pathto></span><br />
<span style="font-style: italic;"><pathto>Filer Icon $HOME 45 homedisc Home</pathto></span><br />
<span style="font-style: italic;"><pathto> EOF</pathto></span><br />
<br />
<span style="font-style: italic;"><pathto> </pathto></span> Now, we just have to run it!<br />
<span style="font-style: italic;"> </span><br />
<span style="font-style: italic;"> export LD_LIBRARY_PATH=`pwd`/lib</span><br />
<span style="font-style: italic;"> export PATH=$PATH:`pwd`/bin</span><br />
<span style="font-style: italic;"> #Uncomment the next line if you need a log of what's happened (useful for debugging) </span><br />
<span style="font-style: italic;"># ROLF_WIMP_LOG=/tmp/rolf_wimp_log \</span><br />
<span style="font-style: italic;">ROLF_RESOURCES=`pwd`/Resources \</span><br />
<span style="font-style: italic;">ROLF_VNC=800x600:2008 \</span><br />
<span style="font-style: italic;">Wimp</span><br />
<br />
<span style="font-style: italic;"> </span> That should have the effect of printing:<br />
<span style="font-weight: bold;">VNC Server waiting for connections on port 2008.</span><br />
<span style="font-weight: bold;"> New file descriptor 3</span><br />
<span style="font-weight: bold;"> New Opaque bitmap VNCFrameBuffer, 800x600</span><br />
<span style="font-weight: bold;"> </span><br />
In another terminal window, type:<br />
<span style="font-style: italic;"> </span><br />
<span style="font-style: italic;"> vncviewer localhost:2008 </span> <br />
<br />
... and a colourful window with an icon bar and a couple of drive icons should appear!Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-71556765892877665122011-01-26T18:27:00.002+01:002011-01-26T18:41:14.515+01:00Progress, with a Video!A couple of bugs have been chased down, so, just for fun, I thought I'd try and make a screen capture video of the state of the emulator.<br />
<br />
At first I tried to use recordmydesktop, but that doesn't seem to play nice with the compiz window manager. So, I found a nice, uncomplicated, picture format (TGA) and modified the user interface to write a screenshot to a file ten times a second (albeit upside down). The user interface, incidentally, is a separate process from the emulator and accesses the files that contain the memory of the emulated RPC directly, much like a real VIDC chip.<br />
<br />
Using mencoder, I produced the following video; it's probably best to watch it in fast-forward since it takes 40 seconds to get to the desktop and I'm not the fastest typer, either!<br />
<br />
The upload to Blogger seems to have scaled it down 50% and reduced the quality considerably, though. The screen looks a lot better than that in use.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='640' height='506' src='https://www.blogger.com/video.g?token=AD6v5dzrYm5QWxTF51agppzy1oH-EuoHKYJ_jHFND2gqFzuxaeLhs4W0HQ-1ZQfZGeNj_5PA-RL1JnzFEus' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><br />
<br />
The command line I used to generate the movie was this:<br />
mencoder mf://*.tga -mf w=640:h=480:fps=10:type=tga -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -o /tmp/screen_cap.mpg -flipSimonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-37612784235598354452011-01-24T19:45:00.001+01:002011-01-24T20:02:50.916+01:00I don't much like C++I came across this statement today which <a href="http://iconbar.com/forums/viewthread.php?threadid=11167&page=2#comments">neatly sums up my experience:</a><br />
<br />
<a href="http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/">"After 15 years programming in C++, I was surprised to discover today that..."</a>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-26503012822834645242011-01-18T12:10:00.004+01:002011-01-18T12:28:15.067+01:00Programs are running, for a while at least.The stand-alone RPC emulator has taken a couple of steps forward in the last few days.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg17wn4JkYZSGLKhS37_bX2559B2RphdXGeeN07HaHSh79VfVtG0Gzp4G6jiO4tTKCp9gru8v8aLsXClUOF7GwNXPFmZXN-PTC33mJTfOkFRemPajczoi3lGU_HtuLYLsgeTM4u/s1600/UnnamedRPCEmulator.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg17wn4JkYZSGLKhS37_bX2559B2RphdXGeeN07HaHSh79VfVtG0Gzp4G6jiO4tTKCp9gru8v8aLsXClUOF7GwNXPFmZXN-PTC33mJTfOkFRemPajczoi3lGU_HtuLYLsgeTM4u/s320/UnnamedRPCEmulator.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Still some problems!</td><td class="tr-caption" style="text-align: center;"></td><td class="tr-caption" style="text-align: center;"></td><td class="tr-caption" style="text-align: center;"></td><td class="tr-caption" style="text-align: center;"><br />
</td><td class="tr-caption" style="text-align: center;"><br />
</td></tr>
</tbody></table><br />
The TEQP implementation was wrongly checking the future processor mode rather than the current one, to see which flags should be affected.<br />
<br />
Once that was fixed, the next problem was dealing with pre-fetch aborts, where the ARM code scanner caused a segmentation violation reading the memory where code would be mapped in by the OS's lazy address decoding.<br />
<br />
There are still problems with caching (see picture); I've missed something that should be clearing the instruction cache between task swaps...<br />
<br />
In addition to stability, I need to:<br />
<br />
<ul><li>Write a module to handle the mouse input (I've done a hack to intercept OS_Mouse calls, but the RO pointer doesn't move with it, just changes shape while staying motionless). The X interface passes on absolute coordinates, like a tablet, rather than relative movement, like a mouse.</li>
<li>Sort out keyboard input (it's a bit hit and miss if a keypress appears when you're typing quickly); I think RISC OS is debouncing the input, so modifying the timing of keyboard events might sort that out.</li>
<li>Intercept more SWIs; networking ones might be a good start.</li>
<li>More graphics modes (limited currently to 640x480x256), maybe change the RISC OS mode when resizing the X window. </li>
</ul><b>What ROLF gets from all this</b><br />
<br />
When it works, ROLF should gain:<br />
<ul><li>a bit of publicity</li>
<li>a test platform for running RISC OS programs under ROLF (I'll be able to examine the behaviour of SWIs under RISC OS when implementing them in the compatibility layer</li>
<li>an X windows front end for a variation on the ROLF Wimp server which will make use of the work done on graphic card acceleration to display the frame buffer (while still remaining compatible with simple frame buffer implementations)</li>
</ul>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com1tag:blogger.com,1999:blog-33414002.post-25492027266044515742010-12-11T12:58:00.004+01:002010-12-12T18:50:42.329+01:00Stalled for months!<div style="text-align: left;">[Updated below; some progress!]<br />
[Updated again, lots more progress!] <br />
<br />
I've been struggling with the RPC emulator over the last few weeks.<br />
<br />
The main problem is accessing a hard disc image. Initially, I intercepted the calls from FileCore to ADFS in order to read (what I thought were) the appropriate areas of the disc image file, but what I returned wasn't accepted by FileCore. Then I tried another track; I integrated the files ide.c, fdc.c and superio.c from RPCEmu to provide the emulation of the fdc37c665 component. This is the result when using the hd4.hdf and cmos.ram from http://b-em.bbcmicro.com/arculator/hdboot.zip (the emulator now has a VNC based front-end that provides keyboard entry):<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEida70nO5iQEunFY-sOJZVSLjo41enSLewU5DdP5tLuDix0UECdin6QvnmpcEMVuPkSDmmwjFmviXfb6SNXMUvPCGOgZA49tjOM4DhhKUw0r7HM7KDoVNvsPar5K97fL1j9BdSD/s1600/Screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEida70nO5iQEunFY-sOJZVSLjo41enSLewU5DdP5tLuDix0UECdin6QvnmpcEMVuPkSDmmwjFmviXfb6SNXMUvPCGOgZA49tjOM4DhhKUw0r7HM7KDoVNvsPar5K97fL1j9BdSD/s320/Screenshot.png" width="320" /></a></div></div><br />
The output I get from the ide.c file (with the addition of the data read from the file) is as follows:<br />
<pre>IDE: First check - spt 63 hpc 16
IDE: Write IDE 000003F6 00 039C0A2C 02107CF4
IDE: Read IDE 000003F6 039C2028 00000000
IDE: Write IDE 000001F6 A0 039C1FEC 02107CF4
IDE: Read IDE 000003F6 039C1FF8 00000000
Callback IDE = 200
IDE: Read IDE 000003F6 039C1B88 00000200
IDE: Write IDE 000001F6 A0 039C1BA0 02107CF4
IDE: Read IDE 000003F6 039C1BB4 00000200
IDE: Write IDE 000001F1 00 039C1BD0 02107CF4
IDE: Write IDE 000001F2 01 039C1BD8 02107CF4
IDE: Write IDE 000001F3 07 039C1BE0 02107CF4
IDE: Write IDE 000001F4 00 039C1BE8 02107CF4
IDE: Write IDE 000001F5 00 039C1BF0 02107CF4
IDE: Write IDE 000001F6 A0 039C1BF8 02107CF4
IDE: Write IDE 000001F7 20 039C1BFC 02107CF4
IDE: New IDE command - 20 0 0 039C1BFC
IDE: Read 1 sectors from sector 7 cylinder 0 head 0
IDE: Read 0 0 7 00000E00
IDE: Read sector callback 7 0 0 offset 00000E00 0 left 1
IDE: Read data: 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 01 00 80 13 03 ................
IDE: Read data: 09 3f 10 00 0d 09 00 00 01 1a 68 00 35 02 00 00 .?........h.5...
IDE: Read data: 00 60 1b 03 00 00 00 00 00 00 00 00 00 00 00 00 .`..............
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
IDE: Read data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5f ..............._
IDE: Read IDE 000001F7 039C17B8 00000002
IDE: Over! packlen 0 512
IDE: Read IDE 000003F6 039C1B88 00000002
IDE: Write IDE 000001F6 AF 039C1BA0 02107CF4
IDE: Read IDE 000003F6 039C1BB4 00000002
IDE: Write IDE 000001F1 00 039C1BD0 02107CF4
IDE: Write IDE 000001F2 3F 039C1BD8 02107CF4
IDE: Write IDE 000001F3 07 039C1BE0 02107CF4
IDE: Write IDE 000001F4 00 039C1BE8 02107CF4
IDE: Write IDE 000001F5 00 039C1BF0 02107CF4
IDE: Write IDE 000001F6 AF 039C1BF8 02107CF4
IDE: Write IDE 000001F7 91 039C1BFC 02107CF4
IDE: New IDE command - 91 0 0 039C1BFC
IDE: Read IDE 000001F7 039C1F84 00000002
c2107f08 00000041 00000006 01c07a90 000001f4 021086ac Callback IDE = 200
IDE: -1338894612 sectors per track, -1338894596 heads per cylinder
IDE: Read IDE 000003F6 039C1B88 00000002
IDE: Write IDE 000001F6 AF 039C1BA0 02107CF4
IDE: Read IDE 000003F6 039C1BB4 00000002
IDE: Write IDE 000001F1 00 039C1BD0 02107CF4
IDE: Write IDE 000001F2 3F 039C1BD8 02107CF4
IDE: Write IDE 000001F3 07 039C1BE0 02107CF4
IDE: Write IDE 000001F4 00 039C1BE8 02107CF4
IDE: Write IDE 000001F5 00 039C1BF0 02107CF4
IDE: Write IDE 000001F6 AF 039C1BF8 02107CF4
IDE: Write IDE 000001F7 91 039C1BFC 02107CF4
IDE: New IDE command - 91 0 0 039C1BFC
IDE: Read IDE 000001F7 039C1F84 00000002
Callback IDE = 200
IDE: -1338894612 sectors per track, -1338894596 heads per cylinder
</pre><br />
Some differences in my use of the RPCEmu code are:<br />
<br />
<ol><li>callbackide is called on the next tick event, ignoring the value of (non-zero) idecallback.</li>
<li>No DMA implemented </li>
</ol>Any bright ideas?<br />
<br />
Update:<br />
<br />
Thanks to Tom Walker pointing out (on <a href="http://www.stardot.org.uk/forums/viewtopic.php?f=30&t=3521">stardot</a>) that the error reported by RISC OS is a floppy disc error, not a hard disc one, I noticed that I wasn't making callbacks required by the fdc.c floppy disc emulation. Now, I have a nice new error to worry about!<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgomW8I-NWTdpKb1-Cz-YyvH_3HjRCUifKI5N46QlTra4jxKXlHQ000LJP1RvjDidqqRm18TdOvDGVWTyLJs29tkp2Zc1S0S3pugacK7AlXCKq-ctqxAuRyq2gkntnyPs1eA5yU/s1600/Screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgomW8I-NWTdpKb1-Cz-YyvH_3HjRCUifKI5N46QlTra4jxKXlHQ000LJP1RvjDidqqRm18TdOvDGVWTyLJs29tkp2Zc1S0S3pugacK7AlXCKq-ctqxAuRyq2gkntnyPs1eA5yU/s1600/Screenshot.png" /></a></div><br />
Update 2: Not so much to worry about, after all. That one turns out to be because my emulation of post-increment LDR wasn't storing the calculated base+offset value into the base register. That's the first bug I've found in the basic emulate-ARM-instructions part of the emulator for a long time, but at least it's just a two line fix.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-4132896192064568312010-10-15T22:01:00.000+02:002010-10-15T22:02:51.162+02:00Emulator progress on RO 4.02<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghGAhNwIul9qc1JlgMLaSfkrs9OWLDB0hY5E00ScPdxV38069677k-I-LGNo8wTgz58xsO47E8q7N_sy4NUPAk4DwTFStpUm6pQO7Ip2d_T1yZ6ROEA-zsPPKYE3ifQE2vUot7/s1600/Screenshot_15.10.2010.png"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghGAhNwIul9qc1JlgMLaSfkrs9OWLDB0hY5E00ScPdxV38069677k-I-LGNo8wTgz58xsO47E8q7N_sy4NUPAk4DwTFStpUm6pQO7Ip2d_T1yZ6ROEA-zsPPKYE3ifQE2vUot7/s320/Screenshot_15.10.2010.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528365678896899138" /></a>Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0tag:blogger.com,1999:blog-33414002.post-92080405459925232002010-09-28T18:40:00.006+02:002010-10-10T18:01:44.165+02:00Using the ROLF Emulator to run RISC OSUpdated below.<br /><br />I've been working on getting RISC OS 4.02 running using the ARM emulator from ROLF.<br /><br />This was initially prompted by a near death experience of my Risc PC, and also a desire to see how well it would do.<br /><br />Also, many years ago, I suggested an approach to getting RO available on (then-current and 26-bit mode supporting) ARM based computers.<br /><br />It was quite simple:<br />1. Identify what the OS absolutely needed from the hardware to be able to run (I guessed memory, one or two timers and some form of static memory, as provided by the CMOS RAM in the RPC)<br /><br />2. Get the hardware manufacturers to provide some startup code to get that hardware running and enter the OS with information about where the RAM/ROM is and a set of pointers to routines to provide each of the required functions.<br /><br />3. At a certain point in the boot process, the hardware manufacturers could start modules to handle other aspects of their computer.<br /><br />It looks, so far, like that approach would have worked. (And, of course, getting the hardware manufacturers to work on the low level aspects would have had the advantage of hugely increasing the number of engineers working on getting the OS to market, at no cost to ROL.)<br /><br />The speed of running the ArtWorks Renderer module on some complex images under the emulator show a speed of approximately 3-4 times that of a 200MHz StrongARM Risc PC. (i.e. celtic_knot3 renders in about 14s, as opposed to nearly a minute on the RPC). There's still some considerable scope for improvements in the code generated by the emulator.<br /><br />As far as I can tell from reading about RPCEmu (I've had difficulties installing it, and not yet suceeded), the speed compares quite well.<br /><br />The main difference, I think, is that ROLF uses the Linux process' memory to provide the emulated RISC OS task with no address translation required. With a single RISC OS Task (process) that is very easy, since memory doesn't have to be switched in and out, as is the case with the whole OS.<br /><br />The approach I've taken is to use some special link parameters to keep the Linux process's memory in an area of the memory map which RISC OS doesn't use. Then, a set of files for ROM, RAM and VRAM are mapped in and out of memory as required by the OS using mmap (this is the part that could turn out to be horrendously slow).<br /><br />Also, I've avoided emulating hardware outside the processor (so it's not really a RiscPC emulator) and chosen to patch some sections of RISC OS with native code. This is an ugly approach, but it has the advantage of being quick and easy as well as identifying those essential hardware elements I was talking about. Longer term it should be possible to integrate RPCEmu's hardware emulation routines (both products are GPL licenced).<br /><br />Update:<br />It seems I've found a problem with Linux. The emulator, when it's producing a lot of debug output, tends to hang in a futex system call. This happens with the shared C library, the static equivalent that came with Knoppix and a specially compiled static glibc-2.5.1. Kernel 2.6.32.6.<br /><br />The other problem is with RISC OS; the routine TranslateMonitorLeadType (which I will be replacing with native code, but that's not the point) makes an XOS_ServiceCall, which causes a jump to zero. I'll look into that before I try to work out the Linux Kernel.<br /><br />Update 2: It seems the ROM files were corrupted somehow.<br /><br />Update 3: Yes, there really is a problem with Linux. The following program will hang, sooner or later, on my system. It's easiest to see if you pipe the output into "grep -n Tick". It is probably related to <a href="http://lwn.net/Articles/124747/">this</a>.<br /><br /><pre><br />#include <signal.h><br />#include <stdio.h><br />#include <time.h><br />#include <sys/types.h><br />#include <sys/stat.h><br />#include <sys/time.h><br /><br />#include <stdint.h><br /><br />static void alrm_action( int code, siginfo_t *info, void *p )<br />{<br /> fprintf( stderr, "Tick" );<br />}<br /><br />int main()<br />{<br /> struct sigaction action = { .sa_sigaction = alrm_action, .sa_flags = SA_SIGINFO };<br /> sigaction( SIGALRM, &action, 0 );<br /><br /> int microseconds = 10000; // 1cs<br /><br /> struct itimerval timer_val = { <br /> .it_interval = { .tv_sec = microseconds / 1000000, .tv_usec = microseconds % 1000000 },<br /> .it_value = { .tv_sec = microseconds / 1000000, .tv_usec = microseconds % 1000000 },<br /> };<br /> struct itimerval old_val;<br /><br /> setitimer( ITIMER_REAL, &timer_val, &old_val );<br /><br /> int x = 0;<br /> while (1) {<br /> fprintf( stderr, "+" );<br /> if (x-- == 0)<br /> {<br /> fprintf( stderr, "\n" );<br /> x = 100;<br /> }<br /> }<br /><br /> return 0;<br />}<br /></pre><br /><br />Update 3: It's not a problem with Linux, fortunately. <a href="http://www.opengroup.orghttp://www.blogger.com/img/blank.gif/onlinepubs/000095399/functions/xsh_chap02_04.html#tag_02_04_03">This</a> document lists 118 functions "that shall be either reentrant or non-interruptible by signals and shall be async-signal-safe"; printf variations are <span style="font-weight:bold;">not</span> included.Simonhttp://www.blogger.com/profile/11289534660572407264noreply@blogger.com0