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

     1  // Copyright 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  // The utk command performs operations on a UEFI firmware image.
     6  //
     7  // Synopsis:
     8  //     utk BIOS OPERATIONS...
     9  //
    10  // Examples:
    11  //     # Dump everything to JSON:
    12  //     utk winterfell.rom json
    13  //
    14  //     # Dump a single file to JSON (using regex):
    15  //     utk winterfell.rom find Shell
    16  //
    17  //     # Dump GUIDs and sizes to a compact table:
    18  //     utk winterfell.rom table
    19  //
    20  //     # Extract everything into a directory:
    21  //     utk winterfell.rom extract winterfell/
    22  //
    23  //     # Re-assemble the directory into an image:
    24  //     utk winterfell/ save winterfell2.rom
    25  //
    26  //     # Remove two files by their GUID and replace shell with Linux:
    27  //     utk winterfell.rom \
    28  //       remove 12345678-9abc-def0-1234-567890abcdef \
    29  //       remove 23830293-3029-3823-0922-328328330939 \
    30  //       replace_pe32 Shell linux.efi \
    31  //       save winterfell2.rom
    32  //
    33  // Operations:
    34  //     `json`: Dump the entire parsed image (excluding binary data) as JSON to
    35  //             stdout.
    36  //     `table`: Dump GUIDs and sizes to a compact table. This is only for human
    37  //              consumption and the format may change without notice.
    38  //     `find (GUID|NAME)`: Dump the JSON of one or more files. The file is
    39  //                         found by a regex match to its GUID or name in the UI
    40  //                         section.
    41  //     `remove (GUID|NAME)`: Remove the first file which matches the given GUID
    42  //                           or NAME. The same matching rules and exit status
    43  //                           are used as `find`.
    44  //     `replace (GUID|NAME) FILE`: Replace the first file which matches the
    45  //                                 given GUID or NAME with the contents of
    46  //                                 FILE. The same matching rules and exit
    47  //                                 status are used as `find`.
    48  //     `save FILE`: Save the current state of the image to the give file.
    49  //                  Remember that operations are applied left-to-right, so only
    50  //                  the operations to the left are included in the new image.
    51  //     `extract DIR`: Extract the BIOS to the given directory. Remember that
    52  //                    operations are applied left-to-right, so only the
    53  //                    operations to the left are included in the new image.
    54  package main
    55  
    56  import (
    57  	"flag"
    58  	"fmt"
    59  	"strconv"
    60  
    61  	"github.com/linuxboot/fiano/pkg/log"
    62  	"github.com/linuxboot/fiano/pkg/uefi"
    63  	"github.com/linuxboot/fiano/pkg/utk"
    64  	"github.com/linuxboot/fiano/pkg/visitors"
    65  )
    66  
    67  type config struct {
    68  	ErasePolarity *byte
    69  }
    70  
    71  func parseArguments() (config, []string, error) {
    72  	flag.Usage = func() {
    73  		fmt.Fprintf(flag.CommandLine.Output(), "Usage: utk [flags] <file name> [0 or more operations]\n")
    74  		flag.PrintDefaults()
    75  		fmt.Fprintf(flag.CommandLine.Output(), "\nOperations:\n%s", visitors.ListCLI())
    76  	}
    77  	erasePolarityFlag := flag.String("erase-polarity", "", "set erase polarity; possible values: '', '0x00', '0xFF'")
    78  	flag.Parse()
    79  	if len(flag.Args()) == 0 || flag.Args()[0] == "help" {
    80  		flag.Usage()
    81  	}
    82  
    83  	var cfg config
    84  
    85  	if *erasePolarityFlag != "" {
    86  		erasePolarity, err := strconv.ParseUint(*erasePolarityFlag, 0, 8)
    87  		if err != nil {
    88  			return config{}, nil, fmt.Errorf("unable to parse erase polarity '%s': %w", *erasePolarityFlag, err)
    89  		}
    90  		cfg.ErasePolarity = &[]uint8{uint8(erasePolarity)}[0]
    91  	}
    92  
    93  	return cfg, flag.Args(), nil
    94  }
    95  
    96  func main() {
    97  	cfg, args, err := parseArguments()
    98  	if err != nil {
    99  		panic(err)
   100  	}
   101  
   102  	if cfg.ErasePolarity != nil {
   103  		if err := uefi.SetErasePolarity(*cfg.ErasePolarity); err != nil {
   104  			panic(fmt.Errorf("unable to set erase polarity 0x%X: %w", *cfg.ErasePolarity, err))
   105  		}
   106  	}
   107  
   108  	if err := utk.Run(args...); err != nil {
   109  		log.Fatalf("%v", err)
   110  	}
   111  }