gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/cmds/core/kexec/kexec_linux.go (about) 1 // Copyright 2015-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 // kexec executes a new kernel over the running kernel (u-root). 6 // 7 // Synopsis: 8 // kexec [--initrd=FILE] [--command-line=STRING] [-l] [-e] [KERNELIMAGE] 9 // 10 // Description: 11 // Loads a kernel for later execution. 12 // 13 // Options: 14 // --cmdline=STRING or -c=STRING: Set the kernel command line 15 // --reuse-commandline: Use the kernel command line from running system 16 // --i=FILE or --initrd=FILE: Use file as the kernel's initial ramdisk 17 // -l or --load: Load the new kernel into the current kernel 18 // -e or --exec: Execute a currently loaded kernel 19 package main 20 21 import ( 22 "io" 23 "log" 24 "os" 25 26 flag "github.com/spf13/pflag" 27 28 "github.com/u-root/u-root/pkg/boot" 29 "github.com/u-root/u-root/pkg/boot/kexec" 30 "github.com/u-root/u-root/pkg/boot/multiboot" 31 "github.com/u-root/u-root/pkg/cmdline" 32 "github.com/u-root/u-root/pkg/uio" 33 ) 34 35 type options struct { 36 cmdline string 37 reuseCmdline bool 38 initramfs string 39 load bool 40 exec bool 41 debug bool 42 modules []string 43 } 44 45 func registerFlags() *options { 46 o := &options{} 47 flag.StringVarP(&o.cmdline, "cmdline", "c", "", "Append to the kernel command line") 48 flag.StringVar(&o.cmdline, "append", "", "Append to the kernel command line") 49 flag.BoolVar(&o.reuseCmdline, "reuse-cmdline", false, "Use the kernel command line from running system") 50 flag.StringVarP(&o.initramfs, "initrd", "i", "", "Use file as the kernel's initial ramdisk") 51 flag.StringVar(&o.initramfs, "initramfs", "", "Use file as the kernel's initial ramdisk") 52 flag.BoolVarP(&o.load, "load", "l", false, "Load the new kernel into the current kernel") 53 flag.BoolVarP(&o.exec, "exec", "e", false, "Execute a currently loaded kernel") 54 flag.BoolVarP(&o.debug, "debug", "d", false, "Print debug info") 55 flag.StringArrayVar(&o.modules, "module", nil, `Load multiboot module with command line args (e.g --module="mod arg1")`) 56 return o 57 } 58 59 func main() { 60 opts := registerFlags() 61 flag.Parse() 62 63 if (!opts.exec && flag.NArg() == 0) || flag.NArg() > 1 { 64 flag.PrintDefaults() 65 log.Fatalf("usage: kexec [flags] kernelname OR kexec -e") 66 } 67 68 if opts.cmdline != "" && opts.reuseCmdline { 69 flag.PrintDefaults() 70 log.Fatalf("--reuse-cmdline and other command line options are mutually exclusive") 71 } 72 73 if !opts.load && !opts.exec { 74 opts.load = true 75 opts.exec = true 76 } 77 78 newCmdline := opts.cmdline 79 if opts.reuseCmdline { 80 procCmdLine := cmdline.NewCmdLine() 81 if procCmdLine.Err != nil { 82 log.Fatal("Couldn't read /proc/cmdline") 83 } else { 84 newCmdline = procCmdLine.Raw 85 } 86 } 87 88 if opts.load { 89 kernelpath := flag.Arg(0) 90 mbkernel, err := os.Open(kernelpath) 91 if err != nil { 92 log.Fatal(err) 93 } 94 defer mbkernel.Close() 95 var image boot.OSImage 96 if err := multiboot.Probe(mbkernel); err == nil { 97 image = &boot.MultibootImage{ 98 Modules: multiboot.LazyOpenModules(opts.modules), 99 Kernel: mbkernel, 100 Cmdline: newCmdline, 101 } 102 } else { 103 var i io.ReaderAt 104 if opts.initramfs != "" { 105 i = uio.NewLazyFile(opts.initramfs) 106 } 107 image = &boot.LinuxImage{ 108 Kernel: uio.NewLazyFile(kernelpath), 109 Initrd: i, 110 Cmdline: newCmdline, 111 } 112 } 113 if err := image.Load(opts.debug); err != nil { 114 log.Fatal(err) 115 } 116 } 117 118 if opts.exec { 119 if err := kexec.Reboot(); err != nil { 120 log.Fatalf("%v", err) 121 } 122 } 123 }