Linux Kernel - mount系统调用

系列目录传送门

Linux Kernel - 文件系统系列


mount系统调用简介

玩过linux的同学对mount系统调用都不会陌生, shell命令mount正是调用内核中的sys_mount函数完成文件系统的挂载. 比如下面的命令:

lqp@lqp-ThinkPad-T540p:~/mnt$ sudo mkfs.minix /dev/ram0
21856 inodes
65535 blocks
Firstdatazone=696 (696)
Zonesize=1024
Maxsize=268966912

lqp@lqp-ThinkPad-T540p:~/mnt$ sudo mount -t minix /dev/ram0 ramdisk

在/dev/ram0中的Ram disk中创建minix文件系统, 并挂载到ramdisk目录下. 这样, 访问ramdisk目录时实际上访问的就是/dev/ram0设备中的minix文件系统, 该文件系统将数据存储在Ram Disk中. 用户通过文件系统的接口与物理磁盘设备交互.

接下来的内容中, 让我们来看一看mount系统调用是如何将文件系统和具体的设备关联起来的.


Minix文件系统示意图

图片取自网络
这里写图片描述
查看原图

从上可以看到, 磁盘块按功能分5部分:
1. Boot block - 用来存放boot loader, 方便操作系统加载的
2. Super block - 用来描述整个文件系统的属性的, 比如inode个数, 设备数据块总数量等
3. I-nodes bitmap和Zone bitmap - 用来管理分配inode和数据页的bitmap, 每一bit代表一个对应的inode或者zone(即数据块)对象
4. inode block - 用来存放inode数据, inode数据中存放了文件的属性, 如文件大小, 创建时间, 文件的数据块对应的块号等
5. 文件的数据块

每一个block对应1024字节, 对应2个扇区(sector, 512字节), 除此之外还有一个重要的概念, page, 对应虚拟内存的内存页面大小, 一般是4096个字节. 这几个概念会不断穿插在文件系统中. 这里简单归纳一下:

  • page - 内存管理相关, 是MMU管理的对象, 可以直接映射到地址空间
  • 文件系统block - 也叫逻辑块, 不同的文件系统可以定义不同的block size
  • sector - 磁盘设备的读取单位, 传统设备的是512字节, 像ssd这种可以配置成一次读取4k. 不过在block io层, 面向设备接口sector对应的是512字节, 设备可以根据自身特性做适配. 在Ram Disk驱动的内部, 就是按4K的page来组织数据的.

约束关系: sector size <= 文件系统block size <= page size, 且成2的指数倍关系.


mount调用流程


如下图所示:
sys_mount
查看原图

其中关键调用点有:

  • step 4: get_fs_type()
  • step 8 : minix_mount()
  • step 11: minix_fill_super()

接下来我们挨个来看一下.


1. get_fs_type()

struct file_system_type *get_fs_type(const char *name)
{
    struct file_system_type *fs;
    const char *dot = strchr(name, '.');
    int len = dot ? dot - name : strlen(name);

    fs = __get_fs_type(name, len);
    if (!fs && (request_module("fs-%.*s", len, name) == 0))
        fs = __get_fs_type(name, len);

    if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
        put_filesystem(fs);
        fs = NULL;
    }
    return fs;
}

可以看到, 该函数接受的是字符串参数, 对minix而言, 则是字符串 “minix”, 然后调用内部函数__get_fs_type来查找内部注册的文件系统链表. 如果链表中没有找到, 那么还会主动加载对应文件系统的驱动来注册所需要的文件系统类型, 然后再查找一次.查找过程中调用了find_filesystem函数, 如下所示:

//lqp comment: 文件系统的查找是简单的根据名字查找文件系统链表

static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
    struct file_system_type **p;
    for (p = &file_systems; *p; p = &(*p)->next)
        if (strncmp(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Linux上安装kernel-headers,可以按照以下步骤进行操作: 1. 打开终端窗口,使用root权限登录系统。 2. 确认系统中已经安装了相应的内核版本,可以使用以下命令查看: uname -r 如果系统中没有安装相应的内核版本,需要先安装内核。 3. 安装kernel-headers,可以使用以下命令: yum install kernel-headers 或者 apt-get install kernel-headers 根据不同的Linux发行版,安装命令可能会有所不同。 4. 安装完成后,可以使用以下命令确认是否安装成功: rpm -qa | grep kernel-headers 或者 dpkg -l | grep kernel-headers 如果能够看到相应的kernel-headers包,说明安装成功。 以上就是在Linux上安装kernel-headers的步骤。 ### 回答2: 在Linux系统中,内核头文件(kernel-headers)包含了编译内核模块所需的头文件和宏定义等信息。它通常被安装在/usr/include/linux目录下。 安装kernel-headers主要是为了在编译驱动程序或者某些软件包的时候需要用到内核头文件。不过,在安装内核头文件之前,我们需要先确认当前的Linux内核版本。 可以通过uname命令获取当前内核版本号,方法如下: $ uname -r 接下来,根据内核版本号选择对应的内核头文件版本进行安装: 1.使用包管理器安装kernel-headers 大多数Linux系统已经预装了包管理器,如yum、apt-get等。使用包管理器安装内核头文件是最简单的方法,只需要执行以下命令即可: - 对于RHEL/CentOS/Fedora系统: $ sudo yum install kernel-devel - 对于Debian/Ubuntu系统: $ sudo apt-get install linux-headers-[kernel_version] 2.手动安装kernel-headers 如果当前系统没有预装包管理器或者无法使用包管理器安装,那么可以通过手动下载和编译的方法来安装内核头文件。具体步骤如下: 第一步,下载对应版本的内核源码包。可以到Linux官网(https://www.kernel.org/)下载最新的内核源码包。 第二步,解压源码包并进入源码目录: $ tar -xvf linux-[kernel_version].tar.xz $ cd linux-[kernel_version] 第三步,编译内核,并安装内核头文件: $ make menuconfig // 对内核进行配置 $ make // 编译内核 $ sudo make modules_install && sudo make install // 安装内核模块和内核头文件 当安装完成后,我们就可以使用内核头文件来编译需要的驱动程序或软件包了。 总之,安装kernel-headers是非常必要的,因为它是编写设备驱动或应用程序时必不可少的文件。对于那些需要编译内核模块的开发者来说,安装kernel-headers是非常必要的。 ### 回答3: Linux是一个强大的操作系统,其最基本的组件就是内核。内核负责管理计算机的硬件资源和操作系统的功能。但是仅有内核是不够的,还需要其他的工具,比如编译器、头文件等,才能正常运行和编译应用程序。 安装kernel-headers是Linux系统中的一种常见操作。kernel-headers包含了内核开发过程中需要的头文件和库文件,这些文件包括内核源代码中的各种宏定义、函数声明等,可以被开发人员用来编写内核模块和驱动程序。 以下是在Linux系统中安装kernel-headers的步骤: 1.首先需要查找系统中已安装的内核版本号。命令行输入“uname -r”,会显示内核版本信息。 2.接下来需要找到相应的kernel-headers包,可以在Linux官网或者各个发行版提供的软件包仓库中搜索。使用命令行安装工具apt-get或者yum来安装。 在Ubuntu系统中,使用命令“apt-get install linux-headers-$(uname -r)”来安装相应的kernel-headers,其中$(uname -r)会自动获取当前系统的内核版本。 在CentOS系统中,使用命令“yum install kernel-devel”,也可以安装相应的kernel-headers。 3.安装完成后,进入/usr/src/kernels目录,可以看到Kernel源码包(tar.gz),以及相应的kernel-headers头文件包。 4.安装完成后,就可以开始编写内核模块或者驱动程序了。 需要注意的一点是,安装kernel-headers并不是必需的,只有在必要的时候才会用到。如果只是普通用户使用Linux系统,一般不需要进行内核级别的编程,因此也不需要安装kernel-headers。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值