Linux源码阅读笔记16-文件系统关联及字符设备操作

简介: Linux源码阅读笔记16-文件系统关联及字符设备操作

文件系统关联

设备文件都是由标准函数处理,类似普通文件。设备文件也是通过虚拟文件系统来管理的,和普通文件都是通过完全相同的接口访问的。

inode中设备文件的成员数据

  • 虚拟文件系统每个文件都关联到一个inode,用于管理文件的属性。源码如下:

  • 唯一地标识与一个设备文件关联的设备,内核在i_mode中存储文件类型(面向块,面向字符),而且在i_rdev中存储主从设备号。主从设备号在内核中合并为一种变量类型为dev*_t
  • 在内核开发当中认为必要的时候会进行修改,只应该使用两个函数imajoriminor来从i_rdev提取主设备号和从设备号,这两个函数都只需要一个指向inode实例的指针作为参数。
  • const struct file_operations* i_fop是一组函数指针的集合,包括许多文件操作(打开,读取,写入等等),这些由虚拟文件系统使用来处理块设备。内核会根据inode表示块设备还是字符设备,使用i_bdevi_cdev指向更具体的信息。
  • 实际上,inodeVFS使用的一个现象,用于存放内核在操作文件或目录时所需要的全部信息。索引节点有两种:一种是VFS节点,存在内核中;另一种具体文件系统的索引节点,存在磁盘当中,使用时将其读入内存填充VFS节点,之后对VFS索引节点的任何修改都将写回磁盘和磁盘的索引节点。

标准文件操作

在打开一个设备文件时,各种文件系统的实现基本都会调用init_special_inode函数,为块设备或字符设备创建一个inode。具体源码如下:

void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
  inode->i_mode = mode;
  if (S_ISCHR(mode)) {
    inode->i_fop = &def_chr_fops;
    inode->i_rdev = rdev;
  } else if (S_ISBLK(mode)) {
    inode->i_fop = &def_blk_fops;
    inode->i_rdev = rdev;
  } else if (S_ISFIFO(mode))
    inode->i_fop = &pipefifo_fops;
  else if (S_ISSOCK(mode))
    ; /* leave it no_open_fops */
  else
    printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
          " inode %s:%lu\n", mode, inode->i_sb->s_id,
          inode->i_ino);
}
EXPORT_SYMBOL(init_special_inode);
  • 除了通过mode传递进来的设备类型之外,底层文件系统还必须返回主从设备号。代码中会根据设备类型,向inode提供不同的文件操作。

字符设备标准操作

每个设备文件都需要一组独立、自定义操作。具体源码如下:

/*
 * Dummy default file-operations: the only thing this does
 * is contain the open that then fills in the correct operations
 * depending on the special file...
 */
const struct file_operations def_chr_fops = {
  .open = chrdev_open,
  .llseek = noop_llseek,
};

块设备标准操作

与自负设备相比,块设备操作的指针会集中到一个叫做blk_fops通用的结构体。具体源码如下:

const struct file_operations def_blk_fops = {
  .open   = blkdev_open,
  .release  = blkdev_close,
  .llseek   = block_llseek,
  .read_iter  = blkdev_read_iter,
  .write_iter = blkdev_write_iter,
  .iopoll   = blkdev_iopoll,
  .mmap   = generic_file_mmap,
  .fsync    = blkdev_fsync,
  .unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
  .compat_ioctl = compat_blkdev_ioctl,
#endif
  .splice_read  = generic_file_splice_read,
  .splice_write = iter_file_splice_write,
  .fallocate  = blkdev_fallocate,
};

字符设备操作

前面说到过,字符设备是由struct cdev表示,同时内核维护一个数据库,包括所有活动的cdev实例。

表示字符设备具体源码如下

打开设备文件

通过chrdev_open打开字符设备的通用函数。具体源码如下:

  • 假设表示设备文件的inode没有被打开过,根据给出的设备编号,kobject_lookup查询字符设备的数据库并返回与该驱动程序关联的kobject实例,返回值可用于获取cdev实例。

  • 获得对应设备的cdev实例,内核通过cdev->ops还可以访问特定于设备的file_operations。接下来我们就设备的各种数据结构之间的关联关系如下图所示:

读写操作

读写字符设备文件,其实虚拟文件和设备驱动程序代码之间已建立关联。调用标准库的读写操作,向内核发出一些系统调用,最终会调用file_operations结构体中的相关操作(重点是read和write)。只需要调用内核函数来完成操作,具体源码如下:

相关文章
|
3月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
214 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
17天前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
65 15
|
22天前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
155 7
|
22天前
|
存储 运维 监控
Linux--深入理与解linux文件系统与日志文件分析
深入理解 Linux 文件系统和日志文件分析,对于系统管理员和运维工程师来说至关重要。文件系统管理涉及到文件的组织、存储和检索,而日志文件则记录了系统和应用的运行状态,是排查故障和维护系统的重要依据。通过掌握文件系统和日志文件的管理和分析技能,可以有效提升系统的稳定性和安全性。
43 7
|
1月前
|
安全 Linux 数据安全/隐私保护
深入Linux操作系统:文件系统和权限管理
在数字世界的海洋中,操作系统是连接用户与硬件的桥梁,而Linux作为其中的佼佼者,其文件系统和权限管理则是这座桥梁上不可或缺的结构。本文将带你探索Linux的文件系统结构,理解文件权限的重要性,并通过实际案例揭示如何有效地管理和控制这些权限。我们将一起航行在Linux的命令行海洋中,解锁文件系统的奥秘,并学习如何保护你的数据免受不必要的访问。
|
2月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
96 8
|
2月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
48 5
|
2月前
|
存储 Linux 文件存储
Linux文件系统
Linux文件系统 一切皆文件 在Linux中,“一切皆文件”的概念意味着系统中的所有资源,包括硬件设备、目录及进程等,均被视为文件。这种设计简化了操作和管理,具体包括: 普通文件:存储数据的常规文件。 目录文件:包含其他文件和子目录的文件。 进程文件:在/proc目录下代表系统中运行的进程。 设备文件:位于/dev目录,代表硬件设备。 网络字节流套接字文件:用于网络通信的数据流。 链接文件:指向另一个文件的符号链接或硬链接。 管道文件:用于进程间通信的文件。
61 7
|
3月前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
55 4
|
3月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
125 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库