Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux rootfs_hdfs shell命令

Linux rootfs_hdfs shell命令

作者头像
全栈程序员站长
发布于 2022-11-10 12:43:43
发布于 2022-11-10 12:43:43
9080
举报

大家好,又见面了,我是你们的朋友全栈君。

本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核。总体上说 Linux下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 VFS(Virtual FilesystemSwitch),三是挂载到 VFS 中的各实际文件系统,例如 ext2,jffs 等。本文侧重于通过具体的代码分析来解释 Linux内核中 VFS 的内在机制,在这过程中会涉及到上层文件系统调用和下层实际文件系统的如何挂载。文章试图从一个比较高的角度来解释Linux 下的 VFS 文件系统机制。

1.摘要

本 文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核。总体上说 Linux下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 VFS(Virtual FilesystemSwitch),三是挂载到 VFS 中的各实际文件系统,例如 ext2,jffs 等。本文侧重于通过具体的代码分析来解释 Linux内核中 VFS 的内在机制,在这过程中会涉及到上层文件系统调用和下层实际文件系统的如何挂载。文章试图从一个比较高的角度来解释Linux 下的 VFS文件系统机制,所以在叙述中更侧重于整个模块的主脉络,而不拘泥于细节,同时配有若干张插图,以帮助读者理解。

相对来说,VFS 部分的代码比较繁琐复杂,希望读者在阅读完本文之后,能对 Linux 下的 VFS整体运作机制有个清楚的理解。建议读者在阅读本文前,先尝试着自己阅读一下文件系统的源代码,以便建立起 Linux下文件系统最基本的概念,比如至少应熟悉 super block, dentry, inode,vfsmount等数据结构所表示的意义,这样再来阅读本文以便加深理解。

2.VFS 概述

VFS 是一种软件机制,也许称它为 Linux的文件系统管理者更确切点,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵VFS 的目录树(在 Linux 的源代码里称之为 namespace),实际上便是在内存中建立相应的数据结构。VFS 目录树在Linux 的文件系统模块中是个很重要的概念,希望读者不要将其与实际文件系统目录树混淆,在笔者看来,VFS中的各目录其主要用途是用来提供实际文件系统的挂载点,当然在 VFS中也会涉及到文件级的操作,本文不阐述这种情况。下文提到目录树或目录,如果不特别说明,均指 VFS 的目录树或目录。图 1是一种可能的目录树在内存中的影像:

图 1:VFS 目录树结构

这 里的文件系统是指可能会被挂载到目录树中的各个实际文件系统,所谓实际文件系统,即是指VFS中的实际操作最终要通过它们来完成而已,并不意味着它们一定要存在于某种特定的存储设备上。比如在笔者的 Linux 机器下就注册有”rootfs”、”proc”、”ext2″、”sockfs” 等十几种文件系统。

3.1 数据结构

在 Linux 源代码中,每种实际的文件系统用以下的数据结构表示:

struct file_system_type { const char *name; int fs_flags; struct super_block *(*read_super) (struct super_block *, void *, int); struct module *owner; struct file_system_type * next; struct list_head fs_supers; };

注册过程实际上将表示各实际文件系统的 struct file_system_type数据结构的实例化,然后形成一个链表,内核中用一个名为 file_systems 的全局变量来指向该链表的表头。

3.2 注册 rootfs 文件系统

在 众多的实际文件系统中,之所以单独介绍 rootfs 文件系统的注册过程,实在是因为该文件系统 VFS 的关系太过密切,如果说ext2/ext3 是 Linux 的本土文件系统,那么 rootfs 文件系统则是 VFS 存在的基础。一般文件系统的注册都是通过module_init 宏以及 do_initcalls() 函数来完成(读者可通过阅读module_init 宏的声明及arch\i386\vmlinux.lds 文件来理解这一过程),但是 rootfs 的注册却是通过 init_rootfs()这一初始化函数来完成,这意味着 rootfs 的注册过程是 Linux 内核初始化阶段不可分割的一部分。

在2.6中,

kernel_start()

|____start_kernel()

|____vfs_caches_init()(fs/dcache.c)

|____dcache_init()

|____inode_init()

|____files_init()

|____mnt_init()

| |____init_rootfs()

| | |___register_filesystem(&rootfs_fs_type)

| |____init_mount_tree()

|____bdev_cache_init()

|____chrdev_init()

init_rootfs() 通过调用register_filesystem(&rootfs_fs_type) 函数来完成 rootfs文件系统注册的,其中rootfs_fs_type 定义如下:

struct file_system_type rootfs_fs_type = { name: "rootfs", read_super: ramfs_read_super, fs_flags: FS_NOMOUNT|FS_LITTER, owner: THIS_MODULE, }

注册之后的 file_systems 链表结构如下图2所示:

图 2: file_systems链表结构

既 然是树,所以根是其赖以存在的基础,本节阐述 Linux 在初始化阶段是如何建立根结点的,即 “/”目录。这其中会包括挂载rootfs 文件系统到根目录 “/” 的具体过程。构造根目录的代码是在 init_mount_tree() 函数(fs\namespace.c) 中。

首 先,init_mount_tree() 函数会调用 do_kern_mount(“rootfs”, 0, “rootfs”,NULL) 来挂载前面已经注册了的 rootfs文件系统。这看起来似乎有点奇怪,因为根据前面的说法,似乎是应该先有挂载目录,然后再在其上挂载相应的文件系统,然而此时 VFS似乎并没有建立其根目录。没关系,这是因为这里我们调用的是do_kern_mount(),这个函数内部自然会创建我们最关心也是最关键的根目录(在 Linux 中,目录对应的数据结构是struct dentry)。

在这个场景里,do_kern_mount() 做的工作主要是:

1)调用 alloc_vfsmnt() 函数在内存里申请了一块该类型的内存空间(struct vfsmount*mnt),并初始化其部分成员变量。(mnt : avfs-internal representation of a mount point)

2) 调用 get_sb_nodev() 函数在内存中分配一个超级块结构 (struct super_block)sb,并初始化其部分成员变量,将成员 s_instances 插入到 rootfs 文件系统类型结构中的 fs_supers指向的双向链表中。

(sb:描述文件系统信息,例如块大小、文件系统版本号、上次mount 的时间等等。)

3) 通过 rootfs 文件系统中的 read_super 函数指针调用 ramfs_read_super()函数。还记得当初注册rootfs 文件系统时,其成员 read_super 指针指向了 ramfs_read_super()函数,参见图2.

4) ramfs_read_super() 函数调用 ramfs_get_inode() 在内存中分配了一个 inode 结构(struct inode) inode,并初始化其部分成员变量,其中比较重要的有 i_op、i_fop 和 i_sb:

inode->i_op = &ramfs_dir_inode_operations; inode->i_fop = &dcache_dir_ops; inode->i_sb = sb;

(一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是 ls-l 命令看到的那些信息,这些信息存在inode中而不是数据块中。每个文件都有一个inode,一个块组中的所有 inode组成了inode表。)

这使得将来通过文件系统调用对 VFS 发起的文件操作等指令将被 rootfs 文件系统中相应的函数接口所接管。

图3

6) 将 mnt 中的 mnt_sb 指针指向 sb,mnt_root 和 mnt_mountpoint 指针指向dentry,而 mnt_parent指针则指向自身。

init_task是系统中的0号进程,也就是第一个进程,这个进程永远不会被撤消,它的描述符被静态的分配到内核数据段中,也就是说init_task的进程描述符是预先由编译器分配的,在运行的过程中保持不变,而其它描述符是在运行的过程中,由系统根据当前的内存状况随机分配的,撤消的时再在归还给系统。

init_task进程0,(start_kernel()->sched_init()->init_idle(current)????)总结一下有如下几个要点:

1. 进程0是所有其他进程的祖先,也称作idle进程或swapper进程。 2. 进程0是在系统初始化时由kernel自身从无到有创建。(过程集中在start_kernel函数内) 3. 进程0的数据成员大部分是静态定义的,即由预先定义好的(如上)INIT_TASK, INIT_MM等宏初始化。

进程0的描述符init_task定义在arch/mips/kernel/init_task.c,由INIT_TASK宏初始化。init_mm等结构体定义在include/linux/init_task.h内,为init_task成员的初始值,分别由对应的初始化宏如INIT_MM等初始化,

进程1:

进程0最终会通过调用kernel_thread创建一个内核线程去执行init函数,这个新创建的内核线程即Process1(这时还是共享着内核线程0的资源属性如地址空间等)。init函数继续完成剩余的内核初始化,并在函数的最后调用execve系统调用装入用户空间的可执行程序/sbin/init,这时进程1就拥有了自己的属性资源,成为一个普通进程(init进程)。至此,内核初始化和启动过程结束。下面就进入了用户空间的初始化,最后运行shell登陆界面。

(注:Init进程一直存活,因为它创建和监控在操作系统外层执行的所有进程的活动。)

进程1的创建过程如下:

start_kernel-> rest_init -> kernel_thread-> init

static void noinline rest_init(void)

__releases(kernel_lock)

{

system_state = SYSTEM_BOOTING_SCHEDULER_OK;

kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);

numa_default_policy();

unlock_kernel();

__preempt_enable_no_resched();

schedule();

preempt_disable();

cpu_idle();

}

执行schedule()启动进程1后,进程0便调用cpu_idle()函数进入睡眠状态。

下面看一下kernel_thread函数

pid_t kernel_thread(int (*fn)(void *), void *arg, unsignedlong flags)

{

struct pt_regs regs;

longpid;

memset(&regs, 0, sizeof(regs));

regs.ARM_r1 = (unsigned long)arg;

regs.ARM_r2 = (unsigned long)fn;

regs.ARM_r3 = (unsigned long)do_exit;

regs.ARM_pc = (unsigned long)kernel_thread_helper;

regs.ARM_cpsr = SVC_MODE;

pid= do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs,0, NULL, NULL);

MARK(kernel_thread_create, “%ld %p”, pid, fn);

return pid;

}

可以发现kernel_thread 最终也是调用的do_fork完成内核线程的创建。

do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, pregs, 0, NULL,NULL);

flag参数标志决定了新创建的进程的行为方式以及父子进程之间共享的资源种类,这里用到的几个flag标志意思如下:

CLONE_FS 父子进程共享文件系统信息

CLONE_SIGHAND 父子进程共享信号处理函数

CLONE_VM 父子进程共享地址空间

CLONE_UNTRACED 防止跟踪进程在子进程上强制执行CLONE_PTRACE

看看新创建的内核线程1(Process 1)做了些什么事: ( 即init函数)

static int init(void * unused)

{

lock_kernel();

set_cpus_allowed(current, CPU_MASK_ALL);

child_reaper = current;

smp_prepare_cpus(max_cpus);

init_hardirqs();

do_pre_smp_initcalls();

smp_init();

sched_init_smp();

cpuset_init_smp();

……

run_init_process(“/sbin/init”);

run_init_process(“/etc/init”);

run_init_process(“/bin/init”);

run_init_process(“/bin/sh”);

panic(“No init found. Try passing init= option tokernel.”);

}

这里的 run_init_process 实际上就是通过execve()来运行 init程序。这里首先运行/sbin/init,如果失败再运行/etc/init,然后是/bin/init,然后是/bin/sh(也就是说,init可执行文件可以放在上面代码中的4 个目录中都可以),如果都失败,则可以通过在系统

启动时在添加的启动参数来指定init,比如init=/ linuxrc。

run_init_process源码如下,最终通过execve系统调用执行/sbin/init程序。

static void run_init_process(char*init_filename)

{

argv_init[0] = init_filename;

execve(init_filename, argv_init, envp_init);

}

Exec函数族(execve为其中一种)提供了一个在进程中启动另外一个程序执行的方法。它可以根据指定的文件名或目录找到可执行文件,并用它来取代原先调用进程的属性包括数据段,代码段和堆栈段等。在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。这里在执行execve之前,进程1还是共享着内核线程0资源属性的内核线程。执行execve后(即执行了用户空间的init程序),此时,进程1就拥有了自己的地址空间等属性,成为一个普通进程。

这 样,当 do_kern_mount() 函数返回时,以上分配出来的各数据结构和 rootfs 文件系统的关系将如上图 3所示。图中 mnt、sb、inode、dentry结构块下方的数字表示它们在内存里被分配的先后顺序。限于篇幅的原因,各结构中只给出了部分成员变量,读者可以对照源代码根据图中所示按图索骥,以加深理解。

最后,init_mount_tree() 函数会为系统最开始的进程(即 init_task进程)准备它的进程数据块中的namespace 域,主要目的是将 do_kern_mount() 函数中建立的 mnt 和dentry 信息记录在了 init_task 进程的进程数据块中,这样所有以后从 init_task 进程 fork出来的进程也都先天地继承了这一信息,在后面用sys_mkdir 在 VFS中创建一个目录的过程中,我们可以看到这里为什么要这样做。为进程建立 namespace 的主要代码如下:

namespace = kmalloc(sizeof(*namespace), GFP_KERNEL); list_add(&mnt->mnt_list, &namespace->list); //mnt is returned by do_kern_mount() namespace->root = mnt; init_task.namespace = namespace; for_each_task(p) { get_namespace(namespace); p->namespace = namespace; } set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root); set_fs_root(current->fs, namespace->root, namespace->root->m

该段代码的最后两行便是将 do_kern_mount() 函数中建立的 mnt 和 dentry 信息记录在了当前进程的 fs结构中。

以 上讲了一大堆数据结构的来历,其实最终目的不过是要在内存中建立一颗 VFS 目录树而已,更确切地说,init_mount_tree() 这个函数为 VFS 建立了根目录”/”,而一旦有了根,那么这棵数就可以发展壮大,比如可以通过系统调用 sys_mkdir在这棵树上建立新的叶子节点等,所以系统设计者又将 rootfs 文件系统挂载到了这棵树的根目录上。关于 rootfs这个文件系统,读者如果看一下前面图 2 中它的file_system_type 结构,会发现它的一个成员函数指针 read_super指向的是 ramfs_read_super,单从这个函数名称中的ramfs,读者大概能猜测出这个文件所涉及的文件操作都是针对内存中的数据对象,事实上也的确如此。从另一个角度而言,因为 VFS本身就是内存中的一个数据对象,所以在其上的操作仅限于内存,那也是非常合乎逻辑的事。在接下来的章节中,我们会用一个具体的例子来讨论如何利用rootfs所提供的函树为 VFS 增加一个新的目录节点。

VFS中各目录的主要用途是为以后挂载文件系统提供挂载点。所以真正的文件操作还是要通过挂载后的文件系统提供的功能接口来进行。

在2.6中,

init_mount_tree()(fs/namespace.c)

|____do_kern_mount(“rootfs”,0,”rootfs”,0)(fs/super.c)

|____vfs_kern_mount(“rootfs”)(fs/super.c)

|___mnt=alloc_vfsmnt(“rootfs”)(分配mnt结构)

|___get_sb(fs_type,…,ramfs_fill_super,mnt)

(就是调用rootfs_get_sb(),get_sb_nodev(),ramfs_fill_super()分配sb块)

|___inode=ramfs_get_inode(sb,…)(分配inode)

|___root=d_alloc_root(inode)(分配root结构,填充’/’目录)

注意:start_kernel()–>…–>kernel_thread(“init”,***)–>init()(在运行内核init前,根文件系统已经建立起来了)–>do_basic_setup();(调用rootfs_initcall()由cpio档填充文件系统内容,并作为根文件系统)–>如果在文件系统中发现了/init文件,交给init处理,否则调用prepare_namespace()继续装载其它文件系统,并mount到之前的rootfs上,并作为根文件系统和运行其上的/init)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/188053.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月28日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux内核有没有rootfs,Linux内核rootfs的初始化过程[通俗易懂]
在Linux shell中执行mount命令,通常可以看到某个做了文件系统的磁盘分区或flash分区或内存文件系统做为所谓的根文件系统被mount到了挂载点/处。
全栈程序员站长
2022/11/10
2.5K0
Linux根目录的文件系统是如何被挂载的
该方法首先拿到上面注册的rootfs文件系统,再调用vfs_kern_mount方法挂载该系统,然后将挂载结果mnt赋值给类型为struct path的变量root,同时将root.dentry赋值为mnt->mnt_root,即挂载的rootfs文件系统的根目录。
KINGYT
2019/06/11
3.8K0
Linux根文件系统(rootfs原理详解)
文件系统是os用来明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。 文件系统由三部分组成:文件系统的接口,对对象操作和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。
JavaEdge
2021/02/23
13.6K0
linux initramfs,Linux INITRAMFS 与 INITRD「建议收藏」
第一步:Kernel首先要注册一个RAMFS文件系统类型(实际注册的类型名称是”ROOTFS”,后续我们可以看到它实际上就是”RAMFS”);
全栈程序员站长
2022/09/22
1K0
rootfs文件_clang编译android内核
ramdisk.img是编译Android生成的一个镜像文件,最后和kernel一起打包生成boot.img镜像。ramdisk.img中主要是存放android启动后第一个用户进程init可执行文件和init.*.rc等相关启动脚本以及sbin目录下的adbd工具。
全栈程序员站长
2022/11/08
2.5K0
android rootfs的挂载流程[通俗易懂]
out/host/linux-x86/bin/mkbootfs out/target/product//root | out/host/linux-x86/bin/minigzip > out/target/product//ramdisk.img 上述命令分两步进行: 1.out/host/linux-x86/bin/mkbootfs out/target/product/*/root 生成一个cpio文件,利用cpio 可将文件或目录从文件库获取出来或将散列文件拷贝到文件库。 2.out/host/linux-x86/bin/minigzip 将生成的cpio文件压缩成一个gzip格式的文件“out/target/product/*/ramdisk.img“
全栈程序员站长
2022/11/08
2.6K0
解析Linux中的VFS文件系统之文件系统的注册(二)
继上一篇文章:https://cloud.tencent.com/developer/article/1053882 3. 文件系统的注册 这里的文件系统是指可能会被挂载到目录树中的各个实际文件系统,所谓实际文件系统,即是指VFS 中的实际操作最终要通过它们来完成而已,并不意味着它们一定要存在于某种特定的存储设备上。比如在笔者的 Linux 机器下就注册有 "rootfs"、"proc"、"ext2"、"sockfs" 等十几种文件系统。 3.1 文件系统的数据结构 在 Linux 源代码中,每种实际的文件
233333
2018/03/07
2.1K0
解析Linux中的VFS文件系统之文件系统的注册(二)
Linux根目录的文件系统是如何被挂载的 . 续
该方法中的saved_root_name变量的值是在kernel启动时,由传给kernel的root参数决定的,对应的设置方法如下:
KINGYT
2019/06/11
4.8K0
深入理解Linux文件系统之文件系统挂载(上)
我们知道,Linux系统中我们经常将一个块设备上的文件系统挂载到某个目录下才能访问这个文件系统下的文件,但是你有没有思考过:为什么块设备挂载之后才能访问文件?挂载文件系统Linux内核到底为我们做了哪些事情?是否可以不将文件系统挂载到具体的目录下也能访问?下面,本文将详细讲解Linxu系统中,文件系统挂载的奥秘。
用户7244416
2021/08/06
2K0
从 lsof 开始,深入理解Linux虚拟文件系统
原文:https://juejin.im/post/6875110082724659213 作者:有疑说
入门笔记
2022/06/02
4480
从 lsof 开始,深入理解Linux虚拟文件系统
从 lsof 开始,深入理解 Linux 虚拟文件系统!
作者:cyningsun 链接:https://juejin.im/post/6875110082724659213
杰哥的IT之旅
2020/09/28
1.4K0
从 lsof 开始,深入理解 Linux 虚拟文件系统!
文件系统专栏 | 之文件系统挂载
ext4文件系统挂载 大家可以使用以下命令挂载一个u盘到 /mnt目录下: mount -t ext4  /dev/sda1 /mnt 其中mount这个应用程序就是使用了mount函数进行系统调用,其系统调用为: SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,   char __user *, type, unsigned long, flags, void __user *, data) {  return
刘盼
2022/08/31
3.4K0
文件系统专栏 | 之文件系统挂载
内核文件系统挂载和Open文件
ext4挂载 在linux 5.x的内核中,实际文件系统的挂载采用新的挂载API,引入了struct fs_context用于内部文件系统挂载的信息。 应用端发起mount命令,进入mount系统调用,执行do_mount的函数 // vfs层保留该小节需要的核心字段 struct super_block { // 文件系统类型 struct file_system_type *s_type; // 文件系统super_block的操作函数 const struct super_operations
用户4700054
2022/08/17
1.1K0
300来行代码带你实现一个能跑的最小Linux文件系统
Linux作为一个类UNIX系统,其文件系统保留了原始UNIX文件系统的表象形式,它看起来是这个样子:
Linux阅码场
2019/09/02
4.9K0
300来行代码带你实现一个能跑的最小Linux文件系统
挂载文件系统出现"kernel panic..." 史上最全解决方案
bootargs为: noitinrd root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200 init=/linurc mem=64M
韦东山
2020/09/30
2.1K0
Linux启动流程 梳理| 思维导图 | 流程图 | 值得收藏
嵌入式与Linux那些事
2024/06/11
3320
Linux启动流程 梳理| 思维导图 | 流程图  | 值得收藏
【openwrt】【overlayfs】Openwrt系统overlayfs挂载流程
overlayfs是一种叠加文件系统,在openwrt和安卓系统中都有很广泛的应用,overlayfs通常用于将只读根文件系统(rootfs)和可写文件系统(jffs2)进行叠加后形成一个新的文件系统,这个新的文件系统“看起来”是可读写的,这种做法的好处是:
知否知否应是绿肥红瘦
2025/02/19
3020
【openwrt】【overlayfs】Openwrt系统overlayfs挂载流程
Ext3 mount过程分析
本质上,Ext3 mount的过程实际上是inode被替代的过程。例如,/dev/sdb块设备被mount到/mnt/alan目录。那么mount这个过程所需要解决的问题就是将/mnt/alan的dentry目录项所指向的inode屏蔽掉,然后重新定位到/dev/sdb所表示的inode索引节点。在没有分析阅读linux vfs mount代码的时候,我的想法是修改dentry所指向的inode索引节点,以此实现mount文件系统的访问。经过分析,在实际的vfs mount实现过程中,还是和我原始的想法略有差别,但是,基本目标还是相同的。
py3study
2020/01/07
1.6K0
《Linux内核分析》之构造一个简单的Linux系统MenuOS 实验总结
在原来配置的基础上,make menuconfig选中如下选项重新配置Linux,使之携带调试信息
WindCoder
2018/09/20
2.3K0
《Linux内核分析》之构造一个简单的Linux系统MenuOS 实验总结
深入理解Linux文件系统之文件系统挂载(下)
注:老内核使用的是vfsmount来描述文件系统的一次挂载,现在内核都使用mount来描述,而vfsmount被内嵌到mount中,主要来描述文件系统的超级块和跟dentry。
用户7244416
2021/08/06
1.9K0
推荐阅读
相关推荐
Linux内核有没有rootfs,Linux内核rootfs的初始化过程[通俗易懂]
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档