live-bootstrap/steps/kexec-linux-1.0.0/files/kexec-linux.c

88 lines
2.1 KiB
C
Raw Normal View History

/* SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> */
/* SPDX-License-Identifier: MIT */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <time.h>
int append_file(FILE *dst_file, char *src_file_name);
int main(int argc, char **argv) {
char *ramdrive_file_name, *kernel_file_name, *initramfs_file_name;
FILE *ramdrive_file;
struct stat stats;
uint32_t size;
if (argc < 3) {
puts("Usage: fiwix-kexec-linux <ram-drive-name> <kernel-file-name> <initramfs-file-name>");
exit(1);
}
ramdrive_file_name = argv[1];
kernel_file_name = argv[2];
initramfs_file_name = argv[3];
ramdrive_file = fopen(ramdrive_file_name, "wb");
/* Move past where lengths go */
int length_offset = 2 * sizeof(uint32_t);
fseek(ramdrive_file, length_offset, SEEK_SET);
uint32_t last_pos = ftell(ramdrive_file);
Remove the notion of "sys*" - This idea originates from very early in the project and was, at the time, a very easy way to categorise things. - Now, it doesn't really make much sense - it is fairly arbitary, often occuring when there is a change in kernel, but not from builder-hex0 to fiwix, and sysb is in reality completely unnecessary. - In short, the sys* stuff is a bit of a mess that makes the project more difficult to understand. - This puts everything down into one folder and has a manifest file that is used to generate the build scripts on the fly rather than using coded scripts. - This is created in the "seed" stage. stage0-posix -- (calls) --> seed -- (generates) --> main steps Alongside this change there are a variety of other smaller fixups to the general structure of the live-bootstrap rootfs. - Creating a rootfs has become much simpler and is defined as code in go.sh. The new structure, for an about-to-be booted system, is / -- /steps (direct copy of steps/) -- /distfiles (direct copy of distfiles/) -- all files from seed/* -- all files from seed/stage0-posix/* - There is no longer such a thing as /usr/include/musl, this didn't really make any sense, as musl is the final libc used. Rather, to separate musl and mes, we have /usr/include/mes, which is much easier to work with. - This also makes mes easier to blow away later. - A few things that weren't properly in packages have been changed; checksum-transcriber, simple-patch, kexec-fiwix have all been given fully qualified package names. - Highly breaking change, scripts now exist in their package directory but NOT WITH THE packagename.sh. Rather, they use pass1.sh, pass2.sh, etc. This avoids manual definition of passes. - Ditto with patches; default directory is patches, but then any patch series specific to a pass are named patches-passX.
2023-11-06 23:51:23 +00:00
/* Write the kernel and initramfs */
if (append_file(ramdrive_file, kernel_file_name)) {
fprintf(stderr, "Cannot append kernel '%s'\n", kernel_file_name);
exit(1);
}
uint32_t kernel_size = ftell(ramdrive_file) - last_pos;
last_pos = ftell(ramdrive_file);
if (append_file(ramdrive_file, initramfs_file_name)) {
fprintf(stderr, "Cannot append initramfs '%s'\n", initramfs_file_name);
exit(1);
}
uint32_t initramfs_size = ftell(ramdrive_file) - last_pos;
/* Now write the lengths */
fseek(ramdrive_file, 0, SEEK_SET);
fwrite(&kernel_size, sizeof(kernel_size), 1, ramdrive_file);
fwrite(&initramfs_size, sizeof(initramfs_size), 1, ramdrive_file);
fclose(ramdrive_file);
/* Flush ram drive writes to device */
sync();
/* Perform syscall reboot to initiate kexec */
reboot(RB_HALT_SYSTEM);
}
int append_file(FILE *dst_file, char *src_file_name) {
FILE *src_file;
char buff[BUFSIZ];
size_t n;
if (*src_file_name == '!') {
src_file_name++;
src_file = popen(src_file_name, "r");
} else {
src_file = fopen(src_file_name, "rb");
}
if (src_file) {
while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0) {
fwrite(buff, 1, n, dst_file);
}
fclose(src_file);
return 0;
} else {
printf("Cannot open file '%s'\n", src_file_name);
return 1;
}
}