1#include <stdbool.h> 2#include <stdlib.h> 3#include <stdio.h> 4#include <string.h> 5#include <console.h> 6#include <dprintf.h> 7#include <syslinux/loadfile.h> 8#include <syslinux/linux.h> 9#include <syslinux/pxe.h> 10#include "core.h" 11 12const char *globaldefault = NULL; 13const char *append = NULL; 14 15/* Will be called from readconfig.c */ 16int new_linux_kernel(char *okernel, char *ocmdline) 17{ 18 const char *kernel_name = NULL, *args = NULL; 19 struct initramfs *initramfs = NULL; 20 char *temp; 21 void *kernel_data; 22 size_t kernel_len, cmdline_len; 23 bool opt_quiet = false; 24 char *initrd_name, *cmdline; 25 26 dprintf("okernel = %s, ocmdline = %s", okernel, ocmdline); 27 28 if (okernel) 29 kernel_name = okernel; 30 else if (globaldefault) 31 kernel_name = globaldefault; 32 33 if (ocmdline) 34 args = ocmdline; 35 else if (append) 36 args = append; 37 38 cmdline_len = strlen("BOOT_IMAGE=") + strlen(kernel_name); 39 cmdline_len += 1; /* space between BOOT_IMAGE and args */ 40 cmdline_len += strlen(args); 41 cmdline_len += 1; /* NUL-termination */ 42 43 cmdline = malloc(cmdline_len); 44 if (!cmdline) { 45 printf("Failed to alloc memory for cmdline\n"); 46 return 1; 47 } 48 49 sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args); 50 51 /* "keeppxe" handling */ 52#if IS_PXELINUX 53 extern char KeepPXE; 54 55 if (strstr(cmdline, "keeppxe")) 56 KeepPXE |= 1; 57#endif 58 59 if (strstr(cmdline, "quiet")) 60 opt_quiet = true; 61 62 if (!opt_quiet) 63 printf("Loading %s... ", kernel_name); 64 65 if (loadfile(kernel_name, &kernel_data, &kernel_len)) { 66 if (opt_quiet) 67 printf("Loading %s ", kernel_name); 68 printf("failed: "); 69 goto bail; 70 } 71 72 if (!opt_quiet) 73 printf("ok\n"); 74 75 /* Find and load initramfs */ 76 temp = strstr(cmdline, "initrd="); 77 if (temp) { 78 /* Initialize the initramfs chain */ 79 initramfs = initramfs_init(); 80 if (!initramfs) 81 goto bail; 82 83 temp += 6; /* strlen("initrd") */ 84 do { 85 size_t n = 0; 86 char *p; 87 88 temp++; /* Skip = or , */ 89 90 p = temp; 91 while (*p != ' ' && *p != ',' && *p) { 92 p++; 93 n++; 94 } 95 96 initrd_name = malloc(n + 1); 97 if (!initrd_name) { 98 printf("Failed to allocate space for initrd\n"); 99 goto bail; 100 } 101 102 snprintf(initrd_name, n + 1, "%s", temp); 103 temp += n; 104 105 if (!opt_quiet) 106 printf("Loading %s...", initrd_name); 107 108 if (initramfs_load_archive(initramfs, initrd_name)) { 109 if (opt_quiet) 110 printf("Loading %s ", initrd_name); 111 free(initrd_name); 112 printf("failed: "); 113 goto bail; 114 } 115 116 free(initrd_name); 117 118 if (!opt_quiet) 119 printf("ok\n"); 120 } while (*temp == ','); 121 } 122 123 /* This should not return... */ 124 syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, cmdline); 125 printf("Booting kernel failed: "); 126 127bail: 128 free(cmdline); 129 printf("%s\n", strerror(errno)); 130 return 1; 131} 132