设为首页 加入收藏

TOP

linux字符设备(一)
2023-08-26 21:10:46 】 浏览:150
Tags:linux 符设备

设计字符设备

文件系统调用系统IO的内核处理过程

inode索引节点是文件系统中的一种数据结构,用于存储文件的元数据信息,包括文件的大小、访问权限、创建时间、修改时间等。每个文件在文件系统中都对应着一个唯一的inode节点,通过inode节点可以查找到文件的实际数据块的位置。inode节点通常存储在磁盘的inode表中,文件系统通过inode号来访问和管理文件。

file_operation结构体是函数指针表,用于定义文件的操作方法。当应用程序通过文件描述符打开文件时,内核会根据文件描述符找到对应的inode节点,并获取与inode节点关联的file_operation表。通过file_operation表中的函数指针,内核可以调用相应的函数来执行文件操作,如open、read、write、close等。不同内核可以有不同的file_operation表,因为不同的内核可能有不同的文件操作方法和特性。

task_struct结构体用于描述和管理进程,内容很多很复杂。里面有个成员变量是struct files_struct *files,用于存储与进程相关的文件描述符表的信息(文件描述符表记录了进程打开的文件以及相应的操作权限等信息)。要想获取进程的文件描述符相关信息,需要通过访问task_struct结构体的files指针来获取files_struct结构体,进而访问文件描述符表的信息。

files_struct结构体用于跟踪和管理进程打开的文件。fd_array[]为指针数组,用于存储进程打开的文件描述符的信息,即每个文件描述符都对应一个files_struct。通过fd_array数组可以快速访问和操作这些文件描述符,数组索引值对应着文件描述符的值。

 

硬件层原理

思路:把底层寄存器配置操作放在文件操作接口里,新建一个文件绑定该文件操作接口,应用程序通过操作指定文件来配置底层寄存器。

基本接口实现:查原理图,数据手册,确定底层需要配置的寄存器。类似于裸机开发。实现一个文件的底层操作接口,这是文件的基本特征。

struct file_operations存放在内核/include/linux/fs.h

struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
        int (*iterate_shared) (struct file *, struct dir_context *);
        __poll_t (*poll) (struct file *, struct poll_table_struct *);
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        unsigned long mmap_supported_flags;
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *, fl_owner_t id);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, loff_t, loff_t, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
        ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
        int (*check_flags)(int);
        int (*flock) (struct file *, int, struct file_lock *);
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
        ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
        int (*setlease)(struct file *, long, struct file_lock **, void **);
        long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);
        void (*show_fdinfo)(struct seq_file *m, struct file *f);
#ifndef CONFIG_MMU
        unsigned (*mmap_capabilities)(struct file *);
#endif
        ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int);
        int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
        int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
        int (*fadvise)(struct file *, loff_t, loff_t, int);
} __randomize_layout;

几乎所有成员都是函数指针,用来实现文件的具体操作。 

 

驱动层原理

设备号(dev_t)是uint32_t类型,主设备号(高12位)+次设备号(低20位)。主设备号用于标识该驱动所管理的设备类型,次设备号用于标识同一类型设备的具体设备实例。

 

cdev_init()存放在内核/fs/char_dev.c。

cdev_init()  //把用户构建的file_operations结构体记录在内
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇docker_1 下一篇深入理解Linux内核——内存管理(..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目