|
25 | 25 |
|
26 | 26 | logger = get_logger() |
27 | 27 |
|
28 | | -# YAFFS1 images always have a first entry as a directory entry with an empty name |
29 | | -# this is how it's done in mkyaffsimage: |
30 | | -# write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL); |
31 | | -YAFFS1_FIRST_ENTRY = b"\xff\xff\x00\x00\x00\x00\x00\x00" |
32 | | - |
33 | 28 | SPARE_START_BIG_ENDIAN_ECC = b"\x00\x00\x10\x00" |
34 | 29 | SPARE_START_BIG_ENDIAN_NO_ECC = b"\xFF\xFF\x00\x00\x10\x00" |
35 | 30 | SPARE_START_LITTLE_ENDIAN_ECC = b"\x00\x10\x00\x00" |
|
41 | 36 |
|
42 | 37 | VALID_PAGE_SIZES = [512, 1024, 2048, 4096, 8192, 16384] |
43 | 38 | VALID_SPARE_SIZES = [16, 32, 64, 128, 256, 512] |
| 39 | +YAFFS1_PAGE_SIZE = 512 |
| 40 | +YAFFS1_SPARE_SIZE = 16 |
44 | 41 |
|
45 | 42 | C_DEFINITIONS = """ |
46 | 43 | struct yaffs1_obj_hdr { |
@@ -653,8 +650,8 @@ def __init__(self, file: File, config: Optional[YAFFSConfig] = None): |
653 | 650 | # is the same size as a NAND flash page (ie. 512 bytes + 16 byte spare). |
654 | 651 | # In the future we might decide to allow for different chunk sizes. |
655 | 652 | config = YAFFSConfig( |
656 | | - page_size=512, |
657 | | - spare_size=16, |
| 653 | + page_size=YAFFS1_PAGE_SIZE, |
| 654 | + spare_size=YAFFS1_SPARE_SIZE, |
658 | 655 | endianness=get_endian_multi(file, BIG_ENDIAN_MAGICS), |
659 | 656 | ecc=False, |
660 | 657 | ) |
@@ -723,8 +720,44 @@ def get_chunks(self, object_id: int) -> Iterable[YAFFS1Chunk]: |
723 | 720 | yield max(chunks, key=lambda chunk: ((chunk.serial + 1) & 3)) |
724 | 721 |
|
725 | 722 |
|
| 723 | +def is_yaffs_v1(file: File, start_offset: int) -> bool: |
| 724 | + struct_parser = StructParser(C_DEFINITIONS) |
| 725 | + file.seek(start_offset, io.SEEK_SET) |
| 726 | + if file[0:4] == b"\x03\x00\x00\x00" or file[0:4] == b"\x01\x00\x00\x00": |
| 727 | + endian = Endian.LITTLE |
| 728 | + else: |
| 729 | + endian = Endian.BIG |
| 730 | + file.seek(start_offset + YAFFS1_PAGE_SIZE, io.SEEK_SET) |
| 731 | + spare = file.read(YAFFS1_SPARE_SIZE) |
| 732 | + |
| 733 | + yaffs_sparse = struct_parser.parse("yaffs_spare_t", spare, endian) |
| 734 | + |
| 735 | + yaffs_packed_tags = struct_parser.parse( |
| 736 | + "yaffs1_packed_tags_t", |
| 737 | + bytes( |
| 738 | + [ |
| 739 | + yaffs_sparse.tag_b0, |
| 740 | + yaffs_sparse.tag_b1, |
| 741 | + yaffs_sparse.tag_b2, |
| 742 | + yaffs_sparse.tag_b3, |
| 743 | + yaffs_sparse.tag_b4, |
| 744 | + yaffs_sparse.tag_b5, |
| 745 | + yaffs_sparse.tag_b6, |
| 746 | + yaffs_sparse.tag_b7, |
| 747 | + ] |
| 748 | + ), |
| 749 | + endian, |
| 750 | + ) |
| 751 | + file.seek(start_offset, io.SEEK_SET) |
| 752 | + return ( |
| 753 | + yaffs_packed_tags.chunk_id == 0 |
| 754 | + and yaffs_packed_tags.serial == 0 |
| 755 | + and yaffs_packed_tags.object_id == 1 |
| 756 | + ) |
| 757 | + |
| 758 | + |
726 | 759 | def instantiate_parser(file: File, start_offset: int = 0) -> YAFFSParser: |
727 | | - if file[start_offset + 8 : start_offset + 16] == YAFFS1_FIRST_ENTRY: |
| 760 | + if is_yaffs_v1(file, start_offset): |
728 | 761 | return YAFFS1Parser(file) |
729 | 762 | return YAFFS2Parser(file) |
730 | 763 |
|
|
0 commit comments