0x1 UBI文件系统简介

UBI文件系统是linux-2.6.27后内核新加入的flash文件系统,开发环境主机要求至少是在linux2.6.27后的内核,且已经有nandsim,ubi等相关模块。

UBI没有FLASH转换层(FTL,Flash Translation Layer),只能工作在裸的flash,因此它不能用于消费类FLASH如MMC, RS-MMC, eMMC, SD, mini-SD, micro-SD, CompactFlash, MemoryStick等,但UBI在嵌入式设备中被广泛使用。

UBI文件系统不能直接挂载,而是要用 nandsim 模拟出一个 mtd 设备,而且这个 mtd 设备要与 ubi 镜像的参数保存一致,否则后面的挂载会失败。

这些参数包括 mtd 设备的物理块擦除大小 (Physical Erase Block, PEB) 和 页大小 (Page Size)。

ubi 镜像有多个 PEB 组成,每个 PEB 包括以下三部分内容

[ UBI_EC_HDR,UBI_VID_HDR,DATA (LEB) ]

这是 ubi 镜像的头部,从 ubi-header.h 中可以了解到这个头部各个字节的含义:

ubi-header.h

struct ubi_ec_hdr {

uint32_t magic; //红色,#define UBI_EC_HDR_MAGIC 0x55424923

uint8_t version;

uint8_t padding1[3];

uint64_t ec; /* Warning: the current limit is 31-bit anyway! */

uint32_t vid_hdr_offset; //蓝色,偏移为0x800=2KB

uint32_t data_offset; //黄色,偏移为0x1000=4KB

uint8_t padding2[36];

uint32_t hdr_crc;

} __attribute__ ((packed));

通常UBI_EC_HDR 和 UBI_VID_HDR 要么在每个 PEB 的头部各占一页大小,要么都在第一页。若第一种,则页大小为2KB;若第二种页大小为4KB。nand flash 常见的页大小是 512byte 和 2KB,4KB 比较少见,故先推测为2KB。

通过检索UBI_EC_HDR_MAGIC 即0x55424923,可以确定本次镜像PEB大小为0x20000=128KB,那么 LEB (Logical Erase Block) =PEB-data_offset=128-4=124KB

0x2 挂载方式

UBI文件系统的挂载方式,可以参考Linux mtd使用文档

1,创建一个需要被挂在的目录

# mkdir /mnt/loop

2,载入mtd模块

# modprobe mtdblock

3,载入ubi模块(前提你的linux环境以支持ubi模块)

# modprobe ubi

4,载入nandsim来模拟nand设备

# modprobe nandsim first_id_byte=0x2c second_id_byte=0xf1 third_id_byte=0x80 fourth_id_byte=0x95

// disk size=128MB, page size=2048 bytes,block size=128KB

nandsim指定的参数需要根据镜像的闪存芯片来选择,以下图某设备为例,存储芯片型号为29F1G08ABAEA,通过检索可知为Micron镁光1Gb=128MB容量闪存:

重点阅读 Read ID 部分,nandsim 后面跟的 4 个参数是 nand flash 芯片的 ID,前三个参数为厂商ID、芯片ID等不太关键的参数,而第 4 个参数决定了生成的 mtd 设备的 PEB 和 页大小。

5,检查加入模块的环境

# cat /proc/mtd

dev: size erasesize name

mtd0: 08000000 00020000 "NAND simulator partition 0"

//即镜像大小size=128MB,PEB=erasesize=128KB

# ls -la /dev/mtd*

crw-rw---- 1 root root 90, 0 2013-08-17 20:02 /dev/mtd0

crw-rw---- 1 root root 90, 1 2013-08-17 20:02 /dev/mtd0ro

brw-rw---- 1 root disk 31, 0 2013-08-17 20:03 /dev/mtdblock0

# mtdinfo /dev/mtd0

mtd0

Name: NAND simulator partition 0

Type: nand

Eraseblock size: 131072 bytes, 128.0 KiB

Amount of eraseblocks: 1024 (134217728 bytes, 128.0 MiB)

Minimum input/output unit size: 2048 bytes

Sub-page size: 512 bytes

OOB size: 64 bytes

Character device major/minor: 90:0

Bad blocks are allowed: true

Device is writable: true

6,将 ubi 与 /dev/mtd0 关联

# modprobe ubi mtd=0

7,把rootfs.ubi加载到mtd的块设备,在这里需要安装mtd-utils工具箱(ubuntu下 直接apt-get install mtd-utils)

# apt install mtd-utils

# ubidetach /dev/ubi_ctrl -m 0 // 格式化前先解绑定

# ubiformat /dev/mtd0 -s 2048 -f rootfs.ubi -O 2048

ubiformat: mtd0 (nand), size 134217728 bytes (128.0 MiB), 1024 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes

libscan: scanning eraseblock 1023 -- 100 % complete

ubiformat: 1024 eraseblocks are supposedly empty

...

ubiformat: flashing eraseblock 208 -- 100 % complete

ubiformat: formatting eraseblock 1023 -- 100 % complete

// 指令功能类似于`dd if=rootfs.ubi of=/dev/mtdblock0 bs=2048`

//-O参数用来指定VID header offset,默认是512,本次镜像从上文分析得知为2048

遇到的坑

ubiformat: error!: file “rootfs.ubi” (size 27267072 bytes) is not multiple of eraseblock size (131072 bytes)如果确定文件rootfs.ubi块大小正确,可以详细检查文件,如下图,某设备镜像就修改了最后一个块的位置,将之修改回正确地址0x1a00000(删掉前面0x12个FF)

修改完成后继续ubiformat,此时提示最后一个修改的块CRC校验错误ubiformat: flashing eraseblock 208 — 100 % complete ubiformat: error!: bad CRC 0xa092c947, should be 0x350fcaaa

0x350fcaaa是原始值,将之修改为提示的0xa092c947即可ubiformat成功

ubiformat: 208 eraseblocks have valid erase counter, mean value is 3

ubiformat: 1 eraseblocks are supposedly empty

ubiformat: 815 corrupted erase counters

ubiformat: warning!: only 208 of 1024 eraseblocks have valid erase counter

ubiformat: erase counter 0 will be used for all eraseblocks

ubiformat: note, arbitrary erase counter value may be specified using -e option

ubiformat: continue? (y/N) y

ubiformat: use erase counter 0 for all eraseblocks

ubiformat: flashing eraseblock 208 -- 100 % complete

ubiformat: formatting eraseblock 1023 -- 100 % complete

8,将ubi模块与已载入了rootfs.ubi的mtd模块关联

# ubiattach /dev/ubi_ctrl -m 0 -O 2048

UBI device number 0, total 1024 LEBs (130023424 bytes, 124.0 MiB), available 1000 LEBs (126976000 bytes, 121.1 MiB), LEB size 126976 bytes (124.0 KiB)

-m指定挂在在mtd0上

-O参数用来指定VID header offset,默认是512,本次镜像从上文分析得知为2048

到这里,模块载入成功,从输出信息可以知道rootfs.ubi镜像大小为124MB、共1024个块,每个LEB (Logical Erase Block) 大小为124KB

9,创建ubi分卷

# ubimkvol /dev/ubi0 -N ubifs_0 -m

10,挂载该模块到指定目录就OK

# mount -t ubifs ubi0:ubifs_0 /mnt/loop/

# ls -ahl /mnt/loop/

总用量 4.0K

drwxr-xr-x 22 root root 1.5K 4月 17 2018 .

drwxr-xr-x 6 root root 4.0K 12月 29 02:51 ..

drwxr-xr-x 2 root root 7.7K 4月 17 2018 bin

drwxr-xr-x 2 root root 160 4月 11 2018 boot

drwxr-xr-x 3 root root 224 4月 17 2018 data

drwxr-xr-x 2 root root 160 4月 11 2018 dev

drwxr-xr-x 24 root root 4.7K 4月 17 2018 etc

drwxr-xr-x 3 root root 224 4月 17 2018 home

drwxr-xr-x 6 root root 504 4月 11 2018 lib

drwxr-xr-x 5 root root 5.0K 4月 11 2018 lib64

drwxr-xr-x 2 root root 160 4月 11 2018 media

drwxr-xr-x 2 root root 160 4月 11 2018 mnt

drwxr-xr-x 2 root root 160 4月 11 2018 proc

drwxr-xr-x 2 root root 160 4月 11 2018 run

drwxr-xr-x 2 root root 4.1K 4月 17 2018 sbin

drwxr-xr-x 2 root root 160 4月 11 2018 sys

drwxr-xr-x 3 root root 224 4月 17 2018 temp

drwxr-xr-x 7 root root 504 4月 17 2018 test

drwxrwxrwt 2 root root 160 4月 11 2018 tmp

drwxr-xr-x 11 root root 736 4月 17 2018 usr

drwxr-xr-x 8 root root 808 4月 17 2018 var

drwxr-xr-x 3 root root 232 4月 17 2018 vendor

遇到的坑

mount: /mnt/loop: unknown filesystem type ‘ubifs’.mount之前先创建ubi分卷即可

11,解挂载&绑定

$ sudo umount /mnt/ubi

$ sudo ubidetach /dev/ubi_ctrl -m 0

查看内核错误信息

如果遇到其他错误可以通过dmesg | tail -20来查看内核错误信息

0x3 ubi解包

上述通过挂载方式读取ubi文件的过程较为繁琐,其实已经有现成开源的解包工具可用。

0x31 ubi_reader

//安装依赖

$ sudo apt-get install liblzo2-dev

$ sudo pip install python-lzo

//安装ubi_reader

$ sudo pip install ubi_reader

ubi_reader工具提供了四个脚本:

ubireader_display_info //获取UBI信息以及布局块等信息

ubireader_extract_images //提取镜像

ubireader_extract_files //提取文件内容

bireader_utils_info //分析UBI镜像并创建shell脚本和UBI配置文件

ubi_reader工具的使用也很简单,可以不需要参数,如下提取镜像里面的文件,输出会保存到./ubifs-root/目录里:

$ ubireader_extract_files rootfs.ubi

$ ls -ahl ./ubifs-root/1726319237/rootfs

total 0

drwxr-xr-x 22 nirva staff 704B Dec 29 18:26 .

drwxr-xr-x 3 nirva staff 96B Dec 29 18:26 ..

drwxr-xr-x 114 nirva staff 3.6K Apr 17 2018 bin

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 boot

drwxr-xr-x 3 nirva staff 96B Apr 17 2018 data

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 dev

drwxr-xr-x 69 nirva staff 2.2K Apr 17 2018 etc

drwxr-xr-x 3 nirva staff 96B Apr 17 2018 home

drwxr-xr-x 7 nirva staff 224B Apr 11 2018 lib

drwxr-xr-x 68 nirva staff 2.1K Apr 11 2018 lib64

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 media

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 mnt

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 proc

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 run

drwxr-xr-x 60 nirva staff 1.9K Apr 17 2018 sbin

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 sys

drwxr-xr-x 3 nirva staff 96B Apr 17 2018 temp

drwxr-xr-x 7 nirva staff 224B Apr 17 2018 test

drwxr-xr-x 2 nirva staff 64B Apr 11 2018 tmp

drwxr-xr-x 11 nirva staff 352B Apr 17 2018 usr

drwxr-xr-x 12 nirva staff 384B Apr 17 2018 var

drwxr-xr-x 3 nirva staff 96B Apr 17 2018 vendor

遇到的坑

ubi_reader工具对于ubi文件要求较为严格,必须补齐每一个块内容,如下当最后一个块内容没填充满,会提示块空间大于文件:read Error: Block ends at 27394048 which is greater than file size 27267072

extract_blocks Fatal: PEB: 208: Bad Read Offset Request

根据PEB块大小,补齐00即可,如下将该块(size=0x20000)用00填充满

0x32 ubidump

相对于ubi_reader,ubidump工具就更为简单,无需对齐块,应该是直接检索块头magic进行提取,该工具地址为:https://github.com/nlitsme/ubidump

ubidump工具只是一个python2的脚本,无需安装,但需要安装依赖:

$ sudo pip install python-lzo

$ sudo pip install crcmod

使用也比较简单:

//查看image.ubi镜像里面的某个文件内容

$ python ubidump.py -c /etc/passwd image.ubi

//显示image.ubi镜像内容

$ python ubidump.py -l image.ubi

//提取镜像,该指令会在指定目录下生成`rootfs`目录

$ python ubidump.py -s . image.ubi

$ ls -ahl ./rootfs

total 0

drwxr-xr-x 11 nirva staff 352B Dec 29 20:32 .

drwx------ 20 nirva staff 640B Dec 29 20:32 ..

drwxr-xr-x 53 nirva staff 1.7K Dec 29 20:32 bin

drwxr-xr-x 3 nirva staff 96B Dec 29 20:32 data

drwxr-xr-x 62 nirva staff 1.9K Dec 29 20:32 etc

drwxr-xr-x 5 nirva staff 160B Dec 29 20:32 lib

drwxr-xr-x 38 nirva staff 1.2K Dec 29 20:32 lib64

drwxr-xr-x 15 nirva staff 480B Dec 29 20:32 sbin

drwxr-xr-x 3 nirva staff 96B Dec 29 20:32 temp

drwxr-xr-x 8 nirva staff 256B Dec 29 20:32 usr

drwxr-xr-x 3 nirva staff 96B Dec 29 20:32 vendor

不过对比 ubi_reader和ubidump工具的输出结果,可以发现ubi_reader提取的内容更为完整,而且也保留了文件的时间戳信息,而时间戳信息对取证等分析很有帮助:

解压ubi文件_IoT(八)ubi文件系统挂载解包相关推荐

  1. java如何解压rar文件怎么打开,Java压缩与解压rar文件

    package com.sunz.fileUpload; public class RarToFile { //cmd 压缩与解压缩命令 private static String rarCmd = ...

  2. win7怎么解压rar文件_win7解压rar文件的方法

    大家知道win7怎么解压rar文件?rar是一种常用的文件压缩与归档的私有格式,用于数据压缩与归档打包.加快传输速度,我们都会将文件进行压缩.但最近有Win7系统用户反映收到rar文件,却不知道w怎么 ...

  3. 7z001怎么解压在安卓手机上面_手机怎么解压zip文件 安卓手机zip文件怎么打开?...

    手机怎么解压zip文件 安卓手机zip文件怎么打开?Zip格式的文件是一种经过压缩的文件,通过压缩之后,文件的体积会变小,从而更有利于在网络上传播.经过压缩的文件,如果想要再次使用,就必须通过解压缩后 ...

  4. java csv文件tozip后损坏_java上传并下载以及解压zip文件有时会报文件被损坏错误分析以及解决...

    情景描述: 1.将本地数据备份成zip文件: 2.将备份的zip文件通过sftp上传到文件服务器: 3.将文件服务器上的zip文件下载到运行服务器: 4.将下载的zip文件解压到本地(文件大小超过50 ...

  5. android解压zip文件进度条,Android实现文件解压带进度条功能

    解压的工具类 package com.example.videodemo.zip; public class ZipProgressUtil { /*** * 解压通用方法 * * @param zi ...

  6. C# 支付宝对账功能(查询+文件下载+解压+遍历文件+读文件)

    C# 支付宝对账功能(查询+文件下载+解压+遍历文件+读文件) **需求** **流程** 1 .调用支付宝接口, 获取zip 下载地址 2.工具代码 需求 定时任务:每天统计昨天的公司支付宝账户实际 ...

  7. java解压zip文件

    package com.chuangqi.tools;import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile ...

  8. JSZip解压PDF文件并批量下载

    JSzip解压PDF文件并批量下载 因需要解压PDF文件并且实现批量下载,但网上找到的基本都是图片的解压和下载,所以参考图片的解压修改了一下. 用到了jszip,jszip-utils,file-sa ...

  9. 水木-如何解压.iso文件

    水木-如何解压.iso文件 水木清华 null [ 返回][转发] 水木-如何解压.iso文件  .iso文件的格式是iso9660,iso9660是cd上的一种文件系统,也就是说是  是数据在cd上 ...

  10. Inno Setup 打包发布exe程序的步骤及注意事项及解决发布后的exe解压后文件都在主目录下导致程序无法正常运行的问题

    目录 一.链接.exe文件的.dll动态链接库 1.1.可以利用QT官网提供的工具windeployqt 生成方式见如下: 1.2.使用脚本文件 二.使用绿色汉化版打包小程序inno setup5.5 ...

最新文章

  1. 汇编call指令详解_我也能写出雷军的的代码吗?最好的汇编语言入门教程在这里!...
  2. 实验吧-catalyst-system
  3. python有道翻译-Python爬去有道翻译
  4. python串口通信_python通信串口pyserial安装及常用语句
  5. 图的存储以及深度优先以及广度优先遍历
  6. java监控数据库的增量_【安德鲁斯】基于脚本的数据库quot;增量更新quot;,如果不改变,每次更新java代码、!...
  7. Hbase集群安装Version1.1.5
  8. java加密 c解密_java+加密解密
  9. AspNetCore中使用Ocelot之 IdentityServer4(1)
  10. prometheus-operator架构部署( prometheus-server, pushgateway, grafana, alertmanater,servicemonitor...)
  11. 11个超实用的创意设计思维训练方法
  12. 4D-Net for Learned Multi-Modal Alignment 论文笔记
  13. 数据中台,什么是数据中台?
  14. 51单片机的智能灯光控制系统
  15. 抓包神器:Fiddler Everywhere
  16. 国际顶会 SIGCOMM,我们来了!
  17. tui.editor所见即所得编辑器的使用
  18. 南通市住房公积金管理中心集成容灾软件部分goldengate
  19. 计算机网络原理参考资料,《计算机网络原理》3 (2021)在线作业参考资料
  20. K455L安装Ubuntu18.04历程

热门文章

  1. [C#复习向整合]反射 -Assembly与Activator
  2. 卡西欧科学计算机使用方法,卡西欧科学计算器使用教程
  3. 【bfs 反向建边】2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16) Jumping
  4. 相对标准偏差用计算机,公路工程用计算器计算相对标准偏差(RSD)
  5. A + B Problem Too
  6. Spring Boot 2.x 基础案例:整合Dubbo 2.7.3 Nacos1.1.3(配置中心)
  7. RabbitMQ之业务场景(四):动态创建,删除队列工具类,拿来即用
  8. 实现Discord聊天机器人
  9. 计算机知识怎么记忆,计算器记忆加怎么用
  10. 存活探针(Liveness Probe)