设备驱动程序学习笔记(1)

1. 主从设备号是用一个32位的整数(dev_t)来表示,这个整数的高12位表示主设备号,后面20位表示从设备号,内核定义了一些宏来转换:

#define MINORBITS 20

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))

#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))

#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))


2. 注册,管理设备

用kobj_map来管理和跟踪各个设备:

// drivers/base/map.c

struct kobj_map {
struct probe {
struct probe *next;
dev_t dev;
unsigned long range;        //从设备号的连续范围
struct module *owner;
kobj_probe_t *get;
int (*lock)(dev_t, void *);
void *data;        //根据设备的不同,data分别指向字符设备cdev和块设备genhd
} *probes[255];
struct mutex *lock;
};

管理为驱动程序分配的设备号范围:

static struct char_device_struct {
struct char_device_struct *next;
unsigned int major;
unsigned int baseminor;        // baseminor是包含minorct个设备号的连续范围中最小的从设备号
int minorct;
char name[64];
struct cdev *cdev;/* will die */
} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];


3. 注册过程

字符设备的注册:

1)调用register_chrdev_region或alloc_chrdev_region来分配设备号的范围

2)调用如下两个函数进行注册

void cdev_init(struct cdev *cdev, const struct file_operations *fops)

int cdev_add(struct cdev *p, dev_t dev, unsigned count)

块设备直接调用一个函数即可以注册:

int register_blkdev(unsigned int major, const char *name);


4. 字符设备的操作

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;        //从设备数
};
字符设备的打开:

在第一次打开一个设备文件时,用fs_devices.c里面的通用函数chrdev_open打开,并根据设备号查找得到cdev实例,同时关联inode和cdev实例,最后调用驱动程序提供的file_operations里的open函数做一些初始化的工作。


你可能感兴趣的:(设备驱动程序学习笔记(1))