Linux/Android文件系统架构深度剖析

文章目录

一、preface

1、资料快车

1)BSP/驱动开发者如何学习 Linux文件系统?

https://mp.weixin.qq.com/s/8DyBd6_0CodmbrI4nY9QSg

2)文件系统、分区、格式化与挂载实践

https://blog.csdn.net/D2005_10_25/article/details/149746668

3)Linux 文件系统(Linux FS)详解:从基础到实践

https://geek-blogs.com/blog/linux-fs/

4)Linux 文件系统挂载全解析:从基础到进阶实践

https://geek-blogs.com/blog/mount-filesystem-linux/

2、概述

1)文件系统作为内核的五大模块之一

1、Linux的运行离不开文件系统;

2、驱动开发更离不开文件系统这个框架 (用户态与内核态的交互的基础);

2)虽然文件系统实现极其庞大复杂,但实际开发项目中,很少去开发文件系统功能,bring up阶段,我们要做的是几类工作:

1、配置文件系统类型;

2、配置分区 - GPT、fstab

1)增加customer客制化的分区;

2)制作烧录bin、升级固件;

3、裁剪内容 - 根据存储器件容量调整分区

3)文件系统本质是内核和用户空间交互的"中间件"!

4)文件系统是Linux的一个内核模块,fuse则实现用户态文件系统-用户态字符设备;

5)文件系统特点是总体理解不难(无非读写文件),但很杂乱,多种文件系统并存,理清这些关系是难点!

6)Linux与Android的文件系统体系差异?

Android作为Linux一个发行版本,主要是在分区、文件系统应用管理有差异

3、专业术语

复制代码
1. sb : superblock
2. acl : access control list

二、Linux文件系统架构

Linux文件系统指的是整一套机制,它不只是 "磁盘上的文件管理机制",它更是:Linux 内核对"可访问对象"的统一抽象模型

1、文件系统框架图

1)文件系统与设备驱动之间的关系

2)应用程序、VFS与设备驱动

3)全景图

1、从上图可以看出,linux非常依赖VFS文件系统,呼应linux下一切皆文件,后续再从代码中体会"文件",

2、看看一切皆文件的威力,比如经常接触到在用户态使用以下命令

复制代码
cat /dev/ttyS0  --串口
cat /sys/class/power_supply/test_battery/capacity  --电源
cat /proc/interrupts  --中断,它不存在于磁盘、没有物理 inode 表、没有扇区,也不会真正落盘。只是内核在读取时动态生成的一段数据。
dd if=/dev/mmcblk0p1 bs=512 count=1  --块设备

这其中包括了字符设备、块设备、电源、CPU中断,他们是完全不同种类的设备,但却都可以在用户态通过访问文件的方式来访问。

3、总的来说Linux 并不是把所有内容 "变成文件", 而是把用户访问内核各种对象的方式,统一成"文件接口形式"。

2、文件系统之块设备字符设备框架

1)从中可以看出内核部分做了层层封装,需要经过一系列的过程才能真正到达驱动,调用硬件;

2)两个关键点,1)通过svc进入内核;2)设备驱动程序需要将方法挂接到VFS中去;

3、内核如何读取文件?

复制代码
1)内核读取文件依然依赖文件系统提供的API,但不同于应用态API;

2)内核读取文件的场景
1、加载内核模块:insmod 最终通过内核的 kernel_read_file_from_fd() 读取 .ko 文件。
2、读取固件(firmware):设备驱动请求固件时,内核会在 /lib/firmware 下查找并读取文件。
3、挂载文件系统:挂载时需要读取超级块、目录等,但这是通过具体的文件系统驱动完成的,并非通用"文件操作"。
4、读写 /proc 或 /sys 中的内核数据:虽然这些是虚拟文件,但实现时也会使用类似 seq_file 的机制。
5、内核崩溃转储(kdump):将 vmcore 写入文件。

3)内核API
1.打开关闭文件
/android/common/common14-5.15/common/fs/open.c
struct file *filp_open(const char *filename, int flags, umode_t mode)
int filp_close(struct file *file, fl_owner_t id)
2.读取文件
1) 读取文件到内核缓冲区
ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
2) 从文件中读取数据到用户空间缓冲区
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

4、文件系统类型

1)持久文件系统

1、本地文件系统
复制代码
1)常见的有ext4(最常用)、XFS(高性能)、Btrfs(高级特性,如快照)、ext3(ext4 的前身),存在实体于FLASH/磁盘

2)内核代码 linux/fs/ext4/file.c、dir.c

3)Linux具备管理Flash/磁盘上的文件数据功能,包括管理:扇区、块、inode、超级块、io算法
2、网络文件系统
复制代码
1)NFS(Linux/Unix 网络共享)、CIFS/SMB(Windows 网络共享)。
2) 挂载命令
mount -t nfs 192.168.1.100:/data/nfs /mnt/nfs 
3)通信模型
主机1(VFS <-> NFS) <-> 网络 <-> 主机2(NFS <-> VFS)

2)运行时文件系统

复制代码
1、指的是Linux内核动态生成的文件,没有在磁盘里存在的真实文件(而是内存数据),直接在RAM里面进行组织,同样也对接VFS,但不会存盘
2、切记一点就是临时的文件系统就是一堆新建的struct结构体,ls查看时使用printk从串口打印出来!
3、运行时文件系统由于读写都在RAM,一般比较简单,具备基本文件系统元素(VFS等的四大要素-superblokc/inode/file/dentry),但没有复杂的IO算法操作;

2、常见的有devfs、tmpfs、devtmpfs:
1)tmpfs(内存临时文件系统)、sysfs(系统设备信息)、procfs(进程信息)。
2)devfs是文件系统形式的device manager。tmpfs存在在内存和swap中,因此只能保存临时文件。devtmpfs是改进的devfs,也是存在内存中,挂载点是/dev/

3)根文件系统

1、根文件系统是持久文件系统和运行时文件系统的结合,会存盘,但在ram上直接运行;

2、Linux设备的rootfs一般作为过渡使用(切换到真正的文件系统之后不再使用),Android不仅用作启动,还作为文件系统的顶层框架;

3、根文件系统的必要性-面对繁杂的嵌入式系统,存储文件系统的设备种类非常多(网络文件系统、磁盘、SD卡、EMMC等等),Linux将文件系统拆分 根文件系统和用户文件系统,这种分层设计大大提高系统组合灵活性;

4)设备文件系统

复制代码
1、字符设备和块设备与其它文件系统稍微不同,可以看做单独的特殊设备文件系统,两部分组成chrdev(挂接file_ops) 和 tmpfs(创建文件 )组合完成,Linux系统默认支持
2、
vfs_caches_init()
----bdev_cache_init();
----chrdev_init()

3.设备文件系统-可以将字符设备,块设备当做是是独立的文件系统,VFS会调用到file记录的ops,其它文件系统则跑new_sync_read
/android/vendor/amlogic/common/kernel/common/fs/read_write.c
ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
	if (file->f_op->read)
		return file->f_op->read(file, buf, count, pos);
	else if (file->f_op->read_iter)
		return new_sync_read(file, buf, count, pos);
	else
		return -EINVAL;
}

5)小结

1、不同阶段使用的文件系统

Linux文件系统种类多,纷繁复杂,Linux系统还在不同阶段设置不同的文件系统!以Android为例

1、系统启动阶段 - 使用rootfs

2、系统启动完成 - 使用ext4

3、系统运行阶段 - tmpfs / procfs / sysfs - 服务于系统设备

虽说文件系统有差异,但主心骨是一样的

2、文件系统的选用策略
3、文件系统数据流

1、串口看到的内容如何映射到RAM和FLASH?串口把结构体数据打印出来;

2、永久文件系统负责组织FLASH的文件,当然最终还是得读到内存;而临时文件系统,则仿照后半部工作,在内存里直接组织;

3、为什么临时文件系统不存盘?存盘耗时,临时文件系统都是动态生成的,变化频率,存盘意义不大还会导致不必要的耗时;

5、文件系统应用程序

1)常用工具命令

复制代码
cat/ls/mkdir/touch

2)文件系统应用工具

复制代码
以Ext2为例
1.系统应用层文件管理
/android/system/core/fs_mgr
2.系统应用层ext2fs管理工具
/android/external/e2fsprogs/lib/ext2fs