github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/multiboot/mutiheader.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  	"bytes"
     9  	"encoding/binary"
    10  	"io"
    11  	"log"
    12  
    13  	"github.com/u-root/u-root/pkg/ubinary"
    14  )
    15  
    16  // mutibootMagic is both the magic value found in the mutiboot kernel header as
    17  // well as the value the loaded OS expects in EAX at boot time.
    18  const mutibootMagic = 0x1BADB005
    19  
    20  type mutibootHeaderFlag uint32
    21  
    22  const (
    23  	// Kernel runs in EL1, not EL2.
    24  	MUTIBOOT_ARCH_FLAG_ARM64_EL1 mutibootHeaderFlag = 1 << 0
    25  	// Must pass video info to OS.
    26  	MUTIBOOT_FLAG_VIDEO mutibootHeaderFlag = 1 << 2
    27  
    28  	// rts_vaddr field is valid.
    29  	MUTIBOOT_FLAG_EFI_RTS_OLD mutibootHeaderFlag = 1 << 17
    30  	// rts vaddr and size fields valid.
    31  	MUTIBOOT_FLAG_EFI_RTS_NEW mutibootHeaderFlag = 1 << 18
    32  	// LoadESX version field valid.
    33  	MUTIBOOT_FLAG_LOADESX_VERSION mutibootHeaderFlag = 1 << 19
    34  	// Video min fields valid.
    35  	MUTIBOOT_FLAG_VIDEO_MIN mutibootHeaderFlag = 1 << 20
    36  )
    37  
    38  type mutibootVideoMode uint32
    39  
    40  const (
    41  	MUTIBOOT_VIDEO_GRAPHIC = 0
    42  	MUTIBOOT_VIDEO_TEXT    = 1
    43  )
    44  
    45  type mutibootHeader struct {
    46  	Magic    uint32
    47  	Flags    mutibootHeaderFlag
    48  	Checksum uint32
    49  
    50  	// unused.
    51  	_ uint32
    52  	_ uint32
    53  
    54  	// video stuff
    55  	MinWidth  uint32
    56  	MinHeight uint32
    57  	MinDepth  uint32
    58  	ModeType  mutibootVideoMode
    59  	Width     uint32
    60  	Height    uint32
    61  	Depth     uint32
    62  
    63  	RuntimeServicesVAddr uint64
    64  	RuntimeServicesSize  uint64
    65  	LoadESXVersion       uint32
    66  }
    67  
    68  func (m *mutibootHeader) name() string {
    69  	return "mutiboot"
    70  }
    71  
    72  func (m *mutibootHeader) bootMagic() uintptr {
    73  	return mutibootMagic
    74  }
    75  
    76  // parseMutiHeader parses mutiboot header.
    77  func parseMutiHeader(r io.Reader) (*mutibootHeader, error) {
    78  	sizeofHeader := binary.Size(mutibootHeader{})
    79  
    80  	var hdr mutibootHeader
    81  	// The multiboot header must be contained completely within the
    82  	// first 8192 bytes of the OS image.
    83  	buf := make([]byte, 8192)
    84  	n, err := io.ReadAtLeast(r, buf, sizeofHeader)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	buf = buf[:n]
    89  
    90  	br := new(bytes.Reader)
    91  	for len(buf) >= sizeofHeader {
    92  		br.Reset(buf)
    93  		if err := binary.Read(br, ubinary.NativeEndian, &hdr); err != nil {
    94  			return nil, err
    95  		}
    96  		if hdr.Magic == mutibootMagic && (hdr.Magic+uint32(hdr.Flags)+hdr.Checksum) == 0 {
    97  			/*if hdr.Flags&flagHeaderUnsupported != 0 {
    98  				return hdr, ErrFlagsNotSupported
    99  			}*/
   100  			if hdr.Flags&MUTIBOOT_FLAG_VIDEO != 0 {
   101  				log.Print("VideoMode flag is not supproted yet, trying to load anyway")
   102  			}
   103  			return &hdr, nil
   104  		}
   105  		// The Multiboot header must be 64-bit aligned.
   106  		buf = buf[8:]
   107  	}
   108  	return nil, ErrHeaderNotFound
   109  }