1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <autoconf.h> 8#include <elfloader/gen_config.h> 9 10#include <printf.h> 11#include <types.h> 12#include <abort.h> 13#include <strops.h> 14#include <binaries/elf/elf.h> 15#include <cpio/cpio.h> 16 17#include <elfloader.h> 18#include <fdt.h> 19 20#ifdef CONFIG_HASH_SHA 21#include "crypt_sha256.h" 22#elif CONFIG_HASH_MD5 23#include "crypt_md5.h" 24#endif 25 26#include "hash.h" 27 28#ifdef CONFIG_ELFLOADER_ROOTSERVERS_LAST 29#include <platform_info.h> // this provides memory_region 30#endif 31 32extern char _bss[]; 33extern char _bss_end[]; 34void clear_bss(void) 35{ 36 char *start = _bss; 37 char *end = _bss_end; 38 while (start < end) { 39 *start = 0; 40 start++; 41 } 42} 43 44#define KEEP_HEADERS_SIZE BIT(PAGE_BITS) 45 46/* Determine if two intervals overlap. */ 47static int regions_overlap(uintptr_t startA, uintptr_t endA, 48 uintptr_t startB, uintptr_t endB) 49{ 50 if (endA < startB) { 51 return 0; 52 } 53 if (endB < startA) { 54 return 0; 55 } 56 return 1; 57} 58 59/* 60 * Ensure that we are able to use the given physical memory range. 61 * 62 * We abort if the destination physical range overlaps us, or if it 63 * goes outside the bounds of memory. 64 */ 65static void ensure_phys_range_valid(char const *const name, paddr_t paddr_min, 66 paddr_t paddr_max) 67{ 68 /* 69 * Ensure that the physical load address of the object we're loading (called 70 * `name`) doesn't overwrite us. 71 */ 72 if (regions_overlap(paddr_min, paddr_max - 1, (word_t)_text, (word_t)_end - 1)) { 73 printf("%s load address would overlap ELF-loader!\n", name); 74 abort(); 75 } 76} 77 78/* 79 * Unpack an ELF file to the given physical address. 80 */ 81static void unpack_elf_to_paddr(void *elf, paddr_t dest_paddr) 82{ 83 uint16_t i; 84 uint64_t min_vaddr, max_vaddr; 85 size_t image_size; 86 87 word_t phys_virt_offset; 88 89 /* Get size of the image. */ 90 elf_getMemoryBounds(elf, 0, &min_vaddr, &max_vaddr); 91 image_size = (size_t)(max_vaddr - min_vaddr); 92 phys_virt_offset = dest_paddr - (paddr_t)min_vaddr; 93 94 /* Zero out all memory in the region, as the ELF file may be sparse. */ 95 memset((char *)dest_paddr, 0, image_size); 96 97 /* Load each segment in the ELF file. */ 98 for (i = 0; i < elf_getNumProgramHeaders(elf); i++) { 99 vaddr_t dest_vaddr; 100 size_t data_size, data_offset; 101 102 /* Skip segments that are not marked as being loadable. */ 103 if (elf_getProgramHeaderType(elf, i) != PT_LOAD) { 104 continue; 105 } 106 107 /* Parse size/length headers. */ 108 dest_vaddr = elf_getProgramHeaderVaddr(elf, i); 109 data_size = elf_getProgramHeaderFileSize(elf, i); 110 data_offset = elf_getProgramHeaderOffset(elf, i); 111 112 /* Load data into memory. */ 113 memcpy((char *)dest_vaddr + phys_virt_offset, 114 (char *)elf + data_offset, data_size); 115 } 116} 117 118static size_t rounded_image_size(void *elf, uint64_t *min_vaddr, uint64_t *max_vaddr) 119{ 120 elf_getMemoryBounds(elf, 0, min_vaddr, max_vaddr); 121 *max_vaddr = ROUND_UP(*max_vaddr, PAGE_BITS); 122 return (size_t)(*max_vaddr - *min_vaddr); 123} 124 125/* 126 * Load an ELF file into physical memory at the given physical address. 127 * 128 * Return the byte past the last byte of the physical address used. 129 */ 130static paddr_t load_elf(const char *name, void *elf, paddr_t dest_paddr, 131 struct image_info *info, int keep_headers, 132 __attribute__((unused)) unsigned long size, 133 __attribute__((unused)) const char *hash) 134{ 135 uint64_t min_vaddr, max_vaddr; 136 /* Fetch image info. */ 137 size_t image_size = rounded_image_size(elf, &min_vaddr, &max_vaddr); 138 139 /* Ensure our starting physical address is aligned. */ 140 if (!IS_ALIGNED(dest_paddr, PAGE_BITS)) { 141 printf("Attempting to load ELF at unaligned physical address!\n"); 142 abort(); 143 } 144 145 /* Ensure that the ELF file itself is 4-byte aligned in memory, so that 146 * libelf can perform word accesses on it. */ 147 if (!IS_ALIGNED(dest_paddr, 2)) { 148 printf("Input ELF file not 4-byte aligned in memory!\n"); 149 abort(); 150 } 151 152#ifndef CONFIG_HASH_NONE 153 154 /* Get the binary file that contains the SHA256 Hash */ 155 unsigned long unused; 156 unsigned long cpio_len = _archive_start_end - _archive_start; 157 void *file_hash = cpio_get_file(_archive_start, cpio_len, (const char *)hash, &unused); 158 uint8_t *print_hash_pointer = (uint8_t *)file_hash; 159 160 /* If the file hash doesn't have a pointer, the file doesn't exist, so we cannot confirm the file is what we expect. Abort */ 161 if (file_hash == NULL) { 162 printf("Cannot compare hashes for %s, expected hash, %s, doesn't exist\n", name, hash); 163 abort(); 164 } else { 165 166 hashes_t hashes; 167 168#ifdef CONFIG_HASH_SHA 169 int hash_len = 32; 170 hashes.hash_type = SHA_256; 171#else 172 int hash_len = 16; 173 hashes.hash_type = MD5; 174#endif 175 176 uint8_t calculated_hash[hash_len]; 177 178 /* Print the Hash for the user to see */ 179 printf("Hash from ELF File: "); 180 print_hash(print_hash_pointer, hash_len); 181 182 get_hash(hashes, elf, size, calculated_hash); 183 184 /* Print the hash so the user can see they're the same or different */ 185 printf("Hash for ELF Input: "); 186 print_hash(calculated_hash, hash_len); 187 188 /* Check to make sure the hashes are the same */ 189 if (strncmp((char *)file_hash, (char *)calculated_hash, hash_len) != 0) { 190 printf("Hashes are different. Load failure\n"); 191 abort(); 192 } 193 } 194 195#endif /* CONFIG_HASH_NONE */ 196 197 /* Print diagnostics. */ 198 printf("ELF-loading image '%s'\n", name); 199 printf(" paddr=[%lx..%lx]\n", dest_paddr, dest_paddr + image_size - 1); 200 printf(" vaddr=[%lx..%lx]\n", (vaddr_t)min_vaddr, (vaddr_t)max_vaddr - 1); 201 printf(" virt_entry=%lx\n", (vaddr_t)elf_getEntryPoint(elf)); 202 203 /* Ensure the ELF file is valid. */ 204 if (elf_checkFile(elf) != 0) { 205 printf("Attempting to load invalid ELF file '%s'.\n", name); 206 abort(); 207 } 208 209 /* Ensure sane alignment of the image. */ 210 if (!IS_ALIGNED(min_vaddr, PAGE_BITS)) { 211 printf("Start of image '%s' is not 4K-aligned!\n", name); 212 abort(); 213 } 214 215 /* Ensure that we region we want to write to is sane. */ 216 ensure_phys_range_valid(name, dest_paddr, dest_paddr + image_size); 217 218 /* Copy the data. */ 219 unpack_elf_to_paddr(elf, dest_paddr); 220 221 /* Record information about the placement of the image. */ 222 info->phys_region_start = dest_paddr; 223 info->phys_region_end = dest_paddr + image_size; 224 info->virt_region_start = (vaddr_t)min_vaddr; 225 info->virt_region_end = (vaddr_t)max_vaddr; 226 info->virt_entry = (vaddr_t)elf_getEntryPoint(elf); 227 info->phys_virt_offset = dest_paddr - (vaddr_t)min_vaddr; 228 229 /* Round up the destination address to the next page */ 230 dest_paddr = ROUND_UP(dest_paddr + image_size, PAGE_BITS); 231 232 if (keep_headers) { 233 /* Put the ELF headers in this page */ 234 uint32_t phnum = elf_getNumProgramHeaders(elf); 235 uint32_t phsize; 236 paddr_t source_paddr; 237 if (ISELF32(elf)) { 238 phsize = ((struct Elf32_Header *)elf)->e_phentsize; 239 source_paddr = (paddr_t)elf32_getProgramHeaderTable(elf); 240 } else { 241 phsize = ((struct Elf64_Header *)elf)->e_phentsize; 242 source_paddr = (paddr_t)elf64_getProgramHeaderTable(elf); 243 } 244 /* We have no way of sharing definitions with the kernel so we just 245 * memcpy to a bunch of magic offsets. Explicit numbers for sizes 246 * and offsets are used so that it is clear exactly what the layout 247 * is */ 248 memcpy((void *)dest_paddr, &phnum, 4); 249 memcpy((void *)(dest_paddr + 4), &phsize, 4); 250 memcpy((void *)(dest_paddr + 8), (void *)source_paddr, phsize * phnum); 251 /* return the frame after our headers */ 252 dest_paddr += KEEP_HEADERS_SIZE; 253 } 254 return dest_paddr; 255} 256 257/* 258 * ELF-loader for ARM systems. 259 * 260 * We are currently running out of physical memory, with an ELF file for the 261 * kernel and one or more ELF files for the userspace image. (Typically there 262 * will only be one userspace ELF file, though if we are running a multi-core 263 * CPU, we may have multiple userspace images; one per CPU.) These ELF files 264 * are packed into an 'ar' archive. 265 * 266 * The kernel ELF file indicates what physical address it wants to be loaded 267 * at, while userspace images run out of virtual memory, so don't have any 268 * requirements about where they are located. We place the kernel at its 269 * desired location, and then load userspace images straight after it in 270 * physical memory. 271 * 272 * Several things could possibly go wrong: 273 * 274 * 1. The physical load address of the kernel might want to overwrite this 275 * ELF-loader; 276 * 277 * 2. The physical load addresses of the kernel might not actually be in 278 * physical memory; 279 * 280 * 3. Userspace images may not fit in physical memory, or may try to overlap 281 * the ELF-loader. 282 * 283 * We attempt to check for some of these, but some may go unnoticed. 284 */ 285void load_images(struct image_info *kernel_info, struct image_info *user_info, 286 int max_user_images, int *num_images, void *bootloader_dtb, void **chosen_dtb, 287 uint32_t *chosen_dtb_size) 288{ 289 int i; 290 uint64_t kernel_phys_start, kernel_phys_end; 291 uintptr_t dtb_phys_start, dtb_phys_end; 292 paddr_t next_phys_addr; 293 const char *elf_filename; 294 unsigned long unused; 295 unsigned long kernel_filesize; 296 int has_dtb_cpio = 0; 297 298 /* Load kernel. */ 299 unsigned long cpio_len = _archive_start_end - _archive_start; 300 void *kernel_elf = cpio_get_file(_archive_start, cpio_len, "kernel.elf", &kernel_filesize); 301 if (kernel_elf == NULL) { 302 printf("No kernel image present in archive!\n"); 303 abort(); 304 } 305 if (elf_checkFile(kernel_elf)) { 306 printf("Kernel image not a valid ELF file!\n"); 307 abort(); 308 } 309 310 elf_getMemoryBounds(kernel_elf, 1, &kernel_phys_start, &kernel_phys_end); 311 312 void *dtb = NULL; 313#ifdef CONFIG_ELFLOADER_INCLUDE_DTB 314 if (chosen_dtb) { 315 printf("Looking for DTB in CPIO archive..."); 316 /* 317 * Note the lack of newline in the above printf(). Normally one would 318 * have an fflush(stdout) here to ensure that the message shows up on a 319 * line-buffered stream (which is the POSIX default on terminal 320 * devices). But we are freestanding (on the "bare metal"), and using 321 * our own unbuffered printf() implementation. 322 */ 323 dtb = cpio_get_file(_archive_start, cpio_len, "kernel.dtb", &unused); 324 if (dtb == NULL) { 325 printf("not found.\n"); 326 } else { 327 has_dtb_cpio = 1; 328 printf("found at %p.\n", dtb); 329 } 330 } 331#endif 332 333 if (chosen_dtb && !dtb && bootloader_dtb) { 334 /* Use the bootloader's DTB if we are not using the DTB in the CPIO archive. */ 335 dtb = bootloader_dtb; 336 } 337 338 /* 339 * Move the DTB out of the way, if it's present. 340 */ 341 if (dtb) { 342 /* keep it page aligned */ 343 next_phys_addr = dtb_phys_start = ROUND_UP(kernel_phys_end, PAGE_BITS); 344 345 *chosen_dtb_size = fdt_size(dtb); 346 if (!*chosen_dtb_size) { 347 printf("Invalid device tree blob supplied!\n"); 348 abort(); 349 } 350 351 /* Make sure this is a sane thing to do */ 352 ensure_phys_range_valid("DTB", next_phys_addr, 353 next_phys_addr + *chosen_dtb_size); 354 355 memmove((void *)next_phys_addr, dtb, *chosen_dtb_size); 356 next_phys_addr += *chosen_dtb_size; 357 next_phys_addr = ROUND_UP(next_phys_addr, PAGE_BITS); 358 dtb_phys_end = next_phys_addr; 359 360 printf("Loaded DTB from %p.\n", dtb); 361 printf(" paddr=[%lx..%lx]\n", dtb_phys_start, dtb_phys_end - 1); 362 *chosen_dtb = (void *)dtb_phys_start; 363 } else { 364 next_phys_addr = ROUND_UP(kernel_phys_end, PAGE_BITS); 365 } 366 load_elf("kernel", kernel_elf, 367 (paddr_t)kernel_phys_start, kernel_info, 0, kernel_filesize, "kernel.bin"); 368 369 /* 370 * Load userspace images. 371 * 372 * We assume (and check) that the kernel is the first file in the archive, 373 * that the DTB is the second if present, 374 * and then load the (n+user_elf_offset)'th file in the archive onto the (n)'th CPU. 375 */ 376 int user_elf_offset = 2; 377 cpio_get_entry(_archive_start, cpio_len, 0, &elf_filename, &unused); 378 if (strcmp(elf_filename, "kernel.elf") != 0) { 379 printf("Kernel image not first image in archive.\n"); 380 abort(); 381 } 382 cpio_get_entry(_archive_start, cpio_len, 1, &elf_filename, &unused); 383 if (strcmp(elf_filename, "kernel.dtb") != 0) { 384 if (has_dtb_cpio) { 385 printf("Kernel DTB not second image in archive.\n"); 386 abort(); 387 } 388 user_elf_offset = 1; 389 } 390 391#ifdef CONFIG_ELFLOADER_ROOTSERVERS_LAST 392 /* work out the size of the user images - this corresponds to how much memory 393 * load_elf uses */ 394 int total_user_image_size = 0; 395 for (i = 0; i < max_user_images; i++) { 396 void *user_elf = cpio_get_entry(_archive_start, cpio_len, i + user_elf_offset, 397 &elf_filename, &unused); 398 uint64_t min_vaddr, max_vaddr; 399 total_user_image_size += rounded_image_size(user_elf, &min_vaddr, &max_vaddr); 400 401 total_user_image_size += KEEP_HEADERS_SIZE; 402 } 403 404 /* work out where to place the user image */ 405 406 next_phys_addr = ROUND_DOWN(memory_region[0].end, PAGE_BITS) - ROUND_UP(total_user_image_size, PAGE_BITS); 407#endif /* CONFIG_ELFLOADER_ROOTSERVERS_LAST */ 408 409 *num_images = 0; 410 for (i = 0; i < max_user_images; i++) { 411 /* Fetch info about the next ELF file in the archive. */ 412 void *user_elf = cpio_get_entry(_archive_start, cpio_len, i + user_elf_offset, 413 &elf_filename, &unused); 414 if (user_elf == NULL) { 415 break; 416 } 417 418 /* Load the file into memory. */ 419 next_phys_addr = load_elf(elf_filename, user_elf, 420 next_phys_addr, &user_info[*num_images], 1, unused, "app.bin"); 421 *num_images = i + 1; 422 } 423} 424 425void __attribute__((weak)) platform_init(void) {} 426