1. 主次设备号:
Linux Kernel用主设备号用来标示驱动程序,使用次设备号来标示设备文件所表示的具体设备。
2. 内部表示:
dev_t 类型用来表示设备号。
typedef __kernel_dev_t dev_t; //
typedef __u32 __kernel_dev_t; //实际上就是一个平台无关的32位整形
3. 操作:
3.1 MAJOR(dev_t dev)
返回主设备号
3.2 MINOR(dev_t dev)
返回次设备号
3.3 MKDVE(int major, int minor)
通过两个表示主次设备号的int构造dev_t类型的变量
3.4 分配和释放设备号
3.4.1 固定分配
/** fs/char_dev.c
* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)
由于是自己只定设备号,有可能会引发设备号冲突问题。
3.4.2 由OS自动分配
/**
* alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.
*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
建议使用的分配设备号的方法,因为是有OS自动分配主设备号。
3.4.2 释放设备号
/**
* unregister_chrdev_region() - return a range of device numbers
* @from: the first in the range of numbers to unregister
* @count: the number of device numbers to unregister
*
* This function will unregister a range of @count device numbers,
* starting with @from. The caller should normally be the one who
* allocated those numbers in the first place...
*/
void unregister_chrdev_region(dev_t from, unsigned count)
释放设备号。
4. 实验:准备设备号&创建字符设备设备节点
4.1 申请&释放设备号
scull.c:
/*
* =====================================================================================
*
* Filename: cdev_num
*
* Description: This file is used for testing char device number allocation
*
* Version: 1.0
* Created: 03/13/2011 09:18:06 PM
* Revision: none
* Compiler: gcc-4.4.5
*
* Author: ville lee (vl), villelee1987@gmail.com
* Company: BUAA
*
* =====================================================================================
*/
#include
#include
#include /* printk */
#include /* MAJOR, MINOR */
#include /* dev_t */
#include /* alloc_chrdev_region, unregister_chrdev_region */
/* add the header file above if needed*/
int major;
int minor;
int count = 4;
dev_t dev_num;
/*
* === FUNCTION ======================================================================
* Name: module_init
* Description:
* =====================================================================================
*/
static int __init cdev_num_init(void)
{
/* allocate the char device number */
int result = alloc_chrdev_region(&dev_num, 0, 4, "scull");
if (result < 0) {
printk(KERN_WARNING "char device number allocation fails\n");
return -1;
}
major = MAJOR(dev_num);
minor = MINOR(dev_num);
printk(KERN_ALERT "The name of the char device is %s\nThe major number is %d\nThe minor number is %d\n"
, "scull", major, minor);
printk(KERN_ALERT "===========================================================\n");
return 0;
} /* ----- end of static function module_init ----- */
/*
* === FUNCTION ======================================================================
* Name: module_exit
* Description:
* =====================================================================================
*/
static void __exit cdev_num_exit(void)
{
unregister_chrdev_region(dev_num, 4);
printk(KERN_ALERT "===========================================================\n");
} /* ----- end of static function module_exit ----- */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ville lee");
MODULE_DESCRIPTION("add your description");
MODULE_VERSION("version 1.0");
module_init(cdev_num_init);
module_exit(cdev_num_exit);
===========================================
这时候,查看/proc/devices会发现多出了scull0-scull3
也就是说明了,只要申请设备号,那么就会在/proc/devices文件中添加设备号,
无论是否创建设备节点,也就表明proc文件系统和dev文件系统并不存在完全的依赖关系。
4.2 加载脚本和卸载脚本
scull_load.sh
#!/bin/bash
# Description:
# This file is used for load the module and create device nodes
module="scull" # module or device name
device="scull"
mode="664" # node access mode for user space
insmod ./$module.ko $* || exit 1
rm -f /dev/${device}[0-3]
major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
# create the device node
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
# allocate proper access-mode, and change the group attributes
# in my fedora 13, there is wheel group but no staff group
group="wheel"
chgrp $group /dev/${device}[0-3]
chmod $mode /dev/${device}[0-3]
=================================
scull_unload.sh
#!/bin/bash
module="scull"
device="scull"
rmmod $module $* || exit 1
rm -f /dev/${device}[0-3]
echo "module $scull and the refered device node has been removed!"
阅读(758) | 评论(0) | 转发(0) |