github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/boot/multiboot/mutiboot_info.go (about)

     1  // Copyright 2020 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  	"github.com/mvdan/u-root-coreutils/pkg/uio"
     9  )
    10  
    11  type esxBootInfoInfo struct {
    12  	cmdline uint64
    13  
    14  	elems []elem
    15  }
    16  
    17  func (m *esxBootInfoInfo) marshal() []byte {
    18  	buf := uio.NewNativeEndianBuffer(nil)
    19  	buf.Write64(m.cmdline)
    20  	buf.Write64(uint64(len(m.elems)))
    21  
    22  	// These elems are encoded as TLV.
    23  	// Which is nice, because then we don't have to encode offsets and shit.
    24  	for _, el := range m.elems {
    25  		b := el.marshal()
    26  		buf.Write32(uint32(el.typ()))
    27  		// The element size is the total size including itself - typ +
    28  		// size + data.
    29  		buf.Write64(uint64(len(b)) + 8 + 4)
    30  		buf.WriteData(b)
    31  	}
    32  	return buf.Data()
    33  }
    34  
    35  type elem interface {
    36  	typ() esxBootInfoType
    37  	marshal() []byte
    38  }
    39  
    40  type esxBootInfoType uint32
    41  
    42  const (
    43  	ESXBOOTINFO_INVALID_TYPE  esxBootInfoType = 0
    44  	ESXBOOTINFO_MEMRANGE_TYPE esxBootInfoType = 1
    45  	ESXBOOTINFO_MODULE_TYPE   esxBootInfoType = 2
    46  	ESXBOOTINFO_VBE_TYPE      esxBootInfoType = 3
    47  	ESXBOOTINFO_EFI_TYPE      esxBootInfoType = 4
    48  	ESXBOOTINFO_LOADESX_TYPE  esxBootInfoType = 5
    49  )
    50  
    51  type esxBootInfoMemRange struct {
    52  	startAddr uint64
    53  	length    uint64
    54  	memType   uint32
    55  }
    56  
    57  func (m esxBootInfoMemRange) typ() esxBootInfoType {
    58  	return ESXBOOTINFO_MEMRANGE_TYPE
    59  }
    60  
    61  func (m *esxBootInfoMemRange) marshal() []byte {
    62  	buf := uio.NewNativeEndianBuffer(nil)
    63  	buf.Write64(m.startAddr)
    64  	buf.Write64(m.length)
    65  	buf.Write32(m.memType)
    66  	return buf.Data()
    67  }
    68  
    69  type esxBootInfoModuleRange struct {
    70  	startPageNum uint64
    71  	numPages     uint32
    72  }
    73  
    74  type esxBootInfoModule struct {
    75  	cmdline    uint64
    76  	moduleSize uint64
    77  	ranges     []esxBootInfoModuleRange
    78  }
    79  
    80  func (m esxBootInfoModule) typ() esxBootInfoType {
    81  	return ESXBOOTINFO_MODULE_TYPE
    82  }
    83  
    84  func (m *esxBootInfoModule) marshal() []byte {
    85  	buf := uio.NewNativeEndianBuffer(nil)
    86  	buf.Write64(m.cmdline)
    87  	buf.Write64(m.moduleSize)
    88  	buf.Write32(uint32(len(m.ranges)))
    89  	for _, r := range m.ranges {
    90  		buf.Write64(r.startPageNum)
    91  		buf.Write32(r.numPages)
    92  		// Padding.
    93  		buf.Write32(0)
    94  	}
    95  	return buf.Data()
    96  }
    97  
    98  type esxBootInfoEfiFlags uint32
    99  
   100  const (
   101  	// 64-bit ARM EFI. (Why would we have to tell the next kernel that it's
   102  	// an aarch64 EFI? Shouldn't it know?)
   103  	ESXBOOTINFO_EFI_ARCH64 esxBootInfoEfiFlags = 1 << 0
   104  
   105  	// EFI Secure Boot in progress.
   106  	ESXBOOTINFO_EFI_SECURE_BOOT esxBootInfoEfiFlags = 1 << 1
   107  
   108  	// UEFI memory map is valid rather than esxBootInfo memory map.
   109  	ESXBOOTINFO_EFI_MMAP esxBootInfoEfiFlags = 1 << 2
   110  )
   111  
   112  type esxBootInfoEfi struct {
   113  	flags  esxBootInfoEfiFlags
   114  	systab uint64
   115  
   116  	// Only set if flags & ESXBOOTINFO_EFI_MMAP.
   117  	memmap         uint64
   118  	memmapNumDescs uint32
   119  	memmapDescSize uint32
   120  	memmapVersion  uint32
   121  }
   122  
   123  func (m esxBootInfoEfi) typ() esxBootInfoType {
   124  	return ESXBOOTINFO_EFI_TYPE
   125  }
   126  
   127  func (m *esxBootInfoEfi) marshal() []byte {
   128  	buf := uio.NewNativeEndianBuffer(nil)
   129  	buf.Write32(uint32(m.flags))
   130  	buf.Write64(m.systab)
   131  	buf.Write64(m.memmap)
   132  	buf.Write32(m.memmapNumDescs)
   133  	buf.Write32(m.memmapDescSize)
   134  	buf.Write32(m.memmapVersion)
   135  	return buf.Data()
   136  }