struct buf * geteblk_special(size_t size, uint32_t control) { struct proc_info * proc = proc_ref(0); const uintptr_t kvaddr = get_ksect_addr(size); struct buf * buf; int err; KASSERT(proc, "Can't get the PCB of pid 0"); proc_unref(proc); if (kvaddr == 0) { KERROR_DBG("Returned kvaddr is NULL\n"); return NULL; } buf = vm_newsect(kvaddr, size, VM_PROT_READ | VM_PROT_WRITE); if (!buf) { KERROR_DBG("vm_newsect() failed\n"); return NULL; } buf->b_mmu.control = control; err = vm_insert_region(proc, buf, VM_INSOP_MAP_REG); if (err < 0) { panic("Mapping a kernel special buffer failed"); } buf->b_data = buf->b_mmu.vaddr; /* Should be same as kvaddr */ return buf; }
static int load_sections(struct proc_info * proc, file_t * file, struct elf32_header * elfhdr, struct elf32_phdr * phdr, uintptr_t rbase, uintptr_t * vaddr_base) { int e_type = elfhdr->e_type; size_t phnum = elfhdr->e_phnum; for (size_t i = 0; i < phnum; i++) { struct buf * sect; int err; if (!(phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0)) continue; if ((err = load_section(§, file, rbase, &phdr[i]))) return err; if (e_type == ET_EXEC && i < 2) { const int reg_nr = (i == 0) ? MM_CODE_REGION : MM_HEAP_REGION; if (i == 0) *vaddr_base = phdr[i].p_vaddr + rbase; err = vm_replace_region(proc, sect, reg_nr, VM_INSOP_MAP_REG); if (err) { KERROR(KERROR_ERR, "Failed to replace a region\n"); return err; } } else { err = vm_insert_region(proc, sect, VM_INSOP_MAP_REG); if (err < 0) { KERROR(KERROR_ERR, "Failed to insert a region\n"); return -1; } } } return 0; }