static int do_boot(void *arg) { thread_sleep(250); /* sniff it to see if it's a bootimage or a raw image */ bootimage_t *bi; if (bootimage_open(lkb_iobuffer, lkb_iobuffer_size, &bi) >= 0) { void *ptr; size_t len; /* it's a bootimage */ TRACEF("detected bootimage\n"); /* find the lk image */ if (bootimage_get_file_section(bi, TYPE_LK, &ptr, &len) >= 0) { TRACEF("found lk section at %p\n", ptr); arch_chain_load(ptr, 5, 6, 7, 8); } } else { /* raw image, just chain load it directly */ TRACEF("raw image, chainloading\n"); arch_chain_load(lkb_iobuffer, 1, 2, 3, 4); } return 0; }
static void zybo_common_target_init(uint level) { status_t err; /* zybo has a spiflash on qspi */ spiflash_detect(); bdev_t *spi = bio_open("spi0"); if (spi) { /* find or create a partition table at the start of flash */ if (ptable_scan(spi, 0) < 0) { ptable_create_default(spi, 0); } struct ptable_entry entry = { 0 }; /* find and recover sysparams */ if (ptable_find("sysparam", &entry) < 0) { /* didn't find sysparam partition, create it */ ptable_add("sysparam", 0x1000, 0x1000, 0); ptable_find("sysparam", &entry); } if (entry.length > 0) { sysparam_scan(spi, entry.offset, entry.length); #if SYSPARAM_ALLOW_WRITE /* for testing purposes, put at least one sysparam value in */ if (sysparam_add("dummy", "value", sizeof("value")) >= 0) { sysparam_write(); } #endif sysparam_dump(true); } /* create bootloader partition if it does not exist */ ptable_add("bootloader", 0x20000, 0x40000, 0); printf("flash partition table:\n"); ptable_dump(); } /* recover boot arguments */ const char *cmdline = bootargs_get_command_line(); if (cmdline) { printf("command line: '%s'\n", cmdline); } /* see if we came from a bootimage */ uintptr_t bootimage_phys; size_t bootimage_size; if (bootargs_get_bootimage_pointer(&bootimage_phys, &bootimage_size) >= 0) { printf("our bootimage is at phys 0x%lx, size %zx\n", bootimage_phys, bootimage_size); void *ptr = paddr_to_kvaddr(bootimage_phys); if (ptr) { bootimage_t *bi; if (bootimage_open(ptr, bootimage_size, &bi) >= 0) { /* we have a valid bootimage, find the fpga section */ const void *fpga_ptr; size_t fpga_len; if (bootimage_get_file_section(bi, TYPE_FPGA_IMAGE, &fpga_ptr, &fpga_len) >= 0) { /* we have a fpga image */ /* lookup the physical address of the bitfile */ paddr_t pa = kvaddr_to_paddr((void *)fpga_ptr); if (pa != 0) { /* program the fpga with it*/ printf("loading fpga image at %p (phys 0x%lx), len %zx\n", fpga_ptr, pa, fpga_len); zynq_reset_fpga(); err = zynq_program_fpga(pa, fpga_len); if (err < 0) { printf("error %d loading fpga\n", err); } printf("fpga image loaded\n"); } } } } } #if WITH_LIB_MINIP /* pull some network stack related params out of the sysparam block */ uint8_t mac_addr[6]; uint32_t ip_addr = IPV4_NONE; uint32_t ip_mask = IPV4_NONE; uint32_t ip_gateway = IPV4_NONE; if (sysparam_read("net0.mac_addr", mac_addr, sizeof(mac_addr)) < (ssize_t)sizeof(mac_addr)) { /* couldn't find eth address, make up a random one */ for (size_t i = 0; i < sizeof(mac_addr); i++) { mac_addr[i] = rand() & 0xff; } /* unicast and locally administered */ mac_addr[0] &= ~(1<<0); mac_addr[0] |= (1<<1); } uint8_t use_dhcp = 0; sysparam_read("net0.use_dhcp", &use_dhcp, sizeof(use_dhcp)); sysparam_read("net0.ip_addr", &ip_addr, sizeof(ip_addr)); sysparam_read("net0.ip_mask", &ip_mask, sizeof(ip_mask)); sysparam_read("net0.ip_gateway", &ip_gateway, sizeof(ip_gateway)); minip_set_macaddr(mac_addr); gem_set_macaddr(mac_addr); if (!use_dhcp && ip_addr != IPV4_NONE) { minip_init(gem_send_raw_pkt, NULL, ip_addr, ip_mask, ip_gateway); } else { /* Configure IP stack and hook to the driver */ minip_init_dhcp(gem_send_raw_pkt, NULL); } gem_set_callback(minip_rx_driver_callback); #endif }
/* try to boot the system from a flash partition */ status_t do_flash_boot(void) { status_t err; LTRACE_ENTRY; /* construct a boot argument list */ const size_t bootargs_size = PAGE_SIZE; #if 0 /* old code */ void *args = (void *)((uintptr_t)lkb_iobuffer + lkb_iobuffer_size - bootargs_size); paddr_t args_phys = lkb_iobuffer_phys + lkb_iobuffer_size - bootargs_size; #elif PLATFORM_ZYNQ /* grab the top page of sram */ paddr_t args_phys = SRAM_BASE + SRAM_SIZE - bootargs_size; void *args = paddr_to_kvaddr(args_phys); #else #error need better way #endif LTRACEF("boot args %p, phys 0x%lx, len %zu\n", args, args_phys, bootargs_size); bootargs_start(args, bootargs_size); bootargs_add_command_line(args, bootargs_size, "what what"); arch_clean_cache_range((vaddr_t)args, bootargs_size); ulong lk_args[4]; bootargs_generate_lk_arg_values(args_phys, lk_args); const void *ptr; if (!ptable_found_valid()) { TRACEF("ptable not found\n"); return ERR_NOT_FOUND; } /* find the system partition */ struct ptable_entry entry; err = ptable_find("system", &entry); if (err < 0) { TRACEF("cannot find system partition\n"); return ERR_NOT_FOUND; } /* get a direct pointer to the device */ bdev_t *bdev = ptable_get_device(); if (!bdev) { TRACEF("error opening boot device\n"); return ERR_NOT_FOUND; } /* convert the bdev to a memory pointer */ err = bio_ioctl(bdev, BIO_IOCTL_GET_MEM_MAP, (void *)&ptr); TRACEF("err %d, ptr %p\n", err, ptr); if (err < 0) { TRACEF("error getting direct pointer to block device\n"); return ERR_NOT_FOUND; } /* sniff it to see if it's a bootimage or a raw image */ bootimage_t *bi; if (bootimage_open((char *)ptr + entry.offset, entry.length, &bi) >= 0) { size_t len; /* it's a bootimage */ TRACEF("detected bootimage\n"); /* find the lk image */ if (bootimage_get_file_section(bi, TYPE_LK, &ptr, &len) >= 0) { TRACEF("found lk section at %p\n", ptr); /* add the boot image to the argument list */ size_t bootimage_size; bootimage_get_range(bi, NULL, &bootimage_size); bootargs_add_bootimage_pointer(args, bootargs_size, bdev->name, entry.offset, bootimage_size); } } else { /* did not find a bootimage, abort */ bio_ioctl(bdev, BIO_IOCTL_PUT_MEM_MAP, NULL); return ERR_NOT_FOUND; } TRACEF("chain loading binary at %p\n", ptr); arch_chain_load((void *)ptr, lk_args[0], lk_args[1], lk_args[2], lk_args[3]); /* put the block device back into block mode (though we never get here) */ bio_ioctl(bdev, BIO_IOCTL_PUT_MEM_MAP, NULL); return NO_ERROR; }
static int do_boot(lkb_t *lkb, size_t len, const char **result) { LTRACEF("lkb %p, len %zu, result %p\n", lkb, len, result); void *buf; paddr_t buf_phys; if (vmm_alloc_contiguous(vmm_get_kernel_aspace(), "lkboot_iobuf", len, &buf, log2_uint(1024*1024), 0, ARCH_MMU_FLAG_UNCACHED) < 0) { *result = "not enough memory"; return -1; } buf_phys = vaddr_to_paddr(buf); LTRACEF("iobuffer %p (phys 0x%lx)\n", buf, buf_phys); if (lkb_read(lkb, buf, len)) { *result = "io error"; // XXX free buffer here return -1; } /* construct a boot argument list */ const size_t bootargs_size = PAGE_SIZE; #if 0 void *args = (void *)((uintptr_t)lkb_iobuffer + lkb_iobuffer_size - bootargs_size); paddr_t args_phys = lkb_iobuffer_phys + lkb_iobuffer_size - bootargs_size; #elif PLATFORM_ZYNQ /* grab the top page of sram */ /* XXX do this better */ paddr_t args_phys = SRAM_BASE + SRAM_SIZE - bootargs_size; void *args = paddr_to_kvaddr(args_phys); #else #error need better way #endif LTRACEF("boot args %p, phys 0x%lx, len %zu\n", args, args_phys, bootargs_size); bootargs_start(args, bootargs_size); bootargs_add_command_line(args, bootargs_size, "what what"); arch_clean_cache_range((vaddr_t)args, bootargs_size); ulong lk_args[4]; bootargs_generate_lk_arg_values(args_phys, lk_args); const void *ptr; /* sniff it to see if it's a bootimage or a raw image */ bootimage_t *bi; if (bootimage_open(buf, len, &bi) >= 0) { size_t len; /* it's a bootimage */ TRACEF("detected bootimage\n"); /* find the lk image */ if (bootimage_get_file_section(bi, TYPE_LK, &ptr, &len) >= 0) { TRACEF("found lk section at %p\n", ptr); /* add the boot image to the argument list */ size_t bootimage_size; bootimage_get_range(bi, NULL, &bootimage_size); bootargs_add_bootimage_pointer(args, bootargs_size, "pmem", buf_phys, bootimage_size); } } else { /* raw image, just chain load it directly */ TRACEF("raw image, chainloading\n"); ptr = buf; } /* start a boot thread to complete the startup */ static struct chainload_args cl_args; cl_args.func = (void *)ptr; cl_args.args[0] = lk_args[0]; cl_args.args[1] = lk_args[1]; cl_args.args[2] = lk_args[2]; cl_args.args[3] = lk_args[3]; thread_resume(thread_create("boot", &chainload_thread, &cl_args, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); return 0; }