/* * ELF-loader for ARM systems. * * We are currently running out of physical memory, with an ELF file for the * kernel and one or more ELF files for the userspace image. (Typically there * will only be one userspace ELF file, though if we are running a multi-core * CPU, we may have multiple userspace images; one per CPU.) These ELF files * are packed into an 'ar' archive. * * The kernel ELF file indicates what physical address it wants to be loaded * at, while userspace images run out of virtual memory, so don't have any * requirements about where they are located. We place the kernel at its * desired location, and then load userspace images straight after it in * physical memory. * * Several things could possibly go wrong: * * 1. The physical load address of the kernel might want to overwrite this * ELF-loader; * * 2. The physical load addresses of the kernel might not actually be in * physical memory; * * 3. Userspace images may not fit in physical memory, or may try to overlap * the ELF-loader. * * We attempt to check for some of these, but some may go unnoticed. */ void load_images(struct image_info *kernel_info, struct image_info *user_info, int max_user_images, int *num_images) { int i; uint64_t kernel_phys_start, kernel_phys_end; paddr_t next_phys_addr; const char *elf_filename; unsigned long unused; /* Load kernel. */ void *kernel_elf = cpio_get_file(_archive_start, "kernel.elf", &unused); if (kernel_elf == NULL) { printf("No kernel image present in archive!\n"); abort(); } if (elf_checkFile(kernel_elf)) { printf("Kernel image not a valid ELF file!\n"); abort(); } elf_getMemoryBounds(kernel_elf, 1, &kernel_phys_start, &kernel_phys_end); next_phys_addr = load_elf("kernel", kernel_elf, (paddr_t)kernel_phys_start, kernel_info); /* * Load userspace images. * * We assume (and check) that the kernel is the first file in the archive, * and then load the (n+1)'th file in the archive onto the (n)'th CPU. */ (void)cpio_get_entry(_archive_start, 0, &elf_filename, &unused); if (strcmp(elf_filename, "kernel.elf") != 0) { printf("Kernel image not first image in archive.\n"); abort(); } *num_images = 0; for (i = 0; i < max_user_images; i++) { /* Fetch info about the next ELF file in the archive. */ void *user_elf = cpio_get_entry(_archive_start, i + 1, &elf_filename, &unused); if (user_elf == NULL) { break; } /* Load the file into memory. */ next_phys_addr = load_elf(elf_filename, user_elf, next_phys_addr, &user_info[*num_images]); *num_images = i + 1; } }
/* Initialise a list of files from the cpio that can be searched and indexed */ static void init_cpio_list(void) { assert(cpio_info(_cpio_archive, &cinfo) == 0); cpio_file_list = malloc(sizeof(cpio_entry_t) * cinfo.file_count); assert(cpio_file_list != NULL); for(int i = 0; i < cinfo.file_count; i++) { cpio_entry_t *ent = &(cpio_file_list[i]); ent->file = cpio_get_entry(_cpio_archive, i, &ent->name, &ent->size); assert(ent->file != NULL); } }
static void print_cpio_info(void) { struct cpio_info info; const char* name; unsigned long size; int i; cpio_info(_cpio_archive, &info); printf("CPIO: %d files found.\n", info.file_count); assert(info.file_count > 0); for (i = 0; i < info.file_count; i++) { void * addr; char buf[info.max_path_sz + 1]; buf[info.max_path_sz] = '\0'; addr = cpio_get_entry(_cpio_archive, i, &name, &size); assert(addr); strncpy(buf, name, info.max_path_sz); printf("%d) %-20s 0x%08x, %8ld bytes\n", i, buf, (uint32_t)addr, size); } printf("\n"); }
static void print_bootinfo(const seL4_BootInfo* info) { int i; /* General info */ dprintf(1, "Info Page: %p\n", info); dprintf(1,"IPC Buffer: %p\n", info->ipcBuffer); dprintf(1,"Node ID: %d (of %d)\n",info->nodeID, info->numNodes); dprintf(1,"IOPT levels: %d\n",info->numIOPTLevels); dprintf(1,"Init cnode size bits: %d\n", info->initThreadCNodeSizeBits); /* Cap details */ dprintf(1,"\nCap details:\n"); dprintf(1,"Type Start End\n"); dprintf(1,"Empty 0x%08x 0x%08x\n", info->empty.start, info->empty.end); dprintf(1,"Shared frames 0x%08x 0x%08x\n", info->sharedFrames.start, info->sharedFrames.end); dprintf(1,"User image frames 0x%08x 0x%08x\n", info->userImageFrames.start, info->userImageFrames.end); dprintf(1,"User image PTs 0x%08x 0x%08x\n", info->userImagePTs.start, info->userImagePTs.end); dprintf(1,"Untypeds 0x%08x 0x%08x\n", info->untyped.start, info->untyped.end); /* Untyped details */ dprintf(1,"\nUntyped details:\n"); dprintf(1,"Untyped Slot Paddr Bits\n"); for (i = 0; i < info->untyped.end-info->untyped.start; i++) { dprintf(1,"%3d 0x%08x 0x%08x %d\n", i, info->untyped.start + i, info->untypedPaddrList[i], info->untypedSizeBitsList[i]); } /* Device untyped details */ dprintf(1,"\nDevice untyped details:\n"); dprintf(1,"Untyped Slot Paddr Bits\n"); for (i = 0; i < info->deviceUntyped.end-info->deviceUntyped.start; i++) { dprintf(1,"%3d 0x%08x 0x%08x %d\n", i, info->deviceUntyped.start + i, info->untypedPaddrList[i + (info->untyped.end - info->untyped.start)], info->untypedSizeBitsList[i + (info->untyped.end-info->untyped.start)]); } dprintf(1,"-----------------------------------------\n\n"); /* Print cpio data */ dprintf(1,"Parsing cpio data:\n"); dprintf(1,"--------------------------------------------------------\n"); dprintf(1,"| index | name | address | size (bytes) |\n"); dprintf(1,"|------------------------------------------------------|\n"); for(i = 0;; i++) { unsigned long size; const char *name; void *data; data = cpio_get_entry(_cpio_archive, i, &name, &size); if(data != NULL){ dprintf(1,"| %3d | %16s | %p | %12d |\n", i, name, data, size); }else{ break; } } dprintf(1,"--------------------------------------------------------\n"); }