github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/smbios/entry32.go (about) 1 // Copyright 2016-2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package smbios 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "fmt" 11 ) 12 13 // Entry32 is the SMBIOS 32-Bit entry point structure, described in DSP0134 5.2.1. 14 type Entry32 struct { 15 Anchor [4]uint8 16 Checksum uint8 17 Length uint8 18 SMBIOSMajorVersion uint8 19 SMBIOSMinorVersion uint8 20 StructMaxSize uint16 21 Revision uint8 22 Reserved [5]uint8 23 IntAnchor [5]uint8 24 IntChecksum uint8 25 StructTableLength uint16 26 StructTableAddr uint32 27 NumberOfStructs uint16 28 BCDRevision uint8 29 } 30 31 // UnmarshalBinary unmarshals the SMBIOS 32-Bit entry point structure from binary data. 32 func (e *Entry32) UnmarshalBinary(data []byte) error { 33 if len(data) < 0x1f { 34 return fmt.Errorf("invalid entry point stucture length %d", len(data)) 35 } 36 if err := binary.Read(bytes.NewReader(data), binary.LittleEndian, e); err != nil { 37 return err 38 } 39 if !bytes.Equal(e.Anchor[:], []byte("_SM_")) { 40 return fmt.Errorf("invalid anchor string %q", string(e.Anchor[:])) 41 } 42 if int(e.Length) != 0x1f { 43 return fmt.Errorf("length mismatch: %d vs %d", e.Length, len(data)) 44 } 45 cs := calcChecksum(data[:e.Length], 4) 46 if e.Checksum != cs { 47 return fmt.Errorf("checksum mismatch: 0x%02x vs 0x%02x", e.Checksum, cs) 48 } 49 if !bytes.Equal(e.IntAnchor[:], []byte("_DMI_")) { 50 return fmt.Errorf("invalid intermediate anchor string %q", string(e.Anchor[:])) 51 } 52 intCs := calcChecksum(data[0x10:0x1f], 5) 53 if e.IntChecksum != intCs { 54 return fmt.Errorf("intermediate checksum mismatch: 0x%02x vs 0x%02x", e.IntChecksum, intCs) 55 } 56 return nil 57 } 58 59 // MarshalBinary marshals the SMBIOS 32-Bit entry point structure to binary data. 60 func (e *Entry32) MarshalBinary() ([]byte, error) { 61 buf := bytes.NewBuffer(nil) 62 if err := binary.Write(buf, binary.LittleEndian, e); err != nil { 63 return nil, err 64 } 65 // Adjust checksums. 66 data := buf.Bytes() 67 data[0x15] = calcChecksum(data[0x10:0x1f], 5) 68 data[4] = calcChecksum(data, 4) 69 return data, nil 70 }