github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/multiboot/mutiboot_info.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 "github.com/u-root/u-root/pkg/uio" 9 ) 10 11 type mutibootInfo struct { 12 cmdline uint64 13 14 elems []elem 15 } 16 17 func (m *mutibootInfo) marshal() []byte { 18 buf := uio.NewNativeEndianBuffer(nil) 19 buf.Write64(m.cmdline) 20 buf.Write64(uint64(len(m.elems))) 21 22 // These elems are encoded as TLV. 23 // Which is nice, because then we don't have to encode offsets and shit. 24 for _, el := range m.elems { 25 b := el.marshal() 26 buf.Write32(uint32(el.typ())) 27 // The element size is the total size including itself - typ + 28 // size + data. 29 buf.Write64(uint64(len(b)) + 8 + 4) 30 buf.WriteData(b) 31 } 32 return buf.Data() 33 } 34 35 type elem interface { 36 typ() mutibootType 37 marshal() []byte 38 } 39 40 type mutibootType uint32 41 42 const ( 43 MUTIBOOT_INVALID_TYPE mutibootType = 0 44 MUTIBOOT_MEMRANGE_TYPE mutibootType = 1 45 MUTIBOOT_MODULE_TYPE mutibootType = 2 46 MUTIBOOT_VBE_TYPE mutibootType = 3 47 MUTIBOOT_EFI_TYPE mutibootType = 4 48 MUTIBOOT_LOADESX_TYPE mutibootType = 5 49 ) 50 51 type mutibootMemRange struct { 52 startAddr uint64 53 length uint64 54 memType uint32 55 } 56 57 func (m mutibootMemRange) typ() mutibootType { 58 return MUTIBOOT_MEMRANGE_TYPE 59 } 60 61 func (m *mutibootMemRange) marshal() []byte { 62 buf := uio.NewNativeEndianBuffer(nil) 63 buf.Write64(m.startAddr) 64 buf.Write64(m.length) 65 buf.Write32(m.memType) 66 return buf.Data() 67 } 68 69 type mutibootModuleRange struct { 70 startPageNum uint64 71 numPages uint32 72 } 73 74 type mutibootModule struct { 75 cmdline uint64 76 moduleSize uint64 77 ranges []mutibootModuleRange 78 } 79 80 func (m mutibootModule) typ() mutibootType { 81 return MUTIBOOT_MODULE_TYPE 82 } 83 84 func (m *mutibootModule) marshal() []byte { 85 buf := uio.NewNativeEndianBuffer(nil) 86 buf.Write64(m.cmdline) 87 buf.Write64(m.moduleSize) 88 buf.Write32(uint32(len(m.ranges))) 89 for _, r := range m.ranges { 90 buf.Write64(r.startPageNum) 91 buf.Write32(r.numPages) 92 // Padding. 93 buf.Write32(0) 94 } 95 return buf.Data() 96 } 97 98 type mutibootEfiFlags uint32 99 100 const ( 101 // 64-bit ARM EFI. (Why would we have to tell the next kernel that it's 102 // an aarch64 EFI? Shouldn't it know?) 103 MUTIBOOT_EFI_ARCH64 mutibootEfiFlags = 1 << 0 104 105 // EFI Secure Boot in progress. 106 MUTIBOOT_EFI_SECURE_BOOT mutibootEfiFlags = 1 << 1 107 108 // UEFI memory map is valid rather than mutiboot memory map. 109 MUTIBOOT_EFI_MMAP mutibootEfiFlags = 1 << 2 110 ) 111 112 type mutibootEfi struct { 113 flags mutibootEfiFlags 114 systab uint64 115 116 // Only set if flags & MUTIBOOT_EFI_MMAP. 117 memmap uint64 118 memmapNumDescs uint32 119 memmapDescSize uint32 120 memmapVersion uint32 121 } 122 123 func (m mutibootEfi) typ() mutibootType { 124 return MUTIBOOT_EFI_TYPE 125 } 126 127 func (m *mutibootEfi) marshal() []byte { 128 buf := uio.NewNativeEndianBuffer(nil) 129 buf.Write32(uint32(m.flags)) 130 buf.Write64(m.systab) 131 buf.Write64(m.memmap) 132 buf.Write32(m.memmapNumDescs) 133 buf.Write32(m.memmapDescSize) 134 buf.Write32(m.memmapVersion) 135 return buf.Data() 136 }