示例#1
0
文件: read.c 项目: billxinli/cs350
int sys_read(int *retval, int fdn, void *buf, size_t nbytes) {
    //Check for Bad memory reference.
    if (!buf || (u_int32_t) buf >= MIPS_KSEG0 || !as_valid_write_addr(curthread->t_vmspace,buf)) {
        return EFAULT;
    }
    //Get the file descriptor from the opened list of file descriptors that the current thread has, based on the fdn given.
    struct filedescriptor* fd = ft_get(curthread->ft, fdn);
    if (fd == NULL) {
        return EBADF;
    }
    //Make sure that the file is opened for writing.
    switch (O_ACCMODE & fd->mode) {
        case O_RDONLY:
        case O_RDWR:
            break;
        default:
            return EBADF;
    }
    //Make the uio
    struct uio u;
    mk_kuio(&u, (void *) buf, nbytes, fd->offset, UIO_READ);
    //Disable interrupt
    //int spl;
    //spl = splhigh();
    //Read
    int sizeread = VOP_READ(fd->fdvnode, &u);
    //splx(spl);
    if (sizeread) {
        return sizeread;
    }
    //Find the number of bytes read
    sizeread = nbytes - u.uio_resid;
    *retval = sizeread;
    //Update the offset
    fd->offset += sizeread;
    return 0;
}
示例#2
0
int
swap_pagein( u_int32_t paddr, int rw, u_int32_t mem, u_int32_t file, u_int32_t offset, int swap, int swap_index)
{
	int result;
	int fillamt;
	struct uio u;
	struct addrspace *as;
//	struct vnode *swap_vnode;

	as = curthread->t_vmspace;

	if(swap == 1)
	{
		result = vfs_open(SWAP_DEVICE, O_RDWR, &swap_vnode);
		mk_kuio(&u, paddr, PAGE_SIZE, swap_index * PAGE_SIZE, UIO_READ);
		result = VOP_READ(swap_vnode, &u);

		if (result) {
			return result;
		}

		vfs_close(swap_vnode);
	}
	else 
	{
		/* Open the file. */
		struct vnode *v;
		result = vfs_open(as->as_progname, O_RDONLY, &v);
		if (result) {
			return result;
		}

		mk_kuio_pd(&u, paddr, mem, file, offset, rw);
		if(rw == UIO_READ)
		{
			result = VOP_READ(v, &u)	;
		}
		else
		{
			result = VOP_WRITE(v, &u);
		}

		if (u.uio_resid != 0) {
			/* short read; problem with executable? */
			kprintf("ELF: short read on segment - file truncated?\n");
			return ENOEXEC;
		}

		/* Fill the rest of the memory space (if any) with zeros */
		fillamt = mem - file;
		if (fillamt > 0) {

			u.uio_resid += fillamt;
			u.uio_rw = UIO_READ;
			result = uiomovezeros(fillamt, &u);
		}
				
		if (result==EIO) {
			panic("swap: EIO on swapfile (offset %ld)\n",
			      (long)as->as_offset1);
		}
		else if (result==EINVAL) {
			panic("swap: EINVAL from swapfile (offset %ld)\n",
			      (long)as->as_offset1);
		}
		else if (result) {
			panic("swap: Error %d from swapfile (offset %ld)\n",
			      result, (long)as->as_offset1);
		}

		/* Done with the file now. */
		vfs_close(v);

		return 0;
	
	}




}
示例#3
0
文件: loadelf.c 项目: gmumar/os161
/*
 * Load an ELF executable user program into the current address space.
 *
 * Returns the entry point (initial PC) for the program in ENTRYPOINT.
 */
int
load_elf(struct vnode *v, vaddr_t *entrypoint)
{
	Elf_Ehdr eh;   /* Executable header */
	Elf_Phdr ph;   /* "Program header" = segment header */
	int result, i;
	struct uio ku;

	/*
	 * Read the executable header from offset 0 in the file.
	 */

	mk_kuio(&ku, &eh, sizeof(eh), 0, UIO_READ);
	result = VOP_READ(v, &ku);
	if (result) {
		return result;
	}

	if (ku.uio_resid != 0) {
		/* short read; problem with executable? */
		kprintf("ELF: short read on header - file truncated?\n");
		return ENOEXEC;
	}

	/*
	 * Check to make sure it's a 32-bit ELF-version-1 executable
	 * for our processor type. If it's not, we can't run it.
	 *
	 * Ignore EI_OSABI and EI_ABIVERSION - properly, we should
	 * define our own, but that would require tinkering with the
	 * linker to have it emit our magic numbers instead of the
	 * default ones. (If the linker even supports these fields,
	 * which were not in the original elf spec.)
	 */

	if (eh.e_ident[EI_MAG0] != ELFMAG0 ||
	    eh.e_ident[EI_MAG1] != ELFMAG1 ||
	    eh.e_ident[EI_MAG2] != ELFMAG2 ||
	    eh.e_ident[EI_MAG3] != ELFMAG3 ||
	    eh.e_ident[EI_CLASS] != ELFCLASS32 ||
	    eh.e_ident[EI_DATA] != ELFDATA2MSB ||
	    eh.e_ident[EI_VERSION] != EV_CURRENT ||
	    eh.e_version != EV_CURRENT ||
	    eh.e_type!=ET_EXEC ||
	    eh.e_machine!=EM_MACHINE) {
		return ENOEXEC;
	}

	/*
	 * Go through the list of segments and set up the address space.
	 *
	 * Ordinarily there will be one code segment, one read-only
	 * data segment, and one data/bss segment, but there might
	 * conceivably be more. You don't need to support such files
	 * if it's unduly awkward to do so.
	 *
	 * Note that the expression eh.e_phoff + i*eh.e_phentsize is 
	 * mandated by the ELF standard - we use sizeof(ph) to load,
	 * because that's the structure we know, but the file on disk
	 * might have a larger structure, so we must use e_phentsize
	 * to find where the phdr starts.
	 */

	for (i=0; i<eh.e_phnum; i++) {
		off_t offset = eh.e_phoff + i*eh.e_phentsize;
		mk_kuio(&ku, &ph, sizeof(ph), offset, UIO_READ);

		result = VOP_READ(v, &ku);
		if (result) {
			return result;
		}

		if (ku.uio_resid != 0) {
			/* short read; problem with executable? */
			kprintf("ELF: short read on phdr - file truncated?\n");
			return ENOEXEC;
		}

		switch (ph.p_type) {
		    case PT_NULL: /* skip */ continue;
		    case PT_PHDR: /* skip */ continue;
		    case PT_MIPS_REGINFO: /* skip */ continue;
		    case PT_LOAD: break;
		    default:
			kprintf("loadelf: unknown segment type %d\n", 
				ph.p_type);
			return ENOEXEC;
		}
		//ph coming from compiler from the elf file loaded
		result = as_define_region(curthread->t_vmspace,
					  ph.p_vaddr, ph.p_filesz,
					  ph.p_flags & PF_R,
					  ph.p_flags & PF_W,
					  ph.p_flags & PF_X,
					  v,
					  ph.p_offset,
					  ph.p_memsz);
		if (result) {
			return result;
		}
	}

	result = as_prepare_load(curthread->t_vmspace);//Does getpages
	if (result) {
		return result;
	}

	/*
	 * Now actually load each segment.
	 */

	/*for (i=0; i<eh.e_phnum; i++) {
		off_t offset = eh.e_phoff + i*eh.e_phentsize;
		mk_kuio(&ku, &ph, sizeof(ph), offset, UIO_READ);

		result = VOP_READ(v, &ku);
		if (result) {
			return result;
		}

		if (ku.uio_resid != 0) {
			//short read; problem with executable?
			kprintf("ELF: short read on phdr - file truncated?\n");
			return ENOEXEC;
		}

		switch (ph.p_type) {
		    case PT_NULL:  continue;
		    case PT_PHDR:  continue;
		    case PT_MIPS_REGINFO:  continue;
		    case PT_LOAD: break;
		    default:
			kprintf("loadelf: unknown segment type %d\n", 
				ph.p_type);
			return ENOEXEC;
		}

		result = load_segment(v, ph.p_offset, ph.p_vaddr, 
				      ph.p_memsz, ph.p_filesz,
				      ph.p_flags & PF_X);
		if (result) {
			return result;
		}
	}*/

	result = as_complete_load(curthread->t_vmspace);
	if (result) {
		return result;
	}

	*entrypoint = eh.e_entry;

	return 0;
}
示例#4
0
int sys_write(int fd, const void *buf, size_t nbytes, int32_t *retval)
{
    if (fd < 0) {
        *retval = EBADF;
        return -1;
    }
    if (fd >= MAX_OPENED_FILES) {
        *retval = EBADF;
        //kprintf("invalid fd!\n");
        return  -1;
    }

    if (buf <= 0x0 || buf + nbytes <= 0x0 || buf >= 0x80000000|| buf + nbytes >= 0x80000000 || buf == 0x40000000 || buf + nbytes == 0x40000000) {
        *retval = EFAULT;
        return -1;
    }


    int result =0;
    if (fd < 3 && ((curthread->files[fd] == NULL))) {
        struct vnode *vn =NULL;
        pid_t notUsed = 0;
        char *consolein = NULL;
        consolein = kstrdup("con:");
        vn = kmalloc (sizeof(struct vnode));
        result = vfs_open(consolein,O_RDONLY,&vn);
        if (result){
            *retval = (int32_t)notUsed;
            return -1;
        }
        curthread->files[0] = files_create(kstrdup("con:"),vn, O_RDONLY);
        curthread->files[1] = files_create(kstrdup("con:"),vn, O_WRONLY);
        curthread->files[2] = files_create(kstrdup("con:"),vn, O_WRONLY);
        kfree(consolein);
    }

    struct uio copyUIO;

    switch (fd) {
        case 0:
            *retval = EBADF;
            return -1;
        case 1:
        case 2:
            {
                int i;
                for (i = 0; i < nbytes; i++) {
                    putch(((char*)buf)[i]);
                }
            }
            break;
        default:
            {
                struct files *file = curthread->files[fd];
                if (file == NULL) {
                    *retval = EBADF;
                    return -1;
                }

                //                void* klebuf = kmalloc (sizeof(nbytes));
                //                copyin (buf, klebuf, nbytes);
                mk_kuio(&copyUIO, (void*)buf, nbytes, file->offset, UIO_WRITE);
                result = VOP_WRITE (file->vn, &copyUIO);
                if (result) {
                    return result;
                }
                //kfree(klebuf);
                /*

                   mk_kuio(&copyUIO, buf, nbytes, file->offset, UIO_WRITE);
                   result = VOP_WRITE (file->vn, &copyUIO);
                   if (result == 0) {
                // check if VOP_WRITE done
                }else{
                }
                */
                *retval = nbytes - copyUIO.uio_resid;
                file->offset += *retval;
            }
    }
    return 0;
}