Drivers (and message passing)

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Drivers (and message passing)

Post by lukem95 »

I'v got to the point where i have a multitasking, application loading OS.

i know want to write some drivers, and load them as user programs. my problem however is how to call functions from the drivers. Getting the data back to the kernel is easy enough, as i can just create a syscall to do so, but how would i do it the other way around?

i'm sure there is a standard way/ways to do this, but i cant seem to think of anything that will work short of a shared memory location, and a spinning loop checking for a bit to be set in the driver, which soudns like a waste of resources.

It may be the only way to go however. Does anybody have any tips or ideas?

lukem95
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

Modules are one solution, although if one goes bad, then the whole kernel can lock up.

You could just run the drivers in Ring0.

My kernel uses modules, and I will make a fail-safe loader system that times out or something.
-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
Telgin
Member
Member
Posts: 72
Joined: Thu Dec 20, 2007 1:45 pm

Post by Telgin »

Um, I think the general method for calling functions in a driver is just to "export" the function addresses from the driver then call them from within the kernel at the address exported. Since you have application loading done though, I'd somewhat assume that you know how to do things like look up the program's entry point and call it.

If that's not what you meant then, did you mean how do you keep the driver running as a program and allow the kernel to call specific functions within the driver to allow it to do stuff?
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

Code: Select all

If that's not what you meant then, did you mean how do you keep the driver running as a program and allow the kernel to call specific functions within the driver to allow it to do stuff?

yeah i mean that... i guess i could have a seperate file for every function, but thats not very resource saving.
~ Lukem95 [ Cake ]
Release: 0.08b
Image
kscguru
Member
Member
Posts: 27
Joined: Sat Jan 19, 2008 12:29 pm

Post by kscguru »

Can you just reverse the problem? Instead of thinking about calling from the kernel into the driver, think about returning to the driver from some previous syscall (e.g. some syscall made at driver load).

Driver loads, has a thread ... that thread does initialization, then makes a magic syscall that blocks in the kernel. Any time another thread wants to call into the driver, it swaps with the driver thread (so the other thread blocks, and the driver thread returns). Driver thread does work, then makes the magic syscall again, which results in another swap (other thread unblocks, driver thread blocks). Put a little parameter-passing in the swap routine, and you have a function call mechanism.

This is roughly how Solaris Doors works, by the way; Solaris is slightly more elaborate in that it creates thread pools on-the-fly so multithreading performance is better. Solaris uses it as an IPC mechanism, but nothing stops you from using it for drivers.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Perhaps this?

All drivers go into the kernel address space in their own respective locations, then they are dynamically linked so that you can run code in them even without knowing their initial location, and then call some init function which sets the driver up and all of the relevant functions with your driver interface.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

Drivers could go into a linked list with the header of each driver containg pointers to its internal routines. That apples to resident drivers, and then installable drivers could then be tagged onto the list. If it wanted to to the kernel could go down the list just once, buiding a table of pointers. If the driver needs to attract the kernel's part way through processing a request it could use a software interrupt with an identifier loaded into one of the registers, and another interrupt to signal completion (so that the process blocked whilst waiting for the driver can be unblocked).
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

A driver in userspace is basically a shared library. The main difference is that its list of exported symbols must have standardized names. The driver has to register itself with the device manager as being the "method" associated with a particular device. The device manager loads the driver, accesses its symbol table for the standard symbols, (calls the driver's init function), and stores those entrypoints in its table. When an app makes a request aimed at a device, the device manager either connects the app directly to the device driver, or acts as a middleman on all calls.

So the main question is: how are you planning on implementing dynamic libraries?
User avatar
AndrewAPrice
Member
Member
Posts: 2300
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

How about IPC?

e.g.

Code: Select all

DeviceRequest request;
bool running = true;

while(running)
{
   ReceiveDeviceRequest(&request);
   switch(request.Type)
   {
   case DR_OPEN:
      break;
   case DR_CLOSE:
      break;
   case DR_READ:
      break;
   case DR_WRITE:
      break;
   case DR_SEEK:
      break;
   case DR_IOCTL:
      break;
   case DR_KILL:
      running = false;
      break;
   }
}
The kernel stores a list of DeviceRequest's as they are sent, and ReceiveDriverRequest receives the next request on the list. And there you go - a basic driver template :D
My OS is Perception.
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

Thanks for your replies, i will consider this some more and post my POA :)
~ Lukem95 [ Cake ]
Release: 0.08b
Image
Post Reply