github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+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 iw.info.Flags |= flagInfoCmdline | flagInfoBootLoaderName 97 98 buf := bytes.Buffer{} 99 if err := binary.Write(&buf, ubinary.NativeEndian, iw.info); err != nil { 100 return nil, err 101 } 102 103 for _, s := range []string{iw.Cmdline, iw.BootLoaderName} { 104 if _, err := buf.WriteString(s); err != nil { 105 return nil, err 106 } 107 if err := buf.WriteByte(0); err != nil { 108 return nil, err 109 } 110 } 111 112 size := (buf.Len() + 3) &^ 3 113 _, err := buf.Write(bytes.Repeat([]byte{0}, size-buf.Len())) 114 return buf.Bytes(), err 115 } 116 117 func (iw infoWrapper) size() (uint, error) { 118 b, err := iw.marshal(0) 119 return uint(len(b)), err 120 }