How to represent device drivers
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am
How to represent device drivers
Hi to all,
What is the best way to represent a device driver as a data structure in an operating system kernel?Informations on how to load the drivers are of no relevance here.
What is the best way to represent a device driver as a data structure in an operating system kernel?Informations on how to load the drivers are of no relevance here.
Hi,
It really depends on the design of the rest of your kernel. I represent a driver as a class, which is self-contained and loads binary information from the driver module.
If you were more in to the C way of doing things, you may just like to define a struct (or a typedef'd struct) containing all interface calls you need. Have a look at James Molloy's Tutorials, specifically the VFS one. Drivers can integrate with your OS in much the same way as James implements Files and the File System, if you so wish.
Cheers,
Adam
It really depends on the design of the rest of your kernel. I represent a driver as a class, which is self-contained and loads binary information from the driver module.
If you were more in to the C way of doing things, you may just like to define a struct (or a typedef'd struct) containing all interface calls you need. Have a look at James Molloy's Tutorials, specifically the VFS one. Drivers can integrate with your OS in much the same way as James implements Files and the File System, if you so wish.
Cheers,
Adam
The design of the system has a LOT to do with it, however in my 'monolithic type' kernel, all my drivers have a simple structure, it contains a few things, like type (i have basic types defined), sub type (like, disk i/o driver would be the type, then cd, floppy, hard disk, etc are sub-types). Sub-types can be 'unknown', because just knowing it's a block device is enough to use it. All drivers have a function named Init, with the structure named DriverInfo, since my files are relocateable, and have symbolic information in them, the kernel first finds the valid DriverInfo structure, reads the type and sub-type (also has version for later uses), then if found, it searches for init, if that is found, it calls Init so the driver can initialize what it needs (like searching for devices and registering them with my block device handler). Each device type will have a standard set of functions that it must adhear to. Although, currently the only function used is Init, since my block device structure carries a function pointer for reading/writing blocks, and those function calls are standard for my block devices. Input devices don't need function calls either, as when a key is pressed, mouse moved, or joystick moved, it calls a kernel function to add the input to a buffer of inputs, which are fed to the current active task. So far I've had no need for any other function interfaces besides Init, but they may come up later depending, and by using a file with symbols it's very easy to see if the proper functions are available and if the vesion is correct. I don't know if it's the best way, as i'm a hobbyist OS dever, but so far it works good.
I started with a very simple driver design -- but I found that it was insufficient. Some of my recent thinking was on this thread:
http://www.osdev.org/phpBB2/viewtopic.php?t=16667
As I said there -- I perceive (now) that there is a definite need for "virtual drivers". Drivers that only talk to other drivers -- not to hardware. There are examples on that thread of pipelines of drivers all passing each other data. Examples I have in mind are things like hardware devices on USB buses. You need a driver for the USB bus, and a driver for the hardware device, too. How do they talk "through" each other? Simlarly for a printer driver. Are you going to hardcode separate versions of the same printer driver for all the possible hardware ports that the printer might be attached to? Or are you going to have ONE copy of a printer driver, that can communicate with the printer "through" a handful of different other drivers (LPT, COM, USB, Ethernet).
So, I have abstracted my concept of drivers into "services" instead -- where a service is a pipeline of drivers, with the same frontend interface as a driver.
Drivers typically export 3 function pointers: read, write, ioctl. One or more can be NULL. Drivers need to be passed a particular set of IO port numbers, memory mapped addresses, subsystem numbers, and perhaps other data. So all of that needs to get stuffed into a class/structure/data packet.
I separate my VFS system from my "services" -- because VFS needs a much larger number of standardized function pointers.
http://www.osdev.org/phpBB2/viewtopic.php?t=16667
As I said there -- I perceive (now) that there is a definite need for "virtual drivers". Drivers that only talk to other drivers -- not to hardware. There are examples on that thread of pipelines of drivers all passing each other data. Examples I have in mind are things like hardware devices on USB buses. You need a driver for the USB bus, and a driver for the hardware device, too. How do they talk "through" each other? Simlarly for a printer driver. Are you going to hardcode separate versions of the same printer driver for all the possible hardware ports that the printer might be attached to? Or are you going to have ONE copy of a printer driver, that can communicate with the printer "through" a handful of different other drivers (LPT, COM, USB, Ethernet).
So, I have abstracted my concept of drivers into "services" instead -- where a service is a pipeline of drivers, with the same frontend interface as a driver.
Drivers typically export 3 function pointers: read, write, ioctl. One or more can be NULL. Drivers need to be passed a particular set of IO port numbers, memory mapped addresses, subsystem numbers, and perhaps other data. So all of that needs to get stuffed into a class/structure/data packet.
I separate my VFS system from my "services" -- because VFS needs a much larger number of standardized function pointers.
I have looked at the same problem in a very different way. With my os, a USB driver exists for each USB host port. All my devices have a node in the VFS.
If I plug in a device to usb0, the driver for that device will lock the usb0 node (by opening it for r/w access and not releasing the handle) and that device driver (say printer0) will then r/w from the usb port via the usb0 FS node.
Individual file systems act in exactly the same way - the fat12 driver reads from the floppy disk via the fdd driver node. If one of the nodes is actually a RAM disk, it doesn't matter - the fat12 driver will just mount /rd0.
Don't quote me, but I guess this is similar to the way Linux does things (although I am not actually aiming directly for unix compatibility).
Cheers,
Adam
If I plug in a device to usb0, the driver for that device will lock the usb0 node (by opening it for r/w access and not releasing the handle) and that device driver (say printer0) will then r/w from the usb port via the usb0 FS node.
Individual file systems act in exactly the same way - the fat12 driver reads from the floppy disk via the fdd driver node. If one of the nodes is actually a RAM disk, it doesn't matter - the fat12 driver will just mount /rd0.
Don't quote me, but I guess this is similar to the way Linux does things (although I am not actually aiming directly for unix compatibility).
Cheers,
Adam
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am