github.com/linuxboot/fiano@v1.2.0/cmds/fspinfo/main.go (about)

     1  // Copyright 2017-2018 the LinuxBoot 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  // fspinfo prints FSP header information.
     6  
     7  package main
     8  
     9  import (
    10  	"encoding/json"
    11  	"errors"
    12  	"flag"
    13  	"fmt"
    14  	"os"
    15  
    16  	"github.com/linuxboot/fiano/pkg/fsp"
    17  	"github.com/linuxboot/fiano/pkg/log"
    18  	"github.com/linuxboot/fiano/pkg/uefi"
    19  )
    20  
    21  var (
    22  	flagJSON = flag.Bool("j", false, "Output as JSON")
    23  )
    24  
    25  // extractFSPHeader decapsulates an FSP header as described by the FSP specification.
    26  // The FSP files from intel contain various components (e.g. FSP-M, FSP-T, FSP-S),
    27  // each contained in a firmware volume.
    28  // Each FSP component has an FSP_INFO_HEADER in the first FFS file in the first firmware
    29  // volume.
    30  // See https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/fsp-architecture-spec-v2.pdf chapter 4.
    31  
    32  // TODO extract the remaining firmware volumes too
    33  func extractFirstFSPHeader(b []byte) (*fsp.CommonInfoHeader, error) {
    34  	fv, err := uefi.NewFirmwareVolume(b, 0, false)
    35  	if err != nil {
    36  		return nil, fmt.Errorf("cannot parse Firmware Volume: %v", err)
    37  	}
    38  	if len(fv.Files) < 1 {
    39  		return nil, errors.New("firmware Volume has no files")
    40  	}
    41  	file := fv.Files[0]
    42  	sec, err := uefi.NewSection(file.Buf()[file.DataOffset:], 0)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("cannot parse section: %v", err)
    45  	}
    46  	// the section header size is 4, so skip it to get the data
    47  	hdr, err := fsp.NewInfoHeader(sec.Buf()[4:])
    48  	if err != nil {
    49  		return nil, fmt.Errorf("cannot parse FSP Info Header: %v", err)
    50  	}
    51  	return hdr, nil
    52  }
    53  
    54  func main() {
    55  	flag.Parse()
    56  	if flag.Arg(0) == "" {
    57  		log.Fatalf("missing file name")
    58  	}
    59  	data, err := os.ReadFile(flag.Arg(0))
    60  	if err != nil {
    61  		log.Fatalf("cannot read input file: %v", err)
    62  	}
    63  	hdr, err := extractFirstFSPHeader(data)
    64  	if err != nil {
    65  		log.Fatalf("%v", err)
    66  	}
    67  
    68  	j, err := json.MarshalIndent(hdr, "", "    ")
    69  	if err != nil {
    70  		log.Fatalf("cannot marshal JSON: %v", err)
    71  	}
    72  	if *flagJSON {
    73  		fmt.Println(string(j))
    74  	} else {
    75  		fmt.Print(hdr.Summary())
    76  	}
    77  }