Ejemplo n.º 1
0
/* get kernel elf map */
static int get_kernel_map(unsigned int *base, unsigned int *limit)
{
    struct boot_params bp;
    get_boot_params(&bp);
    Elf32_Ehdr *elf_header = (Elf32_Ehdr *)(bp.kernel_addr);

    return get_elf_map(bp.kernel_addr, elf_header, base, limit);
}
Ejemplo n.º 2
0
static void __create_task_mm(task_t *task, int num, init_server_t *srv)
{
  struct bin_map *emap = get_elf_map(task,srv);
  per_task_data_t *ptd;
  vmm_t *vmm = task->task_mm;
  ulong_t entry = get_elf_entry(task,srv);
  struct bin_map *cur = emap;
  ulong_t sseek = 0, psize;
  void *sbss;
  int r, flags, kflags;
  int *argc;
  uintptr_t ustack_top;
  uintptr_t *argv, *envp;
  char *arg1, *envp1;

  if(!emap)
    panic("[Service start] Cannot load ELF map of module %d\n", num);

  /* map image sections */
  while(cur) {
    /* check for override */
    if(cur->prev && (cur->virt_addr <
                     PAGE_ALIGN(cur->prev->virt_addr + cur->prev->size))) {
      sseek = PAGE_ALIGN(cur->virt_addr) - cur->virt_addr;
      cur->bin_addr += sseek;
      cur->virt_addr = PAGE_ALIGN(cur->virt_addr);
      cur->size -= sseek;

      /* if it's NO_BITS section it should be zeroed */
      if(cur->type == SHT_NOBITS) {
        sbss = user_to_kernel_vaddr(task_get_rpd(task), PAGE_ALIGN_DOWN(cur->virt_addr -
                                                                        sseek));
        memset((sbss + PAGE_SIZE) - sseek, 0, sseek);
      }
    }

    /* create vm range for this region */
    flags = VMR_PRIVATE | VMR_FIXED;
    kflags = 0;
    if(cur->flags & ESH_EXEC) {
      flags |= VMR_EXEC;
      kflags |= KMAP_EXEC;
    }

    flags |= VMR_READ;
    kflags |= KMAP_READ;

    if(cur->flags & ESH_WRITE) {
      flags |= VMR_WRITE;
      kflags |= KMAP_WRITE;
    }
    if((cur->type == SHT_NOBITS) ||
       (cur->flags & ESH_WRITE)) flags |= VMR_POPULATE;

    psize = (cur->size + (cur->virt_addr - PAGE_ALIGN_DOWN(cur->virt_addr)))
      >> PAGE_WIDTH;
    if(psize<<PAGE_WIDTH < (cur->size + (cur->virt_addr -
                                         PAGE_ALIGN_DOWN(cur->virt_addr)))) psize++;

#if 0
    kprintf("Mapping vmrange %p - %p\n", PAGE_ALIGN_DOWN(cur->virt_addr),
            PAGE_ALIGN_DOWN(cur->virt_addr) + (psize << PAGE_WIDTH));
#endif
    r = vmrange_map(generic_memobj, vmm, PAGE_ALIGN_DOWN(cur->virt_addr), psize,
                    flags, 0);
    if(!PAGE_ALIGN(r))
      panic("Server [#%d]: Failed to create VM range for section. (ERR = %d)", num, r);

    if(cur->type == SHT_PROGBITS) {
      if(cur->flags & ESH_WRITE) {
#if 0
        kprintf("Copying to %p kaddr (%p uaddr) from %p baddr(%p kaddr) (%ld size)\n",
                user_to_kernel_vaddr(task_get_rpd(task), PAGE_ALIGN_DOWN(cur->virt_addr)),
                PAGE_ALIGN_DOWN(cur->virt_addr), PAGE_ALIGN_DOWN(cur->bin_addr),
                pframe_id_to_virt((PAGE_ALIGN_DOWN(cur->bin_addr))>>PAGE_WIDTH), psize << PAGE_WIDTH);
#endif
        memcpy((void *)user_to_kernel_vaddr(task_get_rpd(task),
                                            PAGE_ALIGN_DOWN(cur->virt_addr)),
               (const void *)pframe_id_to_virt((PAGE_ALIGN_DOWN(cur->bin_addr))>>PAGE_WIDTH),
               psize << PAGE_WIDTH);
        r = 0;
      } else {
#if 0
        kprintf("Mapping range %p - %p (%p - %p)\n", PAGE_ALIGN_DOWN(cur->bin_addr),
                PAGE_ALIGN_DOWN(cur->bin_addr) + (psize << PAGE_WIDTH),
                PAGE_ALIGN_DOWN(cur->bin_addr - srv->addr),
                PAGE_ALIGN_DOWN(cur->bin_addr - srv->addr) + (psize << PAGE_WIDTH));
#endif
        r = mmap_core(vmm, PAGE_ALIGN_DOWN(cur->virt_addr),
                      PAGE_ALIGN_DOWN(cur->bin_addr) >> PAGE_WIDTH, psize, kflags);
      }
      if(r)
        panic("Server [#%d]: Failed to map section. (ERR = %d)", num, r);
    }