Linux Device Drivers

Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman

Mentioned 11

Provides information on writing a driver in Linux, covering such topics as character devices, network interfaces, driver debugging, concurrency, and interrupts.

More on Amazon.com

Mentioned in questions and answers.

I would like to learn how to write device drivers because I think it would be fun. I use a Mac OS X Macbook, but I also have an Ubuntu machine (running on a Mac Min). I am pretty familiar with C and currently am reading this book. I have found some links online such as Mac Dev Center. I am doing this because it would be fun. I think there would be real gratification to see hardware operate because of software I wrote.

I guess what I would like is some tips or advice and guidance, and does anyone know of a list of devices that don't have drivers or can I write a driver for something that's already supported (would prefer the former so I'm actually providing value). What's a good device to get started with? Am I biting off more than I can chew? I'm not afraid of low level programming or assembly or whatever amount of effort is required. I'd like a challenge really!

For Linux, you might look into picking up the O'Reilly Linux Device Drivers book or reading PDFs online. In my opinion, it is one of the better texts around on the subject.

The Linux Kernel Module Programming Guide is another good resource.

You may also want to pick up a book specifically on the Linux Kernel. I picked up a copy of Robert Love's Linux Kernel Development (2nd Edition) for this purpose (3rd Edition on the way).

I'm an android developer and I've been doing ROMs for a long time and I wanna get going with kernel development, I understand it's relating to linux kernel itself and got nothing to do with android.

Problem is I can't find any online resources to help me get going. So what I'm looking for is something a bit official, like the developer site for android,the java tutorials for java, the python tutorials........etc

Is there any thing like that? from linux.org maybe, but I can't find anything on their site. And what are the things I'm supposed to have a full understanding of? like programming languages (I know it's in C) or anything else?

Keep in mind that I'm only looking to learn driver configuration and compilation.

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?

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.

Noting the lack of BSDs here, I figured I'd chip in:

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.

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.

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.

I want to code drivers in C in linux os, though I think its very tough. Can I get some hints as to how to start or books to follow? Drivers can be from my USB port to graphics card!!

I know as to where I can search for books, I would like to know as to what the basic knowledge I should start with. Do I need to have hardware knowledge and which specific books are good for novice like me?

Before you jump into designing drivers you should first get exceptional C skills and probably some Linux Kernel know-how. Desigining drivers is not trivial and might scare you off if you are not used to programming on a low-level.

I might recommend The C programming Language if you are not accustomed to C as it is, in my opinion, the primer on C if you have some programming background.

Several texts:

"Linux Device Drivers" (the O'Reilley book) by Rubini and Corbet is the definitive book for Linux Device Drivers.

Cool! see the free pdf version in Roddy's answer & kristina's comment!

What is a good resource to get started with Windows file system driver development for a newbie?

This book: http://www.amazon.com/Windows-2000-Device-Driver-Book/dp/0130204315/ref=sr_1_1?ie=UTF8&s=books&qid=1246856381&sr=8-1

or any newer book you can find by an Art Baker. I read his NT Device Driver book about 10 years ago, and it finally made everything clear.

BTW, the books from 10 years ago or more/less still valid. You can't use the examples, but the model has basically not changed - just gotten more complex in typical M$ fashion. The IRP stuff is all still valid.

The OSR stuff is good - but expensive... I think for a full understanding of the whole design Baker can't be beat. Also, anyone reading this just trying to learn Windows drivers - I would avoid the NTFS stuff... its super complicated, and has nothing to do with what you need to accomplish a simple USB driver, or even a DMA device.

For Windows drivers also see this blog: http://blogs.msdn.com/doronh/

For Linux based development, two good books come to mind: Linux Device Drivers and Linux Kernel Development. The Linux Device Drivers book can be a bit daunting so a good introduction to the Kernel is a useful starting point.

As far as i know there are 255 virtual IRQ's in Windows system (chipset only allows 16 physical) and they all usually use physical IRQ 11.In Linux systems there is also a notion of virtual IRQ's.

So, I'm interested how does this mapping implented?Sourse code samples from Linux kernel or just algorithm will be appreciated.

The exact implementation of interrupt handling will vary between architectures and platforms. This answer predominantly addresses Linux as source is available. For Linux at least, there is a generic IRQ handling layer against which drivers are written so that the drivers can be compatible between architectures, independent of the underlying interrupt architecture.

Modern platforms may have multiple interrupt controllers, so its the platform specific code which handles the mapping of an IRQ number requested with request_irq() to a specific interrupt controller.

Take for example the mach-pxa architecture on Linux for PXAxxx base platforms. The platform irq.c file contains two struct irq_chip references indicating two different interrupt controllers. When pxa_init_irq() is called, it assigns a virtual interrupt number to a specific interrupt controller. The platform code ensures that unique interrupt numbers are assigned to every possible interrupt source.

There are quite a few details which are too detailed to post here, so I'd suggest getting a copy of the Linux source and digging in. If you're looking for the mappings, look specifically in the different arch directories.

If you do a make htmldocs from the top level, you'll get a Documentation/DocBook/index.html which you can peruse. Look at the genericirq section for some more details.

Additionally, the Linux Device Drivers, Corbet, Rubini, Kroah-Hartman book is an excellent source of information.

I am learning now days programming drivers.

I am doing my learning from this book Linux Device Drivers

But I am little bit lack of practice. Can you recommend me some simple projects that I can get started with.

Or some open source project that newbie can understand what is going on.

Additional examples and tutorials will be welcomed .

Thanks for help.

Free software magazine has an article about that :

http://www.freesoftwaremagazine.com/articles/drivers_linux?page=0%2C0

this tutorial is downloadable as PDF.

This article describes the programming of a USB driver for a home made multicolored light. I think its quite interesting :)

http://www.linuxjournal.com/article/7353

For more "complete" drivers, I would look at the code of "serial" drivers (meaning driver for devices connected to a plain old serial port or USB port) because the data transfer between your computer and the device feels more natural.

I want to implement a counter in linux device drivers which increments after every fixed interval of time.I want to do this with the help of timers. Can anyone please guide me how do I go about doing this? A sample code snippet would be very useful.

Depending on what you exactly want to do, you can directly use jiffies to measure time, as it has been suggested in the comments. You can also use kernel timers, and given the information in your question, they seem to be a better fit.

The kernel timers API is quite intuitive:

#include <linux/timer.h>
struct timer_list {
        /* ... */
        unsigned long expires;
        void (*function)(unsigned long);
        unsigned long data;
};

void init_timer(struct timer_list *timer);
struct timer_list TIMER_INITIALIZER(_function, _expires, _data);

void add_timer(struct timer_list * timer);
int del_timer(struct timer_list * timer);

So you would just need to define a timer function and then initialize and start the timer.

You have several sources to further learn about this topic:

  • Understanding the Linux Kernel. This book is a sort of bible for the kernel. It is somehow outdated in some areas, but still a really good source of information.
  • Linux Device Drivers. This is a very useful book when developing device drivers. There is an online version too here. The chapter dealing with time, timers, etc. is chapter 7. This book may be also a bit outdated since it is from 2005 too.
  • Linux Kernel Development. I have not checked this book, but the good point is that it is much newer (from 2010), so you may find some updated information compared to the previous two books.

for a software i'm writing i need to know when the linux framebuffer gets updated. I need something like Windows Mirror Drivers (for more infos look Mirror_driver on wikipedia).

Looking around i haven't finded anything, so i'm looking a way to accomplish this.

From what i've seen, i need to write a module that gets loaded after framebuffer specific module and that hooks fb ops structure to inject own stuff and catch updates.

Can someone give me an hint? I don't have much experience with kernel module writing.

Thank you!

For general kernel module writing tips, you can read the books:Linux Kernel Development, Linux Kernel in a Nutshell and Linux Device Drivers.

After you understand the basics on how to build & install your own kernel modules, you can read the source code of the kernel to figure out where the framebuffer stuff is (start at Documentation/fb/framebuffer.txt). I'm not sure whether you can just hook up on the framebuffer driver like that, if not, you might need to add the hook support yourself or 'hijack' the main driver's events to simulate hooking. For example, suppose that there's a function that is called whenever there's an update. You find where the pointer to this function is declared, save the value, then modify it with a pointer to your function. Inside your function you call the original function, then your own code to manipulate what you want and return properly.

I don't know much about the framebuffer stuff, so I'm just guessing what your options are. It's possible that there might be a discussion list somewhere specific to the subject of linux-fb. This might me a good start.

What happens internally when I mount a file system on UNIX using the following command:

mount -t ext3 /dev/sda1 /home/users

Please give references (articles, books etc.)

Consider your position: do you want to read this? Can you read this? http://freebsd.active-venture.com/FreeBSD-srctree/newsrc/ufs/ffs/ffs_softdep.c.html

It is McKusick's base code for the ffs file system, which is generally considered the parent of modern UNIX file systems. There is no finer detail than reading source.

The reason I posted: when I taught this stuff long ago, there was a text, and then I presented example code. Students seemed to get a lot out of it... those who actually worked on the material, to be more correct.

In this case the ffs.c code was kind of a defacto model. So it provides a how-we-got-here-from-there.

Now all you need to do is get this: http://www.amazon.com/Linux-Device-Drivers-Jonathan-Corbet/dp/0596005903/ref=sr_1_1?s=books&ie=UTF8&qid=1354930353&sr=1-1&keywords=linux+drivers

Then ultimately download code for ext3. And read it.