Module calls...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
DarylD

Module calls...

Post by DarylD »

I am in the process (actually nearly finished) of restructuring my code to resolve some issues, one of which was the excessive use of structs to pass values from my API library to the kernel. Essentially what I was doing was having an API call like:

int FS_Read(handle, bytes needed)

The above is not actual code but you get the idea. Now what happens next is the FS_Read functions will pack all this into a struct that could be called fsread_t and then this is dropped on the stack and an int 0xXX made where the kernel will then pick up this struct and extract the contents again.

Its fairly standard behaviour but I wan't to do things a little different.

I will have some code in the API (user space) that will create a package of parameters. This will be reused for ALL calls that need to pass data to the kernel. The kernel will then call the necessary function and unpackage all the data.

But, for the example above the kernel FSRead call may take several parameters. What I want to know is, how can I extract contents from this "parameter package" and then pass it directly to the kernel function as separate parameters.

Obviously the issue here is different functions take different parameters.

I assume I need to do something using va_args, but this is not an area I have delved into very much.

Any help would be *muchly* appreciated.

Daryl.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Module calls...

Post by Pype.Clicker »

can you explain more precisely what you mean with the 'package' ?
and also how you envision its reuse ?
DarylD

Re:Module calls...

Post by DarylD »

I am probably making this sound more complex than it is!

Basically, in the API function, I would have something like this:

Code: Select all

pack_t sPackage;
AddParameter(&sPackage, PARAMETER_INT, 100);
AddParameter(&sPackage, PARAMETER_INT, 50);
AddParameter(&sPackage, PARAMETER_STRING, &string);
Module_Call(moduleid, callid, &sPackage);
pack_t would be something like a fixed structure holding up to say 16 parameters and their type. It would be passed with the Module_Call function.

Inside the kernel it would check that the package parameters match what is specified when the module call was created. This is not necessary but would at least pick up errors in the API library.

The kernel would then call the necessary function (i.e. maybe a function set as an I/O mount call) and would pass the parameters to it. So for example if the prototype for IORead was:

Code: Select all

KStatus IORead(int num1, int num2, char *string);
I would need a way of mapping the package parameters into the call parameters for IORead.

Does that makes sense?

Its just a simple way of handling variant parameters to different modules without creating a million and one struct's.

Daryl.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Module calls...

Post by distantvoices »

you could implement messaging.

system calls will be transferred to messages passed to the responsible subsystem(fs,mm,etc). The kernel should this message passing.

the IO subsystem is responsible for all the nitty gritty, neither the kernel nor the user that issues the api call needs to know about, so it knows about what to do with a message passed to it.

if its an absolute weird and impossible idea,let me know this. *g* so i can go another way in the design of my own kernel &mm&fs conglommerate.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
DarylD

Re:Module calls...

Post by DarylD »

No, I thought about messaging, but I wanted something a little lighter in weight. I have a message passing system in place which I could add parameters to in about an hour of coding, but I am worried about performance. I would have to have lots of string checking to see if a parameter is called "InputA" for example.

Daryl.
Lantz

Re:Module calls...

Post by Lantz »

One way would be to start every package with an int or something that specifies whats in the package so the kernel can do some typecasting and stuff to handle it.

Perhaps something like this:

Code: Select all

void kernel_cmd( void* package )
{
    int pkgtype = *( (int*)package );
    switch( pkgtype )
    {
        case PKGTYPE_OPENFILE:
                fs_openfile( (OPENFILE_PKG*)package );
                break;
        case PKGTYPE_WRITEFILE:
                fs_writefile( (WRITEFILE_PKG*)package );
                break;
    }
}
DarylD

Re:Module calls...

Post by DarylD »

That is essentially what I had before, but I found I had to declare tons of structs everywhere.

What I want is a system without that. I reckon I pretty much have it sorted out now.

Daryl.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Module calls...

Post by Pype.Clicker »

DarylD wrote: No, I thought about messaging, but I wanted something a little lighter in weight. I have a message passing system in place which I could add parameters to in about an hour of coding, but I am worried about performance. I would have to have lots of string checking to see if a parameter is called "InputA" for example.
Performing string-checking at run time everytime the service call is done will indeed be a nuisance, imho. Maybe one for the service name or something alike, but one per argument will for sure be unaffordable.

What you could do is resolve those strings at load-time: when your program is loaded, it will invoke the Service Resolver and translate every argument string ("InputA") into a flat unique number (within the numbering space of "MyArgumentsPackage").

Code: Select all

class PutPixelPackage extends Package {
      static const PackageModel model=PackageModel.lookup("gfx.putpixel");
      static const int X=model.getID("x");
      static const int Y=model.getID("y");
      static const int COLOR=model.getID("color");
   }
  
    PutPixelPackage(int x, int y, Color color) {
        new Package(model.ID);
        addArgument(X,INTEGER,x);
        addArgument(Y,INTEGER,y);
        addArgument(COLOR,COLOR_T,color);
    }
}
Now, i must reckon that it only replace a "tons of structures" problem by a "tons of initializ0rs" problem (to fill all those static const integers holding parameters indexes).
But this can be easily done by a smart loader that will recognize the 'long mangled name' __$package$_gfx$putpixel$x as a request to fill in the putpixel.
now just do

Code: Select all

extern void* _X asm("__$package$_gfx$putpixel$x");
#define X (int)_X
and you'll be done with your strings.


BTW, i think that you will not love writing "tons of addArguments" at each function call. Maybe the only way to solve the problem out is to use an intermediate Interface Description Language that will be used to generate all the stubs and structures automagically...
DarylD

Re:Module calls...

Post by DarylD »

I have decided to go with my addParameter system for passing parameters. It will only be done in the API library so it will not be too annoying to code with. The user app will just call FSOpen(...) or something similar, the code for FSOpen will do all the addParameter gubbins.

I have also decided to go with run-time linking of module id's and module call id's as you suggested Pype, should speed things up a little and keep things clean and simple.

Incidentally, I have finished the rewrite of my code, most of it has stayed the same but I changed naming anc calling conventions. For example my I/O system now uses pointers to functions for open/mount etc. rather than going through a module call interface. Should help speed things up a bit in the future.

Daryl.
Therx

Re:Module calls...

Post by Therx »

Rather than using interupts I think you should use direct pointers as they are much quicker

eg.

Code: Select all

typedef int (*ptr_t)(int callid, some_t parameters);

ptr_t modulecall;

modulecall = (ptr_t) 0x90000;  //Address of sys call function

modulecall(10, paras);
I don't know any further details as I'm not that far in my OS but this is what I plan to use
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Module calls...

Post by Pype.Clicker »

there's a drawback with constant pointers address which is ... that they are constant. So the component that implements FSopen will "have" to be at 0x9000. Interrupts are a first step to get rid of this constraint, but still they force all components to agree that FSOpen is accessed through interrupt 21h, service 3Fh ...

With a quickly developing system, and if you want to avoid the Unix "ioctl" problem of having 90% of your system calls going through a too generic and meaningless interface, i suggest that service addressing should be resolved at load-time rather than compile-time.

This way you can easily set up new services: the service provider will add symbolic informations into the system so that its client can locate and invoke it .
Post Reply