From 2cc4264f72a16abd3840678068798485e7a6206b Mon Sep 17 00:00:00 2001 From: RinHizakura Date: Wed, 22 Dec 2021 00:06:05 +0800 Subject: [PATCH] Introduce the new method for chardev registration Instead of using the old register_chrdev / unregister_chrdev API, cdev interface which is newer and would be better for new driver programmers in most cases. This commit is trying to give the brief overview for this different interface. --- lkmpg.tex | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lkmpg.tex b/lkmpg.tex index 7a45590..744759b 100644 --- a/lkmpg.tex +++ b/lkmpg.tex @@ -896,6 +896,43 @@ First, the driver itself can print the newly assigned number and we can make the Second, the newly registered device will have an entry in \verb|/proc/devices|, and we can either make the device file by hand or write a shell script to read the file in and make the device file. The third method is that we can have our driver make the device file using the \cpp|device_create| function after a successful registration and \cpp|device_destroy| during the call to \cpp|cleanup_module|. +However, \cpp|register_chrdev()| would occupy a range of minor numbers associated with the given major. +The recommended way to reduce waste for char device registration is using cdev interface. + +The newer interface completes the char device registration in two distinct steps. +First, we should register a range of device numbers, which can be completed with \cpp|register_chrdev_region| or \cpp|alloc_chrdev_region|. + +\begin{code} +int register_chrdev_region(dev_t from, unsigned count, const char *name); +int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name); +\end{code} + +The choose of two different functions depend on whether you know the major numbers for your device. +Using \cpp|register_chrdev_region| if you know the device major number and \cpp|alloc_chrdev_region| if you would like to allocate a dynamicly-allocated major number. + +Second, we should initialize the data structure \cpp|struct cdev| for our char device and associate it with the device numbers. +To initialize the \cpp|struct cdev|, we can achieve by the similar sequence of the following codes. + +\begin{code} +struct cdev *my_dev = cdev_alloc(); +my_cdev->ops = &my_fops; +\end{code} + +However, the common usage pattern will embed the \cpp|struct cdev| within a device-specific structure of your own. +In this case, we'll need \cpp|cdev_init| for the initialization. + +\begin{code} +void cdev_init(struct cdev *cdev, const struct file_operations *fops); +\end{code} + +Once we finish the initialization, we can add the char device to the system by using the \cpp|cdev_add|. + +\begin{code} +int cdev_add(struct cdev *p, dev_t dev, unsigned count); +\end{code} + +To find a example using the interface, you can see \verb|ioctl.c| described in section \ref{sec:device_files}. + \subsection{Unregistering A Device} \label{sec:unregister_device} We can not allow the kernel module to be \sh|rmmod|'ed whenever root feels like it.