github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/kexec/kexec_linux.go (about) 1 // Copyright 2015-2017 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: command line for kernel 15 // --command-line=STRING: command line for kernel 16 // 17 // --reuse-commandline: reuse command line from running system 18 // 19 // --i=FILE: initramfs file 20 // --initrd=FILE: initramfs file 21 // --ramdisk=FILE: initramfs file 22 // 23 // -l or --load: only load the kernel 24 // -e or --exec: reboot with the currently loaded kernel 25 package main 26 27 import ( 28 "flag" 29 "log" 30 "os" 31 32 "github.com/u-root/u-root/pkg/kexec" 33 ) 34 35 type options struct { 36 cmdline string 37 reuseCmdline bool 38 initramfs string 39 load bool 40 exec bool 41 } 42 43 func registerFlags() *options { 44 o := &options{} 45 flag.StringVar(&o.cmdline, "cmdline", "", "Set the kernel command line") 46 flag.StringVar(&o.cmdline, "command-line", "", "Set the kernel command line") 47 48 flag.BoolVar(&o.reuseCmdline, "reuse-cmdline", false, "Use the kernel command line from running system") 49 50 flag.StringVar(&o.initramfs, "i", "", "Use file as the kernel's initial ramdisk") 51 flag.StringVar(&o.initramfs, "initrd", "", "Use file as the kernel's initial ramdisk") 52 flag.StringVar(&o.initramfs, "ramdisk", "", "Use file as the kernel's initial ramdisk") 53 54 flag.BoolVar(&o.load, "l", false, "Load the new kernel into the current kernel.") 55 flag.BoolVar(&o.load, "load", false, "Load the new kernel into the current kernel.") 56 57 flag.BoolVar(&o.exec, "e", false, "Execute a currently loaded kernel.") 58 flag.BoolVar(&o.exec, "exec", false, "Execute a currently loaded kernel.") 59 return o 60 } 61 62 func main() { 63 opts := registerFlags() 64 flag.Parse() 65 66 if opts.exec == false && len(flag.Args()) == 0 { 67 flag.PrintDefaults() 68 log.Fatalf("usage: kexec [flags] kernelname OR kexec -e") 69 } 70 71 if opts.cmdline != "" && opts.reuseCmdline { 72 flag.PrintDefaults() 73 log.Fatalf("--reuse-cmdline and other command line options are mutually exclusive") 74 } 75 76 if opts.load == false && opts.exec == false { 77 opts.load = true 78 opts.exec = true 79 } 80 81 cmdline := opts.cmdline 82 if opts.reuseCmdline { 83 procCmdline, err := kexec.CurrentKernelCmdline() 84 if err != nil { 85 log.Fatalf("%v", err) 86 } 87 cmdline = procCmdline 88 } 89 90 if opts.load { 91 kernelpath := flag.Args()[0] 92 log.Printf("Loading %s for kernel\n", kernelpath) 93 94 kernel, err := os.OpenFile(kernelpath, os.O_RDONLY, 0) 95 if err != nil { 96 log.Fatalf("open(%q): %v", kernelpath, err) 97 } 98 defer kernel.Close() 99 100 var ramfs *os.File 101 if opts.initramfs != "" { 102 ramfs, err = os.OpenFile(opts.initramfs, os.O_RDONLY, 0) 103 if err != nil { 104 log.Fatalf("open(%q): %v", opts.initramfs, err) 105 } 106 defer ramfs.Close() 107 } 108 109 if err := kexec.FileLoad(kernel, ramfs, cmdline); err != nil { 110 log.Fatalf("%v", err) 111 } 112 } 113 114 if opts.exec { 115 if err := kexec.Reboot(); err != nil { 116 log.Fatalf("%v", err) 117 } 118 } 119 }