Exemplo n.º 1
0
Arquivo: commands.c Projeto: M1cha/lk
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;
}
Exemplo n.º 2
0
Arquivo: init.c Projeto: yuanguo8/lk
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
}
Exemplo n.º 3
0
/* 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;
}
Exemplo n.º 4
0
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;
}