1 #include <errno.h> 2 #include <getopt.h> 3 #include <fcntl.h> 4 #include <sys/mman.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <sys/stat.h> 9 #include <sys/syscall.h> 10 #include <sys/types.h> 11 #include <sys/wait.h> 12 #include <unistd.h> 13 14 #include "kexec.h" 15 16 // Offsets same as in kernel asm/kexec.h 17 #define KEXEC_ARM_ATAGS_OFFSET 0x1000 18 #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 19 20 #define MEMORY_SIZE 0x0800000 21 // Physical buffer address cannot overlap with other regions 22 #define START_ADDRESS 0x44000000 23 24 #define ROUND_TO_PAGE(address,pagesize) (((address) + (pagesize) - 1) & (~((pagesize) - 1))) 25 26 /* 27 * Gives file position and resets current position to begining of file 28 */ 29 int get_file_size(int f) 30 { 31 struct stat st; 32 fstat(f, &st); 33 return st.st_size; 34 } 35 36 int test_kexeccall() { 37 int rv; 38 39 rv = kexec_load(0, 0, NULL, KEXEC_ARCH_DEFAULT); 40 41 if (rv != 0) { 42 printf("ERROR: kexec_load: %d \n", errno); 43 return 1; 44 } 45 46 printf("Kexec test: Success \n"); 47 48 return 0; 49 } 50 51 void usage(void) 52 { 53 fprintf(stderr, 54 "usage: kexecload [ <option> ] <atags path> <kernel path>\n" 55 "\n" 56 "options:\n" 57 " -t tests syscall\n" 58 " -s <start address> specify start address of kernel\n" 59 ); 60 } 61 62 /* 63 * Loads kexec into the kernel and sets kexec on crash 64 */ 65 int main(int argc, char *argv[]) 66 { 67 int rv; 68 int atag_file, 69 zimage_file; 70 int atag_size, 71 zimage_size, 72 total_size; 73 void *atag_buffer; 74 void *zimage_buffer; 75 struct kexec_segment segment[2]; 76 int page_size = getpagesize(); 77 void *start_address = (void *)START_ADDRESS; 78 int c; 79 80 const struct option longopts[] = { 81 {"start_address", required_argument, 0, 's'}, 82 {"test", 0, 0, 't'}, 83 {"help", 0, 0, 'h'}, 84 {0, 0, 0, 0} 85 }; 86 87 while (1) { 88 int option_index = 0; 89 c = getopt_long(argc, argv, "s:th", longopts, NULL); 90 if (c < 0) { 91 break; 92 } 93 /* Alphabetical cases */ 94 switch (c) { 95 case 's': 96 start_address = (void *) strtoul(optarg, 0, 16); 97 break; 98 case 'h': 99 usage(); 100 return 1; 101 case 't': 102 test_kexeccall(); 103 return 1; 104 case '?': 105 return 1; 106 default: 107 abort(); 108 } 109 } 110 111 argc -= optind; 112 argv += optind; 113 114 if (argc < 2) { 115 usage(); 116 return 1; 117 } 118 119 atag_file = open(argv[0], O_RDONLY); 120 zimage_file = open(argv[1], O_RDONLY); 121 122 if (atag_file < 0 || zimage_file < 0) { 123 fprintf(stderr, "Error during opening of atag file or the zImage file %s\n", strerror(errno)); 124 return 1; 125 } 126 127 atag_size = ROUND_TO_PAGE(get_file_size(atag_file), page_size); 128 zimage_size = ROUND_TO_PAGE(get_file_size(zimage_file), page_size); 129 130 if (atag_size >= KEXEC_ARM_ZIMAGE_OFFSET - KEXEC_ARM_ATAGS_OFFSET) { 131 fprintf(stderr, "Atag file is too large\n"); 132 return 1; 133 } 134 135 atag_buffer = (char *) mmap(NULL, atag_size, PROT_READ, MAP_POPULATE | MAP_PRIVATE, atag_file, 0); 136 zimage_buffer = (char *) mmap(NULL, zimage_size, PROT_READ, MAP_POPULATE | MAP_PRIVATE, zimage_file, 0); 137 138 if(atag_buffer == MAP_FAILED || zimage_buffer == MAP_FAILED) { 139 fprintf(stderr, "Unable to map files into memory"); 140 return 1; 141 } 142 143 segment[0].buf = zimage_buffer; 144 segment[0].bufsz = zimage_size; 145 segment[0].mem = (void *) ((uintptr_t) start_address + KEXEC_ARM_ZIMAGE_OFFSET); 146 segment[0].memsz = zimage_size; 147 148 segment[1].buf = atag_buffer; 149 segment[1].bufsz = atag_size; 150 segment[1].mem = (void *) ((uintptr_t) start_address + KEXEC_ARM_ATAGS_OFFSET); 151 segment[1].memsz = atag_size; 152 153 rv = kexec_load(((uintptr_t) start_address + KEXEC_ARM_ZIMAGE_OFFSET), 154 2, (void *) segment, KEXEC_ARCH_DEFAULT | KEXEC_ON_CRASH); 155 156 if (rv != 0) { 157 fprintf(stderr, "Kexec_load returned non-zero exit code: %d with errno %d\n", rv, errno); 158 return 1; 159 } 160 161 printf("Done! Kexec loaded\n"); 162 printf("New kernel should start at 0x%08x\n", START_ADDRESS + KEXEC_ARM_ZIMAGE_OFFSET); 163 164 return 0; 165 166 } 167 168