Products > Programming

Topic donated. No longer about learning to write a driver for fun and with ease

<< < (3/3)

As a general thought, writing drivers for a micro-kernel tends to be much easier and less error-prone than for a monolithic kernel. Not that it helps if you have to deal with a Linux-based system.


--- Quote from: janoc on September 18, 2023, 02:20:06 pm ---
--- Quote from: RoGeorge on September 17, 2023, 09:22:09 am ---Starting a drivers-101 with a block device might be a block.  Even the pros want them gone, like in FreeBSD:

--- End quote ---

I wonder what relevance have FreeBSD drivers/manuals for writing Linux drivers?

--- End quote ---

Your post was pointing that drivers are not easy, and you were giving the examples of a block device and/or a USB driver as not easy, or at least that's what I understood.  True that, some drivers are not easy, but we don't want to discourage by starting with the most complicated.

Indeed, some drivers are so nasty that even the professional developers would want them gone, as for example in FreeBSD.  FreeBSD is not GNU/Linux, but I guess the difficulties for a block device driver are the same no matter the OS.  That's why bringing the FreeBSD.

Though, I never wrote such a driver for any modern OS, so I might be wrong with that guess.  The closest I've wrote was a driver for a floppy disk for CP/M, a very different OS and from long ago.  Not much would still apply today.

About the USB, it stands for Universal Serial Bus, and it is indeed "universal" if we think at the plethora of hardware that can make use of the USB.  No trolling, only a different viewpoint.  I'm an electronist, when I say USB I picture the hardware first.  Usually, by serial communication the default I picture is the UART.

Compared to the humble UART, USB has a very complicated behavior.  USB has many working modes, speed negotiation, it is plug and play, hot swapable, power/voltage negotiation, device enumeration, hubs, additional regulations for VID/PID allocation, and who knows what else.

So yes, you are correct, some drivers are far from easy, such as the two examples you gave.
Only argued against those examples in order to keep the learning easy, no trolling intended.

Nominal Animal:
Is anything worthwhile easy?  Among things that do not already exist, and haven't been reinvented time and time again?

I prefer to use 'straightforward', because when you know how the driver needs to operate, writing the code itself using the existing kernel guidelines is laborious but not difficult: it is a lot of work, but all the needed information and tools are available online for free.  It's like digging a ditch: the first thing to do is to ensure it is dug where it performs the desired purpose, and does not accidentally move a nearby lake a couple of miles in the wrong direction.

The difficult part about drivers is to find out exactly what the driver has to do to be useful, and what it needs to do to perform the desired task or tasks.  Stuff like locking, memory accounting, workers and workqueues, and so on.  This is both difficult (because of its complexity), taking a long time, but also requires experience, or you'll get bogged down in all the myriad traps for new players.  The design part is the hard part, not the coding part.

In DiTBho's case, probing order and hardware details, and having to maintain/backport/update/upgrade a driver someone else designed, I bet is a major source of pain.  Not Linux per se, unless you count in the "why doesn't this already exist in this form for this bloody arch?" sense.

As SiliconWizard mentioned, microkernel drivers tend to be easier to design because the privilege separation also forces one to use simpler interfaces between drivers and subsystems, so the design work is more structured.  In monolithic kernels, existing interfaces can have all sorts of inefficiencies and idiosyncracies.  In the case of the Linux kernel, those interfaces are constantly evolving; no stable kernel-internal interfaces exist at all.  The fewer subsystems a Linux driver interacts with, the easier it is to write; and vice versa.  PCI/PCIe + bus management + locking + memory can get quite hairy to properly design, and if you are "forced" to continue someone elses design you aren't even sure is sane, would give me the heebie-jeebies.  Add to more than one concurrent userspace user for that driver, and I start getting hives: designing something robust with that kind of complexity takes a lot of effort.

(I've long since learned to treat code rewrites as design-wide refactoring, where you use the old stuff to see what works, make that central and stable, and try to make it possible to try something better for the stuff the old stuff didn't do right.  Then again, even with a high output rate, that is not "a commercially viable use of development resources", because users are nowadays used (pun intended) to less than reliable tools; nobody is willing to pay for such work to be done.)

For USB devices, the usbfs /dev/bus/usb/jjj/kkk device interface is rather nice for userspace drivers.  It is no longer a separate filesystem in current kernels, and is included in the USB core, so its name is misleading; but it does support even async bulk and isochronous transfers and so on.

For anyone wishing/having to/considering doing Linux driver development, I do warmly recommend looking through the Linux Kernel Driver Implementer's API Guide, it being the documentation kernel developers themselves try to keep up to date.  Just getting an intuitive picture of how different drivers and hardware architectures work in Linux, will help with the difficult and hard driver design work.


[0] Message Index

[*] Previous page

There was an error while thanking
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod