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; }
/* * 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; }
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; }
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; } }
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; }