linux设备文件

一、前言

  在调用了alloc_chrdev_region函数或register_chrdev_region函数之后可以在/proc/devices中看到该设备的主设备号,比如我注册的hello模块的主设备号为1024,如下图:

  

  现在使用lsmod能看到驱动名,使用cat /proc/devices能看到设备名,那怎么来使用这个设备呢,这个时候我们还需要一个设备文件,这个设备文件就是在应用程序中用open函数打开的文件。

二、创建设备文件

  方法一:手动创建

    使用mknod指令,mknod用法:mknod <filename> <type> <major> <minor>

    filename:设备文件名

    type:设备类型

    major:主设备号

    minor:次设备号

    如:mknod /dev/haha c 1024 0

    这就是说创建了一个/dev/haha的文件,类型是字符设备,主设备号为1024,次设备号为0

  方法二:自动创建

  

三、struct file

  有了设备文件之后,便可以用open打开这个设备文件,然后用read,write等函数来操作这个文件,但是在用户态中怎么调用到内核的东西呢。

  系统每打开一个文件在内核空间都有一个相关联的struct file,它由内核在打开文件时创建,在关闭文件后释放。

  struct file的定义如下:

  

 1 struct file {
 2     union {
 3         struct llist_node    fu_llist;
 4         struct rcu_head     fu_rcuhead;
 5     } f_u;
 6     struct path        f_path;
 7     struct inode        *f_inode;    /* cached value */
 8     const struct file_operations    *f_op;
 9
10     /*
11      * Protects f_ep_links, f_flags.
12      * Must not be taken from IRQ context.
13      */
14     spinlock_t        f_lock;
15     atomic_long_t        f_count;
16     unsigned int         f_flags;
17     fmode_t            f_mode;
18     struct mutex        f_pos_lock;
19     loff_t            f_pos;
20     struct fown_struct    f_owner;
21     const struct cred    *f_cred;
22     struct file_ra_state    f_ra;
23
24     u64            f_version;
25 #ifdef CONFIG_SECURITY
26     void            *f_security;
27 #endif
28     /* needed for tty driver, and maybe others */
29     void            *private_data;
30
31 #ifdef CONFIG_EPOLL
32     /* Used by fs/eventpoll.c to link all the hooks to this file */
33     struct list_head    f_ep_links;
34     struct list_head    f_tfile_llink;
35 #endif /* #ifdef CONFIG_EPOLL */
36     struct address_space    *f_mapping;
37 } __attribute__((aligned(4)));    /* lest something weird decides that 2 is OK */

其中有一个重要成员就是 const struct file_operations *f_op;

struct file_operations的定义如下:

 1 struct file_operations {
 2     struct module *owner;
 3     loff_t (*llseek) (struct file *, loff_t, int);
 4     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
 5     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 6     ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
 7     ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
 8     int (*iterate) (struct file *, struct dir_context *);
 9     unsigned int (*poll) (struct file *, struct poll_table_struct *);
10     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
11     long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
12     int (*mmap) (struct file *, struct vm_area_struct *);
13     int (*open) (struct inode *, struct file *);
14     int (*flush) (struct file *, fl_owner_t id);
15     int (*release) (struct inode *, struct file *);
16     int (*fsync) (struct file *, loff_t, loff_t, int datasync);
17     int (*aio_fsync) (struct kiocb *, int datasync);
18     int (*fasync) (int, struct file *, int);
19     int (*lock) (struct file *, int, struct file_lock *);
20     ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
21     unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
22     int (*check_flags)(int);
23     int (*flock) (struct file *, int, struct file_lock *);
24     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
25     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
26     int (*setlease)(struct file *, long, struct file_lock **, void **);
27     long (*fallocate)(struct file *file, int mode, loff_t offset,
28               loff_t len);
29     void (*show_fdinfo)(struct seq_file *m, struct file *f);
30 #ifndef CONFIG_MMU
31     unsigned (*mmap_capabilities)(struct file *);
32 #endif
33 };

  这里面就包含了打开文件之后可以对文件的操作,在用open打开一个文件之后获得一个文件描述符fd,比如要对该文件进行写操作,则调用write函数,实际上会调用到 file_operations中的read函数,而在内核驱动中是需要自己编写read函数的,这样就能实现应用和内核之间的交互。

  

原文地址:https://www.cnblogs.com/Suzkfly/p/11768444.html

时间: 2024-11-09 00:57:05

linux设备文件的相关文章

使用 udev 管理 Linux 设备文件

本文以通俗的方法阐述 udev 及相关术语的概念.udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例.本文会使那些需要高效地.方便地管理 Linux 设备的用户受益匪浅,这些用户包括 Linux 最终用户.设备驱动开发人员.设备测试人员和系统管理员等等. 概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 eth0, eth1, sda, sdb 等等.通过观察这些设备的内核设备名称,用户通常能知道

Linux设备文件自动生成

第一种是使用mknod手工创建:# mknod <devfilename> <devtype> <major> <minor> 第二种是自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置. 具体udev相关知识这里不详细阐述,可以移步Linux 文件系统与设备文件系统 -- udev 设备文件系统,这里主要讲使用方法. 在驱动用加入对udev 的支持主要做的就是:在驱动初始化的代码里调

Linux 设备文件的创建和mdev

引子 本文是嵌入式企鹅圈开篇--<linux字符设备驱动剖析>的姐妹篇,在上述文章里面我们具体描写叙述了字符设备驱动框架涉及的驱动注冊.通过设备文件来訪问驱动等知识.并明白通过device_create接口并结合mdev来创建设备文件.但没有展开这个知识点. 本文将从代码级去理解Linux设备类和设备文件的创建过程. 通过这两篇文章,我们将能够对linux字符设备驱动的机制和脉络有全面的认识. 下面程序分析没有缩进,编辑了好几次都不行,耐心点才干跟踪完整个代码:-) 一.设备类相关知识 设备类

使用 udev 高效、动态地管理 Linux 设备文件

概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 eth0, eth1, sda, sdb 等等.通过观察这些设备的内核设备名称,用户通常能知道这些是什么类型的设备,但是不知道哪一个设备是他们想要的.例如,在一个充斥着本地磁盘和光纤磁盘的设备名清单 (/dev/sd*) 中,用户无法找到一个序列号为"35000c50000a7ef67"的磁盘.在这种情况下,udev 就能动态地在 /dev目录里产生自己想要的.标识性强的设备文件或者设备链接,以此帮助用户方便快捷地找到所需的

linux 设备文件

设备文件: b:按块为单位,随机访问的设备 如:硬盘 c:按字符为单位,线性设备 如:键盘 [[email protected] tm]# ll /dev/crw-rw---- 1 root audio   14,   12 Feb 18 00:28 adspbrw-rw---- 1 root floppy   2,    0 Feb 18 00:28 fd0 14,   12和2,    0分别表示 主设备号 标识设备类型 次设备号 标识同一种类型中不同的设备 mknod    创建设备文件

Linux设备文件简介(转载)

Linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取).块设备(有缓冲且可以随机存取).每个字符设备和块设备都必须有主.次设备号,主设备号相同的设 备是同类设备(使用同一个驱动程序).这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件, 又称为"虚拟设备").每个设备在 /dev 目录下都有一个对应的文件(节点).可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号.内核能够识别的所

Linux 设备文件简介

概述 设备管理是 Linux 中比较基础的知识,与内核的关系也比较密切.随着 Udev 的广泛使用,Linux 发行版的智能程度越来越高,许多 Linux 新用户对 /dev 目录下的东西变得不再熟悉,有时候遇见问题就会抓狂. Linux 中的设备按照存取方式的不同,可以分为两种: 字符设备 无缓冲且只能顺序存取 块设备 有缓冲且可以随机(乱序)存取 而按照是否对应物理实体,也可以分为两种: 物理设备 对实际存在的物理硬件的抽象 虚拟设备 不依赖于特定的物理硬件,仅是内核自身提供的某种功能 无论

/dev设备文件命名或符号链接建立

udev是一个用户空间服务,负责监听内核设备变动事件,从/sysfs---中读取发生变动的设备属性信息,遍历 命名规则文件,进行属性规则的匹配,如果匹配,就进行执行命名自定义动作 udev 的规则和规则文件 规则文件是 udev 里最重要的部分,默认是存放在 /etc/udev/rules.d/下.所有的规则文件必须以".rules"为后缀名.RHEL 有默认的规则文件,这些默认规则文件不仅为设备产生内核设备名称,还会产生标识性强的符号链接.例如: 1 2 [[email protec

linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是在linux-2.6.29/include/linux下面寻找源文件.#include <asm/***.h> 是在linux-2.6.29/arch/arm/include/asm下面寻找源文件.#include <mach/***.h> 是在linux-2.6.29/arch/ar