mirror of
https://github.com/sysprog21/lkmpg.git
synced 2024-11-22 13:58:19 +08:00
Merge pull request #135 from RinHizakura/master
Revise chardev registration
This commit is contained in:
commit
785c2fe600
37
lkmpg.tex
37
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.
|
||||
|
|
Loading…
Reference in New Issue
Block a user