Search icon CANCEL
Subscription
0
Cart icon
Cart
Close icon
You have no products in your basket yet
Save more on your purchases!
Savings automatically calculated. No voucher code required
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
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

Product type Book
Published in Mar 2021
Publisher Packt
ISBN-13 9781801079518
Pages 452 pages
Edition 1st Edition
Languages
Author (1):
Kaiwan N. Billimoria Kaiwan N. Billimoria
Profile icon Kaiwan N. Billimoria
Toc

Table of Contents (11) Chapters close

Preface 1. Section 1: Character Device Driver Basics
2. Writing a Simple misc Character Device Driver 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

Writing the misc driver code – part 3

Now, the init code is done, the driver functionality has been set up via the file operations structure, and the driver is registered to the kernel misc framework. So, what happens next? Well, nothing really, until a process opens the device file (associated with your driver) and performs I/O (Input/Output, i.e., reads/writes) of some sort.

So, let's assume that a user-mode process (or thread) issues the open(2) system call on your driver's device node (recall, the device node has been auto-created when the driver registered itself to the kernel's misc framework). Most important, as you learned in the Understanding the connection between the process, the driver, and the kernel section, for any file-related system calls issued upon your device node, the VFS will essentially invoke the driver's (f_op) registered method. So, here, the VFS will do this: filp->f-op->open(), thus invoking our driver's open method within our file_operations structure, which is the open_miscdrv() function!

But how should you, the driver author, implement this code of the open method of your driver? The key point is this: the signature of your open function should be identical to that of the file_operation structure open; in fact, this is true of any function. Thus, we implement the open_miscdrv() function like this:

/*
* open_miscdrv()
* The driver's open 'method'; this 'hook' will get invoked by the kernel VFS
* when the device file is opened. Here, we simply print out some relevant info.
* The POSIX standard requires open() to return the file descriptor on success;
* note, though, that this is done within the kernel VFS (when we return). So,
* all we do here is return 0 indicating success.
* (The nonseekable_open(), in conjunction with the fop's llseek pointer set to
* no_llseek, tells the kernel that our device is not seek-able).
*/
static int open_miscdrv(struct inode *inode, struct file *filp)
{
char *buf = kzalloc(PATH_MAX, GFP_KERNEL);

if (unlikely(!buf))
return -ENOMEM;
PRINT_CTX(); // displays process (or atomic) context info
pr_info(" opening \"%s\" now; wrt open file: f_flags = 0x%x\n",
file_path(filp, buf, PATH_MAX), filp->f_flags);
kfree(buf);
return nonseekable_open(inode, filp);
}

Notice how the signature of our open routine, the open_miscdrv() function, precisely matches that of the f_op structure's open function pointer (you can always lookup the file_operations structure for 5.4 Linux here at https://elixir.bootlin.com/linux/v5.4/source/include/linux/fs.h#L1814).

In this simple driver, in our open method, we don't really have much to do. We allocate some memory for a buffer (to hold the pathname of our device) via kzalloc(), issue our PRINT_CTX() macro (it's in the convenient.h header) to show the current context – the process that is currently opening the device. We then emit a printk (via pr_info()) showing a few VFS layer details (the pathname and open flags value); you can get the path name of a file by using the convenience API file_path(), as we do here (to do so, we need to allocate and, after usage, free a kernel memory buffer). Then, as we don't support seeking in this driver, we invoke the nonseekable_open() API (as discussed in the Handling unsupported methods section).

The open(2) system call on the device file should succeed. The user-mode process will now have a valid file descriptor – a handle to the open file (which, here, is actually a device node). Now, let's say the user-mode process wants to read data from the hardware; it therefore issues the read(2) system call. As explained already, the kernel VFS will now auto-invoke our driver's read method, read_miscdrv(). Again, its signature exactly imitates the read function signature from the file_operations data structure. Here's the simple code of our driver's read method:

/*
* read_miscdrv()
* The driver's read 'method'; it has effectively 'taken over' the read syscall
* functionality! Here, we simply print out some info.
* The POSIX standard requires that the read() and write() system calls return
* the number of bytes read or written on success, 0 on EOF (for read) and -1 (-ve errno)
* on failure; we simply return 'count', pretending that we 'always succeed'.
*/
static ssize_t read_miscdrv(struct file *filp, char __user *ubuf, size_t count, loff_t *off)
{
pr_info("to read %zd bytes\n", count);
return count;
}

The preceding comment is self-explanatory. Within it, we emit pr_info(), showing the number of bytes the user space process wants to read. Then, we simply return the number of bytes read, implying success! In reality, we have done (essentially) nothing. The remaining driver methods are quite similar.

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 €14.99/month. Cancel anytime