github.com/shaardie/u-root@v4.0.1-0.20190127173353-f24a1c26aa2e+incompatible/pkg/multiboot/info.go (about) 1 // Copyright 2018 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 // Multiboot info as defined in 6 // https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format 7 package multiboot 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 13 "github.com/u-root/u-root/pkg/ubinary" 14 ) 15 16 var sizeofInfo = uint32(binary.Size(Info{})) 17 18 type Flag uint32 19 20 const ( 21 flagInfoMemory Flag = 1 << iota 22 flagInfoBootDev 23 flagInfoCmdLine 24 flagInfoMods 25 flagInfoAoutSyms 26 flagInfoElfSHDR 27 flagInfoMemMap 28 flagInfoDriveInfo 29 flagInfoConfigTable 30 flagInfoBootLoaderName 31 flagInfoAPMTable 32 flagInfoVideoInfo 33 flagInfoFrameBuffer 34 ) 35 36 // Info represents the Multiboot v1 info passed to the loaded kernel. 37 type Info struct { 38 Flags Flag 39 MemLower uint32 40 MemUpper uint32 41 42 // BootDevice is not supported, always zero. 43 BootDevice uint32 44 45 CmdLine uint32 46 47 ModsCount uint32 48 ModsAddr uint32 49 50 // Syms is not supported, always zero array. 51 Syms [4]uint32 52 53 MmapLength uint32 54 MmapAddr uint32 55 56 // Following fields except BootLoaderName are not suppoted yet, 57 // the values are always set to zeros. 58 59 DriversLength uint32 60 DrivesrAddr uint32 61 62 ConfigTable uint32 63 64 BootLoaderName uint32 65 66 APMTable uint32 67 68 VBEControlInfo uint32 69 VBEModeInfo uint32 70 VBEMode uint16 71 VBEInterfaceSeg uint16 72 VBEInterfaceOff uint16 73 VBEInterfaceLen uint16 74 75 FramebufferAddr uint16 76 FramebufferPitch uint16 77 FramebufferWidth uint32 78 FramebufferHeight uint32 79 FramebufferBPP byte 80 FramebufferType byte 81 ColorInfo [6]byte 82 } 83 84 type infoWrapper struct { 85 Info 86 87 CmdLine string 88 BootLoaderName string 89 } 90 91 // marshal writes out the exact bytes of multiboot info 92 // expected by the kernel being loaded. 93 func (iw *infoWrapper) marshal(base uintptr) ([]byte, error) { 94 offset := sizeofInfo + uint32(base) 95 iw.Info.CmdLine = offset 96 offset += uint32(len(iw.CmdLine)) + 1 97 iw.Info.BootLoaderName = offset 98 99 buf := bytes.Buffer{} 100 if err := binary.Write(&buf, ubinary.NativeEndian, iw.Info); err != nil { 101 return nil, err 102 } 103 104 for _, s := range []string{iw.CmdLine, iw.BootLoaderName} { 105 if _, err := buf.WriteString(s); err != nil { 106 return nil, err 107 } 108 if err := buf.WriteByte(0); err != nil { 109 return nil, err 110 } 111 } 112 113 size := (buf.Len() + 3) &^ 3 114 _, err := buf.Write(bytes.Repeat([]byte{0}, size-buf.Len())) 115 return buf.Bytes(), err 116 } 117 118 func (iw infoWrapper) size() (uint, error) { 119 b, err := iw.marshal(0) 120 return uint(len(b)), err 121 }