OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 1:39 pm

All times are UTC - 6 hours




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 29 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Device drivers
PostPosted: Wed Apr 10, 2019 4:01 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Hi,

One of the recent threads on drivers made me thinking. It would be nice to have common, reusable driver set for hobby OSes, but so far all such attempts failed. I was thinking about why, and how could we avoid their mistakes. This is what I got this far:

- BSD, Linux etc.: OpenSource true, but they are tied to their kernels way too much
- CDI, UDI: they are way too complex trying to solve everything and their structure not ideal for a microkernel
- Minix: as it has a separated message queue interface, this is the best candidate so far, but not suitable for monolithic kernels
- FUSE: is a good working example on how such a source compatible interface can be done

So what if we wouldn't want to solve all the issues (like UDI) instead we focus on the smallest common denominator and aim for K.I.S.S.? Could it be viable and would there be enough interest in such a project?

What I have in mind, is to define a source compatible interface in each and every driver. The spec would not care about how to name or organise your device files (or if you have a /dev file system at all), it would not care how you call those functions (directly from the FS layer or from a message dispatcher), and it would not care about how you detect the devices, those would be up to the kernel entirely.

Instead what it would do, is to provide the following functions in every compatible driver:
- init: checks if the device really exists and sets up internal data structures. Called on boot or when the device is attached
- open: called with a device index when the corresponding device file opened (if there's no /dev then it's the kernel's responsibility to call this hook with the appropriate device index before any reads or writes)
- read: called with a device index and buffer address, size. The driver is supposed to read size bytes into the buffer from the device indexed by the argument.
- write: similar to read, but for writes
- ioctl: set up or query device characteristics. Same arguments as read/write, the command buffer would be device type specific. For queries, the response would be placed in the command buffer.
- seek: set position for the given device index if applicable. Character devices (like uart) would simply do nothing in this function
- irq: called with the device index when irq is fired
- reset: reset the device to it's defaults.
- close: called when the corresponding device file closed. Could be an empty function (if there's no /dev. then the kernel should call this with the appropriate device index when reads or writes are done)
- fini: called when the device is removed or when the system is shutting down

The header would provide ANSI C function prototypes for these functions, gathered together in a struct typedef with a C++ wrapper (and maybe a C++ class template if there's interest in that). The struct typedefs for the ioctl commands would be defined here too. I'm planning to have common structs here, so not like ath5k_setmtu_struct_t and such, but instead command with two 64 bit arguments, command with a buffer and 3 32 bit arguments etc. For example all serial drivers would be expected to use the same, single command struct for setting baud, data bits, parity, stop bits etc. This header would define the error codes too (negative return values, like device timed out, buffer not big enough etc.)

On a typical UNIX-like system, the device index would be the device minor number. Other kernels must face the fact that there can be more devices of the same kind, handled by the same driver, so they must index those somehow. This index would be passed to every function as a first argument, and there it would select the proper device context from the internal data.

The spec would expect a compliant kernel to provide "register_irq", "malloc" and "free", but those could be macros.

Integration in a monolithic kernel: the FS layer should call driver functions directly when needed. The provided malloc should be a macro and should allocate kernel heap memory.

Integration in a microkernel: there's a need to create a dispatcher main() function to receive a message and call one of these functions accordingly (there should be no common wrapper, like fuse_main() for example, because it's up to every kernel how it implements messaging). The malloc could be a standard libc malloc implementation.

We could call this spec OSDev Drivers, or ODD in short (because it's odd to specify only the smallest subset in each and every driver, but if you think about it, helps portability a lot).

Any thoughts? Would you be interested in such a minimalistic approach?
bzt


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Wed Apr 10, 2019 4:55 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
Do you consider the fact that a lot of folks have patchy understanding and handle of things like:
  • memory management, especially with page translation
  • exclusive/atomic accesses, race conditions, deadlocks
  • multi-processor system issues
  • interrupts
  • device specifics
  • format and protocol specifics
  • C
  • assembly
  • error handling
  • design (especially, well structured and testable)
  • debugging
  • testing
  • tools
Implementing the building blocks isn't easy. Putting a system together using those blocks isn't easy either (besides, it may be not enough fun for everyone). One needs to do that while really understanding what they're doing, how the components work and interact with one another, etc.

Or do you think those are non-issues? (If they weren't, well, everyone would have proper drivers and minimally functional OSes (and not just some crappy hello-world-like boot loaders) in a matter of months) What if they can't understand your code or satisfy its requirements because, well, they just aren't up to the task yet or they're doing something inherently incompatible with your code for one reason or another?

IOW, what's your idea as to why there is a problem and what it is? Are you sure you aren't trying to help with the wrong thing?


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Wed Apr 10, 2019 5:00 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
One question that comes to mind is how to handle synchronous / asynchronous drivers? In contrast to synchronous drivers that just return from the entry point, asynchronous drivers probably want to complete operations by invoking a callback. Would that be out of scope?

In addition to that, there needs to be some way to access hardware (e.g., to map MMIO regions from PCI BARs and/or legacy HW).

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Wed Apr 10, 2019 5:30 am 
Offline
Member
Member

Joined: Fri Jun 28, 2013 1:48 am
Posts: 62
For simple devices like pit and ps2 keyboard, I'd rather write my own driver. Since those devices are tightly coupled with the kernel, and they are very easy.

ODD spec is only good for big and complex devices, like graphics adaptor, network card, sound card, etc. That also means we have to define a set of kernel API, just like ACPICA does.

_________________
Reinventing the Wheel, code: https://github.com/songziming/wheel


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 3:27 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Hi,

Thanks for the answers! I think there's a misunderstanding on the goal of this project, I'll try to explain below.

alexfru wrote:
Do you consider the fact that a lot of folks have patchy understanding and handle of things like
No. I don't care what folks can't do. I'm interested in helping those who can. Developers with patchy understanding of those things wouldn't be able to write their OS, and no interface can help with that. They must learn and practice more, that's the only way. But beginners are not ODD's target audiance. It's aimed for advanced developers, who have implemented a lot already in their kernels, and now want to increase the number of supported devices.

alexfru wrote:
Implementing the building blocks isn't easy. Putting a system together using those blocks isn't easy either
No it is not. But easier than to get and read all hw specs and implement everything on your own. ODD does not provide ready-to-use building blocks btw, that's not the goal. It's just a recommendation on driver source interfaces. You definitely need to do some integration work in your kernel with that, but that's okay as ODD doesn't want to tell you how you should write your kernel or if you want async or sync calls or microkernel or monolithic kernel etc.

alexfru wrote:
One needs to do that while really understanding what they're doing, how the components work and interact with one another, etc.
That's why I'm aiming at a minimalistic approach. ODD does not care about the components nor how they interact, except for the lowest layer of the driver, but only at source compatibility level.

alexfru wrote:
What if they can't understand your code or satisfy its requirements because, well, they just aren't up to the task yet or they're doing something inherently incompatible with your code for one reason or another?
Then they won't be able to understand the hw specs and write their own drivers either. Simple as that. Again, ODD is not a complex code, just some definitions in a single C header. It's just an interface that encapsulates the lowest layer of the driver. By following it's recommendations and using it's typedefs, hobby OSes could exchange driver sources with minimal integration effort (but not with zero effort).

alexfru wrote:
IOW, what's your idea as to why there is a problem and what it is? Are you sure you aren't trying to help with the wrong thing?
Positive. I'm not trying to design a complex API, or binary compatible drivers or anything like that. I'm just suggesting a minimalistic source driver interface with some kernel hooks to make porting device drivers among hobby OSes easier.

Korona wrote:
One question that comes to mind is how to handle synchronous / asynchronous drivers?
Out of the scope. This spec is a lower layer than that. This only provides somewhat standardized way to read/write from a device, but it does not care when and how you call those. That's a higher abstraction level which I deliberatly don't want to address. The point is to create a simple interface for the drivers so that you can integrate them into your kernel more easily.

Korona wrote:
In addition to that, there needs to be some way to access hardware (e.g., to map MMIO regions from PCI BARs and/or legacy HW).
That's correct.

songziming wrote:
ODD spec is only good for big and complex devices, like graphics adaptor, network card, sound card, etc.
Exactly. Let's say you already have a networking stack but only one network card driver. With ODD, you can increase the number of supported network cards easily (but you have to have a networking stack, as ODD does not want to solve everything). Another example, you have implemented a GUI with shiny screen resolution chooser, but you have only one video card driver. With ODD, you can add more (but you have to have the GUI and screen resolution chooser as ODD does not provide those).

songziming wrote:
That also means we have to define a set of kernel API, just like ACPICA does.
Definitely not. ACPICA tries to solve all aspects and create fully functional driver ecosystem and therefore is very complex. ODD just tries to somewhat standardize driver interfaces to ease portability. Fundamentally different goals. But it is true that it requires some hooks from the kernel, but I definitely want to keep that as small as possible (4-5 functions tops).

I hope this makes it clear what ODD is and isn't. To sum it up, it's a C/C++ header file to provide a standardized driver API and interface to make porting drivers among hobby OSes easier. Nothing more, nothing less.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 3:41 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
bzt wrote:
I hope this makes it clear what ODD is and isn't. To sum it up, it's a C/C++ header file to provide a standardized driver API and interface to make porting drivers among hobby OSes easier. Nothing more, nothing less.


init, open, close, read, write, lseek, ioctl? :)


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 4:12 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
alexfru wrote:
init, open, close, read, write, lseek, ioctl? :)
Could be any other names. I've choosen those to help with understanding of their purpose. That's why I've also written a small description for each.

But if you like, could be: attach, startop, endop, getdata, senddata, setpos, command (and deattach instead of fini).

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 4:32 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
bzt wrote:
alexfru wrote:
init, open, close, read, write, lseek, ioctl? :)
Could be any other names.


My point is that you've pretty much chosen the old (I'm not saying necessarily/universally bad) paradigm of everything being a file with a small hole for extensions to it and exceptions from it (ioctl, AKA Pandora's box :) ). It's been around for a long time and has become a practical standard.

If the intended audience, as you say, is knowledgeable and experienced, couldn't they pull off something similar, write the same kind of familiar (UNIXish?) API?

Or is there an actual intent to supply the API with implementations? Are you gonna write them? If not, who? Whom and how are you going to convince to code their stuff to your API?


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 6:08 am 
Offline
Member
Member

Joined: Thu Jul 05, 2007 8:58 am
Posts: 223
As you currently suggest it, there are several problems with your proposed interface

First, the suggested interface really only works for a kernel implementation that "pulls" information out of its device drivers. For example, suppose you would have a network card driver adhering to this interface. Then you would need to have something (probably a thread) continously calling read and waiting for its results to inject packets into the rest of the network stack. This might be far from ideal for systems that are designed with the idea in mind that network card drivers "push" received packets up through the rest of the network stack. You claim this is out of scope, but this actually determines on the lowest level how a driver is structured.

Second, while the open/read/write/ioctl/seek/close interface works decent (although it definitely has its problems) for cramming direct device access through file systems, it is in my opinion a lot less suitable for an internal kernel device interface. The main issue is that for quite a number of devices, there will be a significant device-agnostic stack on top of it interacting with the device. For example, for a network interface, there is typically a complete tcp/ip stack handling the traffic of all the individual interfaces, which therefore would need to talk with individual network card drivers. To make this possible, you will need to specify a lot more specifically how a network card is to expose its functionality over this interface. Similar problems also come up with things like sound cards, serial ports, keyboards and displays.

Third, you are certainly going to need more than just "register_irq", "malloc" and "free" for the operating system interface. At a minimum, most drivers will need the ability to request access to: port ranges (port io), specific memory regions (memory mapped io). Beyond that, for things like dma, they will need some way to deal with physical adresses and physically contiguous buffers.


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 10:31 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Hi,

alexfru wrote:
My point is that you've pretty much chosen the old (I'm not saying necessarily/universally bad) paradigm of everything being a file
I have not. Where are the files in my proposed interface? You are biased by the names, but again, could be "attach, startop, endop, getdata, senddata, setpos, command (and deattach instead of fini)." As I've said, I've only used the names you are familiar with to help understanding of the purpose of each function. There's a good reason why I wrote the first argument is a device index (and not a file descriptor nor a FILE struct pointer), because there are no files involved at all.

davidv1992 wrote:
This might be far from ideal for systems that are designed with the idea in mind that network card drivers "push" received packets up through the rest of the network stack.
There's no "pull" or "push" defined here. You are lost in the abstractions. There's only a function to get the data (the received packet) from the device, and a function to send data (packet to be sent) to the device that's all. ODD does not tell you when to call those and what to do with the data (that's a higher abstraction layer), you can push that received data up to your network stack if you like. Since you have mentioned the network stack, if I wrote that ODD driver is only responsible for communicating the ISO/OSI physical layer 1 with the device, but does not care how that data is used by layer 2 and above, would it make now sense to you?
Another example: a storage driver would allow you to read and write a sector, but it won't parse a partitioning table for you as that's a higher abstraction layer.

davidv1992 wrote:
device access through file systems
No files or file systems at all. Just drivers and device indeces. For example you have a machine with two ne2k cards. Then it is up to your kernel how to access the driver; ODD only expects that the ne2k driver should consistently choose the same card for the index 0 and 1. Likewise, if you have 4 serial ports, then it is up to your kernel how you call the uart driver; ODD only expects that index 0-3 should consistently select the same port (which can be "COM1:", "/dev/ttyS1", used by a special CommOpen(1) API whatever, ODD doesn't care).


Okay, let's forget it. It seems the concept of a source-compatible, low level interface is beyond your comprehention, you are confused by similar names and lost in abstraction layers. That's a pity. (No offense meant, the answers made it clear people on this forum are not ready yet to collaborate on such a project.)

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 11:25 am 
Offline
Member
Member

Joined: Mon Jul 25, 2016 6:54 pm
Posts: 223
Location: Adelaide, Australia
bzt wrote:
Okay, let's forget it. It seems the concept of a source-compatible, low level interface is beyond your comprehention, you are confused by similar names and lost in abstraction layers. That's a pity. (No offense meant, the answers made it clear people on this forum are not ready yet to collaborate on such a project.)


If you can't respond to pretty straight forward and obvious criticism about your ideas without getting huffy, maybe it's you who isn't ready to collaborate with others. If you brought something to the table beyond an idea people might offer something beyond critique of the idea in return.

Personally, I doubt such a simple interface would encapsulate meaningful functionality for anything but the simplest devices, so I don't see the point of it since it won't actually make the task of porting drivers any easier.


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 12:02 pm 
Offline
Member
Member

Joined: Sat Jul 02, 2016 7:02 am
Posts: 207
The original post describes the standard driver interfaces found in commercial systems, although they are not source-compatible on their own, which is what is being sold.

The goal seems to be to write a framework (each OS will implement and maintain it in different ways) which provides a common interface so that a driver can be written under its specification, and be used anywhere that framework runs.

The cost of this framework has to be less than the cost it takes to write separate drivers for each of the participating systems. I doubt that that condition will be satisfied.

But, there are these limited to smaller subsystems:
Windows has storport port driver, to whose API specification the storage vendors write their miniport drivers. Windows also has a NDIS. Interestingly, Linux can run some NDIS drivers through a wrapper. I concede that they belong to a single OS (namely, Windows) but they are still (specialized) interfaces meant to reduce the effort spent by developers (vendors) writing the corresponding drivers.

An important point to note here is that, even though this is a single OS, NDIS and storport are two /different/ frameworks, each catering to devices possessing different properties.

bzt wrote:
There's a good reason why I wrote the first argument is a device index (and not a file descriptor nor a FILE struct pointer), because there are no files involved at all.

A distinction without a difference. The index/fd/FILE all identify the device and help in locating/managing the device's state.

bzt wrote:
Okay, let's forget it. It seems the concept of a source-compatible, low level interface is beyond your comprehention, you are confused by similar names and lost in abstraction layers. That's a pity. (No offense meant, the answers made it clear people on this forum are not ready yet to collaborate on such a project.)

Please don't lose hope on account of us pitiable folks. Take two OS (I suggest Linux and one of the BSDs), remove the built-in support for a device (for e.g. a usb host controller) in both, and build and publish the interfaces and the common driver.


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Thu Apr 11, 2019 12:39 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
One thing that might make the effort more approachable is separating what the drivers provide from what driver demand. Both can be specified individually, possibly in two different documents. For example, in microkernels it could be reasonable for drivers to demand access to (part of) a standard C library. Hence, stuff like malloc() does not need to be specified in this case. Instead, it would be possible to first focus on what drivers provide, for example, the read()/write()/ioctl() interfaces.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Fri Apr 12, 2019 1:02 am 
Offline

Joined: Fri Apr 05, 2019 11:04 pm
Posts: 3
bzt wrote:
Instead what it would do, is to provide the following functions in every compatible driver: open ... read ... write

What if a driver interface looks completly different? For example my kernel doesn't have general read/write functions at all. There is only an open function that returns function pointers to the driver's read/write routines. How would this work with your idea?


Top
 Profile  
 
 Post subject: Re: Device drivers
PostPosted: Fri Apr 12, 2019 1:50 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
Sturm wrote:
bzt wrote:
Instead what it would do, is to provide the following functions in every compatible driver: open ... read ... write

What if a driver interface looks completly different? For example my kernel doesn't have general read/write functions at all. There is only an open function that returns function pointers to the driver's read/write routines. How would this work with your idea?


IOCTL will handle everything. It's specifically designed for abuse.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 55 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group