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