Merge branch 'bugfix/fatfs_fatfsparse_relaxed' into 'master'

bugfix(fatfs): Fixed fatfsparse.py parses FAT boot sector too strictly

See merge request espressif/esp-idf!26888
This commit is contained in:
Radek Tandler 2023-12-08 23:48:25 +08:00
commit 12011d2057
4 changed files with 21 additions and 13 deletions

View File

@ -1,9 +1,9 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from inspect import getmembers, isroutine
from typing import Optional
from construct import Const, Int8ul, Int16ul, Int32ul, PaddedString, Struct, core
from construct import Bytes, Const, Int8ul, Int16ul, Int32ul, PaddedString, Padding, Struct, core
from .exceptions import InconsistentFATAttributes, NotInitialized
from .fatfs_state import BootSectorState
@ -29,8 +29,7 @@ class BootSector:
BOOT_HEADER_SIZE = 512
BOOT_SECTOR_HEADER = Struct(
# this value reflects BS_jmpBoot used for ESP32 boot sector (any other accepted)
'BS_jmpBoot' / Const(b'\xeb\xfe\x90'),
'BS_jmpBoot' / Bytes(3),
'BS_OEMName' / PaddedString(MAX_OEM_NAME_SIZE, SHORT_NAMES_ENCODING),
'BPB_BytsPerSec' / Int16ul,
'BPB_SecPerClus' / Int8ul,
@ -45,12 +44,12 @@ class BootSector:
'BPB_HiddSec' / Int32ul,
'BPB_TotSec32' / Int32ul, # zero if the FAT type is 12/16, otherwise number of sectors
'BS_DrvNum' / Const(b'\x80'),
'BS_Reserved1' / Const(EMPTY_BYTE),
'BS_Reserved1' / Padding(1),
'BS_BootSig' / Const(b'\x29'),
'BS_VolID' / Int32ul,
'BS_VolLab' / PaddedString(MAX_VOL_LAB_SIZE, SHORT_NAMES_ENCODING),
'BS_FilSysType' / PaddedString(MAX_FS_TYPE_SIZE, SHORT_NAMES_ENCODING),
'BS_EMPTY' / Const(448 * EMPTY_BYTE),
'BS_EMPTY' / Padding(448),
'Signature_word' / Const(FATDefaults.SIGNATURE_WORD)
)
assert BOOT_SECTOR_HEADER.sizeof() == BOOT_HEADER_SIZE
@ -73,7 +72,8 @@ class BootSector:
* EMPTY_BYTE)
self.boot_sector_state.binary_image = (
BootSector.BOOT_SECTOR_HEADER.build(
dict(BS_OEMName=pad_string(boot_sector_state.oem_name, size=BootSector.MAX_OEM_NAME_SIZE),
dict(BS_jmpBoot=(b'\xeb\xfe\x90'),
BS_OEMName=pad_string(boot_sector_state.oem_name, size=BootSector.MAX_OEM_NAME_SIZE),
BPB_BytsPerSec=boot_sector_state.sector_size,
BPB_SecPerClus=boot_sector_state.sectors_per_cluster,
BPB_RsvdSecCnt=boot_sector_state.reserved_sectors_cnt,
@ -91,8 +91,7 @@ class BootSector:
BS_VolLab=pad_string(boot_sector_state.volume_label,
size=BootSector.MAX_VOL_LAB_SIZE),
BS_FilSysType=pad_string(boot_sector_state.file_sys_type,
size=BootSector.MAX_FS_TYPE_SIZE)
)
size=BootSector.MAX_FS_TYPE_SIZE))
) + pad_header + fat_tables_content + root_dir_content + data_content
)

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
@ -100,7 +100,7 @@ def remove_wear_levelling_if_exists(fs_: bytes) -> bytes:
boot_sector__.parse_boot_sector(fs_)
if boot_sector__.boot_sector_state.size == len(fs_):
return fs_
except construct.core.ConstError:
except UnicodeDecodeError:
pass
plain_fs: bytes = remove_wl(fs_)
return plain_fs
@ -124,6 +124,9 @@ if __name__ == '__main__':
default=None,
help="If detection doesn't work correctly, "
'you can force analyzer to or not to assume WL.')
argument_parser.add_argument('--verbose',
action='store_true',
help='Prints details about FAT image.')
args = argument_parser.parse_args()
@ -157,6 +160,10 @@ if __name__ == '__main__':
boot_sector_ = BootSector()
boot_sector_.parse_boot_sector(fs)
if args.verbose:
print(str(boot_sector_))
fat = FAT(boot_sector_.boot_sector_state, init_=False)
boot_dir_start_ = boot_sector_.boot_sector_state.root_directory_start

View File

@ -136,8 +136,9 @@ It is a reverse tool of (:component_file:`fatfsgen.py <fatfs/fatfsgen.py>`), i.e
Usage::
./fatfsparse.py [-h] [--wl-layer {detect,enabled,disabled}] fatfs_image.img
./fatfsparse.py [-h] [--wl-layer {detect,enabled,disabled}] [--verbose] fatfs_image.img
Parameter --verbose prints detailed information from boot sector of the FatFs image to the terminal before folder structure is generated.
High-level API Reference
------------------------

View File

@ -136,8 +136,9 @@ FatFs 分区分析器
可以使用::
./fatfsparse.py [-h] [--wl-layer {detect,enabled,disabled}] fatfs_image.img
./fatfsparse.py [-h] [--wl-layer {detect,enabled,disabled}] [--verbose] fatfs_image.img
生成文件夹结构之前,参数 --verbose 将根据 FatFs 镜像的引导扇区在终端打印详细信息。
高级 API 参考
------------------------