github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/multiboot/mutiheader.go (about) 1 // Copyright 2020 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 multiboot 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "io" 11 "log" 12 13 "github.com/u-root/u-root/pkg/ubinary" 14 ) 15 16 // mutibootMagic is both the magic value found in the mutiboot kernel header as 17 // well as the value the loaded OS expects in EAX at boot time. 18 const mutibootMagic = 0x1BADB005 19 20 type mutibootHeaderFlag uint32 21 22 const ( 23 // Kernel runs in EL1, not EL2. 24 MUTIBOOT_ARCH_FLAG_ARM64_EL1 mutibootHeaderFlag = 1 << 0 25 // Must pass video info to OS. 26 MUTIBOOT_FLAG_VIDEO mutibootHeaderFlag = 1 << 2 27 28 // rts_vaddr field is valid. 29 MUTIBOOT_FLAG_EFI_RTS_OLD mutibootHeaderFlag = 1 << 17 30 // rts vaddr and size fields valid. 31 MUTIBOOT_FLAG_EFI_RTS_NEW mutibootHeaderFlag = 1 << 18 32 // LoadESX version field valid. 33 MUTIBOOT_FLAG_LOADESX_VERSION mutibootHeaderFlag = 1 << 19 34 // Video min fields valid. 35 MUTIBOOT_FLAG_VIDEO_MIN mutibootHeaderFlag = 1 << 20 36 ) 37 38 type mutibootVideoMode uint32 39 40 const ( 41 MUTIBOOT_VIDEO_GRAPHIC = 0 42 MUTIBOOT_VIDEO_TEXT = 1 43 ) 44 45 type mutibootHeader struct { 46 Magic uint32 47 Flags mutibootHeaderFlag 48 Checksum uint32 49 50 // unused. 51 _ uint32 52 _ uint32 53 54 // video stuff 55 MinWidth uint32 56 MinHeight uint32 57 MinDepth uint32 58 ModeType mutibootVideoMode 59 Width uint32 60 Height uint32 61 Depth uint32 62 63 RuntimeServicesVAddr uint64 64 RuntimeServicesSize uint64 65 LoadESXVersion uint32 66 } 67 68 func (m *mutibootHeader) name() string { 69 return "mutiboot" 70 } 71 72 func (m *mutibootHeader) bootMagic() uintptr { 73 return mutibootMagic 74 } 75 76 // parseMutiHeader parses mutiboot header. 77 func parseMutiHeader(r io.Reader) (*mutibootHeader, error) { 78 sizeofHeader := binary.Size(mutibootHeader{}) 79 80 var hdr mutibootHeader 81 // The multiboot header must be contained completely within the 82 // first 8192 bytes of the OS image. 83 buf := make([]byte, 8192) 84 n, err := io.ReadAtLeast(r, buf, sizeofHeader) 85 if err != nil { 86 return nil, err 87 } 88 buf = buf[:n] 89 90 br := new(bytes.Reader) 91 for len(buf) >= sizeofHeader { 92 br.Reset(buf) 93 if err := binary.Read(br, ubinary.NativeEndian, &hdr); err != nil { 94 return nil, err 95 } 96 if hdr.Magic == mutibootMagic && (hdr.Magic+uint32(hdr.Flags)+hdr.Checksum) == 0 { 97 /*if hdr.Flags&flagHeaderUnsupported != 0 { 98 return hdr, ErrFlagsNotSupported 99 }*/ 100 if hdr.Flags&MUTIBOOT_FLAG_VIDEO != 0 { 101 log.Print("VideoMode flag is not supproted yet, trying to load anyway") 102 } 103 return &hdr, nil 104 } 105 // The Multiboot header must be 64-bit aligned. 106 buf = buf[8:] 107 } 108 return nil, ErrHeaderNotFound 109 }