mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(fatfs): Fixed fatfsparse.py parsing of FAT boot sector
The fatfsparse.py script was too strict in parsing the FAT boot sector, causing it to fail in certain cases. This commit fixes the issue by making the parsing less strict and allowing for more flexibility in the boot sector format. This change improves the reliability and compatibility of the fatfsparse.py script, ensuring that it can correctly parse a wider range of FAT boot sectors. Docs updated
This commit is contained in:
parent
0e69fcb8ac
commit
a640626b76
@ -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
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
------------------------
|
||||
|
@ -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 参考
|
||||
------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user