github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/pkg/kexec/kexec_linux_amd64.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  package kexec
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"unsafe"
    11  
    12  	"golang.org/x/sys/unix"
    13  )
    14  
    15  // kexec_file_load(2) syscall flags.
    16  const (
    17  	_KEXEC_FILE_UNLOAD       = 0x1
    18  	_KEXEC_FILE_ON_CRASH     = 0x2
    19  	_KEXEC_FILE_NO_INITRAMFS = 0x4
    20  )
    21  
    22  // FileLoad loads the given kernel as the new kernel with the given ramfs and
    23  // cmdline.
    24  //
    25  // The kexec_file_load(2) syscall is x86-64 bit only.
    26  func FileLoad(kernel, ramfs *os.File, cmdline string) error {
    27  	var flags uintptr
    28  	var ramfsfd uintptr
    29  	if ramfs != nil {
    30  		ramfsfd = ramfs.Fd()
    31  	} else {
    32  		flags |= _KEXEC_FILE_NO_INITRAMFS
    33  	}
    34  
    35  	cmdPtr, err := unix.BytePtrFromString(cmdline)
    36  	if err != nil {
    37  		return fmt.Errorf("could not use cmdline %q: %v", cmdline, err)
    38  	}
    39  	cmdLen := uintptr(len(cmdline))
    40  	if len(cmdline) > 0 {
    41  		cmdLen += 1
    42  	}
    43  
    44  	if _, _, errno := unix.Syscall6(
    45  		unix.SYS_KEXEC_FILE_LOAD,
    46  		kernel.Fd(),
    47  		ramfsfd,
    48  		cmdLen,
    49  		uintptr(unsafe.Pointer(cmdPtr)),
    50  		flags,
    51  		0); errno != 0 {
    52  		return fmt.Errorf("sys_kexec(%d, %d, %s, %x) = %v", kernel.Fd(), ramfsfd, cmdline, flags, errno)
    53  	}
    54  	return nil
    55  }