// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
using System.Collections.Generic;
namespace Kaitai
{
///
/// UF2 is a file format, developed by Microsoft for PXT (also known as
/// Microsoft MakeCode), that is particularly suitable for flashing
/// microcontrollers over MSC (Mass Storage Class; aka removable flash drive).
///
/// The list of family IDs is stored in a separate JSON file:
///
/// <https://github.com/microsoft/uf2/blob/master/utils/uf2families.json>
///
/// This JSON file is regularly updated. The `family_id` enum should be kept in
/// sync with it. For simplicity and consistency, it's strongly recommended to
/// auto-generate this enum from `uf2families.json` directly. This was last done
/// using the following commands:
///
/// ```bash
/// $ curl -fsSLO https://github.com/microsoft/uf2/raw/90e9741f217f5a40c98ba74d663e408041037578/utils/uf2families.json
/// $ jq -r '
/// .[]
/// | " \(.id | ascii_downcase):\n"
/// + " id: \(.short_name | ascii_downcase | gsub("-"; "_"))\n"
/// + " doc: \(.description | tojson)"
/// ' uf2families.json
/// ```
///
/// Test files, picked to cover as many different shapes as possible:
///
/// * <https://micropython.org/download/RPI_PICO/> - a typical case: all blocks
/// have the same family ID and `num_blocks`.
/// * <https://micropython.org/download/RPI_PICO2/> - these .uf2 files are
/// actually two UF2 files concatenated. The first UF2 file is the standalone
/// `family_id::rp2xxx_absolute` block that `picotool` prepends (see the
/// `is_rp2350_e10_block` value instance in the `block` type).
/// * <https://circuitpython.org/downloads> - the builds for SAMD boards (for
/// example
/// [Feather M0 Express](https://circuitpython.org/board/feather_m0_express/))
/// set no flags at all, so the field at offset 28 is read as `file_size` rather
/// than `family_id`.
/// * <https://github.com/raspberrypi/pico-sdk-prebuilts/releases> -
/// [Universal UF2](https://github.com/raspberrypi/pico-examples/blob/c81c855ffdedc825975a40ba357723a71358ddf0/universal/README.md#universal-binary-vs-universal-uf2)
/// files, which are again two UF2 files concatenated. What's interesting about
/// these is that the last block of the first file (with the family ID
/// `family_id::rp2040`) is moved to the end of the second file, which was
/// intended for `family_id::rp2xxx_absolute` (see
/// <https://github.com/raspberrypi/pico-examples/blob/c81c855ffdedc825975a40ba357723a71358ddf0/universal/CMakeLists.txt#L159-L169>).
/// * <https://github.com/microsoft/pxt-microsoft-boot-sequence/releases> - some
/// files contain blocks with the `flags.is_file_container` flag set (for
/// example
/// <https://github.com/microsoft/pxt-microsoft-boot-sequence/releases/download/v0.0.4/arcade-p0.uf2>
/// is a pure file container for
/// `file_name == "Projects/microsoft-boot-sequence.elf"`). Generated by
/// MakeCode, the only known producer of file container UF2s.
/// * <https://github.com/umi-eng/uftwo/tree/35bccf75b4f81c43f088696a8c4a9912f1f4104e/uftwo/tests> -
/// synthetic test files for features that real firmware doesn't seem to use
/// (e.g. MD5 checksums).
///
///
/// Reference: Source
///
public partial class Uf2 : KaitaiStruct
{
public static Uf2 FromFile(string fileName)
{
return new Uf2(new KaitaiStream(fileName));
}
public enum ExtensionTagType
{
End = 0,
PageSize = 780791,
Description = 6622621,
Rp2IgnoreBlock = 10049507,
Version = 10471356,
Sha2Checksum = 11824560,
DeviceTypeId = 13149993,
}
public enum FamilyId
{
Stm32l4 = 16738585,
Stm32l5 = 69471199,
Stm32f411xc = 114362747,
M0sense = 299792458,
Atmega32 = 374814231,
Saml21 = 407992330,
Nrf52 = 458716255,
Esp32 = 475996592,
Stm32l1 = 505365293,
Stm32l0 = 539900561,
Stm32wl = 558239728,
Rtl8710b = 585160444,
Lpc55 = 716994540,
Esp32c2 = 730387100,
Stm32f411xe = 767756741,
Stm32g0 = 806311475,
Esp32s31 = 822212545,
Gd32f350 = 835856582,
Esp32h2 = 858203894,
Rtl8720d = 863621090,
Esp32p4 = 1026592404,
MaixplayU4 = 1265126769,
Stm32g4 = 1282483210,
Stm32h5 = 1318001757,
Csk4 = 1332399698,
Mimxrt10xx = 1337120189,
Xr809 = 1374225320,
Stm32f7 = 1404571392,
Esp32c6 = 1410195298,
Samd51 = 1427194976,
Stm32f4 = 1467308631,
Fx2 = 1511523995,
Stm32f2 = 1561987630,
Stm32f1 = 1591873650,
Nrf52833 = 1646171002,
Stm32f0 = 1685595318,
Bk7231u = 1733968048,
Samd21 = 1760373640,
Ch32v = 1771791084,
Bk7251 = 1786956866,
Stm32f3 = 1803837832,
Stm32f407 = 1829315322,
Stm32h7 = 1840668802,
Csk6 = 1853049000,
Nrf52832xxab = 1869948536,
Stm32wb = 1892771411,
Nrf52832xxaa = 1920081230,
Max32690 = 1947226634,
Esp32c61 = 2010665156,
Bk7231n = 2067722800,
Ra4m1 = 2078840685,
Py32f071Uvk5V3 = 2105173743,
Esp8266 = 2125160941,
Kl32l2 = 2139350931,
Nrf52820 = 2181929567,
Stm32f407vg = 2410701054,
Max78002 = 2446589208,
Rza1lu = 2501329455,
Gd32vf103 = 2599435827,
Esp32h4 = 2651564682,
Rtl8710a = 2684343619,
At32f415 = 2697558926,
Nrf52840 = 2913282112,
Esp32h21 = 3067936943,
Esp32s2 = 3218951918,
Esp32s3 = 3296614247,
Esp32c3 = 3559628908,
Max32650 = 3594487346,
Bl602 = 3725750455,
Rtl8720c = 3767498084,
Rp2040 = 3834380118,
Rp2xxxAbsolute = 3834380119,
Rp2xxxData = 3834380120,
Rp2350ArmS = 3834380121,
Rp2350Riscv = 3834380122,
Rp2350ArmNs = 3834380123,
Max32666 = 4039314801,
Esp32c5 = 4145808195,
}
public Uf2(KaitaiStream p__io, KaitaiStruct p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root ?? this;
_read();
}
private void _read()
{
_firstBlock = new Block(m_io, this, m_root);
_blocks = new List();
for (var i = 0; i < FirstBlock.NumBlocks - 1; i++)
{
_blocks.Add(new Block(m_io, this, m_root));
}
}
public partial class Block : KaitaiStruct
{
public static Block FromFile(string fileName)
{
return new Block(new KaitaiStream(fileName));
}
public Block(KaitaiStream p__io, Uf2 p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_isRp2350E10Block = false;
f_numBlocks = false;
_read();
}
private void _read()
{
_magic = m_io.ReadBytes(4);
if (!((KaitaiStream.ByteArrayCompare(_magic, new byte[] { 85, 70, 50, 10 }) == 0)))
{
throw new ValidationNotEqualError(new byte[] { 85, 70, 50, 10 }, _magic, m_io, "/types/block/seq/0");
}
_secondMagic = m_io.ReadBytes(4);
if (!((KaitaiStream.ByteArrayCompare(_secondMagic, new byte[] { 87, 81, 93, 158 }) == 0)))
{
throw new ValidationNotEqualError(new byte[] { 87, 81, 93, 158 }, _secondMagic, m_io, "/types/block/seq/1");
}
_flags = new Flags(m_io, this, m_root);
_targetAddress = m_io.ReadU4le();
{
uint M_ = _targetAddress;
if (!(KaitaiStream.Mod(M_, 4) == 0))
{
throw new ValidationExprError(_targetAddress, m_io, "/types/block/seq/3");
}
}
_lenPayload = m_io.ReadU4le();
{
uint M_ = _lenPayload;
if (!(KaitaiStream.Mod(M_, 4) == 0))
{
throw new ValidationExprError(_lenPayload, m_io, "/types/block/seq/4");
}
}
_blockNumber = m_io.ReadU4le();
_numBlocksRaw = m_io.ReadU4le();
if (!(_numBlocksRaw >= BlockNumber + 1))
{
throw new ValidationLessThanError(BlockNumber + 1, _numBlocksRaw, m_io, "/types/block/seq/6");
}
if (!(Flags.HasFamilyId)) {
_fileSize = m_io.ReadU4le();
}
if (Flags.HasFamilyId) {
_familyId = ((Uf2.FamilyId) m_io.ReadU4le());
}
__raw_data = m_io.ReadBytes(476);
var io___raw_data = new KaitaiStream(__raw_data);
_data = new BlockData(io___raw_data, this, m_root);
_finalMagic = m_io.ReadBytes(4);
if (!((KaitaiStream.ByteArrayCompare(_finalMagic, new byte[] { 48, 111, 177, 10 }) == 0)))
{
throw new ValidationNotEqualError(new byte[] { 48, 111, 177, 10 }, _finalMagic, m_io, "/types/block/seq/10");
}
}
private bool f_isRp2350E10Block;
private bool _isRp2350E10Block;
///
/// Determines whether this is a block that `picotool` prepends to RP2350
/// flash images as a workaround for erratum RP2350-E10 (i.e. a hardware
/// bug in the A2 version of the RP2350 boot ROM).
///
/// Such a block is always written on its own, but its `num_blocks_raw` is
/// set to 2. If we trusted this value, we would attempt to read one block
/// too many (which would most likely fail). Therefore, we must correct it
/// to 1 before using it.
///
/// The conditions for detecting this block come from the
/// [`check_abs_block()`](https://github.com/raspberrypi/picotool/blob/6f6458d792b93685a11423b244a585eaa99eafcf/elf2uf2/elf2uf2.cpp#L147)
/// function in `picotool`. However, there are some differences:
///
/// 1. In Kaitai Struct, we cannot easily check whether all 256 payload
/// bytes are set to `0xef`, so we only check the first and last bytes.
/// 2. There are .uf2 files in the wild where `flags.has_extension_tags`
/// is true, but there are actually no extension tags (the first and
/// only tag has a size of 0, which is just a terminator), so our
/// condition allows for this case. You can download an example of such
/// a .uf2 file here:
/// <https://github.com/neednotapply/DC32-cfw/releases/tag/1.69.13.37>
///
/// It's worth noting that we cannot require the presence of the
/// `extension_tag_type::rp2_ignore_block`
/// (`UF2_EXTENSION_RP2_IGNORE_BLOCK`) tag because the UF2 files generated
/// by `picotool` prior to
/// <https://github.com/raspberrypi/picotool/commit/78c9bd121b09399823b67ee7ea89003ca0d3315f>
/// don't have it. Therefore, we check whether this tag is present only if
/// `flags.has_extension_tags` is set.
///
/// Test .uf2 files with this special block can be downloaded from
/// <https://micropython.org/download/RPI_PICO2/>. Note that all the .uf2
/// files there are actually two UF2 (sub)files concatenated, and this
/// Kaitai Struct implementation parses only one at a time (so in order to
/// parse both, you need something like the helper spec `uf2_files.ksy`
/// from
/// <https://github.com/kaitai-io/kaitai_struct_formats/pull/542#discussion_r3906386820>).
/// v1.24.x releases predate the `extension_tag_type::rp2_ignore_block`
/// tag, while releases v1.25.0 and later include it.
///
///
/// Reference: Git tag "2.3.0"
///
///
/// Reference: Source
///
public bool IsRp2350E10Block
{
get
{
if (f_isRp2350E10Block)
return _isRp2350E10Block;
f_isRp2350E10Block = true;
_isRp2350E10Block = (bool) ( (( ((Flags.Value == 8192) || (Flags.Value == 40960)) ) && (FamilyId == Uf2.FamilyId.Rp2xxxAbsolute) && (NumBlocksRaw == 2) && (BlockNumber == 0) && (LenPayload == 256) && (Data.Payload[0] == 239) && (Data.Payload[Data.Payload.Length - 1] == 239) && ( ((!(Flags.HasExtensionTags)) || (Data.ExtensionTags[0].LenTag == 0) || ( ((Data.ExtensionTags[0].LenTag == 4) && (Data.ExtensionTags[0].TagType == Uf2.ExtensionTagType.Rp2IgnoreBlock)) )) )) );
return _isRp2350E10Block;
}
}
private bool f_numBlocks;
private uint _numBlocks;
public uint NumBlocks
{
get
{
if (f_numBlocks)
return _numBlocks;
f_numBlocks = true;
_numBlocks = (uint) ((IsRp2350E10Block ? 1 : NumBlocksRaw));
return _numBlocks;
}
}
private byte[] _magic;
private byte[] _secondMagic;
private Flags _flags;
private uint _targetAddress;
private uint _lenPayload;
private uint _blockNumber;
private uint _numBlocksRaw;
private uint? _fileSize;
private FamilyId _familyId;
private BlockData _data;
private byte[] _finalMagic;
private Uf2 m_root;
private Uf2 m_parent;
private byte[] __raw_data;
public byte[] Magic { get { return _magic; } }
public byte[] SecondMagic { get { return _secondMagic; } }
public Flags Flags { get { return _flags; } }
///
/// Address in flash where `data.payload` should be written, or an offset
/// in the file specified by `data.file_name` if `flags.is_file_container`
/// is set.
///
/// The [official
/// spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#payload-sizes)
/// says:
///
/// > In any event, payload size and target address should always be
/// > 4-byte aligned.
///
public uint TargetAddress { get { return _targetAddress; } }
///
/// The [official
/// spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#payload-sizes)
/// says:
///
/// > In any event, payload size and target address should always be
/// > 4-byte aligned.
///
public uint LenPayload { get { return _lenPayload; } }
public uint BlockNumber { get { return _blockNumber; } }
///
/// Number of blocks that make up the UF2 file to which this block
/// belongs. Every block of a file has the same value. It is at least 1
/// and every `block_number` in the file must be less than this value
/// (which is validated by this Kaitai Struct implementation).
///
public uint NumBlocksRaw { get { return _numBlocksRaw; } }
///
/// Size of the file this block belongs to, but only if
/// `flags.is_file_container` is true. Otherwise, the official spec allows
/// this field to be set to anything - though in practice, it's always
/// zero.
///
public uint? FileSize { get { return _fileSize; } }
public FamilyId FamilyId { get { return _familyId; } }
public BlockData Data { get { return _data; } }
public byte[] FinalMagic { get { return _finalMagic; } }
public Uf2 M_Root { get { return m_root; } }
public Uf2 M_Parent { get { return m_parent; } }
public byte[] M_RawData { get { return __raw_data; } }
}
public partial class BlockData : KaitaiStruct
{
public static BlockData FromFile(string fileName)
{
return new BlockData(new KaitaiStream(fileName));
}
public BlockData(KaitaiStream p__io, Uf2.Block p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_md5Checksum = false;
_read();
}
private void _read()
{
_payload = m_io.ReadBytes(M_Parent.LenPayload);
if (M_Parent.Flags.IsFileContainer) {
_fileName = System.Text.Encoding.GetEncoding("UTF-8").GetString(m_io.ReadBytesTerm(0, false, true, true));
}
if (M_Parent.Flags.HasExtensionTags) {
_extensionTags = new List();
{
var i = 0;
ExtensionTag M_;
do {
M_ = new ExtensionTag(m_io, this, m_root);
_extensionTags.Add(M_);
i++;
} while (!(M_.LenTag == 0));
}
}
}
private bool f_md5Checksum;
private Md5Checksum _md5Checksum;
///
/// Describes a region that doesn't need to be flashed again if the
/// checksum matches.
///
/// The [official
/// spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#md5-checksum)
/// says that "This is currently only used on ESP32", but no real-world
/// firmware sample has been found (at least none of the .uf2 files from
/// <https://github.com/adafruit/tinyuf2/releases>,
/// [MicroPython](https://micropython.org/download/) or
/// [CircuitPython](https://circuitpython.org/downloads) contain it). It
/// was found only in some synthetic test files, e.g.
/// <https://github.com/umi-eng/uftwo/blob/35bccf75b4f81c43f088696a8c4a9912f1f4104e/uftwo/tests/checksum_256.uf2>.
///
public Md5Checksum Md5Checksum
{
get
{
if (f_md5Checksum)
return _md5Checksum;
f_md5Checksum = true;
if (M_Parent.Flags.HasMd5Checksum) {
long _pos = m_io.Pos;
m_io.Seek(M_Io.Size - 24);
_md5Checksum = new Md5Checksum(m_io, this, m_root);
m_io.Seek(_pos);
}
return _md5Checksum;
}
}
private byte[] _payload;
private string _fileName;
private List _extensionTags;
private Uf2 m_root;
private Uf2.Block m_parent;
///
/// The bytes to be written to `_parent.target_address`, which is either
/// an address in flash, or an offset in the file specified by `file_name`
/// if `_parent.flags.is_file_container` is set.
///
public byte[] Payload { get { return _payload; } }
public string FileName { get { return _fileName; } }
public List ExtensionTags { get { return _extensionTags; } }
public Uf2 M_Root { get { return m_root; } }
public Uf2.Block M_Parent { get { return m_parent; } }
}
///
/// Reference: Source
///
public partial class ExtensionTag : KaitaiStruct
{
public static ExtensionTag FromFile(string fileName)
{
return new ExtensionTag(new KaitaiStream(fileName));
}
public ExtensionTag(KaitaiStream p__io, Uf2.BlockData p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_lenValue = false;
f_minLenTag = false;
_read();
}
private void _read()
{
_lenTag = m_io.ReadU1();
{
byte M_ = _lenTag;
if (!( ((M_ == 0) || (M_ >= MinLenTag)) ))
{
throw new ValidationExprError(_lenTag, m_io, "/types/extension_tag/seq/0");
}
}
_tagType = ((Uf2.ExtensionTagType) m_io.ReadBitsIntLe(24));
m_io.AlignToByte();
if (LenTag != 0) {
_value = m_io.ReadBytes(LenValue);
}
_padding = m_io.ReadBytes(KaitaiStream.Mod(-(LenTag), 4));
}
private bool f_lenValue;
private int _lenValue;
public int LenValue
{
get
{
if (f_lenValue)
return _lenValue;
f_lenValue = true;
_lenValue = (int) ((LenTag >= MinLenTag ? LenTag - MinLenTag : 0));
return _lenValue;
}
}
private bool f_minLenTag;
private int _minLenTag;
public int MinLenTag
{
get
{
if (f_minLenTag)
return _minLenTag;
f_minLenTag = true;
_minLenTag = (int) (1 + 3);
return _minLenTag;
}
}
private byte _lenTag;
private ExtensionTagType _tagType;
private byte[] _value;
private byte[] _padding;
private Uf2 m_root;
private Uf2.BlockData m_parent;
///
/// Total size of the tag in bytes, including this byte and `tag_type`, so
/// at least 4. The exception is the last tag which terminates the list -
/// it specifies a total size of 0.
///
public byte LenTag { get { return _lenTag; } }
public ExtensionTagType TagType { get { return _tagType; } }
public byte[] Value { get { return _value; } }
///
/// Tags are 4-byte aligned, so a tag whose size is not a multiple
/// of 4 is followed by padding.
///
public byte[] Padding { get { return _padding; } }
public Uf2 M_Root { get { return m_root; } }
public Uf2.BlockData M_Parent { get { return m_parent; } }
}
///
/// Reference: Source
///
///
/// Reference: Git tag "2.3.0"
///
public partial class Flags : KaitaiStruct
{
public static Flags FromFile(string fileName)
{
return new Flags(new KaitaiStream(fileName));
}
public Flags(KaitaiStream p__io, Uf2.Block p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
f_hasExtensionTags = false;
f_hasFamilyId = false;
f_hasMd5Checksum = false;
f_isFileContainer = false;
f_notMainFlash = false;
_read();
}
private void _read()
{
_value = m_io.ReadU4le();
{
uint M_ = _value;
if (!( (((M_ & ~61441) == 0) && (!( ((IsFileContainer) && (HasExtensionTags)) ))) ))
{
throw new ValidationExprError(_value, m_io, "/types/flags/seq/0");
}
}
}
private bool f_hasExtensionTags;
private bool _hasExtensionTags;
///
/// Indicates whether extension tags are present after the payload.
///
public bool HasExtensionTags
{
get
{
if (f_hasExtensionTags)
return _hasExtensionTags;
f_hasExtensionTags = true;
_hasExtensionTags = (bool) ((Value & 32768) != 0);
return _hasExtensionTags;
}
}
private bool f_hasFamilyId;
private bool _hasFamilyId;
///
/// The field at offset 28 in the block is `family_id` instead of
/// `file_size`.
///
public bool HasFamilyId
{
get
{
if (f_hasFamilyId)
return _hasFamilyId;
f_hasFamilyId = true;
_hasFamilyId = (bool) ((Value & 8192) != 0);
return _hasFamilyId;
}
}
private bool f_hasMd5Checksum;
private bool _hasMd5Checksum;
///
/// Indicates whether `md5_checksum` is present at the end of `data`.
///
public bool HasMd5Checksum
{
get
{
if (f_hasMd5Checksum)
return _hasMd5Checksum;
f_hasMd5Checksum = true;
_hasMd5Checksum = (bool) ((Value & 16384) != 0);
return _hasMd5Checksum;
}
}
private bool f_isFileContainer;
private bool _isFileContainer;
///
/// When set, the UF2 format is used as a container for regular files
/// (akin to a TAR file, or ZIP archive without compression).
///
/// `target_address` is the offset in the file where the payload is to be
/// written, and `file_size` is the size of that file. The name of the
/// destination file is stored in `data.file_name`.
///
public bool IsFileContainer
{
get
{
if (f_isFileContainer)
return _isFileContainer;
f_isFileContainer = true;
_isFileContainer = (bool) ((Value & 4096) != 0);
return _isFileContainer;
}
}
private bool f_notMainFlash;
private bool _notMainFlash;
///
/// Indicates that this block should be skipped when writing the device
/// flash. It can be used to store data that does not fit on the device,
/// typically embedded source code or debug info.
///
public bool NotMainFlash
{
get
{
if (f_notMainFlash)
return _notMainFlash;
f_notMainFlash = true;
_notMainFlash = (bool) ((Value & 1) != 0);
return _notMainFlash;
}
}
private uint _value;
private Uf2 m_root;
private Uf2.Block m_parent;
///
/// Only the five bits that we cover in value instances below are defined,
/// and no other bit may be set. The [official
/// spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#flags)
/// says "Currently, there are five flags defined". If any other flags are
/// added in the future, this .ksy spec will need to be updated.
///
/// The `is_file_container` and `has_extension_tags` flags disagree about
/// what follows the payload in `data` (a file name or a list of extension
/// tags), so this Kaitai Struct implementation treats them as mutually
/// exclusive and will reject a block that sets both. The official spec
/// does not specify how this should be handled, but logically there's a
/// conflict, so we've decided to strictly treat it as an error.
///
public uint Value { get { return _value; } }
public Uf2 M_Root { get { return m_root; } }
public Uf2.Block M_Parent { get { return m_parent; } }
}
///
/// Reference: Source
///
public partial class Md5Checksum : KaitaiStruct
{
public static Md5Checksum FromFile(string fileName)
{
return new Md5Checksum(new KaitaiStream(fileName));
}
public Md5Checksum(KaitaiStream p__io, Uf2.BlockData p__parent = null, Uf2 p__root = null) : base(p__io)
{
m_parent = p__parent;
m_root = p__root;
_read();
}
private void _read()
{
_startAddress = m_io.ReadU4le();
_lenRegion = m_io.ReadU4le();
_md5 = m_io.ReadBytes(16);
}
private uint _startAddress;
private uint _lenRegion;
private byte[] _md5;
private Uf2 m_root;
private Uf2.BlockData m_parent;
public uint StartAddress { get { return _startAddress; } }
public uint LenRegion { get { return _lenRegion; } }
public byte[] Md5 { get { return _md5; } }
public Uf2 M_Root { get { return m_root; } }
public Uf2.BlockData M_Parent { get { return m_parent; } }
}
private Block _firstBlock;
private List _blocks;
private Uf2 m_root;
private KaitaiStruct m_parent;
public Block FirstBlock { get { return _firstBlock; } }
public List Blocks { get { return _blocks; } }
public Uf2 M_Root { get { return m_root; } }
public KaitaiStruct M_Parent { get { return m_parent; } }
}
}