linux设备文件

Posted Suzkfly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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函数的,这样就能实现应用和内核之间的交互。

  

以上是关于linux设备文件的主要内容,如果未能解决你的问题,请参考以下文章

Linux SPI通过设备树文件添加设备

c_cpp 快速代码片段,用于在统计(阻止)/ dev / rdsk中的设备时验证fstat64和stat64的行为。

来自 FragmentActivity 的片段在某些设备上不显示背景图像

[linux][c/c++]代码片段01

linux设备模型与sys文件系统

[linux][c/c++]代码片段02