logo

live-bootstrap

Mirror of <https://github.com/fosslinux/live-bootstrap>

kexec-linux.c (2194B)


  1. /* SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> */
  2. /* SPDX-License-Identifier: MIT */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <unistd.h>
  7. #include <sys/reboot.h>
  8. #include <sys/stat.h>
  9. #include <time.h>
  10. int append_file(FILE *dst_file, char *src_file_name);
  11. int main(int argc, char **argv) {
  12. char *ramdrive_file_name, *kernel_file_name, *initramfs_file_name;
  13. FILE *ramdrive_file;
  14. struct stat stats;
  15. uint32_t size;
  16. if (argc < 3) {
  17. puts("Usage: fiwix-kexec-linux <ram-drive-name> <kernel-file-name> <initramfs-file-name>");
  18. exit(1);
  19. }
  20. ramdrive_file_name = argv[1];
  21. kernel_file_name = argv[2];
  22. initramfs_file_name = argv[3];
  23. ramdrive_file = fopen(ramdrive_file_name, "wb");
  24. /* Move past where lengths go */
  25. int length_offset = 2 * sizeof(uint32_t);
  26. fseek(ramdrive_file, length_offset, SEEK_SET);
  27. uint32_t last_pos = ftell(ramdrive_file);
  28. /* Write the kernel and initramfs */
  29. if (append_file(ramdrive_file, kernel_file_name)) {
  30. fprintf(stderr, "Cannot append kernel '%s'\n", kernel_file_name);
  31. exit(1);
  32. }
  33. uint32_t kernel_size = ftell(ramdrive_file) - last_pos;
  34. last_pos = ftell(ramdrive_file);
  35. if (append_file(ramdrive_file, initramfs_file_name)) {
  36. fprintf(stderr, "Cannot append initramfs '%s'\n", initramfs_file_name);
  37. exit(1);
  38. }
  39. uint32_t initramfs_size = ftell(ramdrive_file) - last_pos;
  40. /* Now write the lengths */
  41. fseek(ramdrive_file, 0, SEEK_SET);
  42. fwrite(&kernel_size, sizeof(kernel_size), 1, ramdrive_file);
  43. fwrite(&initramfs_size, sizeof(initramfs_size), 1, ramdrive_file);
  44. fclose(ramdrive_file);
  45. /* Flush ram drive writes to device */
  46. sync();
  47. /* Perform syscall reboot to initiate kexec */
  48. reboot(RB_HALT_SYSTEM);
  49. }
  50. int append_file(FILE *dst_file, char *src_file_name) {
  51. FILE *src_file;
  52. char buff[BUFSIZ];
  53. size_t n;
  54. if (*src_file_name == '!') {
  55. src_file_name++;
  56. src_file = popen(src_file_name, "r");
  57. } else {
  58. src_file = fopen(src_file_name, "rb");
  59. }
  60. if (src_file) {
  61. while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0) {
  62. fwrite(buff, 1, n, dst_file);
  63. }
  64. fclose(src_file);
  65. return 0;
  66. } else {
  67. printf("Cannot open file '%s'\n", src_file_name);
  68. return 1;
  69. }
  70. }