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  }