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 }