Example #1
0
void
Loader::_load_memory(vaddr_t kv, vsize_t memsz, void *data)
{
	struct PageTag *pvec;
	vaddr_t kv_start = kv, v;
	paddr_t p, pvec_paddr;

	DPRINTF((TEXT("\t->load 0x%08x+0x%08x=0x%08x\n"),
	    kv, memsz, kv + memsz));
	if (memsz > _tpsz) {
		/* XXX failure */
		return;
	}

	_opvec_prev = _pvec_prev;
	if (!_mem->getTaggedPage(v, p, &pvec, pvec_paddr))
		_error = TRUE;
	memcpy((void *)v, data, memsz);
	_pvec_prev->src = ptokv(p);
	_pvec_prev->dst = kv;
	_pvec_prev->sz = memsz;
#ifdef PAGE_LINK_DUMP
	_pvec_prev->next =(u_int32_t)pvec;
#else
	_pvec_prev->next = ptokv(pvec_paddr);
#endif
	_pvec_prev = pvec;

	_kernend = kv + memsz;
	++_nload_link;
}
Example #2
0
/*
 * Load the program from specified ELF image stored in memory.
 * The boot information is filled after loading the program.
 */
int
load_elf(char *img, struct module *m)
{
	Elf32_Ehdr *ehdr;
	Elf32_Phdr *phdr;

	ELFDBG(("\nelf_load\n"));

	ehdr = (Elf32_Ehdr *)img;

	/*  Check ELF header */
	if ((ehdr->e_ident[EI_MAG0] != ELFMAG0) ||
	    (ehdr->e_ident[EI_MAG1] != ELFMAG1) ||
	    (ehdr->e_ident[EI_MAG2] != ELFMAG2) ||
	    (ehdr->e_ident[EI_MAG3] != ELFMAG3)) {
		DPRINTF(("Invalid ELF image\n"));
		return -1;
	}

	phdr = (Elf32_Phdr *)((paddr_t)ehdr + ehdr->e_ehsize);

	if (nr_img == 0) {
		/*  Initialize the load address */
		load_base = (vaddr_t)ptokv(phdr->p_paddr);
		if (load_base == 0) {
			DPRINTF(("Invalid load address\n"));
			return -1;
		}
		ELFDBG(("kernel base=%lx\n", load_base));
		load_start = load_base;
	}
	else if (nr_img == 1) {
		/* 2nd image => Driver */
		ELFDBG(("driver base=%lx\n", load_base));
	}
	else {
		/* Other images => Boot tasks */
		ELFDBG(("task base=%lx\n", load_base));
	}

	switch (ehdr->e_type) {
	case ET_EXEC:
		if (load_executable(img, m) != 0)
			return -1;
		break;
	case ET_REL:
		if (load_relocatable(img, m) != 0)
			return -1;
		break;
	default:
		ELFDBG(("Unsupported file type\n"));
		return -1;
	}
	nr_img++;
	return 0;
}
Example #3
0
void
SA1100Architecture::jump(paddr_t info, paddr_t pvec)
{
	kaddr_t sp;
	vaddr_t v;
	paddr_t p;

	// stack for bootloader
	_mem->getPage(v, p);
	sp = ptokv(p) + _mem->getPageSize();
	DPRINTF((TEXT("sp for bootloader = %08x + %08x = %08x\n"),
	    ptokv(p), _mem->getPageSize(), sp));

	// writeback whole D-cache
	WritebackDCache();

	SetKMode(1);
	FlatJump(info, pvec, sp, _loader_addr);
	// NOTREACHED
}
struct PageTag *
Loader::_load_page(vaddr_t kv, off_t ofs, size_t sz, struct PageTag *prev)
{
	struct PageTag *pvec;
	paddr_t p, pvec_paddr;
	vaddr_t v;

	if (!_mem->getTaggedPage(v, p, &pvec, pvec_paddr))
		_error = TRUE;
	_file->read((void *)v, sz, ofs);
	prev->src = ptokv(p);
	prev->dst = kv;
	prev->sz = sz;
#ifdef PAGE_LINK_DUMP
	prev->next = (uint32_t)pvec;
#else
	prev->next = ptokv(pvec_paddr);
#endif

	return pvec;
}
Example #5
0
void
diag_init(void)
{
	struct bootinfo *bi;

	machine_bootinfo(&bi);

	vram = ptokv(VID_RAM);
	pos_x = 0;
	pos_y = 0;
	screen_x = bi->video.text_x;
	screen_y = bi->video.text_y;
}
void
Loader::_load_memory(vaddr_t kv, vsize_t memsz, void *data)
{
	struct PageTag *pvec;
	paddr_t p, pvec_paddr;
	vaddr_t v;
	vaddr_t dst;
	vsize_t remsz;

	DPRINTF((TEXT("\t->load 0x%08x+0x%08x=0x%08x\n"),
	    kv, memsz, kv + memsz));

	dst = kv;
	remsz = memsz;
	while (remsz > 0) {
		_opvec_prev = _pvec_prev;
		if (!_mem->getTaggedPage(v, p, &pvec, pvec_paddr))
			_error = TRUE;

		vsize_t tocopy = (remsz < _tpsz) ? remsz : _tpsz;
		memcpy((void *)v, data, tocopy);
		_pvec_prev->src = ptokv(p);
		_pvec_prev->dst = dst;
		_pvec_prev->sz = tocopy;
#ifdef PAGE_LINK_DUMP
		_pvec_prev->next = (uint32_t)pvec;
#else
		_pvec_prev->next = ptokv(pvec_paddr);
#endif
		data = (char *)data + tocopy;
		dst += tocopy;
		remsz -= tocopy;

		_pvec_prev = pvec;
		++_nload_link;
	}

	_kernend = kv + memsz;
}
void
Loader::_load_segment(vaddr_t kv, vsize_t memsz, off_t fileofs, size_t filesz)
{
	int j, n;
	vaddr_t kv_start = kv;

	DPRINTF((TEXT("\t->load 0x%08x+0x%08x=0x%08x ofs=0x%08x+0x%x\n"),
	    kv, memsz, kv + memsz, fileofs, filesz));
	_kernend = kv + memsz;

	if (filesz) {
		n = filesz / _tpsz;
		for (j = 0; j < n; j++) {
			_opvec_prev = _pvec_prev;
			_pvec_prev = _load_page(kv, fileofs,
			    _tpsz, _pvec_prev);
			kv += _tpsz;
			fileofs += _tpsz;
			++_nload_link;
		}
		size_t rest = filesz % _tpsz;
		if (rest) {
			_opvec_prev = _pvec_prev;
			_pvec_prev = _load_page(kv, fileofs, rest, _pvec_prev);
			++_nload_link;
		}
	}

	// zero clear tag
	if (filesz < memsz) {
		_pvec_prev->src = ~0;
		_pvec_prev->dst = kv_start + filesz;
		_pvec_prev->sz = memsz - filesz;
#ifdef PAGE_LINK_DUMP
		_pvec_prev->next = (uint32_t)_pvec_clr;
#else
		_pvec_prev->next = ptokv(_pvec_clr_paddr);
#endif
		DPRINTF((TEXT("\t->zero 0x%08x+0x%08x=0x%08x\n"),
		    _pvec_prev->dst, _pvec_prev->sz,
		    _pvec_prev->dst + _pvec_prev->sz));
		_opvec_prev = _pvec_prev;
		_pvec_prev = _pvec_clr++;
		_pvec_clr_paddr += sizeof(struct PageTag);
		++_n0clr_link;
	}
}
Example #8
0
static int
load_relocatable(char *img, struct module *m)
{
	Elf32_Ehdr *ehdr;
	Elf32_Shdr *shdr;
	paddr_t sect_base, bss_base;
	int i;

	strshndx = 0;
	ehdr = (Elf32_Ehdr *)img;
	shdr = (Elf32_Shdr *)((paddr_t)ehdr + ehdr->e_shoff);
	bss_base = 0;
	m->phys = load_base;
	ELFDBG(("phys addr=%lx\n", load_base));

	/* Copy sections */
	for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {
		sect_addr[i] = 0;
		if (shdr->sh_type == SHT_PROGBITS) {

			ELFDBG(("sh_addr=%x\n", shdr->sh_addr));
			ELFDBG(("sh_size=%x\n", shdr->sh_size));
			ELFDBG(("sh_offset=%x\n", shdr->sh_offset));
			ELFDBG(("sh_flags=%x\n", shdr->sh_flags));

			switch (shdr->sh_flags & SHF_VALID) {
			case (SHF_ALLOC | SHF_EXECINSTR):
				/* Text */
				m->text = (vaddr_t)ptokv(load_base);
				break;
			case (SHF_ALLOC | SHF_WRITE):
				/* Data */
				if (m->data == 0) {
					m->data = (vaddr_t)ptokv(load_base +
								 shdr->sh_addr);
				}
				break;
			case SHF_ALLOC:
				/* rodata */
				/* Note: rodata is treated as text. */
				break;
			default:
				continue;
			}
			sect_base = load_base + shdr->sh_addr;
			memcpy((char *)sect_base, img + shdr->sh_offset,
			       (size_t)shdr->sh_size);
			ELFDBG(("load: offset=%lx size=%x\n",
				 sect_base, (int)shdr->sh_size));

			sect_addr[i] = (char *)sect_base;
		} else if (shdr->sh_type == SHT_NOBITS) {
			/* BSS */
			m->bsssz = (size_t)shdr->sh_size;
			sect_base = load_base + shdr->sh_addr;
			bss_base = sect_base;

			/* Zero fill BSS */
			memset((char *)bss_base, 0, (size_t)shdr->sh_size);

			sect_addr[i] = (char *)sect_base;
		} else if (shdr->sh_type == SHT_SYMTAB) {
			/* Symbol table */
			ELFDBG(("load: symtab index=%d link=%d\n",
				i, shdr->sh_link));
			sect_addr[i] = img + shdr->sh_offset;
			if (strshndx != 0)
				panic("Multiple symtab found!");
			strshndx = (int)shdr->sh_link;
		} else if (shdr->sh_type == SHT_STRTAB) {
			/* String table */
			sect_addr[i] = img + shdr->sh_offset;
			ELFDBG(("load: strtab index=%d addr=%x\n",
				i, sect_addr[i]));
		}
	}
	m->textsz = (size_t)(m->data - m->text);
	m->datasz = (size_t)((char *)ptokv(bss_base) - m->data);

	load_base = bss_base + m->bsssz;
	load_base = round_page(load_base);

	ELFDBG(("module load_base=%lx text=%lx\n", load_base, m->text));
	m->size = (size_t)(load_base - kvtop(m->text));
	m->entry = (vaddr_t)ptokv(ehdr->e_entry + m->phys);
	ELFDBG(("module size=%x entry=%lx\n", m->size, m->entry));

	/* Process relocation */
	shdr = (Elf32_Shdr *)((paddr_t)ehdr + ehdr->e_shoff);
	for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {
		if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
			if (relocate_section(img, shdr) != 0) {
				DPRINTF(("Relocation error: module=%s\n", m->name));
				return -1;
			}
		}
	}
	return 0;
}