// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT. import ( "github.com/kaitai-io/kaitai_struct_go_runtime/kaitai" "bytes" ) /** * This is an unnamed and undocumented partition table format implemented by * the bootloader and kernel that Amlogic provides for their Linux SoCs (Meson * series at least, and probably others). They appear to use this rather than GPT, * the industry standard, because their BootROM loads and executes the next stage * loader from offset 512 (0x200) on the eMMC, which is exactly where the GPT * header would have to start. So instead of changing their BootROM, Amlogic * devised this partition table, which lives at an offset of 36MiB (0x240_0000) * on the eMMC and so doesn't conflict. This parser expects as input just the * partition table from that offset. The maximum number of partitions in a table * is 32, which corresponds to a maximum table size of 1304 bytes (0x518). * @see Source * @see Source */ type AmlogicEmmcPartitions struct { Magic []byte Version string NumPartitions int32 Checksum uint32 Partitions []*AmlogicEmmcPartitions_Partition _io *kaitai.Stream _root *AmlogicEmmcPartitions _parent interface{} } func NewAmlogicEmmcPartitions() *AmlogicEmmcPartitions { return &AmlogicEmmcPartitions{ } } func (this *AmlogicEmmcPartitions) Read(io *kaitai.Stream, parent interface{}, root *AmlogicEmmcPartitions) (err error) { this._io = io this._parent = parent this._root = root tmp1, err := this._io.ReadBytes(int(4)) if err != nil { return err } tmp1 = tmp1 this.Magic = tmp1 if !(bytes.Equal(this.Magic, []uint8{77, 80, 84, 0})) { return kaitai.NewValidationNotEqualError([]uint8{77, 80, 84, 0}, this.Magic, this._io, "/seq/0") } tmp2, err := this._io.ReadBytes(int(12)) if err != nil { return err } tmp2 = kaitai.BytesTerminate(tmp2, 0, false) this.Version = string(tmp2) tmp3, err := this._io.ReadS4le() if err != nil { return err } this.NumPartitions = int32(tmp3) if !(this.NumPartitions >= 1) { return kaitai.NewValidationLessThanError(1, this.NumPartitions, this._io, "/seq/2") } if !(this.NumPartitions <= 32) { return kaitai.NewValidationGreaterThanError(32, this.NumPartitions, this._io, "/seq/2") } tmp4, err := this._io.ReadU4le() if err != nil { return err } this.Checksum = uint32(tmp4) for i := 0; i < int(this.NumPartitions); i++ { _ = i tmp5 := NewAmlogicEmmcPartitions_Partition() err = tmp5.Read(this._io, this, this._root) if err != nil { return err } this.Partitions = append(this.Partitions, tmp5) } return err } /** * To calculate this, treat the first (and only the first) partition * descriptor in the table below as an array of unsigned little-endian * 32-bit integers. Sum all those integers mod 2^32, then multiply the * result by the total number of partitions, also mod 2^32. Amlogic * likely meant to include all the partition descriptors in the sum, * but their code as written instead repeatedly loops over the first * one, once for each partition in the table. */ type AmlogicEmmcPartitions_Partition struct { Name string Size uint64 Offset uint64 Flags *AmlogicEmmcPartitions_Partition_PartFlags Padding []byte _io *kaitai.Stream _root *AmlogicEmmcPartitions _parent *AmlogicEmmcPartitions _raw_Flags []byte } func NewAmlogicEmmcPartitions_Partition() *AmlogicEmmcPartitions_Partition { return &AmlogicEmmcPartitions_Partition{ } } func (this *AmlogicEmmcPartitions_Partition) Read(io *kaitai.Stream, parent *AmlogicEmmcPartitions, root *AmlogicEmmcPartitions) (err error) { this._io = io this._parent = parent this._root = root tmp6, err := this._io.ReadBytes(int(16)) if err != nil { return err } tmp6 = kaitai.BytesTerminate(tmp6, 0, false) this.Name = string(tmp6) tmp7, err := this._io.ReadU8le() if err != nil { return err } this.Size = uint64(tmp7) tmp8, err := this._io.ReadU8le() if err != nil { return err } this.Offset = uint64(tmp8) tmp9, err := this._io.ReadBytes(int(4)) if err != nil { return err } tmp9 = tmp9 this._raw_Flags = tmp9 _io__raw_Flags := kaitai.NewStream(bytes.NewReader(this._raw_Flags)) tmp10 := NewAmlogicEmmcPartitions_Partition_PartFlags() err = tmp10.Read(_io__raw_Flags, this, this._root) if err != nil { return err } this.Flags = tmp10 tmp11, err := this._io.ReadBytes(int(4)) if err != nil { return err } tmp11 = tmp11 this.Padding = tmp11 return err } /** * The start of the partition relative to the start of the eMMC, in bytes */ type AmlogicEmmcPartitions_Partition_PartFlags struct { IsCode bool IsCache bool IsData bool _io *kaitai.Stream _root *AmlogicEmmcPartitions _parent *AmlogicEmmcPartitions_Partition } func NewAmlogicEmmcPartitions_Partition_PartFlags() *AmlogicEmmcPartitions_Partition_PartFlags { return &AmlogicEmmcPartitions_Partition_PartFlags{ } } func (this *AmlogicEmmcPartitions_Partition_PartFlags) Read(io *kaitai.Stream, parent *AmlogicEmmcPartitions_Partition, root *AmlogicEmmcPartitions) (err error) { this._io = io this._parent = parent this._root = root tmp12, err := this._io.ReadBitsIntLe(1) if err != nil { return err } this.IsCode = tmp12 != 0 tmp13, err := this._io.ReadBitsIntLe(1) if err != nil { return err } this.IsCache = tmp13 != 0 tmp14, err := this._io.ReadBitsIntLe(1) if err != nil { return err } this.IsData = tmp14 != 0 return err }