Hi,
Dragon_Hilord wrote:Not to mention, to be compatable with my kernel, you need security extensions and such.
This is a good idea - if we all post our OSs requirements for device drivers, then maybe people will realize how impossible a "uniform driver interface" actually is.
The following are the requirements for my OS...
To be suitable for my OS it'd need to do as much as possible asynchroniously, be confined to it's own address space (messaging and bounce buffers used for transferring large amounts of data, rather than using DMA directly into the callers address space) and must not use any form of dynamic linking (flat binary only).
When a device driver is started it's told which I/O ports, etc it may use (they are pre-detected), and the first I/O port is always I/O port 0x0000. For example, a serial port driver would be told to use I/O ports from 0x0000 to 0x0007, so that these I/O ports can be hard-coded regardless of whether the actual device uses a base I/O port of 0x02E8, 0x02F8, 0x03E8, 0x03F8 or something else. When a device driver tries to access an I/O port it actually causes a general protection fault, and the kernel's GPF handler works out if access is allowed, adds the base I/O port, performs the I/O port operation and then returns.
I expect I/O ports to be cached where possible. For example, for a serial port driver the baud rate divisor, interrupt enable register, LCR and MCR always contain the value that was written to them last, so these values can be cached in memory and read from memory instead of reading from the I/O ports. This is for performance only (I/O port access is very slow, even without the GPF stuff on top).
Any memory used by any form of DMA or bus mastering must be allocated using special kernel functions, and normal RAM pages must never be used. This allows the kernel to terminate the device driver at any point without the device driver's prior knowledge. For example, if the device driver crashes in the middle of a DMA transfer, the kernel will put these DMA pages into a "cooling off" area so that they aren't re-used while the hardware is still transferring data into them.
All devices are classified into types, where each type of device has a specific interface to the OS. All interfaces are implemented on top of asynchronious messaging. These interfaces include the storage device interface (disks, scanners, printers), the communications device interface (network cards, serial ports, parallel ports), the keyboard interface, the pointing device interface (mouse, joystick, touch screen), the sound interface and the video interface. There will be a specification for each interface that must be followed.
All device drivers must be able to completely initialize their device from any state. This initialization must not include any ROM code (for e.g. a video driver must not rely on the video card's ROM to pre-initialize the card).
All device drivers must support a "pass through" mode, which allows the raw device to be assigned to a "hyper-visor". This pass through mode includes the ability to return status information (text strings) back to the hyper-visor for debugging purposes, including full details of the entire device's state, and a short note on every operation.
Device drivers for some devices must maintain their own internal "operations queue", which is sorted according to the priority given to the operation by the caller. For example, imagine a hard disk driver with one partition being used for swap space and another partition being used to store files. Now consider what happens when the user asks to save a very large file, but just after this the swap space manager asks to transfer a page of data to/from swap space. In this case I'd want the swap space operation to be have a higher priority and be completed as soon as possible (with lower priority operations being delayed).
Device drivers may be written in any language, as long as the binary format used can be generated and as long as that language supports the kernel API. For example, it's not too hard to get LD/GCC to generate the binary header, etc but you may need to rewrite library functions before you can use it to write device drivers, etc properly. My OS is not POSIX compliant in any way (and never will be with any luck).
Cheers,
Brendan