How to practice writing real Linux Device Drivers? - linux

I am a intermediate level programmer with a decent experience in Linux Kernel Programming. During my internship I was mostly involved in debugging the kernel and driver code. I recently finished studying the Kernel Development book by Robert Love. I am halfway through the Linux Device Drivers Book by Jonathan Corbet. But I am now faced with a troubling issue. None of these books teach me how to actually write real (Hardware) Device Drivers. the LDD3e book tells me how to write memory based software drivers and sysfs interfacing in which I'm pretty good at. So where do I start ? What are the requirements and how do I go about it ?
P.S: I have begun reading the book 'Essential Linux Device Drivers by Sreekrishnan Venkateswaran'

You should DO it rather than just read it.
There is a great way to DO it first hand with fun.
Follow eudyptula challenge. Just got to eudyptula-challenge.org and do what they say. There are 20 tasks. After solving them you will not only know about kernel, but you would have done things with linux and kernel.
They says that they are using script to verify your drivers during challenge tasks, but I highly doubt it due to humorous and funny responses I get from them!

Related

Linux Kernel API: meaning and stability of nodes under `/sys/devices/pci...` tree in sysfs

The essence of my question is almost painfully simple:
Given my current hardware, would the design of Linux sysfs allow me to expect that the device at /sys/devices/pci0000:00/0000:00:14.0/usb1/1-6 will always be the same device at that same location every time that I boot?
I'm 99% certain that the answer is "yes", but getting an expert to quickly weigh in seems prudent, to make sure I don't do anything stupid.
The inverse way to ask my question would be:
Is there any non-determinism in how the kernel enumerates pci and usb hardware at boot? (Assume the hardware is always fixed in advance of the boot.)
Supporting details:
Kernel in use on this hardware is 5.4.0-58-generic
This PCI and USB connection is all inside of the custom device enclosure, and is part of the "permanent" hardware design. There is no possibility of "hot-plugging" or unplugging or any end-user intervention with regard to changing/reconfiguring these connections.
The actual device that I care about, located at usb1/1-6, is an stm32f103 microcontroller, in case that matters. (I suspect it does not matter.)
The hardware design is fixed, and made by someone other than myself. I am writing software (mostly high-level GUI software) that runs on this device. As you can probably guess, my kernel knowledge is a bit weak.
As I said, I'm fairly convinced that the structure of the path /sys/devices/pci0000:00/0000:00:14.0/usb1/1-6 is derived entirely from the real-world structure of the hardware, but am looking for confirmation.
I've been reading about sysfs (such as here: https://www.kernel.org/doc/html/latest/admin-guide/sysfs-rules.html), but I still feel a lack of stumbling into any single unambiguous sentence which would resolve my uncertainty.

important topics for linux programming in C

i have an interview in 10 days for a job. requirements are: (1)Strong Linux kernel or device driver design and programming.(2)Demonstrated skills in C/C++ programming under Linux, and system prototyping with good knowledge of Linux and Windows server technologies.
since i hv only 10 days, hw can i learn somethings which would help me in the interview.
I think Mr McLaughlin is right, for a lot of reasons, first of all because you can't learn how to move (as a user and also as a programmer) in linux in just 10 days.
Anyway, you should read this one: http://tldp.org/LDP/tlk/tlk-toc.html
You also have to know how POSIX systems work and take a look at this: http://www.linuxbase.org/betaspecs/fhs/fhs.html
This two links are a bunch of stuff for 10 days (since you should read&try everything to get used to it) but I think you have to read them to get a little (very basic) understanding on how life goes on on a linux-powered machine.
Good luck.
In 10 days you probably won't have time to learn enough, so don't aim to get that precise job.
But if Linux is interesting for you, consider
installing and using a Linux distribution on your computer
reading the Advanced Unix Programming book
reading the Advanced Linux Programming book
becoming fluent in shell and command line Linux tools
learning to build and install from its source code several free software
actively contributing to some free software on Linux coded in C
learning more about Linux system administration (at least being able to administrate with command line tools your computer).
This will take you months, not days!
Try this:
Writing device drivers in Linux: A brief tutorial: http://fsmsh.com/1238
This:
HOWTO do Linux kernel development: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/HOWTO;hb=HEAD
And:
Linux Kernel Development (3rd Edition)
http://goo.gl/XS7hq (There is e-book version that is delivered immediately)

Resources that explain Linux source code

Looking for resources that can help getting 'into' the Linux code. Could not get much help on Google. I have no issues on the distro covered by the book/resource, but will like if Fedora is the base. Also, it would be great if the resource is well maintained and updated.
this looks promising:
http://kernelnewbies.org/KernelHacking
Note that you will need to be familiar with Operating Systems concepts to even understand the concepts of how memory is allocated, how processes are scheduled, and whatnot. Also, the code of the linux kernel is monstrously complex.
You are undertaking a daunting task. But have fun with it. You might want to start with a small device driver's code.
http://www.makelinux.net/kernel_map may be a good place to start. A clickable map which takes you to the part of the source you clicked. Readable in a browser.
If you are talking about the Linux kernel, kernel newbies is absolutely awesome. Besides that, I don't think theres a single resource to recommend.
If you are trying to understand the linux kernel source code, then the exact distribution you are using, is not very relevant.
I would recommend the book from Robert Love: Linux Kernel Development, currently in its third edition. It will give you an understanding of the main parts of the kernel.

Question regarding Unix/Linux kernel programming

I would like to learn about linux/Unix kernel programming for scalable multi processors (smps). I found this book UNIX(R) Systems for Modern Architectures http://www.amazon.com/UNIX-Systems-Modern-Architectures-Multiprocessing/dp/0201633388/ref=pd_rhf_p_t_3 . Is there any other good resources or a better book since its released in 1994. Thank you very much in advance.
Thanks & Regards,
Mousey.
Definitely buy this excellent book! You will get thorough introduction into:
caches, their types, and how to deal with them in the kernel,
synchronization and what hardware primitives are behind it,
general kernel designs as related to concurrency (cli/sti, giant lock, cli+spinlock, etc.)
The book is general enough not to be out of date by now. The only thing I don't remember mentioned there is NUMA, but I don't think there are any good published texts on this subjects yet except for maybe Gorman's Linux memman paper (somebody correct me if I'm wrong here).
I think the book was really worth the money.
Understanding the Linux Kernel is a great book about how the Linux kernel is built, it describes Linux 2.2, 2.4 and 2.6 (Third Edition).
If you want to make drivers, there's Linux Device Drivers , and is also a reference about how Linux is built.
For Linux, Rusty's Unreliable Guide to Kernel Locking is a must-read. After that, you can also read the file Documentation/spinlocks.txt located in the Linux kernel sources.

What's the best way to get to know linux or BSD kernel internals? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
I'd like to gain better knowledge of operating system internals. Process management, memory management, and stuff like that.
I was thinking of learning by getting to know either linux or BSD kernel.
Which one kernel is better for learning purposes?
What's the best place to start?
Can you recommend any good books?
In college, I had an operating systems class where we used a book by Tanenbaum. In the class, we implemented a device driver in the Minix operating system. It was a lot of fun, and we learned a lot.
One thing to note though, if you pick Minix, it is designed for learning. It is a microkernel, while Linux and BSD are a monolithic kernel, so what you learn may not be 100% translatable to be able to work with Linux or BSD, but you can still gain a lot out of it, without having to process quite as much information.
As a side note, if you've read Just for Fun, Linus actually was playing with Minix before he wrote Linux, but it just wasn't enough for his purposes.
As a Linux user I'd say Linux has a great community for people to learn about the kernel. http://kernelnewbies.org is a great place to start asking questions and learning about how the kernel works. I can't make a book reccomendation, but once you've read the starting material on kernelnewbies the source is very well documented.
Aside from the good books already mentioned (Opeating System Design & Implementation is particularly good), get a hold of a 1.x release Linux Kernel, load it into VMWare or VirtualBox and start playing around from there.
You will need to spend a lot of time browsing source code. For this, check out http://lxr.linux.no/ which is a browsable linked version of the source and makes life a lot easier. For the very first version of Linux (0.01) check out http://lxr.linux.no/linux-old+v0.01/. The fun begins at http://lxr.linux.no/linux-old+v0.01/boot/boot.s. As you progress from version to version, check out the ChangeLog and dig into those parts that have changed to save you re-reading the whole thing again.
Once you've gotten a hold of the concepts, look at 2.0, then 2.2, etc. Be prepared to sink A LOT of time into the process.
Linux
Device Drivers
Linux Core Kernel Commentary
Operating Systems Design and Implementation
I had previously bought these books on recommendation for the same purpose but I never got to studying them myself so only take them as second-hand advice.
I recommend you the BSD kernels! BSD kernels have far fewer hackers so following their evolution is easier. Either BSD and Linux kernels have great hackers, but some people argue that BSD lower fame filters out novice ones. Also taking design decisions is easier when the sources are not being updated 100 times a day.
Among the BSD choices, my favorite one is NetBSD. It might not be the pain-free choice you want for your desktop, but because it has a strong focus on portability, the quality is quite good. I think this part say it all:
Some systems seem to have the philosophy of “If it works, it's right”. In that light NetBSD's philosophy could be described as “It doesn't work unless it's right”
If you have been working long enough, you will know that NetBSD is a quite joy for learning good coding. Although professionally you will find more chances with Linux
Whichever choice you take, start joining their mail lists, follow the discussions. Study some patches and finally try to do your own bug-fixing. Regarding books, search for Diomidis Spinellis articles and his book. It is not exactly a kernel book, but has NetBSD examples and helps a lot to tackle large software.
Noting the lack of BSDs here, I figured I'd chip in:
The Design and Implementation of the FreeBSD Operating System (dead-tree book)
Unix and BSD Courses (courses and videos)
FreeBSD Architecture Handbook (online book)
I haven't taken any of the courses myself, but I've heard Marshall Kirk McKusick speak on other occasions, and he is really good at what he does.
And of course the BSD man pages, which are an excellent resource as they are maintained to a far greater extent than your average Linux man-page. Take for instance the uvm(9) man-page, describing the virtual memory interface in OpenBSD.
Not quite related, but I'll also recommend the video History of the Berkeley Software Distributions as it gives a nice introduction to the BSD parts of the UNIX history and culture as well as plenty of hilarious anectodes from back when.
There's no substitute for diving into the code. Try to find a driver or subsystem that you're interested in and poke around with it. With tools like VMware Workstation it's super easy to make whatever changes you want, snapshot the VM, and run your modified kernel. If the kernel panics on boot, who cares? Just jump back to the snapshot and fix the problem.
For books, I strongly recommend Linux Kernel Development by Robert Love. It's a wonderfully written book -- lots of information, organized sanely, and humorous... not dry reading at all.
Take Mike Stone's advice and start with Minix. That's what Linus did! The textbook is really well written, and Tannenbaum does a great job of showing how the various features are implemented in a real system.
Nobody seems to have mentioned that code-wise BSD is much cleaner and more consistent. The documentation's way better too (as already mentioned). But since there's a whole lot of fiddling with whatever system you choose - I'd pick the one you use more often.
Linux and Minix are fun to learn. If you also want to learn how a modern micro-kernel operating system looks like, you can look at QNX. The complete documentation is available online and it is very accessible. For example, this online book.
When I was at uni I spent a semester studying operating systems, and as part of this had an assignment where we had to implement a RAM-based filesystem in Linux.
It was a fantastic way to get to understand the internals of the Linux keurnel and to get a grasp on how everything fits together - And a heck of a lot of fun playing around with how it interacts with standard tools too.
I haven't tried it myself, but you can go to Linux From Scratch and start building your own Linux distribution. Sounds like something that'll take a junkload of time, but will result in an intimate knowledge of the guts of the Linux kernel and how each part works. Of course, you can supplement this learning by following any of the other tips here.

Resources