littlefs是arm面向嵌入式設備推出的一款掉電安全的小型文件系統,具備抗掉電,動態磨損均衡,RAM/ROM需求少等特色,具體介紹可見 https://github.com/ARMmbed/littlefshtml
做爲一款在嵌入式設備上使用的文件系統,出問題時,通常是須要將數據dump出來進行分析的。此時就須要PC端的調試工具了。node
這個項目提供了一個littlefs的FUSE封裝,也就是你能夠藉助此項目,在PC上直接將littlefs鏡像掛載起來,並正常進行一些文件系統的操做。git
源碼位於:https://github.com/ARMmbed/littlefs-fusegithub
咱們直接下載下來安全
$ git clone https://github.com/ARMmbed/littlefs-fuse.git $ cd littlefs-fuse
先看下結構bash
$ 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便可,很是方便。async
根據README,項目依賴 FUSE version 2.6及以上的版本,可使用以下命令查看版本ide
fusermount -V
另外還須要安裝下 libfuse-dev:工具
sudo apt-get install libfuse-dev
依賴項知足以後,直接make便可生成lfs應用程序oop
make
首先須要造一個塊設備出來
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,因此須要先格式化,
./lfs --format /dev/loop0
再掛載
mkdir -p mount ./lfs /dev/loop0 mount
掛載成功後,執行mount能夠看到掛載狀況
$ 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上時什麼樣的數據格式了,例如
$ 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
使用完畢以後,用如下命令卸載
umount mount sudo losetup -d /dev/loop0
以上是生成了空的鏡像,格式化再掛載。若是要掛載一個現成的鏡像,步驟也是差很少的,只是鏡像換一下。假設現成的鏡像叫littlefs.img,則
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
卸載命令沒有差異
umount mount sudo losetup -d /dev/loop0
但從設備上dump出的littlefs鏡像,其配置不必定會跟littlefs-fuse的默認配置匹配。
此時爲了能正確掛載,以及準確地模擬littlefs在設備上運行的狀況,咱們須要將配置改爲同樣的。
解決方式一,直接修改源碼,例如
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生成便可
解決方式二,在調用的時候,經過命令行參數指定,例如
./lfs --block_size=512 --format /dev/loop0 ./lfs --block_size=512 /dev/loop0 mount
支持的選項,能夠在help中找到
$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
make DEBUG=1 clean all # build with debug info gdb --args ./lfs -d /dev/loop0 mount # run with gdb
本文地址:https://www.cnblogs.com/zqb-all/p/12078659.html