linux 驱动相关
linux 将外设抽象为 /dev
下的文件,通过统一的文件读写接口访问外设
linux与外设通信:
- I/O 端口:通过 I/O 读写访问设备
- I/O 内存映射:对 I/O 端口进行内存映射,将外设地址映射到内存地址,PCI 总线寻址通过内存映射完成
- 中断
设备访问:
分为块设备/字符型设备ls -alh /dev
块设备权限首位为 b
字符设备权限首位 c
目录首位 d
链接首位 l
用户,组 后面两个数字为 主设备号,从设备号
主设备对应一个驱动程序,其下若干从设备由该驱动程序管理
查找驱动根据设备类型(块设备/字符设备)+设备主编号定位驱动
主从设备号 唯一对应一个设备
关于 linux 中 /dev/null
:
/* drivers/char/mem.c */
static const struct file_operations null_fops = {
.llseek = null_lseek,
.read = read_null,
.write = write_null,
.read_iter = read_iter_null,
.write_iter = write_iter_null,
.splice_write = splice_write_null,
};
static ssize_t read_null(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t write_null(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}
static ssize_t read_iter_null(struct kiocb *iocb, struct iov_iter *to)
{
return 0;
}
ioctl
用户通过 ioctl
向 driver 发送设备操作
static long my_ioctl (struct file *file, unsigned int cmd, unsigned long arg);
arg 请求参数
cmd 32位 记录请求:
- bit31-30 dir : 区别读写请求,
_IOC_NONE
无数据传输,_IOC_READ
读,_IOC_WRITE
写,_IOC_READ | _IOC_WRITE
双向 - bit29-16 size : arg 部分大小
- bit15-8 type : magic number,定义于
Documentation/ioctl/ioctl-number.txt
- bit7-0 nr : 命令序号
linux kernel 定义了宏 _IOC(dir, type, nr, size)
用于转换 cmd
其他辅助宏:_IO(type, nr)
: _IOC(_IOC_NONE,(type),(nr),0)
无数据传输情况_IOR(type, nr, type_of_data)
, _IOW(type, nr, type_of_data)
, _IOWR(type, nr, type_of_data)
,注意第三个参数为 arg 变量类型而非 size