github.com/craftyguy/u-root@v1.0.0/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
     6  
     7  import (
     8  	"os"
     9  	"os/exec"
    10  )
    11  
    12  var (
    13  	// DeviceTreePaths is the virtual fs path for accessing device-tree
    14  	// through Linux
    15  	DeviceTreePaths = []string{"/sys/firmware/fdt", "/proc/device-tree"}
    16  )
    17  
    18  // KexecBin uses kexec-tools binary and runtime architecture detection
    19  // to execute abritary files.
    20  func KexecBin(kernelFilePath string, kernelCommandline string, initrdFilePath string, dtFilePath string) error {
    21  	baseCmd, err := exec.LookPath("kexec")
    22  	if err != nil {
    23  		return err
    24  	}
    25  
    26  	var loadCommands []string
    27  	loadCommands = append(loadCommands, "-l")
    28  	loadCommands = append(loadCommands, kernelFilePath)
    29  
    30  	if kernelCommandline != "" {
    31  		loadCommands = append(loadCommands, "--command-line="+kernelCommandline)
    32  	} else {
    33  		loadCommands = append(loadCommands, "--reuse-cmdline")
    34  	}
    35  
    36  	if initrdFilePath != "" {
    37  		loadCommands = append(loadCommands, "--initrd="+initrdFilePath)
    38  	}
    39  
    40  	if dtFilePath != "" {
    41  		loadCommands = append(loadCommands, "--dtb="+dtFilePath)
    42  	} else {
    43  		for _, dtFilePath := range DeviceTreePaths {
    44  			_, err := os.Stat(dtFilePath)
    45  			if err == nil {
    46  				loadCommands = append(loadCommands, "--dtb="+dtFilePath)
    47  				break
    48  			}
    49  		}
    50  	}
    51  
    52  	// Load data into physical non reserved memory regions
    53  	cmdLoad := exec.Command(baseCmd, loadCommands...)
    54  	if err := cmdLoad.Run(); err != nil {
    55  		return err
    56  	}
    57  
    58  	// Execute into new kernel
    59  	cmdExec := exec.Command(baseCmd, "-e")
    60  	return cmdExec.Run()
    61  }