github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/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  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  }