Skip to content

Commit 785c2fe

Browse files
authored
Merge pull request #135 from RinHizakura/master
Revise chardev registration
2 parents e401601 + 2cc4264 commit 785c2fe

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

lkmpg.tex

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,43 @@ \subsection{Registering A Device}
896896
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.
897897
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|.
898898

899+
However, \cpp|register_chrdev()| would occupy a range of minor numbers associated with the given major.
900+
The recommended way to reduce waste for char device registration is using cdev interface.
901+
902+
The newer interface completes the char device registration in two distinct steps.
903+
First, we should register a range of device numbers, which can be completed with \cpp|register_chrdev_region| or \cpp|alloc_chrdev_region|.
904+
905+
\begin{code}
906+
int register_chrdev_region(dev_t from, unsigned count, const char *name);
907+
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
908+
\end{code}
909+
910+
The choose of two different functions depend on whether you know the major numbers for your device.
911+
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.
912+
913+
Second, we should initialize the data structure \cpp|struct cdev| for our char device and associate it with the device numbers.
914+
To initialize the \cpp|struct cdev|, we can achieve by the similar sequence of the following codes.
915+
916+
\begin{code}
917+
struct cdev *my_dev = cdev_alloc();
918+
my_cdev->ops = &my_fops;
919+
\end{code}
920+
921+
However, the common usage pattern will embed the \cpp|struct cdev| within a device-specific structure of your own.
922+
In this case, we'll need \cpp|cdev_init| for the initialization.
923+
924+
\begin{code}
925+
void cdev_init(struct cdev *cdev, const struct file_operations *fops);
926+
\end{code}
927+
928+
Once we finish the initialization, we can add the char device to the system by using the \cpp|cdev_add|.
929+
930+
\begin{code}
931+
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
932+
\end{code}
933+
934+
To find a example using the interface, you can see \verb|ioctl.c| described in section \ref{sec:device_files}.
935+
899936
\subsection{Unregistering A Device}
900937
\label{sec:unregister_device}
901938
We can not allow the kernel module to be \sh|rmmod|'ed whenever root feels like it.

0 commit comments

Comments
 (0)