static int do_bootm_barebox(struct image_data *data) { void *barebox; barebox = read_file(data->os_file, NULL); if (!barebox) return -EINVAL; if (IS_ENABLED(CONFIG_OFTREE) && data->of_root_node) { data->oftree = of_get_fixed_tree(data->of_root_node); fdt_add_reserve_map(data->oftree); of_print_cmdline(data->of_root_node); if (bootm_verbose(data) > 1) of_print_nodes(data->of_root_node, 0); } if (bootm_verbose(data)) { printf("\nStarting barebox at 0x%p", barebox); if (data->oftree) printf(", oftree at 0x%p", data->oftree); printf("...\n"); } start_linux(barebox, 0, 0, 0, data->oftree); restart_machine(); }
static int do_bootm_kwbimage_v0_v1(struct image_data *data) { int fd, ret; loff_t offset; char header[0x20]; u32 image_size, image_source; void (*barebox)(void); fd = open(data->os_file, O_RDONLY); if (fd < 0) return fd; ret = read_full(fd, header, 0x20); if (ret < 0x20) { pr_err("Failed to read header\n"); if (ret >= 0) return -EINVAL; return -errno; } image_size = header[4] | header[5] << 8 | header[6] << 16 | header[7] << 24; image_source = header[0xc] | header[0xd] << 8 | header[0xe] << 16 | header[0xf] << 24; if (data->verbose) pr_info("size: %u\noffset: %u\n", image_size, image_source); offset = lseek(fd, image_source, SEEK_SET); if (offset < 0) { pr_err("Failed to seek to image (%lld, %d)\n", offset, errno); return -errno; } barebox = xzalloc(image_size); ret = read_full(fd, barebox, image_size); if (ret < image_size) { pr_err("Failed to read image\n"); if (ret >= 0) ret = -EINVAL; else ret = -errno; goto out_free; } if (is_barebox_arm_head((void *)barebox)) put_unaligned_le32(MVEBU_REMAP_INT_REG_BASE, barebox + 0x30); shutdown_barebox(); barebox(); restart_machine(); out_free: free(barebox); return ret; }
static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap) { unsigned long kernel; unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0; int ret; kernel = data->os_res->start + data->os_entry; initrd_start = data->initrd_address; if (initrd_start == UIMAGE_INVALID_ADDRESS) { initrd_start = PAGE_ALIGN(free_mem); if (bootm_verbose(data)) { printf("no initrd load address, defaulting to 0x%08lx\n", initrd_start); } } if (bootm_has_initrd(data)) { ret = bootm_load_initrd(data, initrd_start); if (ret) return ret; } if (data->initrd_res) { initrd_start = data->initrd_res->start; initrd_end = data->initrd_res->end; initrd_size = resource_size(data->initrd_res); free_mem = PAGE_ALIGN(initrd_end + 1); } ret = bootm_load_devicetree(data, free_mem); if (ret) return ret; if (bootm_verbose(data)) { printf("\nStarting kernel at 0x%08lx", kernel); if (initrd_size) printf(", initrd at 0x%08lx", initrd_start); if (data->oftree) printf(", oftree at 0x%p", data->oftree); printf("...\n"); } if (data->dryrun) return 0; start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree); restart_machine(); return -ERESTARTSYS; }
static int do_bootm_linux(struct image_data *data) { void (*kernel)(void *, void *, unsigned long, unsigned long, unsigned long); int ret; ret = bootm_load_os(data, data->os_address); if (ret) return ret; data->oftree = of_get_fixed_tree(data->of_root_node); if (!data->oftree) { pr_err("bootm: No devicetree given.\n"); return -EINVAL; } /* Relocate the device tree if outside the initial * Linux mapped TLB. */ if (IS_ENABLED(CONFIG_MPC85xx)) { void *addr = data->oftree; if ((addr + data->oftree->totalsize) > LINUX_TLB1_MAX_ADDR) { addr = (void *)data->os_address; if (bootm_relocate_fdt(addr, data)) goto error; } } fdt_add_reserve_map(data->oftree); kernel = (void *)(data->os_address + data->os_entry); /* * Linux Kernel Parameters (passing device tree): * r3: ptr to OF flat tree, followed by the board info data * r4: physical pointer to the kernel itself * r5: NULL * r6: NULL * r7: NULL */ kernel(data->oftree, kernel, 0, 0, 0); restart_machine(); error: return -1; }
void __noreturn panic(const char *fmt, ...) { va_list args; va_start(args, fmt); vprintf(fmt, args); putchar('\n'); va_end(args); dump_stack(); led_trigger(LED_TRIGGER_PANIC, TRIGGER_ENABLE); if (IS_ENABLED(CONFIG_PANIC_HANG)) { hang(); } else { udelay(100000); /* allow messages to go out */ restart_machine(); } }
static int do_bootm_barebox(struct image_data *data) { void (*barebox)(void); barebox = read_file(data->os_file, NULL); if (!barebox) return -EINVAL; if (data->dryrun) { free(barebox); return 0; } shutdown_barebox(); barebox(); restart_machine(); }
static int do_bootm_aimage(struct image_data *data) { struct resource *snd_stage_res; int fd, ret; struct android_header __header, *header; void *buf; int to_read; struct android_header_comp *cmp; unsigned long mem_free; unsigned long mem_start, mem_size; ret = sdram_start_and_size(&mem_start, &mem_size); if (ret) return ret; fd = open(data->os_file, O_RDONLY); if (fd < 0) { perror("open"); return 1; } header = &__header; ret = read(fd, header, sizeof(*header)); if (ret < sizeof(*header)) { printf("could not read %s\n", data->os_file); goto err_out; } printf("Android Image for '%s'\n", header->name); /* * As on tftp we do not support lseek and we will just have to seek * for the size of a page - 1 max just buffer instead to read to dummy * data */ buf = xmalloc(header->page_size); to_read = header->page_size - sizeof(*header); ret = read_full(fd, buf, to_read); if (ret < 0) { printf("could not read dummy %d from %s\n", to_read, data->os_file); goto err_out; } cmp = &header->kernel; data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size); if (!data->os_res) { pr_err("Cannot request region 0x%08x - 0x%08x, using default load address\n", cmp->load_addr, cmp->size); data->os_address = mem_start + PAGE_ALIGN(cmp->size * 4); data->os_res = request_sdram_region("akernel", data->os_address, cmp->size); if (!data->os_res) { pr_err("Cannot request region 0x%08x - 0x%08x\n", cmp->load_addr, cmp->size); ret = -ENOMEM; goto err_out; } } ret = aimage_load_resource(fd, data->os_res, buf, header->page_size); if (ret < 0) { perror("could not read kernel"); goto err_out; } /* * fastboot always expect a ramdisk * in barebox we can be less restrictive */ cmp = &header->ramdisk; if (cmp->size) { data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size); if (!data->initrd_res) { ret = -ENOMEM; goto err_out; } ret = aimage_load_resource(fd, data->initrd_res, buf, header->page_size); if (ret < 0) { perror("could not read initrd"); goto err_out; } } if (!getenv("aimage_noverwrite_bootargs")) linux_bootargs_overwrite(header->cmdline); if (!getenv("aimage_noverwrite_tags")) armlinux_set_bootparams((void*)header->tags_addr); cmp = &header->second_stage; if (cmp->size) { void (*second)(void); snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size); if (!snd_stage_res) { ret = -ENOMEM; goto err_out; } ret = aimage_load_resource(fd, snd_stage_res, buf, header->page_size); if (ret < 0) { perror("could not read initrd"); goto err_out; } second = (void*)snd_stage_res->start; shutdown_barebox(); second(); restart_machine(); } close(fd); /* * Put devicetree right after initrd if present or after the kernel * if not. */ if (data->initrd_res) mem_free = PAGE_ALIGN(data->initrd_res->end); else mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M); return __do_bootm_linux(data, mem_free, 0); err_out: linux_bootargs_overwrite(NULL); close(fd); return ret; }