device number 2
This post is about handling device numbers in kernel Programming.
ref: Linux Device Drivers
data type:
The dev_t
type defined in <linux/types.h>
holds a device’s number.
Use the macros in <linux/kdev_t.h>
to obtain the major or minor parts of dev_t
:
|
|
or turn a pair of major & minor numbers into dev_t
:
MKDEV(int major, int minor);
Allocationg & Freeing Device Numbers
|
|
register_chardev_region()
does what its name suggests. It request access to a range of device numbers. first
is the beginning device number, count
is the total number of contiguous device numbers to be requested. name
is the name of device; it will appear in /proc/devices
and sysfs
.
However it’s often unkown in advance which device number will be used. The device number can by dynamicaly allocated by the kernel on the fly with the second function alloc_chardev_region()
. firstminor
should be the requested first minor number to use(usually 0). The disadvantage of this method is that a node can’t be created in advance.
To load a driver using dynamic major number, a script can be called: after calling insmod
, read /proc/devices
to create the nodes.
These 2 functions return 0 upon success, and negative error code upon failures, in which case the requested region can’t be accessed.
The 3rd function frees the device number. It’s usually paced in module’s cleanup function.
Some major numbers are stratically assigned to the most common devices. Here is a list: Linux Kernel Documentations
So dynamic allocation is suggested…
The script to load a module (as showcased in LDD the book):
#!/bin/sh
module="name_of_module"
device="name_of_device"
mode="664"
# invoke insmod with all arguments we got
# and use a pathname, as newer modutils don't look in . by defult.
/sbin/insmod ./$module.ko $* || exit 1
# remove stale nodes
rm -f /dev/${device}[0-3]
major=$(awk "\\$2==\"$module\" {print \\$1}" /proc/devices)
mknod /dev/${device}0 c $major 0
mknod /dev/${device}1 c $major 1
mknod /dev/${device}2 c $major 2
mknod /dev/${device}3 c $major 3
# give appropriate group/permissions, and change the group.
# since this script is run by superuser, the newly created
# nodes are owned by root.
# Not all distributions have staff, some have "wheel" instead.
group="staff"
grep -q '^wheel:' /etc/group || group="wheel"
chgrp $group /dev/${device}[0-3]
chmod $mode /dev/${device}[0-3]