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_section(struct buf ** region, file_t * file, uintptr_t rbase, struct elf32_phdr * phdr) { vnode_t * vn = file->vnode; int prot; struct buf * sect; if (phdr->p_memsz < phdr->p_filesz) return -ENOEXEC; prot = elf32_trans_prot(phdr->p_flags); sect = vm_newsect(phdr->p_vaddr + rbase, phdr->p_memsz, prot); if (!sect) return -ENOMEM; if (phdr->p_filesz > 0) { int err; void * ldp; struct uio uio; if (vn->vnode_ops->lseek(file, phdr->p_offset, SEEK_SET) < 0) return -ENOEXEC; ldp = (void *)(sect->b_data + (phdr->p_vaddr - sect->b_mmu.vaddr)); uio_init_kbuf(&uio, ldp, phdr->p_filesz); err = vn->vnode_ops->read(file, &uio, phdr->p_filesz); if (err < 0) { if (sect->vm_ops->rfree) sect->vm_ops->rfree(sect); return -ENOEXEC; } } *region = sect; return 0; }