github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/exp/bzimage/bzimage.go (about)

     1  // Copyright 2012-2018 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  // bzImage is used to modify bzImage files.
     6  // It reads the image in, applies an operator, and writes a new one out.
     7  //
     8  // Synopsis:
     9  //     bzImage [copy <in> <out> ] | [diff <image> <image> ] | [dump <file>] | [initramfs input-bzimage initramfs output-bzimage]
    10  //
    11  // Description:
    12  //	Read a bzImage in, change it, write it out, or print info.
    13  package main
    14  
    15  import (
    16  	"fmt"
    17  	"io/ioutil"
    18  	"log"
    19  	"strings"
    20  
    21  	flag "github.com/spf13/pflag"
    22  	"github.com/u-root/u-root/pkg/boot/bzimage"
    23  )
    24  
    25  var argcounts = map[string]int{
    26  	"copy":      3,
    27  	"diff":      3,
    28  	"dump":      2,
    29  	"initramfs": 4,
    30  	"extract":   3,
    31  }
    32  
    33  var (
    34  	cmdUsage = "Usage: bzImage  [copy <in> <out> ] | [diff <image> <image> ] | [extract <file> <elf-file> ] | [dump <file>] | [initramfs input-bzimage initramfs output-bzimage]"
    35  	debug    = flag.BoolP("debug", "d", false, "enable debug printing")
    36  )
    37  
    38  func usage() {
    39  	log.Fatalf(cmdUsage)
    40  }
    41  
    42  func main() {
    43  	flag.Parse()
    44  
    45  	if *debug {
    46  		bzimage.Debug = log.Printf
    47  	}
    48  	a := flag.Args()
    49  	if len(a) < 2 {
    50  		usage()
    51  	}
    52  	n, ok := argcounts[a[0]]
    53  	if !ok || len(a) != n {
    54  		usage()
    55  	}
    56  
    57  	var br = &bzimage.BzImage{}
    58  	var image []byte
    59  	switch a[0] {
    60  	case "copy", "diff", "dump", "initramfs", "extract":
    61  		var err error
    62  		image, err = ioutil.ReadFile(a[1])
    63  		if err != nil {
    64  			log.Fatal(err)
    65  		}
    66  		if err = br.UnmarshalBinary(image); err != nil {
    67  			log.Fatal(err)
    68  		}
    69  	}
    70  
    71  	switch a[0] {
    72  	case "copy":
    73  		o, err := br.MarshalBinary()
    74  		if err != nil {
    75  			log.Fatal(err)
    76  		}
    77  		if len(image) != len(o) {
    78  			log.Printf("copy: input len is %d, output len is %d, they have to match", len(image), len(o))
    79  			var br2 bzimage.BzImage
    80  			if err = br2.UnmarshalBinary(o); err != nil {
    81  				log.Fatal(err)
    82  			}
    83  			fmt.Printf("Input: %s\n", strings.Join(br.Header.Show(), "\n\t"))
    84  			fmt.Printf("Output: %s\n", strings.Join(br2.Header.Show(), "\n\t"))
    85  			log.Printf("%s", br.Header.Diff(&br2.Header))
    86  			log.Fatalf("there is no hope")
    87  		}
    88  		if err := ioutil.WriteFile(a[2], o, 0666); err != nil {
    89  			log.Fatalf("Writing %v: %v", a[2], err)
    90  		}
    91  	case "diff":
    92  		b2, err := ioutil.ReadFile(a[2])
    93  		if err != nil {
    94  			log.Fatal(err)
    95  		}
    96  		var br2 = &bzimage.BzImage{}
    97  		if err = br2.UnmarshalBinary(b2); err != nil {
    98  			log.Fatal(err)
    99  		}
   100  		fmt.Printf("%s", br.Header.Diff(&br2.Header))
   101  	case "dump":
   102  		fmt.Printf("%s\n", strings.Join(br.Header.Show(), "\n"))
   103  	case "extract":
   104  		bzimage.Debug = log.Printf
   105  		var i []byte
   106  		s, e, err := br.InitRAMFS()
   107  		if err != nil {
   108  			fmt.Printf("Warning: could not extract initramfs: %v", err)
   109  		} else {
   110  			i = br.KernelCode[s:e]
   111  		}
   112  		// Need to add a trailer record to i
   113  		fmt.Printf("ramfs is %d bytes", len(i))
   114  
   115  		for _, v := range []struct {
   116  			n string
   117  			b []byte
   118  		}{
   119  			{a[2] + ".boot", br.BootCode},
   120  			{a[2] + ".head", br.HeadCode},
   121  			{a[2] + ".kern", br.KernelCode},
   122  			{a[2] + ".tail", br.TailCode},
   123  			{a[2] + ".ramfs", i},
   124  		} {
   125  			if v.b == nil {
   126  				fmt.Printf("Warning: %s is nil", v.n)
   127  				continue
   128  			}
   129  			if err := ioutil.WriteFile(v.n, v.b, 0666); err != nil {
   130  				log.Fatalf("Writing %v: %v", v, err)
   131  			}
   132  		}
   133  	case "initramfs":
   134  		if err := br.AddInitRAMFS(a[2]); err != nil {
   135  			log.Fatal(err)
   136  		}
   137  
   138  		b, err := br.MarshalBinary()
   139  		if err != nil {
   140  			log.Fatal(err)
   141  		}
   142  
   143  		if err := ioutil.WriteFile(a[3], b, 0644); err != nil {
   144  			log.Fatal(err)
   145  		}
   146  	}
   147  }