github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/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/u-root/u-root/pkg/uio"
     9  )
    10  
    11  type mutibootInfo struct {
    12  	cmdline uint64
    13  
    14  	elems []elem
    15  }
    16  
    17  func (m *mutibootInfo) 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() mutibootType
    37  	marshal() []byte
    38  }
    39  
    40  type mutibootType uint32
    41  
    42  const (
    43  	MUTIBOOT_INVALID_TYPE  mutibootType = 0
    44  	MUTIBOOT_MEMRANGE_TYPE mutibootType = 1
    45  	MUTIBOOT_MODULE_TYPE   mutibootType = 2
    46  	MUTIBOOT_VBE_TYPE      mutibootType = 3
    47  	MUTIBOOT_EFI_TYPE      mutibootType = 4
    48  	MUTIBOOT_LOADESX_TYPE  mutibootType = 5
    49  )
    50  
    51  type mutibootMemRange struct {
    52  	startAddr uint64
    53  	length    uint64
    54  	memType   uint32
    55  }
    56  
    57  func (m mutibootMemRange) typ() mutibootType {
    58  	return MUTIBOOT_MEMRANGE_TYPE
    59  }
    60  
    61  func (m *mutibootMemRange) 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 mutibootModuleRange struct {
    70  	startPageNum uint64
    71  	numPages     uint32
    72  }
    73  
    74  type mutibootModule struct {
    75  	cmdline    uint64
    76  	moduleSize uint64
    77  	ranges     []mutibootModuleRange
    78  }
    79  
    80  func (m mutibootModule) typ() mutibootType {
    81  	return MUTIBOOT_MODULE_TYPE
    82  }
    83  
    84  func (m *mutibootModule) 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 mutibootEfiFlags 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  	MUTIBOOT_EFI_ARCH64 mutibootEfiFlags = 1 << 0
   104  
   105  	// EFI Secure Boot in progress.
   106  	MUTIBOOT_EFI_SECURE_BOOT mutibootEfiFlags = 1 << 1
   107  
   108  	// UEFI memory map is valid rather than mutiboot memory map.
   109  	MUTIBOOT_EFI_MMAP mutibootEfiFlags = 1 << 2
   110  )
   111  
   112  type mutibootEfi struct {
   113  	flags  mutibootEfiFlags
   114  	systab uint64
   115  
   116  	// Only set if flags & MUTIBOOT_EFI_MMAP.
   117  	memmap         uint64
   118  	memmapNumDescs uint32
   119  	memmapDescSize uint32
   120  	memmapVersion  uint32
   121  }
   122  
   123  func (m mutibootEfi) typ() mutibootType {
   124  	return MUTIBOOT_EFI_TYPE
   125  }
   126  
   127  func (m *mutibootEfi) 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  }