Topic donated.  No longer about learning to write a driver for fun and with ease - Page 1
Forum section: electronics / general

author: RoGeorge
author_rank: Super Contributor
timestamp: September 16, 2023, 07:22:52 pm
content: - How easy?- This easy!The 'hello_drv.c' file:Code:#include <linux/module.h>#include <linux/init.h>int __init my_init(void){printk("hello_drv - Hello from the kernel!\n");return 0;}void __exit my_exit(void){printk("hello_drv - Bye, bye, driver unloaded.\n");}MODULE_LICENSE("GPL");MODULE_AUTHOR("RoGeorge");MODULE_DESCRIPTION("The Hello World of a Loadable Kernel Module");module_init(my_init);module_exit(my_exit);The 'Makefile':Code:obj-m += hello_drv.oall:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean- How?- From a terminal, install the build tools, make the .ko module then load/unload your driver into the Linux kernel!('hello_drv.c', 'Makefile' and a compiled 'hello_drv.ko' are in the zip archive attached at the end of this post)Code:/** # as seen in the https://www.youtube.com/watch?v=2-vKcbfa0bc**Linux Driver Workshop at Kieler Linuxtage (english)*Johannes 4GNU_Linux*by Johannes Roith, 2023-09-15** sudo apt install build-essential* sudo apt install linux-headers-$(uname -r)** make** sudo dmesg* sudo insmod ./hello_drv.ko# loads the driver module into the Linux kernel* # sudo modprobe ./hello_drv.ko# loads the driver including its dependencies* sudo dmesg# observe the message in the kernel log ' hello_drv - Hello from the kernel!'** lsmod | grep hello_drv** sudo rmmod ./hello_drv.ko* sudo dmesg# observe the message ' hello_drv - Bye, bye, driver unloaded.** modinfo ./hello_drv.ko** make clean*/Interested for more than just the Hello World? See the full workshop (1.5 hours):Linux Driver Workshop at Kieler Linuxtage (english)Johannes 4GNU_Linuxhttps://youtu.be/2-vKcbfa0bcor the playlist 'Let's code a Linux Driver' from the same YT channel:https://www.youtube.com/playlist?list=PLCGpd0Do5-I3b5TtyqeF1UdyD4C-S-dMa

author: janoc
author_rank: Super Contributor
timestamp: September 16, 2023, 10:00:28 pm
content: That may sound a bit pedantic but what you have there is not a driver of any kind, only a Linux kernel module (for the uninitiated - sort of a kernel plugin). Most drivers are modules these days but not every module is a driver and not every driver is/can be a module.Try to write a driver e.g. for a new block device or some USB device, then the "It's easy" would have more relevance

author: magic
author_rank: Super Contributor
timestamp: September 17, 2023, 07:46:41 am
content: The use of "code" as a verb is an instant giveaway that you are dealing with a layman or a material dumbed down for laymen.Literally nobody in the industry uses it that way.

author: RoGeorge
author_rank: Super Contributor
timestamp: September 17, 2023, 09:22:09 am
content: A software jedi master Yoda is not. Yrsssss!Quote from: janoc on September 16, 2023, 10:00:28 pmMaster Yoda said "No, try not. Do, or do not."Starting a drivers-101 with a block device might be a block. Even the pros want them gone, like in FreeBSD:QuoteSource:https://docs.freebsd.org/en/books/arch-handbook/driverbasics/#driverbasics-blockThen, the USB is as its name tells: universal, with so many possibilities it will confuse anyone at some point.

author: DiTBho
author_rank: Super Contributor
timestamp: September 17, 2023, 02:45:20 pm
content: Quote from: janoc on September 16, 2023, 10:00:28 pmI still have a serious problem with the kernel module of a fiber optic card. After thousands of hours of debugging I still haven't understood why if compiled statically (kernel built-in) the probe succeeds, while if compiled as a module it fails randomly.It cannot be compiled as kernel module due to severe restrictions in the final embedded diskless environment, so it's ok as kernel built-in, but ... what the bloody hello is wrong with the Probe? It's just out of curiosity and I don't have time to investigate further as you have a layer of things to look at, starting with PCI, and then going up to all the layers above.The next person who tells me "uh, oh, it's simple", I swear I'll throw the card at their head!And it doesn't weigh little, it's 450g, coiunting a massive copper heatsink and thick connectors!

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 17, 2023, 09:02:51 pm
content: Quote from: DiTBho on September 17, 2023, 02:45:20 pmWhile it's impossible to "debug" this particular issue from a distance and without any details, one general point that makes a difference between built-in kernel modules and loadable kernel modules is memory allocation, so that's what I would look at specifically first if I were to debug this.There's a short introduction there:https://tldp.org/HOWTO/html_single/Module-HOWTO/#MEMALLOC

author: janoc
author_rank: Super Contributor
timestamp: September 18, 2023, 02:20:06 pm
content: Quote from: RoGeorge on September 17, 2023, 09:22:09 amI wonder what relevance have FreeBSD drivers/manuals for writingLinuxdrivers?This is way more relevant:https://linux-kernel-labs.github.io/refs/heads/master/labs/block_device_drivers.htmlBlock device is something like a disk drive, RAID or e.g. USB mass storage and they certainly aren't going anywhere.Quote from: RoGeorge on September 17, 2023, 09:22:09 amI wonder whether you are a victim of a crappy clueless course or just trolling ...

author: RoGeorge
author_rank: Super Contributor
timestamp: September 18, 2023, 02:57:34 pm
content: Quote from: DiTBho on September 17, 2023, 02:45:20 pmKeep in mind that what you just did, posting physical assault threats, is not something to joke about.Nobody said "simple", title says "easy". And it says that about writing a hello-world driver, doesn't say that about existing drivers, or about your FO card. Please open a new topic if you need help with your card drivers, don't hijack this one.The plan was to build both the hardware and the drivers for them, step by step.The hardware was to come later, first example with an I2C device (for an analog multiplier, well, not exactly an analog multiplier but close, based on this idea:https://hackaday.io/project/7542-rogeorge-cell). The second hardware example was to be a PCIe JTAG withSN74BCT8245.In the opening post there is no hardware, only the very first steps, setting the tools, compile an empty module, and load/unload it as a sanity check. It was so in order to keep it short, and to test if there is any interest with the subject.This topic was meant to be a joyful 101 journey on the land of PCIe bus and the Linux kernel. It was meant for the absolute beginners, like me.Well, I guess fouling around with a "Yoda speaking" title (without stating the goals) was a bad idea, or at least confusing, so just to make it clear, I am not Yoda.To recap, from my side it looked like this:- Hey, let's learn to write a Linux driver, look how easy could be.- No, some are hard. (OK, for sure some are, but learning has to start with something easy)- I have the proof op is layman and shows dumbed down material. (good observation, otherwise "literally nobody" might have missed that clue, and might have took Yoda phrasing as an academic paper)- I am unable to compile and don't understand why, won't open my topic and will just vent here, and will break the head of whoever begs to differ my opinion! (you OK now?)- feeding the offtopicWhat am I missing here? Why trying to curb down the enthusiasm of others?Did the planets just misaligned yesterday, or did I do something wrong?

author: IanB
author_rank: Super Contributor
timestamp: September 18, 2023, 06:09:47 pm
content: Quote from: janoc on September 18, 2023, 02:20:06 pmThe point to realize is that "USB" is not a device, it is a device bus (device interface) that can service many kinds of devices and device classes that might sit on the bus. So you have to write a driver for the device/USB combination, which will depend heavily on the kind of device. So it is, indeed, complicated.

author: DiTBho
author_rank: Super Contributor
timestamp: September 18, 2023, 06:46:57 pm
content: Quote from: RoGeorge on September 18, 2023, 02:57:34 pmQuote from: RoGeorge on September 18, 2023, 02:57:34 pmphysical assault?hijack?I did nothing butpoint out what has already been written to you by others: that is, that your topic title is all wrong, as well as your fanatical and ignorant attitude.Sure,I did it in a jocking wayQuote from: DiTBhono one threatens to physically hit anyone, it's just a jocking way to remind the reader of reality, that anything is neither "simple" nor "easy", and I think you have deliberately distorted the tone, in order to throw more mud.I happen to develop/debug kernel modules for VxWorks, sometimes I have to "port" them to Linux. Sometimes I have to "debug" and "fix" other people' kernel modules, I know how frustrating it is, thus the reason for the jocking tone instead of throwing the same concept in your face with much more cynical ways and words: because dude, "code", "easy", "simple" only denote that you don't have no @#'£!$% idea what you're talking about, you just talk nonsense, as usual.Seriously, enjoy my ignore list.

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 18, 2023, 08:46:53 pm
content: 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.

author: RoGeorge
author_rank: Super Contributor
timestamp: September 18, 2023, 10:35:45 pm
content: Quote from: janoc on September 18, 2023, 02:20:06 pmYour 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.

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 18, 2023, 11:01:58 pm
content: 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 islaboriousbut notdifficult: 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. Thedesignpart is the hard part, not thecodingpart.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/kkkdevice 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 theLinux 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.