Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Linux Kernel Programming Part 2 - Char Device Drivers and Kernel Synchronization

You're reading from   Linux Kernel Programming Part 2 - Char Device Drivers and Kernel Synchronization Create user-kernel interfaces, work with peripheral I/O, and handle hardware interrupts

Arrow left icon
Product type Paperback
Published in Mar 2021
Publisher Packt
ISBN-13 9781801079518
Length 452 pages
Edition 1st Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Kaiwan N. Billimoria Kaiwan N. Billimoria
Author Profile Icon Kaiwan N. Billimoria
Kaiwan N. Billimoria
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Section 1: Character Device Driver Basics
2. Writing a Simple misc Character Device Driver FREE CHAPTER 3. User-Kernel Communication Pathways 4. Working with Hardware I/O Memory 5. Handling Hardware Interrupts 6. Working with Kernel Timers, Threads, and Workqueues 7. Section 2: Delving Deeper
8. Kernel Synchronization - Part 1 9. Kernel Synchronization - Part 2 10. Other Books You May Enjoy

Understanding the connection between the process, the driver, and the kernel

Here, we will delve into just a bit of the kernel internals surrounding the successful registration of a character device driver on Linux. In effect, you will come to understand the workings of the underlying raw character driver framework.

The file_operations structure, or the fops (pronounced eff-opps), as it's commonly referred to, is of critical importance to driver authors; the majority of the members of the fops structure are function pointers – think of them as virtual methods. They represent all possible file-related system calls that could be issued on a (device) file. So, it has openread, write, poll, mmap, release, and several more members (most of which are function pointers). A few of the members of this critical data structure are shown here:

// include/linux/fs.h
struct file_operations
{
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
[...]
__poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
unsigned long mmap_supported_flags;
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
[...]
int (*fadvise)(struct file *, loff_t, loff_t, int);
} __randomize_layout;

A key job of the driver author (or the underlying kernel framework) is to populate these function pointers, thus linking them to actual code within the driver. You needn't implement every single function, of course; please refer to the Handling unsupported methods section for details.

Now, let's assume you have written your driver to set up functions for some of the f_op methods. Once your driver is registered with the kernel, typically via a kernel framework, when any user space process (or thread) opens a device file registered to this driver, the kernel Virtual Filesystem Switch (VFS) layer will take over. Without going into deep detail, suffice it to say that the VFS allocates and initializes that process's open file data structure (struct file) for the device file. Now, recall the last line in our struct miscdevice initialization; it's this:

   .fops = &llkd_misc_fops, /* connect to this driver's 'functionality' */

This line of code has a key effect: it ties the process's file operations pointer (which is within the process' open file structure) to the device driver's file operations structure. The functionality – what the driver will do – is now set up for this device file! 

Let's flesh this out. Now (after your driver has initialized itself),  a user-mode process opens your driver's device file, by issuing the open(2) system call on it. Assuming all goes well (and it should), the process is now connected to your driver via the file_operations structure pointers deep inside the kernel. Here's a critical point: after the open(2) system call returns successfully, and the process issues any file-related system call foo() on that (device) file, the kernel VFS layer will, be having in an object-oriented fashion (we have pointed this out before in this book!), blindly and trustingly invoke the registered fops->foo() method! The file opened by the user space process, typically a device file in /dev, is internally represented by the struct file metadata structure (a pointer to this, struct file *filp, is passed along to the driver). So, in terms of pseudo-code, when user space issues a file-related system call foo(), this is what the kernel VFS layer effectively does:

/* pseudocode: kernel VFS layer (not the driver) */
if (filp->f_op->foo)
filp->f_op->foo(); /* invoke the 'registered' driver method corresponding to 'foo()' */

Thus, if the user space process that opened a device file invokes the read(2) system call upon it, the kernel VFS will invoke filp->f_op->read(...), in effect, redirecting control to the device driver. Your job as the device driver author is to provide the functionality of read(2)! The same goes for all other file-related system calls. This, essentially, is how Unix and Linux implement the well-known if it's not a process, it's a file design principle.

You have been reading a chapter from
Linux Kernel Programming Part 2 - Char Device Drivers and Kernel Synchronization
Published in: Mar 2021
Publisher: Packt
ISBN-13: 9781801079518
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime