static const void *
mpbios_map(paddr_t pa, int len, struct mp_map *handle)
{
	paddr_t pgpa = x86_trunc_page(pa);
	paddr_t endpa = x86_round_page(pa + len);
	vaddr_t va = uvm_km_alloc(kernel_map, endpa - pgpa, 0, UVM_KMF_VAONLY);
	vaddr_t retva = va + (pa & PGOFSET);

	handle->pa = pa;
	handle->pg = pgpa;
	handle->psize = len;
	handle->baseva = va;
	handle->vsize = endpa-pgpa;

	do {
		pmap_kenter_pa(va, pgpa, VM_PROT_READ, 0);
		va += PAGE_SIZE;
		pgpa += PAGE_SIZE;
	} while (pgpa < endpa);
	pmap_update(pmap_kernel());

	return (const void *)retva;
}
Beispiel #2
0
int
exec_multiboot(const char *file, char *args)
{
	struct multiboot_info *mbi;
	struct multiboot_module *mbm;
	struct bi_modulelist_entry *bim;
	int		i, len;
	u_long		marks[MARK_MAX];
	u_long		extmem;
	u_long		basemem;
	char		*cmdline;

	mbi = alloc(sizeof(struct multiboot_info));
	mbi->mi_flags = MULTIBOOT_INFO_HAS_MEMORY;

	if (common_load_kernel(file, &basemem, &extmem, 0, 0, marks))
		goto out;

	mbi->mi_mem_upper = extmem;
	mbi->mi_mem_lower = basemem;

	if (args) {
		mbi->mi_flags |= MULTIBOOT_INFO_HAS_CMDLINE;
		len = strlen(file) + 1 + strlen(args) + 1;
		cmdline = alloc(len);
		snprintf(cmdline, len, "%s %s", file, args);
		mbi->mi_cmdline = (char *) vtophys(cmdline);
	}

	/* pull in any modules if necessary */
	if (boot_modules_enabled) {
		module_init(file);
		if (btinfo_modulelist) {
			mbm = alloc(sizeof(struct multiboot_module) *
					   btinfo_modulelist->num);

			bim = (struct bi_modulelist_entry *)
			  (((char *) btinfo_modulelist) +
			   sizeof(struct btinfo_modulelist));
			for (i = 0; i < btinfo_modulelist->num; i++) {
				mbm[i].mmo_start = bim->base;
				mbm[i].mmo_end = bim->base + bim->len;
				mbm[i].mmo_string = (char *)vtophys(bim->path);
				mbm[i].mmo_reserved = 0;
				bim++;
			}
			mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
			mbi->mi_mods_count = btinfo_modulelist->num;
			mbi->mi_mods_addr = vtophys(mbm);
		}
	}

#ifdef DEBUG
	printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
	    marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
#endif


#if 0
	if (btinfo_symtab.nsym) {
		mbi->mi_flags |= MULTIBOOT_INFO_HAS_ELF_SYMS;
		mbi->mi_elfshdr_addr = marks[MARK_SYM];
	btinfo_symtab.nsym = marks[MARK_NSYM];
	btinfo_symtab.ssym = marks[MARK_SYM];
	btinfo_symtab.esym = marks[MARK_END];
#endif

	multiboot(marks[MARK_ENTRY], vtophys(mbi),
		  x86_trunc_page(mbi->mi_mem_lower*1024));
	panic("exec returned");

out:
        dealloc(mbi, 0);
	return -1;
}

void
x86_progress(const char *fmt, ...)
{
	va_list ap;

	if ((howto & AB_SILENT) != 0)
		return;
	va_start(ap, fmt);
	vprintf(fmt, ap);
	va_end(ap);
}
Beispiel #3
0
int
exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto, int floppy,
	    void (*callback)(void))
{
	u_long          boot_argv[BOOT_NARGS];
	u_long		marks[MARK_MAX];
	struct btinfo_symtab btinfo_symtab;
	u_long		extmem;
	u_long		basemem;

#ifdef	DEBUG
	printf("exec: file=%s loadaddr=0x%lx\n",
	       file ? file : "NULL", loadaddr);
#endif

	BI_ALLOC(32); /* ??? */

	BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));

	howto = boothowto;

	if (common_load_kernel(file, &basemem, &extmem, loadaddr, floppy, marks))
		goto out;

	boot_argv[0] = boothowto;
	boot_argv[1] = 0;
	boot_argv[2] = vtophys(bootinfo);	/* old cyl offset */
	boot_argv[3] = marks[MARK_END];
	boot_argv[4] = extmem;
	boot_argv[5] = basemem;

	/* pull in any modules if necessary */
	if (boot_modules_enabled) {
		module_init(file);
		if (btinfo_modulelist) {
			BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
			    btinfo_modulelist_size);
		}
	}

	userconf_init();
	if (btinfo_userconfcommands != NULL)
		BI_ADD(btinfo_userconfcommands, BTINFO_USERCONFCOMMANDS,
	btinfo_userconfcommands_size);

#ifdef DEBUG
	printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
	    marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
#endif

	btinfo_symtab.nsym = marks[MARK_NSYM];
	btinfo_symtab.ssym = marks[MARK_SYM];
	btinfo_symtab.esym = marks[MARK_END];
	BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab));

	/* set new video mode if necessary */
	vbe_commit();
	BI_ADD(&btinfo_framebuffer, BTINFO_FRAMEBUFFER,
	    sizeof(struct btinfo_framebuffer));

	if (callback != NULL)
		(*callback)();
	startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
		  x86_trunc_page(basemem*1024));
	panic("exec returned");

out:
	BI_FREE();
	bootinfo = 0;
	return -1;
}
Beispiel #4
0
/*
 * Write bytes somewhere in the kernel text.  Make the text
 * pages writable temporarily.
 */
static void
db_write_text(vaddr_t addr, size_t size, const char *data)
{
	pt_entry_t *pte, oldpte, tmppte;
	vaddr_t pgva;
	size_t limit;
	char *dst;

	if (size == 0)
		return;

	dst = (char *)addr;

	do {
		/*
		 * Get the PTE for the page.
		 */
		pte = kvtopte(addr);
		oldpte = *pte;

		if ((oldpte & PG_V) == 0) {
			printf(" address %p not a valid page\n", dst);
			return;
		}

		/*
		 * Get the VA for the page.
		 */
		if (oldpte & PG_PS)
			pgva = (vaddr_t)dst & PG_LGFRAME;
		else
			pgva = x86_trunc_page(dst);

		/*
		 * Compute number of bytes that can be written
		 * with this mapping and subtract it from the
		 * total size.
		 */
		if (oldpte & PG_PS)
			limit = NBPD_L2 - ((vaddr_t)dst & (NBPD_L2 - 1));
		else
			limit = PAGE_SIZE - ((vaddr_t)dst & PGOFSET);
		if (limit > size)
			limit = size;
		size -= limit;

		tmppte = (oldpte & ~PG_KR) | PG_KW;
#ifdef XEN
		xpmap_update(pte, tmppte);
#else
		*pte = tmppte;
#endif
		pmap_update_pg(pgva);

		/*
		 * Page is now writable.  Do as much access as we
		 * can in this page.
		 */
		for (; limit > 0; limit--)
			*dst++ = *data++;

		/*
		 * Restore the old PTE.
		 */
#ifdef XEN
		xpmap_update(pte, oldpte);
#else
		*pte = oldpte;
#endif

		pmap_update_pg(pgva);
		
	} while (size != 0);
}