github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/boot/image/image.go (about) 1 // Copyright 2022 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 image contains a parser for Arm64 Linux Image format. It 6 // assumes little endian arm. 7 package image 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 "errors" 13 "fmt" 14 "math" 15 ) 16 17 const ( 18 // Magic values used in Image header. 19 Magic = 0x644d5241 20 ) 21 22 var ( 23 kernelImageSize = uint64(math.Pow(2, 24)) // 16MB, a guess value similar to that used in kexec-tools. 24 25 errBadMagic = errors.New("bad header magic") 26 errBadEndianess = errors.New("invalid Image endianess, expected little") 27 ) 28 29 // Arm64Header is header for Arm64 Image. 30 type Arm64Header struct { 31 Code0 uint32 `offset:"0x00"` 32 Code1 uint32 `offset:"0x04"` 33 TextOffset uint64 `offset:"0x08"` 34 ImageSize uint64 `offset:"0x10"` 35 Flags uint64 `offset:"0x18"` 36 Res2 uint64 `offset:"0x20"` 37 Res3 uint64 `offset:"0x28"` 38 Res4 uint64 `offset:"0x30"` 39 Magic uint32 `offset:"0x38"` 40 Res5 uint32 `offset:"0x3c"` 41 } 42 43 // Image abstracts Arm64 Image. 44 type Image struct { 45 Header Arm64Header 46 Data []byte 47 } 48 49 // ParseFromBytes parse an Image from bytes slice. 50 func ParseFromBytes(data []byte) (*Image, error) { 51 img := &Image{} 52 53 if err := binary.Read(bytes.NewBuffer(data), binary.LittleEndian, &img.Header); err != nil { 54 return img, fmt.Errorf("unmarshaling arm64 header: %w", err) 55 } 56 57 if img.Header.Magic != Magic { 58 return img, errBadMagic 59 } 60 61 if img.Header.ImageSize == 0 { 62 /* For 3.16 and older kernels. */ 63 img.Header.TextOffset = 0x80000 64 img.Header.ImageSize = kernelImageSize 65 } 66 67 // v3.17: https://www.kernel.org/doc/Documentation/arm64/booting.txt 68 // 69 // NOTE(10000TB): For now assumes and support little endian arm. 70 // Error out if Image is not little endian. 71 if int(img.Header.Flags&0x1) != 0 { 72 return img, errBadEndianess 73 } 74 75 img.Data = data 76 77 return img, nil 78 }