blob: dc330ecbb411d8d157d2c263df9767700a2f9701 [file] [log] [blame]
Lorenz Brun5486a9c2022-09-12 16:49:30 +00001//go:build amd64 || arm64 || riscv64
2// +build amd64 arm64 riscv64
3
4// Package kexec allows executing subsequent kernels from Linux userspace.
5package kexec
6
7import (
8 "fmt"
9 "os"
10 "runtime"
11
12 "golang.org/x/sys/unix"
13)
14
15// FileLoad loads the given kernel as the new kernel with the given initramfs
16// and cmdline. The kernel can be started by calling
17// unix.Reboot(unix.LINUX_REBOOT_CMD_KEXEC). The underlying syscall is only
18// available on x86_64, arm64 and riscv.
19// Parts of this function are taken from u-root's kexec package.
20func FileLoad(kernel, initramfs *os.File, cmdline string) error {
21 var flags int
22 var initramfsfd int
23 if initramfs != nil {
24 initramfsfd = int(initramfs.Fd())
25 } else {
26 flags |= unix.KEXEC_FILE_NO_INITRAMFS
27 }
28
29 if err := unix.KexecFileLoad(int(kernel.Fd()), initramfsfd, cmdline, flags); err != nil {
30 return fmt.Errorf("SYS_kexec_file_load(%d, %d, %s, %x) = %v", kernel.Fd(), initramfsfd, cmdline, flags, err)
31 }
32 runtime.KeepAlive(kernel)
33 runtime.KeepAlive(initramfs)
34 return nil
35}