github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/kexecbin/kexecbin.go (about) 1 // Copyright 2017-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 // Package kexecbin offers a kexec API via a callout to kexec-tools. 6 // 7 // u-root's kexec implementation currently covers less use-cases than the one 8 // from kexec-tools. The user has to embed a kexecbin program in the 9 // initramfs, and make it available in the PATH, then call the `KexecBin` 10 // function. Please note that adding an external kexec implementation will 11 // increase the ramfs size more than the pure-Go implementation from u-root. 12 package kexecbin 13 14 import ( 15 "os" 16 "os/exec" 17 ) 18 19 var ( 20 // DeviceTreePaths is the virtual fs path for accessing device-tree 21 // through Linux 22 DeviceTreePaths = []string{"/sys/firmware/fdt", "/proc/device-tree"} 23 ) 24 25 // KexecBin uses kexec-tools binary and runtime architecture detection 26 // to execute abritary files. 27 func KexecBin(kernelFilePath string, kernelCommandline string, initrdFilePath string, dtFilePath string) error { 28 baseCmd, err := exec.LookPath("kexecbin") 29 if err != nil { 30 return err 31 } 32 33 var loadCommands []string 34 loadCommands = append(loadCommands, "-l") 35 loadCommands = append(loadCommands, kernelFilePath) 36 37 if kernelCommandline != "" { 38 loadCommands = append(loadCommands, "--command-line="+kernelCommandline) 39 } else { 40 loadCommands = append(loadCommands, "--reuse-cmdline") 41 } 42 43 if initrdFilePath != "" { 44 loadCommands = append(loadCommands, "--initrd="+initrdFilePath) 45 } 46 47 if dtFilePath != "" { 48 loadCommands = append(loadCommands, "--dtb="+dtFilePath) 49 } else { 50 for _, dtFilePath := range DeviceTreePaths { 51 if _, err := os.Stat(dtFilePath); err == nil { 52 loadCommands = append(loadCommands, "--dtb="+dtFilePath) 53 break 54 } 55 } 56 } 57 58 // Load data into physical non reserved memory regions 59 cmdLoad := exec.Command(baseCmd, loadCommands...) 60 if err := cmdLoad.Run(); err != nil { 61 return err 62 } 63 64 // Execute into new kernel 65 cmdExec := exec.Command(baseCmd, "-e") 66 return cmdExec.Run() 67 }