void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end, u32 ram_size) { u32 pg_start, pg_end, pg_len, fdt_len; void *fdt_new; void (*barebox)(void *fdt, u32 fdt_len, u32 ram_size); puts_ll("pbl_main_entry()\n"); /* clear bss */ memset(__bss_start, 0, __bss_stop - __bss_start); pg_start = (u32)&input_data; pg_end = (u32)&input_data_end; pg_len = pg_end - pg_start; barebox_uncompress(&input_data, pg_len); fdt_len = (u32)fdt_end - (u32)fdt; fdt_new = (void *)PAGE_ALIGN_DOWN(TEXT_BASE - MALLOC_SIZE - STACK_SIZE - fdt_len); memcpy(fdt_new, fdt, fdt_len); barebox = (void *)TEXT_BASE; barebox(fdt_new, fdt_len, ram_size); }
__noreturn void barebox_single_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t offset; uint32_t pg_start, pg_end, pg_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; endmem -= STACK_SIZE; /* stack */ if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) relocate_to_current_adr(); /* Get offset between linked address and runtime address */ offset = get_runtime_offset(); pg_start = (uint32_t)&input_data - offset; pg_end = (uint32_t)&input_data_end - offset; pg_len = pg_end - pg_start; if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_barebox_image_place(membase + memsize); else barebox_base = TEXT_BASE; if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) || region_overlap(pg_start, pg_len, barebox_base, pg_len * 4))) { /* * copy piggydata binary to its link address */ memcpy(&input_data, (void *)pg_start, pg_len); pg_start = (uint32_t)&input_data; } setup_c(); if (IS_ENABLED(CONFIG_MMU_EARLY)) { endmem &= ~0x3fff; endmem -= SZ_16K; /* ttb */ mmu_early_enable(membase, memsize, endmem); } endmem -= SZ_128K; /* early malloc */ free_mem_ptr = endmem; free_mem_end_ptr = free_mem_ptr + SZ_128K; pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len); arm_early_mmu_cache_flush(); flush_icache(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); else barebox = (void *)barebox_base; barebox(membase, memsize, boarddata); }
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 void noinline uncompress(uint32_t membase, uint32_t memsize, uint32_t boarddata) { uint32_t offset; uint32_t pg_len; void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t); uint32_t endmem = membase + memsize; unsigned long barebox_base; uint32_t *ptr; void *pg_start; arm_early_mmu_cache_invalidate(); endmem -= STACK_SIZE; /* stack */ if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) relocate_to_current_adr(); /* Get offset between linked address and runtime address */ offset = get_runtime_offset(); if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_barebox_image_place(membase + memsize); else barebox_base = TEXT_BASE; setup_c(); if (IS_ENABLED(CONFIG_MMU_EARLY)) { endmem &= ~0x3fff; endmem -= SZ_16K; /* ttb */ mmu_early_enable(membase, memsize, endmem); } endmem -= SZ_128K; /* early malloc */ free_mem_ptr = endmem; free_mem_end_ptr = free_mem_ptr + SZ_128K; ptr = (void *)__image_end; pg_start = ptr + 1; pg_len = *(ptr); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); arm_early_mmu_cache_flush(); flush_icache(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); else barebox = (void *)barebox_base; barebox(membase, memsize, boarddata); }
static int do_bootm_barebox(struct image_data *data) { void (*barebox)(void); barebox = read_file(data->os_file, NULL); if (!barebox) return -EINVAL; shutdown_barebox(); barebox(); reset_cpu(0); }
void __naked __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize, uint32_t boarddata) { unsigned long barebox_base; void __noreturn (*barebox)(uint32_t, uint32_t, uint32_t); barebox_base = ld_var(__image_end) - get_runtime_offset() + 4; if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); else barebox = (void *)barebox_base; barebox(membase, memsize, boarddata); }
void __section(.text_entry) pbl_main_entry(void) { u32 pg_start, pg_end, pg_len; void (*barebox)(void); puts_ll("pbl_main_entry()\n"); /* clear bss */ memset(__bss_start, 0, __bss_stop - __bss_start); pg_start = (u32)&input_data; pg_end = (u32)&input_data_end; pg_len = pg_end - pg_start; barebox_uncompress(&input_data, pg_len); barebox = (void *)TEXT_BASE; barebox(); }
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(); }
/** * ls1046a_esdhc_start_image - Load and start a 2nd stage from the ESDHC controller * * This loads and starts a 2nd stage barebox from an SD card and starts it. We * assume the image has been generated with scripts/pblimage.c which puts the * second stage to an offset of 128KiB in the image. * * Return: If successful, this function does not return. A negative error * code is returned when this function fails. */ int ls1046a_esdhc_start_image(unsigned long r0, unsigned long r1, unsigned long r2) { int ret; uint32_t val; struct esdhc esdhc = { .regs = IOMEM(0x01560000), .is_be = true, }; unsigned long sdram = 0x80000000; void (*barebox)(unsigned long, unsigned long, unsigned long) = (void *)(sdram + LS1046A_SD_IMAGE_OFFSET); /* * The ROM leaves us here with a clock frequency of around 400kHz. Speed * this up a bit. FIXME: The resulting frequency has not yet been verified * to work on all cards. */ val = esdhc_read32(&esdhc, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET); val &= ~0x0000fff0; val |= (8 << 8) | (3 << 4); esdhc_write32(&esdhc, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET, val); esdhc_write32(&esdhc, ESDHC_DMA_SYSCTL, ESDHC_SYSCTL_DMA_SNOOP); ret = esdhc_read_blocks(&esdhc, (void *)sdram, ALIGN(barebox_image_size + LS1046A_SD_IMAGE_OFFSET, 512)); if (ret) { pr_err("%s: reading blocks failed with: %d\n", __func__, ret); return ret; } icache_invalidate(); printf("Starting barebox\n"); barebox(r0, r1, r2); return -EINVAL; }
void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t pg_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; uint32_t *image_end; void *pg_start; unsigned long pc = get_pc(); image_end = (void *)ld_var(__image_end) - get_runtime_offset(); if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) { /* * If we run from inside the memory just relocate the binary * to the current address. Otherwise it may be a readonly location. * Copy and relocate to the start of the memory in this case. */ if (pc > membase && pc - membase < memsize) relocate_to_current_adr(); else relocate_to_adr(membase); } /* * image_end is the first location after the executable. It contains * the size of the appended compressed binary followed by the binary. */ pg_start = image_end + 1; pg_len = *(image_end); if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_mem_barebox_image(membase, endmem, pg_len); else barebox_base = TEXT_BASE; setup_c(); pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); if (IS_ENABLED(CONFIG_MMU_EARLY)) { unsigned long ttb = arm_mem_ttb(membase, endmem); pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb); mmu_early_enable(membase, memsize, ttb); } free_mem_ptr = arm_mem_early_malloc(membase, endmem); free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx\n", pg_start, pg_len, barebox_base); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); arm_early_mmu_cache_flush(); flush_icache(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); else barebox = (void *)barebox_base; pr_debug("jumping to uncompressed image at 0x%p\n", barebox); barebox(membase, memsize, boarddata); }