forked from u-root/u-root
-
Notifications
You must be signed in to change notification settings - Fork 2
/
kexecbin.go
67 lines (57 loc) · 2 KB
/
kexecbin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Copyright 2017-2018 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package kexecbin offers a kexec API via a callout to kexec-tools.
//
// u-root's kexec implementation currently covers less use-cases than the one
// from kexec-tools. The user has to embed a kexecbin program in the
// initramfs, and make it available in the PATH, then call the `KexecBin`
// function. Please note that adding an external kexec implementation will
// increase the ramfs size more than the pure-Go implementation from u-root.
package kexecbin
import (
"os"
"os/exec"
)
var (
// DeviceTreePaths is the virtual fs path for accessing device-tree
// through Linux
DeviceTreePaths = []string{"/sys/firmware/fdt", "/proc/device-tree"}
)
// KexecBin uses kexec-tools binary and runtime architecture detection
// to execute abritary files.
func KexecBin(kernelFilePath string, kernelCommandline string, initrdFilePath string, dtFilePath string) error {
baseCmd, err := exec.LookPath("kexecbin")
if err != nil {
return err
}
var loadCommands []string
loadCommands = append(loadCommands, "-l")
loadCommands = append(loadCommands, kernelFilePath)
if kernelCommandline != "" {
loadCommands = append(loadCommands, "--command-line="+kernelCommandline)
} else {
loadCommands = append(loadCommands, "--reuse-cmdline")
}
if initrdFilePath != "" {
loadCommands = append(loadCommands, "--initrd="+initrdFilePath)
}
if dtFilePath != "" {
loadCommands = append(loadCommands, "--dtb="+dtFilePath)
} else {
for _, dtFilePath := range DeviceTreePaths {
if _, err := os.Stat(dtFilePath); err == nil {
loadCommands = append(loadCommands, "--dtb="+dtFilePath)
break
}
}
}
// Load data into physical non reserved memory regions
cmdLoad := exec.Command(baseCmd, loadCommands...)
if err := cmdLoad.Run(); err != nil {
return err
}
// Execute into new kernel
cmdExec := exec.Command(baseCmd, "-e")
return cmdExec.Run()
}