Image filing system in C
Matthew Phillips (473) 721 posts |
I am trying to implement an image filing system in C. During module initialisation an image filing system registers with FileSwitch via OS_FSControl 35 (PRM 2-116) and passes in R2 the offset to the image filing system information block. Most of the words in the block are offsets to the various image filing system entry points for FileSwitch to call. My printed Acorn C/C++ manual states on p. 291 that you should declare the routines to CMHG as irq-handlers:
The documentation for CMunge (supplied with GCC) and the ChangeLogs.CMHG file supplied with Norcroft both suggest vector-handlers should be used instead of irq-handlers these days. But I cannot find any clear information as to what you are supposed to return from the C handler function. The prototype of the handler function is: The help in the Acorn C/C++ manual p. 291 says you should return 0 if you handled the interrupt and non-zero if you did not. It explains you can updated r0 to r9 through the _kernel_swi_regs structure. That’s all very well for an interrupt handler, but what about an image filing system entry point? For image filing system calls it needs to be possible for R0 to point to an error block and for the V flag to be set. I have no idea how you are supposed to set the V flag given _kernel_swi_regs only coves R0 to R9. Also, I am not sure what you are supposed to return if there is no error. I got as far as registering skeletal handlers for all the image filing system entry points, and when double-clicking my image file, ImageEntry_Func 21 (PRM 2-567) is called to notify me of the new image. But returning 0 from the handler causes the Filer to throw an error, and my image filing system entry points do not get any further calls, so something must be wrong. This is all remarkably badly documented. Perhaps I will have to resort to disassembling the object code that CMHG generates for the veneers to see how it works! I have tried looking at the source code to Fat32FS but that uses its own veneer functions. Is that because the vector-handler veneers from CMHG do not, actually, do the job despite the documentation saying they are appropriate? Are there any other image filing systems written in C with CMHG that might be a good guide? |
Matthew Phillips (473) 721 posts |
Just thought to look at SparkFS, which includes its own way of forming veneers for the image filing system entry points. Can anyone confirm if this is how you have to do it, i.e. that CMHG is of no actual help here? |
Chris Mahoney (1684) 2165 posts |
Mine (Issue 4, April 2015), says on page 351:
It goes on to say:
The specifics of an image filing system are beyond me! |
Charles Ferguson (8243) 427 posts |
If you generate the example CMHG file with ; Vector veneers are used to provide a simple C environment for SVC and IRQ ; modes. You should register the Entry routine as the external interface (ie ; provide it as the code address to call). The Handler routine will be ; called from this. You can return 0 or 1 from your routine to say you ; either handled the vector, or did not. Parameters for the veneer may be ; specified in brackets in the same form as command keywords : ; ({<field>: <value>}) ; Field names: ; error-capable: Veneer is capable of claiming the vector and returning an ; error vector-handlers: Vector_Entry/Vector_Handler If you specify the vector handler with error-capable, eg: vector-handlers: Vector_Entry(error-capable:)/Vector_Handler … this allows the vector handler to return errors. The C header file generated describes this (generate with /*************************************************************************** * Function: Vector_Handler * Description: Vector handler function * Parameters: r = pointer to register block on entry * pw = private word for module * On exit: Update r to alter return values * Return VECTOR_PASS to claim (return via stack) * Return VECTOR_CLAIM to pass on (return via r14) **************************************************************************/ int Vector_Handler(_kernel_swi_regs *r, void *pw); /* VECTOR_PASSON can be returned from vectors to pass the call on to other * handlers. */ #define VECTOR_PASSON (1) /* VECTOR_CLAIM can be returned from vectors to claim the vector and return * with the updated register block. */ #define VECTOR_CLAIM (0) /* VECTOR_ERROR(err) can be returned from routines which have been marked as * capable of having an error returned as well as claiming the call. All * other registers are preserved if the error pointer is not NULL. */ #define VECTOR_ERROR(err) ((int)(err)) CMHG does not have this functionality; it was added to CMunge (IIRC) explicitly for the case of filing system vectors. |
Rick Murray (539) 13840 posts |
There’s an argument to be made for having some of the lesser parts of the DDE opened up, so things like this could be fixed. I mean, seriously, wouldn’t making a vector handler cater for returning an error be just a handful of extra instructions? |
Stuart Swales (8827) 1357 posts |
Er, isn’t this what generic-veneers was added for? For a concrete example of use with FS entry points, see CRAMFS: https://www.riscosopen.org/forum/forums/3/topics/17019 |
Charles Ferguson (8243) 427 posts |
Stuart wrote:
generic-veneers are for direct veneers, such as callbacks, entry points for CDFS, etc, colourtrans transfer functions, etc. vector-handlers are for veneers to vectors specifically. They’re different because they can include a claim of the vector, where they pull the R14 from the stack to prevent passing it on to other claimants. However, vector-handlers never had the ability in CMHG to return errors. This is a requirement for the filesystem vectors, in order to report errors to the client. So the vector-handlers, were updated in CMunge to be able to allow for this.
RAMFS isn’t using the FS entry points, though – it is a FileCore module, not a FileSystem module. It uses the FileCore registration interfaces which aren’t vectors – that code would use generic-veneers for those operations, I presume, as it doesn’t have the option to ‘claim’ the FileCore interface. |
Stuart Swales (8827) 1357 posts |
Acorn C/C++: “Generic veneers are general-purpose entry points that can be used for things like callback handlers registered with OS_AddCallBack and filing system entry points. They work in the same way as vector handlers, except they either return preserving processor flags, or set V to return an error.” I can’t remember when they were added in CMHG, possibly quite late. |
Charles Ferguson (8243) 427 posts |
It might say that but I believe that it’s not correct (or at least wasn’t correct in versions of CMHG that I have access to). Generic veneers return via r14 if you return 0. They return via r14 with VS if you return non-0. With the CMunge error-capable flag set, the Vector veneers return via the stack if you return a non-0, non-1 value, with VS. It’s possible that CMHG was updated in later years, but I’m going by 5.42 and earlier. HOWEVER, I’ve just realised that I’m mistaken and that’s what you were pointing out… the entry points for the ImageFS aren’t vectors, so what I’ve been talking about doesn’t help. Yes, the filesystem registered entry points should be using generic-veneers, and thus returning errors. What I was talking about was the Filing system vectors, which you might want to return errors from or claim, or pass on. So what Matthew was asking about is actually that he should be using generic-veneers for those entry points, not vector-handlers. Because they’re not vectors. Apologies for my misunderstanding… the point about vector-handlers being capable of returning errors in CMunge is true – just not relevant. |
Matthew Phillips (473) 721 posts |
Thank you both for the help. I clearly need to get an updated Acorn C/C++ manual! Stuart, when you quoted from the manual which version was it? Is it a later printing, or an electronic version. My last electronic copy was on the RISC OS PRM CD which RISC OS Ltd produced sometime before RISC OS Select. The pointer to CRAMFS is going to be very useful. We have a train trip today, so we might try getting a bit further, using RPCEmu. |
Sprow (202) 1158 posts |
Are you sure about that Matthew? In May 2021 you quoted from the electronic copy in DDE30a, so all you need to do is locate and open that same copy (hint: it’s in Documents.Manuals.C_C++/pdf). The latest is Issue 6 from July 2021 which at a guess would have coincided with the updates to add C18 language support, but that’s not relevant to CMHG discussed here. |
Stuart Swales (8827) 1357 posts |
I was quoting from C/C++ Issue 6 PDF; generic-veneers were certainly documented back in C/C++ Issue 3 (first ROOL one) but NOT in Issue 2 (Castle). |
David Pilling (8394) 96 posts |
The SparkFS code mentioned above. There was an Acorn example of how to write a filing system in C, which I followed for SparkFS – this was on RISC OS 2, so before image file systems. When image file systems came out I generalised the veneer code to them. I have dim recollection that later I thought cmhg could be used, but since what I had worked I did not pursue that idea. |
Matthew Phillips (473) 721 posts |
Thanks Sprow! I need to get my computer better organised as my brain is clearly not up to it. We had fun on the train and the image filing system compiles and shows a single file in a directory, which you then can’t do anything with. No further progress this week, but it’s not my project. Thanks for the history, David. I had a feeling SparkFS predated image filing systems, but that was in my non-RISC OS period (1990 to 1998). |