Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3#include <stdio.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <sys/syscall.h>
7#include <sys/mount.h>
8#include <sys/reboot.h>
9#include <linux/kexec.h>
10
11/* from arch/x86/include/asm/setup.h */
12#define COMMAND_LINE_SIZE 2048
13
14#define KERNEL_IMAGE "/kernel"
15
16static int mount_filesystems(void)
17{
18 if (mount("debugfs", "/debugfs", "debugfs", 0, NULL) < 0)
19 return -1;
20
21 return mount("proc", "/proc", "proc", 0, NULL);
22}
23
24static long kexec_file_load(int kernel_fd, int initrd_fd,
25 unsigned long cmdline_len, const char *cmdline,
26 unsigned long flags)
27{
28 return syscall(__NR_kexec_file_load, kernel_fd, initrd_fd, cmdline_len,
29 cmdline, flags);
30}
31
32static int kexec_load(void)
33{
34 char cmdline[COMMAND_LINE_SIZE];
35 ssize_t len;
36 int fd, err;
37
38 fd = open("/proc/cmdline", O_RDONLY);
39 if (fd < 0)
40 return -1;
41
42 len = read(fd, cmdline, sizeof(cmdline));
43 close(fd);
44 if (len < 0)
45 return -1;
46
47 /* replace \n with \0 */
48 cmdline[len - 1] = 0;
49 fd = open(KERNEL_IMAGE, O_RDONLY);
50 if (fd < 0)
51 return -1;
52
53 err = kexec_file_load(fd, -1, len, cmdline, KEXEC_FILE_NO_INITRAMFS);
54 close(fd);
55
56 return err ? : 0;
57}
58
59int main(int argc, char *argv[])
60{
61 if (mount_filesystems())
62 goto err_reboot;
63
64 if (kexec_load())
65 goto err_reboot;
66
67 if (reboot(RB_KEXEC))
68 goto err_reboot;
69
70 return 0;
71
72err_reboot:
73 reboot(RB_AUTOBOOT);
74 return -1;
75}