首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用littlefs-fuse在PC端调试littlefs文件系统

使用littlefs-fuse在PC端调试littlefs文件系统

作者头像
zqb_all
修改于 2020-02-16 04:47:58
修改于 2020-02-16 04:47:58
2.9K0
举报
文章被收录于专栏:QB杂货铺QB杂货铺

背景

littlefs是arm面向嵌入式设备推出的一款掉电安全的小型文件系统,具有抗掉电,动态磨损均衡,RAM/ROM需求少等特点,具体介绍可见 https://github.com/ARMmbed/littlefs

作为一款在嵌入式设备上使用的文件系统,出问题时,一般是需要将数据dump出来进行分析的。此时就需要PC端的调试工具了。

littlefs-fuse简介

这个项目提供了一个littlefs的FUSE封装,也就是你可以借助此项目,在PC上直接将littlefs镜像挂载起来,并正常进行一些文件系统的操作。

源码位于:https://github.com/ARMmbed/littlefs-fuse

结构

我们直接下载下来

代码语言:txt
AI代码解释
复制
 $ git clone https://github.com/ARMmbed/littlefs-fuse.git
 $ cd littlefs-fuse

先看下结构

代码语言:txt
AI代码解释
复制
$ tree -L 2

.
├── lfs_fuse_bd.c
├── lfs_fuse_bd.h
├── lfs_fuse.c
├── LICENSE.md
├── littlefs
│   ├── DESIGN.md
│   ├── emubd
│   ├── lfs.c
│   ├── lfs.h
│   ├── lfs_util.c
│   ├── lfs_util.h
│   ├── LICENSE.md
│   ├── Makefile
│   ├── README.md
│   ├── scripts
│   ├── SPEC.md
│   └── tests
├── Makefile
└── README.md

外层是封装,里面则直接包含了littlefs文件夹。当我们需要特定版本的littlefs,例如使用跟设备上同一版本的littlefs时,只需要替换掉里层的这个littlefs即可,非常方便。

编译

根据README,项目依赖 FUSE version 2.6及以上的版本,可以使用如下命令查看版本

代码语言:txt
AI代码解释
复制
fusermount -V

另外还需要安装下 libfuse-dev:

代码语言:txt
AI代码解释
复制
sudo apt-get install libfuse-dev

依赖项满足之后,直接make即可生成lfs应用程序

代码语言:txt
AI代码解释
复制
make

生成设备并挂载使用

首先需要造一个块设备出来

代码语言:txt
AI代码解释
复制
sudo chmod a+rw /dev/loop0                  # make loop device user accessible
dd if=/dev/zero of=image bs=512 count=2048  # create a 1MB image
losetup /dev/loop0 image                    # attach the loop device

我们上一步是dd生成了一个空的image,所以需要先格式化,

代码语言:txt
AI代码解释
复制
./lfs --format /dev/loop0

再挂载

代码语言:txt
AI代码解释
复制
mkdir -p mount
./lfs /dev/loop0 mount

挂载成功后,执行mount可以看到挂载情况

代码语言:txt
AI代码解释
复制
$ mount | grep lfs
/home/zhuangqiubin/debug_littlefs/littlefs-fuse/lfs on /home/zhuangqiubin/debug_littlefs/littlefs-fuse/mount type fuse.lfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

现在就可以在mount目录下,随意进行操作了,创建删除读出写入,都会被转换成littlefs的操作,最终作用到image上

过程中,可以随时dump出数据,就可以看到你的操作,最终存储到littlefs上时什么样的数据格式了,例如

代码语言:txt
AI代码解释
复制
$ echo "www.cnblogs.com/zqb-all/" >> mount/test_littlefs.txt

$ hexdump -C image
00000000  03 00 00 00 f0 0f ff f7  6c 69 74 74 6c 65 66 73  |........littlefs|
00000010  2f e0 00 10 00 00 02 00  00 02 00 00 00 08 00 00  |/...............|
00000020  ff 00 00 00 ff ff ff 7f  fe 03 00 00 20 00 04 09  |............ ...|
00000030  74 65 73 74 5f 6c 69 74  74 6c 65 66 73 2e 74 78  |test_littlefs.tx|
00000040  74 20 00 00 11 70 0f f9  b7 ee c0 48 bb ff ff ff  |t ...p.....H....|
00000050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000200  04 00 00 00 f0 0f ff f7  6c 69 74 74 6c 65 66 73  |........littlefs|
00000210  2f e0 00 10 00 00 02 00  00 02 00 00 00 08 00 00  |/...............|
00000220  ff 00 00 00 ff ff ff 7f  fe 03 00 00 20 00 04 09  |............ ...|
00000230  74 65 73 74 5f 6c 69 74  74 6c 65 66 73 2e 74 78  |test_littlefs.tx|
00000240  74 20 00 00 08 77 77 77  2e 63 6e 62 6c 6f 67 73  |t ...www.cnblogs|
00000250  2e 63 6f 6d 2f 7a 71 62  2d 61 6c 6c 2f 0a 70 0f  |.com/zqb-all/.p.|
00000260  f9 87 46 fe c1 ad ff ff  ff ff ff ff ff ff ff ff  |..F.............|
00000270  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000400  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

使用完毕之后,用以下命令卸载

代码语言:txt
AI代码解释
复制
umount mount
sudo losetup -d /dev/loop0

挂载一个指定镜像

以上是生成了空的镜像,格式化再挂载。如果要挂载一个现成的镜像,步骤也是差不多的,只是镜像换一下。假设现成的镜像叫littlefs.img,则

代码语言:txt
AI代码解释
复制
sudo chmod a+rw /dev/loop0                  # make loop device user accessible
losetup /dev/loop0 littlefs.img                    # attach the loop device
mkdir -p mount
./lfs /dev/loop0 mount

卸载命令没有差别

代码语言:txt
AI代码解释
复制
umount mount
sudo losetup -d /dev/loop0

但从设备上dump出的littlefs镜像,其配置不一定会跟littlefs-fuse的默认配置匹配。

此时为了能正确挂载,以及准确地模拟littlefs在设备上运行的情况,我们需要将配置改成一样的。

解决方式一,直接修改源码,例如

代码语言:txt
AI代码解释
复制
diff --git a/lfs_fuse.c b/lfs_fuse.c
index 3c87dad..d1a99a2 100644
--- a/lfs_fuse.c
+++ b/lfs_fuse.c
@@ -26,7 +26,16 @@
 
 
 // config and other state
-static struct lfs_config config = {0};
+/* static struct lfs_config config = {0}; */
+static struct lfs_config config = {
+    .read_size = 256,
+    .prog_size = 256,
+    .block_size = 4096,
+    .block_count = 1224,
+    .block_cycles = 512,
+    .cache_size = 256,
+    .lookahead_size = 32
+};

修改后重新make生成即可

解决方式二,在调用的时候,通过命令行参数指定,例如

代码语言:txt
AI代码解释
复制
./lfs --block_size=512 --format /dev/loop0
./lfs --block_size=512 /dev/loop0 mount

支持的选项,可以在help中找到

代码语言:txt
AI代码解释
复制
$lfs -h
usage: ./lfs [options] device mountpoint

general options:
    -o opt,[opt...]        FUSE options
    -h   --help            print help
    -V   --version         print version

littlefs options:
    --format               format instead of mounting
    --migrate              migrate previous version  instead of mounting
    -b   --block_size      logical block size, overrides the block device
    --block_count          block count, overrides the block device
    --block_cycles         number of erase cycles before eviction (512)
    --read_size            readable unit (block_size)
    --prog_size            programmable unit (block_size)
    --cache_size           size of caches (block_size)
    --lookahead_size       size of lookahead buffer (8192)
    --name_max             max size of file names (255)
    --file_max             max size of file contents (2147483647)
    --attr_max             max size of custom attributes (1022)

FUSE options:
    -d   -o debug          enable debug output (implies -f)
    -f                     foreground operation
    -s                     disable multi-threaded operation

    -o allow_other         allow access to other users
    -o allow_root          allow access to root
    -o auto_unmount        auto unmount on process termination
    -o nonempty            allow mounts over non-empty file/dir
    -o default_permissions enable permission checking by kernel
    -o fsname=NAME         set filesystem name
    -o subtype=NAME        set filesystem type
    -o large_read          issue large read requests (2.4 only)
    -o max_read=N          set maximum size of read requests

    -o hard_remove         immediate removal (don't hide files)
    -o use_ino             let filesystem set inode numbers
    -o readdir_ino         try to fill in d_ino in readdir
    -o direct_io           use direct I/O
    -o kernel_cache        cache files in kernel
    -o [no]auto_cache      enable caching based on modification times (off)
    -o umask=M             set file permissions (octal)
    -o uid=N               set file owner
    -o gid=N               set file group
    -o entry_timeout=T     cache timeout for names (1.0s)
    -o negative_timeout=T  cache timeout for deleted names (0.0s)
    -o attr_timeout=T      cache timeout for attributes (1.0s)
    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)
    -o noforget            never forget cached inodes
    -o remember=T          remember cached inodes for T seconds (0s)
    -o nopath              don't supply path if not necessary
    -o intr                allow requests to be interrupted
    -o intr_signal=NUM     signal to send on interrupt (10)
    -o modules=M1[:M2...]  names of modules to push onto filesystem stack

    -o max_write=N         set maximum size of write requests
    -o max_readahead=N     set maximum readahead
    -o max_background=N    set number of maximum background requests
    -o congestion_threshold=N  set kernel's congestion threshold
    -o async_read          perform reads asynchronously (default)
    -o sync_read           perform reads synchronously
    -o atomic_o_trunc      enable atomic open+truncate support
    -o big_writes          enable larger than 4kB writes
    -o no_remote_lock      disable remote file locking
    -o no_remote_flock     disable remote file locking (BSD)
    -o no_remote_posix_lock disable remove file locking (POSIX)
    -o [no_]splice_write   use splice to write to the fuse device
    -o [no_]splice_move    move data while splicing to the fuse device
    -o [no_]splice_read    use splice to read from the fuse device

Module options:

[iconv]
    -o from_code=CHARSET   original encoding of file names (default: UTF-8)
    -o to_code=CHARSET      new encoding of the file names (default: UTF-8)

[subdir]
    -o subdir=DIR       prepend this directory to all paths (mandatory)
    -o [no]rellinks     transform absolute symlinks to relative

调试

既然可以在PC上模拟挂载和读写,那首先最直观的,就是可以在littlefs的源码中按需添加调试代码,再重新挂载dump出来的镜像,通过打印来分析问题。

其次,必要的时候,我们还可以上gdb

代码语言:txt
AI代码解释
复制
make DEBUG=1 clean all                # build with debug info
gdb --args ./lfs -d /dev/loop0 mount  # run with gdb

其他

本文地址:https://cloud.tencent.com/developer/article/1560535

欢迎点击链接,扫码关注公众号:QB杂货铺

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OpenHarmony 轻内核M核源码分析系列二一 02 文件系统LittleFS
会分2部分来介绍结构体部分,先介绍LittleFS文件系统的结构体,然后介绍LiteOS-M内核中提供的和LittleFS相关的一些结构体。
小帅聊鸿蒙
2025/05/20
1630
RT-Thread进阶之文件系统
在早期的嵌入式系统中,需要存储的数据比较少,数据类型也比较单一,往往使用直接在存储设备中的指定地址写入数据的方法来存储数据。然而随着嵌入式设备功能的发展,需要存储的数据越来越多,也越来越复杂,这时仍使用旧方法来存储并管理数据就变得非常繁琐困难。因此我们需要新的数据管理方式来简化存储数据的组织形式,这就是文件系统的由来。
AIoT-KK
2020/07/13
2.5K0
RT-Thread进阶之文件系统
linux 创建虚拟块设备,制作文件系统并挂载,用于测试lustre
https://blog.csdn.net/baimafujinji/article/details/78810042
西湖醋鱼
2020/12/30
2.5K0
linux 创建虚拟块设备,制作文件系统并挂载,用于测试lustre
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
早起的鸟儿有虫吃
2025/04/11
2080
从青铜到王者系列:深入浅出理解DeepSeek 3FS (2)从内核到用户态文件系统的设计之路
深入理解文件系统:文件IO的一生
”走暗路、耕瘦田、进窄门、见微光” 告诉我 面试关键就 深入理解自己项目 这个才是最考察基本功的地方。
早起的鸟儿有虫吃
2025/05/04
1520
深入理解文件系统:文件IO的一生
系统硬件以及各类信息查看
描述:hwinfo 意即硬件信息工具,是另外一种很好的实用工具。它被用来检测系统中已存在的硬件,并且以可读的格式显示各种硬件组件的细节信息。 系统发行版安装 hwinfo:
全栈工程师修炼指南
2022/09/28
4.1K0
在Linux系统下限制指定目录的大小以及文件/文件夹数量
在Linux操作系统下有时需要限制一个指定文件夹的大小和文件夹内可存储的文件数量,有可能是出于安全的考量或者定制化的配置,这里我们提供了一种方案:用dd创建一个空的img镜像,进行格式化的配置,然后将其绑定到指定的文件夹上可以限制该文件夹的一些属性。
DechinPhy
2021/05/21
4K0
【linux命令讲解大全】131.循环设备(loop)在Linux中的应用及使用方法
losetup命令用来设置循环设备。循环设备可将文件虚拟成块设备,以此来模拟整个文件系统,让用户可以将其视为硬盘驱动器、光驱或软驱等设备,并挂载为目录来使用。
全栈若城
2024/03/02
1.3K0
FUSE 文件系统和 libfuse 介绍
这几天为了解决浏览器产品中的一个问题,研究了一下 FUSE(Filesystem in Userspace)。通常,应用程序开发只需要使用系统 API 进行文件读写操作,不需要了解文件系统的细节。在 Chromium 中为了实现跨平台,甚至对各操作系统的文件 API 进行了封装。在代码中使用封装 API,都不需要了解各操作系统所提供的文件系统 API。但由于我们的浏览器产品中使用了 FUSE 进行加密存储,所以有必要了解 FUSE 和 libfuse。
云水木石
2025/01/23
3850
FUSE 文件系统和 libfuse 介绍
如何调试操作系统源码
上一篇文章中,我们介绍了如何创建一个简单的引导扇区,触发 BIOS 中断,从而在计算机屏幕上显示出一行我们想要的字符串。 计算机是如何启动的?如何制作自己的操作系统
用户3147702
2022/06/27
1.8K0
如何调试操作系统源码
【Linux】学习笔记(八) Linux 磁盘管理
du与df du(estimate file space usage) df(report file system disk space usage) df 查看磁盘容量 df 加上-h参数 更方便的查看 human-readable df -h du 查看目录的容量 # 默认同样以 块 的大小展示 du # 加上`-h`参数,以更易读的方式展示 du -h du -h #同--human-readable 以K,M,G为单位,提高信息的可读性。 du -a #同--all 显示目录中所有文件的大小。 d
韩旭051
2020/06/24
1.1K0
深入linux下磁盘Disk,分区Partition,挂载Mount
以上是目录结构 以下是文件存储结构 在linux正统的文件系统(eg:ext2、ext3)中,一个文件由以下三个部分组成: 1. 目录项:包括文件名和inode节点号。 2. Inode::又称文件索引节点,记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码。 3. data block:实际记录文件的内容,若文件太大时,会占用多个block。
sunsky
2020/08/20
8.2K0
深入linux下磁盘Disk,分区Partition,挂载Mount
文件系统杂谈
文件系统中重要的概念有大概有超级块、inode、file、文件描述符、文件缓存系统、目录。下面我们逐个说一下。
theanarkh
2020/02/25
1.6K0
文件系统杂谈
ignite
Ignite是一个启动firecracker vm的引擎,它使用容器的方式承载了firecracker vm。目前项目处于停滞阶段,也比较可惜,通过阅读了解ignite的工作方式,学习到了很多,希望能借此维护该项目。
charlieroro
2023/08/17
1.2K0
ignite
【linux学习指南】磁盘分区挂载到目录,形成文件系统挂载点
Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被 划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设 定block大小为1024、2048或4096字节。而上图中启动块(Boot Block)的大小是确定的
学习起来吧
2024/11/09
8630
【linux学习指南】磁盘分区挂载到目录,形成文件系统挂载点
KVM镜像管理利器-guestfish使用详解
1. 虚拟机镜像挂载及w2k8虚拟机启动自检慢问题解决办法 2. KVM虚拟化与guestfish套件 3. guestfish安装与注意事项 4. 使用guestfish查看虚拟机信息 5. 使用guestfish查看虚拟机分区及文件系统 6. 去掉磁盘空洞--KVM虚拟镜像的稀疏问题 7. 用guestfish操作虚拟机内部文件 8. guestfish修改镜像格式和大小 9. guestfish挂载、修改、运行救援方式
力哥聊运维与云计算
2019/06/28
3.4K0
深入理解Linux文件系统之文件系统挂载(上)
我们知道,Linux系统中我们经常将一个块设备上的文件系统挂载到某个目录下才能访问这个文件系统下的文件,但是你有没有思考过:为什么块设备挂载之后才能访问文件?挂载文件系统Linux内核到底为我们做了哪些事情?是否可以不将文件系统挂载到具体的目录下也能访问?下面,本文将详细讲解Linxu系统中,文件系统挂载的奥秘。
用户7244416
2021/08/06
2K0
【文件系统】如何在ubi之上运行squashfs
由于ubifs是运行在UBI卷之上的文件系统,而squashfs是运行在block device之上的文件系统,二者本来无任何交集,但是UBI提供了能够在ubi卷之上创建只读块设备的特性(R/O block devices on top of UBI volumes),这使得squashfs也能够“运行”在ubi卷之上。
知否知否应是绿肥红瘦
2025/02/19
2730
【文件系统】如何在ubi之上运行squashfs
模拟内核实现简易磁盘文件系统实现
背景 内核的磁盘文件系统核心是如何组织充分利用物理磁盘文件空间来组织数据的存储,其中的数据存储包括的file metadata和file data.磁盘文件系统包括了核心的数据结构,其中包括了磁盘文件系统的超级块、inode bitmap、block bitmap、block data。文件系统的超级块存储了文件系统的元数据,包括文件系统block大小、inode个数、block个数等信息。inode bitmap存储了inode的使用情况;block bitmap存储block的使用情况;block da
用户4700054
2022/08/17
6120
模拟内核实现简易磁盘文件系统实现
Proxmox Virtual Environment如何修改镜像硬盘大小及OpenWrt如何修改大小
网页版操作不是直接在Disk上,而是Hardware > Hard Disk > Disk Action > Resize
繁华是客
2024/05/10
9220
推荐阅读
相关推荐
OpenHarmony 轻内核M核源码分析系列二一 02 文件系统LittleFS
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档