Esempio n. 1
0
// Dispatches to the correct kernel function, passing the arguments.
int64_t
syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
//	panic("syscall not implemented");

	switch (syscallno) {

	case SYS_cputs:
			sys_cputs((const char *)a1, (size_t)a2);
			return 0;
	case SYS_cgetc:
			return sys_cgetc();
        case SYS_getenvid:
			return sys_getenvid();
        case SYS_env_destroy:
			return sys_env_destroy(a1);
	case SYS_yield:
			sys_yield();
			return 0;			
	case SYS_page_alloc:
        		return sys_page_alloc((envid_t)a1, (void *)a2,(int)a3);
	case SYS_page_map:
			return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);        
	case SYS_page_unmap:
			return sys_page_unmap((envid_t)a1, (void *)a2);        
	case SYS_exofork:
			return sys_exofork();        
	case SYS_env_set_status:
			return sys_env_set_status((envid_t)a1, a2);	
	case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall((envid_t)a1,(void *)a2);		
	case SYS_ipc_try_send:
			return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, a4);
	case SYS_ipc_recv:
			return sys_ipc_recv((void *)a1);	
	case SYS_env_set_trapframe:
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
	case SYS_time_msec:
			return sys_time_msec();
	case SYS_packet_transmit:
			return sys_packet_transmit((char*)a1,(size_t)a2);
	case SYS_packet_receive:
                        return sys_packet_receive((char *)a1);
	//lab 7 code from here
	case SYS_insmod:
			return sys_insmod((char *)a1, (char *)a2,(char *)a3);
	case SYS_rmmod:
			return sys_rmmod((char *)a1);
	case SYS_lsmod:
			return sys_lsmod();
	case SYS_depmod:
			return sys_depmod((char *)a1);
	//lab7 code ends here
	default:
		return -E_NO_SYS;
	}
}
Esempio n. 2
0
File: syscall.c Progetto: ichaos/jos
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
        curenv->env_syscalls++;
        switch(syscallno){
        case SYS_cputs:
                sys_cputs((char *)a1, (size_t)a2);break;
        case SYS_cgetc:
                sys_cgetc();break;
        case SYS_getenvid:
                return sys_getenvid();
        case SYS_env_destroy:
                return sys_env_destroy((envid_t)a1);
        case SYS_dump_env:
                sys_dump_env();break;
        case SYS_page_alloc:
                return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
        case SYS_page_map: {
                return sys_page_map((envid_t)a1, (void *)a2,
                                    (envid_t)a3, (void *)a4, (int)a5);
        }
        case SYS_page_unmap:
                return sys_page_unmap((envid_t)a1, (void *)a2);
        case SYS_exofork:
                return sys_exofork();
        case SYS_env_set_status:
                return sys_env_set_status((envid_t)a1,(int)a2);
        case SYS_env_set_trapframe:
                return sys_env_set_trapframe((envid_t)a1,
                                             (struct Trapframe *)a2);
        case SYS_env_set_pgfault_upcall:
                return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
        case SYS_yield:
                sys_yield();break;//new add syscall for lab4;
        case SYS_ipc_try_send:
                return sys_ipc_try_send((envid_t)a1, (uint32_t)a2,
                                        (void *)a3, (unsigned)a4);
        case SYS_ipc_recv:
                return sys_ipc_recv((void *)a1);
        case SYS_ide_read:
                sys_ide_read((uint32_t)a1, (void *)a2, (size_t)a3);
                break;
        case SYS_ide_write:
                sys_ide_write((uint32_t)a1, (void *)a2, (size_t)a3);
                break;
        case SYS_time_msec:
                return sys_time_msec();
        case NSYSCALLS:
                break;
        default:
                return -E_INVAL;
        }
        return 0;

	//panic("syscall not implemented");
}
Esempio n. 3
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

//	panic("syscall not implemented");

	switch (syscallno) {
	case SYS_cputs:
		sys_cputs((char *)a1, a2);
		break;
	case SYS_cgetc:
		return sys_cgetc();
	case SYS_env_destroy:
		return sys_env_destroy(a1);
	case SYS_getenvid:
		return sys_getenvid();
	case SYS_yield:
		sys_yield();
		break;
	case SYS_page_alloc:
		return sys_page_alloc(a1, (void *)a2, a3);
	case SYS_page_map:
		return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5);
	case SYS_page_unmap:
		return sys_page_unmap(a1, (void *)a2);
	case SYS_env_set_status:
		return sys_env_set_status(a1, a2);
	case SYS_exofork:
		return sys_exofork();
	case SYS_env_set_pgfault_upcall:
		return sys_env_set_pgfault_upcall(a1, (void *)a2);
	case SYS_ipc_try_send:
		return sys_ipc_try_send(a1, a2, (void*)a3, a4);
	case SYS_ipc_recv:
		return sys_ipc_recv((void*)a1);
	case SYS_env_set_trapframe:
		return sys_env_set_trapframe(a1, (struct Trapframe *)a2);
	case SYS_time_msec:
		return sys_time_msec();
	case SYS_trans_pkt:
		return sys_trans_pkt((void*)a1, a2);
	case SYS_recv_pkt:
		return sys_recv_pkt((void *)a1, (size_t *)a2);
	default:
		return -E_INVAL;
	}

	return 0;
}
Esempio n. 4
0
// Dispatches to the correct kernel function, passing the arguments.
	int64_t
syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	uint64_t retval = 0;

	switch (syscallno) {
		case SYS_cputs:
			sys_cputs((char *) a1, (size_t) a2);
			return retval;
		case SYS_cgetc:
			return (int64_t) sys_cgetc();
		case SYS_getenvid:
			return (int64_t) sys_getenvid();
		case SYS_env_destroy:
			return (int64_t) sys_env_destroy((envid_t) a1);
		case SYS_yield:
			sys_yield();
			return retval;
		case SYS_exofork:
			return (int64_t)sys_exofork();
		case SYS_page_alloc:
			return (int64_t)sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
		case SYS_page_map:
			return (int64_t)sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);
		case SYS_page_unmap:
			return (int64_t)sys_page_unmap((envid_t)a1, (void *)a2);
		case SYS_env_set_status:
			return (int64_t)sys_env_set_status((envid_t)a1, (int)a2);
		case SYS_env_set_pgfault_upcall:
			return (int64_t)sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
		case SYS_ipc_try_send:
			return (int64_t) sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (unsigned) a4);
		case SYS_ipc_recv:
			return (int64_t)sys_ipc_recv((void*)a1);
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
		case SYS_time_msec:
			return sys_time_msec();
		case SYS_net_try_send:
			return sys_net_try_send((char *) a1, (int) a2);
		case SYS_net_try_receive:
			return sys_net_try_receive((char *) a1, (int *) a2);
		default:
			return -E_INVAL;
	}

	panic("syscall not implemented");
}
Esempio n. 5
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	switch (syscallno){
		case SYS_getenvid:
			return sys_getenvid();
		case SYS_cputs:
			sys_cputs((const char*)a1, a2);
			return 0;
		case SYS_cgetc:
			return sys_cgetc();
		case SYS_env_destroy:
			return sys_env_destroy(a1);
		case SYS_map_kernel_page:
			return sys_map_kernel_page((void*)a1, (void*)a2);
		case SYS_sbrk:
			return sys_sbrk(a1);
		case SYS_yield:
			sys_yield();
			return 0;
		case SYS_exofork:
			return sys_exofork();
		case SYS_env_set_status:
			return sys_env_set_status((envid_t)a1, (int)a2);
		case SYS_page_alloc:
			return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
		case SYS_page_map:
			return sys_page_map((envid_t)*((uint32_t*)a1), (void*)*((uint32_t*)a1+1), 
					(envid_t)*((uint32_t*)a1+2), (void*)*((uint32_t*)a1+3), (int)*((uint32_t*)a1+4));
		case SYS_page_unmap:
			return sys_page_unmap((envid_t)a1, (void*)a2);
		case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2);
		case SYS_ipc_recv:
			return sys_ipc_recv((void*)a1);
		case SYS_ipc_try_send:
			return sys_ipc_try_send((envid_t)a1, a2, (void*)a3, (int)a4);
		case SYS_env_set_priority:
			return sys_env_set_priority((envid_t)a1, (int) a2);
		case SYS_env_set_trapframe: 
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
		default:
			return -E_INVAL;
	}

//	panic("syscall not implemented");
}
Esempio n. 6
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	switch (syscallno) {
		case (SYS_cputs):
			sys_cputs((const char *) a1, a2);
			return 0;
		case (SYS_cgetc):
			return sys_cgetc();
		case (SYS_getenvid):
			return sys_getenvid();
		case (SYS_env_destroy):
			return sys_env_destroy(a1, a2);
		case (SYS_yield):
			sys_yield();
			return 0;
		case (SYS_exofork):
			return sys_exofork();
		case (SYS_env_set_status):
			return sys_env_set_status(a1, a2);
		case (SYS_page_alloc):
			return sys_page_alloc(a1, (void *) a2, a3);
		case (SYS_page_map):
			return sys_page_map(a1, (void *) a2, a3, (void *) a4, a5);
		case (SYS_page_unmap):
			return sys_page_unmap(a1, (void *) a2);
		case (SYS_env_set_pgfault_upcall):
			return sys_env_set_pgfault_upcall(a1, (void *) a2);
		case (SYS_ipc_try_send):
			return sys_ipc_try_send(a1, a2, (void *) a3, a4);
		case (SYS_ipc_recv):
			return sys_ipc_recv((void *) a1);
		case (SYS_env_set_trapframe):
			return sys_env_set_trapframe(a1, (struct Trapframe *) a2);
		case (SYS_time_msec):
			return sys_time_msec();
		case (SYS_e1000_transmit):
			return sys_e1000_transmit(a1, (char *) a2, a3);
	default:
		return -E_INVAL;
	}
}
Esempio n. 7
0
// Dispatches to the correct kernel function, passing the arguments.
uint32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	switch (syscallno){
	
		case SYS_cputs:
			sys_cputs( (const char *)a1, a2);
			return 0;
		case SYS_cgetc:
			return sys_cgetc();
		case SYS_getenvid:
			return sys_getenvid();
		case SYS_env_destroy:
			return sys_env_destroy(a1);		
		case SYS_yield:
			sys_yield();
			return 0;
		case SYS_exofork:
			return sys_exofork();
		case SYS_env_set_status:
			return sys_env_set_status(a1, a2);
		case SYS_page_alloc:	
			return sys_page_alloc(a1, (void *)a2, a3);
		case SYS_page_map:
			return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5);
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe(a1, (struct Trapframe *)a2);		
		case SYS_page_unmap:
			return sys_page_unmap(a1, (void *)a2);
		case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall(a1, (void *)a2);
		case SYS_ipc_try_send:
			return sys_ipc_try_send(a1, a2, (void *)a3, a4);
		case SYS_ipc_recv:
			return sys_ipc_recv((void *)a1);

		default: panic("this syscall ( %d )is not yet implemented", syscallno); 
	}
}
Esempio n. 8
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	// My code: gmenghani
	// An invalid system call
	if(syscallno >= NSYSCALLS)
		return -E_INVAL;

	switch(syscallno) {
		case SYS_cputs: 	sys_cputs((char *) a1, (size_t)a2);
					return 0;
		case SYS_cgetc:		return sys_cgetc();
		case SYS_getenvid:	return sys_getenvid();
		case SYS_env_destroy:	return sys_env_destroy((envid_t)a1);
		case SYS_yield : sys_yield(); break;
		case SYS_exofork : return sys_exofork();
		case SYS_env_set_status : return sys_env_set_status((envid_t)a1, (int)a2);
		case SYS_page_alloc : return sys_page_alloc((envid_t)a1, (void*)a2, (int)a3);
		case SYS_page_map : return sys_page_map((envid_t)a1, (void*)a2, (envid_t)a3, (void*)a5, (int)a4);
		case SYS_page_unmap : return sys_page_unmap((envid_t)a1, (void*)a2);
		// For Challenge problem 1 Lab 4a
		case SYS_env_set_nice:	sys_env_set_nice(a1);
					return 0;
		case SYS_env_set_pgfault_upcall: sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
		                                 return 0;
		case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void*)a3, (unsigned)a5);
		case SYS_ipc_recv: return sys_ipc_recv((void*)a1);
		case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
		case SYS_time_msec: return sys_time_msec();
		case SYS_net_send: return sys_net_send((void*)a1, (uint32_t) a2);
		case SYS_net_recv: return sys_net_recv((void*)a1, (uint16_t*) a2);
	}
	return 0;
}
Esempio n. 9
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	switch(syscallno){
		case SYS_cputs:
			user_mem_assert(curenv, (void *)a1, a2, PTE_U);
			sys_cputs((char *)a1, a2);
			return 0;
			break;
		case SYS_cgetc:
			return sys_cgetc();
			break;
		case SYS_getenvid:
			return sys_getenvid();
			break;
		case SYS_getenv_parent_id:
			return sys_getenv_parent_id(a1);
			break;
		case SYS_env_destroy:
			return sys_env_destroy(a1);
			break;
		case SYS_page_alloc:
			return sys_page_alloc(a1, (void *)a2, a3);
			break;
		case SYS_page_map:
			return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5);
			break;
		case SYS_page_unmap:
			return sys_page_unmap(a1, (void *)a2);
			break;
		case SYS_exofork:
			return sys_exofork();
			break;
		case SYS_env_set_status:
			return sys_env_set_status(a1, a2);
			break;
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe(a1, (struct Trapframe *)a2);
			break;
		case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall(a1, (void *)a2);
			break;
		case SYS_env_get_curdir:
			return sys_env_get_curdir((envid_t)a1, (char *)a2);
			break;
		case SYS_env_set_curdir:
			return sys_env_set_curdir((envid_t)a1, (char *)a2);
			break;
		case SYS_yield:
			sys_yield();
			break;
		case SYS_ipc_try_send:
			return sys_ipc_try_send(a1, a2, (void *)a3, a4);
			break;
		case SYS_ipc_recv:
			return sys_ipc_recv((void *)a1);
			break;
		case SYS_time_msec:
			return sys_time_msec();
			break;
		case SYS_net_send:
			return sys_net_send((void *)a1, a2);
			break;
		case SYS_net_recv:
			return sys_net_recv((void *)a1, a2);
			break;
		case NSYSCALLS:
		default:
			return -E_INVAL;
			break;
	}
	return 0;
}
Esempio n. 10
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	/*stone's solution for lab3-B*/
	int32_t ret = -E_INVAL;
	switch (syscallno){
		case SYS_cputs:
			sys_cputs((char*)a1, a2);
			ret = 0;
			break;
		case SYS_cgetc:
			ret = sys_cgetc();
			break;
		case SYS_getenvid:
			ret = sys_getenvid();
			break;
		case SYS_env_destroy:
			ret = sys_env_destroy(a1);
			break;
		case SYS_map_kernel_page:
			ret = sys_map_kernel_page((void*)a1, (void*)a2);
			break;
		case SYS_sbrk:
			ret = sys_sbrk(a1);
			break;
		/*stone's solution for lab4-A*/
		case SYS_yield:
			sys_yield();
			ret = 0;
			break;
		case SYS_exofork:
			ret = sys_exofork();
			break;
		case SYS_env_set_status:
			ret = sys_env_set_status(a1, a2);
			break;
		case SYS_env_set_pgfault_upcall:
			ret = sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2);
			break;
		case SYS_page_alloc:
			ret = sys_page_alloc((envid_t)a1, (void*)a2, (int)a3);
			break;
		case SYS_page_map:
			/*stone: see lib/syscall.c for modification details*/
			ret = sys_page_map(*((uint32_t*)a1), (void*)*((uint32_t*)a1 + 1), *((uint32_t*)a1 + 2), (void*)*((uint32_t*)a1 + 3), *((uint32_t*)a1 + 4));
			//ret = sys_page_map(a1, (void*)a2, a3, (void*)a4, a5);
			break;
		case SYS_page_unmap:
			ret = sys_page_unmap(a1, (void*)a2);
			break;
		case SYS_ipc_recv:
			ret = sys_ipc_recv((void*)a1);
			break;
		case SYS_ipc_try_send:
			ret = sys_ipc_try_send((envid_t)a1, a2, (void*)a3, (int)a4);
			break;
		case SYS_env_set_trapframe:
			ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
			break;
		default:
			break;
	}
	return ret;
	//panic("syscall not implemented");
}
Esempio n. 11
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	
	// We need to lock the kernel for any calls we know use sysenter
	syscall_cond_lock(syscallno, 1);
	
	int32_t ret = 0;
	switch(syscallno)
	{
		case SYS_cputs:
			sys_cputs((char *)a1, a2);
			break;
		case SYS_cgetc:
			ret = sys_cgetc();
			break;
		case SYS_env_destroy:
			ret = sys_env_destroy(a1);
			break;
		case SYS_env_set_pgfault_upcall:
			ret = sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2);
			break;
		case SYS_getenvid:
			ret = sys_getenvid();
			break;
		case SYS_yield:
			sys_yield();
			break;
		case SYS_exofork:
			ret = sys_exofork();
			break;
		case SYS_env_set_status:
			ret = sys_env_set_status((envid_t)a1, a2);
			break;
		case SYS_page_alloc:
			ret = sys_page_alloc((envid_t)a1, (void*)a2, a3);
			break;
		case SYS_page_map:
			ret = sys_page_map((envid_t)a1, (void*)a2, (envid_t)a3, (void*)a4, a5);
			break;
		case SYS_page_unmap:
			ret = sys_page_unmap((envid_t)a1, (void*)a2);
			break;
		case SYS_ipc_try_send:
			ret = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, 
														 (void*)a3, (unsigned) a4);
			break;
		case SYS_ipc_recv:
			ret = sys_ipc_recv((void*)a1);
			break;
		case SYS_env_set_trapframe:
			ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2);
			break;
		default:
			ret = -E_INVAL;
			break;
	}

	syscall_cond_lock(syscallno, 0);
	return ret;
}
Esempio n. 12
0
// Spawn a child process from a program image loaded from the file system.
// prog: the pathname of the program to run.
// argv: pointer to null-terminated array of pointers to strings,
// 	 which will be passed to the child as its command-line arguments.
// Returns child envid on success, < 0 on failure.
int
spawn(const char *prog, const char **argv)
{
	unsigned char elf_buf[512];
	struct Trapframe child_tf;
	envid_t child;

	int fd, i, r;
	struct Elf *elf;
	struct Proghdr *ph;
	int perm;

	// This code follows this procedure:
	//
	//   - Open the program file.
	//
	//   - Read the ELF header, as you have before, and sanity check its
	//     magic number.  (Check out your load_icode!)
	//
	//   - Use sys_exofork() to create a new environment.
	//
	//   - Set child_tf to an initial struct Trapframe for the child.
	//
	//   - Call the init_stack() function above to set up
	//     the initial stack page for the child environment.
	//
	//   - Map all of the program's segments that are of p_type
	//     ELF_PROG_LOAD into the new environment's address space.
	//     Use the p_flags field in the Proghdr for each segment
	//     to determine how to map the segment:
	//
	//	* If the ELF flags do not include ELF_PROG_FLAG_WRITE,
	//	  then the segment contains text and read-only data.
	//	  Use read_map() to read the contents of this segment,
	//	  and map the pages it returns directly into the child
	//        so that multiple instances of the same program
	//	  will share the same copy of the program text.
	//        Be sure to map the program text read-only in the child.
	//        Read_map is like read but returns a pointer to the data in
	//        *blk rather than copying the data into another buffer.
	//
	//	* If the ELF segment flags DO include ELF_PROG_FLAG_WRITE,
	//	  then the segment contains read/write data and bss.
	//	  As with load_icode() in Lab 3, such an ELF segment
	//	  occupies p_memsz bytes in memory, but only the FIRST
	//	  p_filesz bytes of the segment are actually loaded
	//	  from the executable file - you must clear the rest to zero.
	//        For each page to be mapped for a read/write segment,
	//        allocate a page in the parent temporarily at UTEMP,
	//        read() the appropriate portion of the file into that page
	//	  and/or use memset() to zero non-loaded portions.
	//	  (You can avoid calling memset(), if you like, if
	//	  page_alloc() returns zeroed pages already.)
	//        Then insert the page mapping into the child.
	//        Look at init_stack() for inspiration.
	//        Be sure you understand why you can't use read_map() here.
	//
	//     Note: None of the segment addresses or lengths above
	//     are guaranteed to be page-aligned, so you must deal with
	//     these non-page-aligned values appropriately.
	//     The ELF linker does, however, guarantee that no two segments
	//     will overlap on the same page; and it guarantees that
	//     PGOFF(ph->p_offset) == PGOFF(ph->p_va).
	//
	//   - Call sys_env_set_trapframe(child, &child_tf) to set up the
	//     correct initial eip and esp values in the child.
	//
	//   - Start the child process running with sys_env_set_status().

	if ((r = open(prog, O_RDONLY)) < 0)
		return r;
	fd = r;

	// Read elf header
	elf = (struct Elf*) elf_buf;
	if (readn(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf)
	    || elf->e_magic != ELF_MAGIC) {
		close(fd);
		cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC);
		return -E_NOT_EXEC;
	}

	// Create new child environment
	if ((r = sys_exofork()) < 0)
		return r;
	child = r;

	// Set up trap frame, including initial stack.
	child_tf = envs[ENVX(child)].env_tf;
	child_tf.tf_eip = elf->e_entry;

	if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0)
		return r;

	// Set up program segments as defined in ELF header.
	ph = (struct Proghdr*) (elf_buf + elf->e_phoff);
	for (i = 0; i < elf->e_phnum; i++, ph++) {
		if (ph->p_type != ELF_PROG_LOAD)
			continue;
		perm = PTE_P | PTE_U;
		if (ph->p_flags & ELF_PROG_FLAG_WRITE)
			perm |= PTE_W;
		if ((r = map_segment(child, ph->p_va, ph->p_memsz,
				     fd, ph->p_filesz, ph->p_offset, perm)) < 0)
			goto error;
	}
	close(fd);
	fd = -1;

	// Copy shared library state.
	if ((r = copy_shared_pages(child)) < 0)
		panic("copy_shared_pages: %e", r);

	if ((r = sys_env_set_trapframe(child, &child_tf)) < 0)
		panic("sys_env_set_trapframe: %e", r);

	if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0)
		panic("sys_env_set_status: %e", r);

	return child;

error:
	sys_env_destroy(child);
	close(fd);
	return r;
}
Esempio n. 13
0
File: syscall.c Progetto: gzs715/JOS
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	uint32_t result = -E_INVAL;
	//cprintf("syscallno:%08x\n",syscallno);
	switch(syscallno)
	{
		case SYS_cputs:
			sys_cputs((char *)a1,(size_t)a2);
			result = SYS_cputs;
			break;
		case SYS_getenvid:
			result = sys_getenvid();
			break;
		case SYS_cgetc:
			result = sys_cgetc();
			break;
		case SYS_env_destroy:
			result = sys_env_destroy((envid_t)a1);
			break;
		case SYS_env_set_trapframe:
			result = sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
			break;
		case SYS_yield:
			sys_yield();
			result = SYS_yield;
			break;
		case SYS_exofork:
			result = sys_exofork();
			break;
		case SYS_env_set_status:
			result = sys_env_set_status((envid_t)a1,(int)a2);
			break;
		case SYS_page_alloc:
			result = sys_page_alloc((envid_t)a1,(void *)a2,(int)a3);
			break;
		case SYS_page_map:
			result = sys_page_map((envid_t)a1,(void *)a2,(envid_t)a3,(void *)a4,(int)a5);
			break;
		case SYS_page_unmap:
			result = sys_page_unmap((envid_t)a1,(void *)a2);
			break;	
		case SYS_env_set_pgfault_upcall:
			result = sys_env_set_pgfault_upcall((envid_t)a1,(void*)a2);
			break;	
		case SYS_ipc_recv:
			result = sys_ipc_recv((void*)a1);
			break;
		case SYS_ipc_try_send:
			result = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4);
			break;
		case SYS_for_fork:
			result = sys_for_fork((envid_t)a1, (void *)a2, (int)a3);
			break;
		case SYS_set_shforkid:
			result = sys_set_shforkid((envid_t)a1);
			break;	
			
		default:
			result = -E_INVAL;
	}
	return result;
}
Esempio n. 14
0
File: spawn.c Progetto: gzs715/JOS
// Spawn a child process from a program image loaded from the file system.
// prog: the pathname of the program to run.
// argv: pointer to null-terminated array of pointers to strings,
// 	 which will be passed to the child as its command-line arguments.
// Returns child envid on success, < 0 on failure.
int
spawn(const char *prog, const char **argv)
{
	
	unsigned char elf_buf[512];
	struct Trapframe child_tf;
	envid_t child;

	// Insert your code, following approximately this procedure:
	//
	//   - Open the program file.
	//
	//   - Read the ELF header, as you have before, and sanity check its
	//     magic number.  (Check out your load_icode!)
	//
	//   - Use sys_exofork() to create a new environment.
	//
	//   - Set child_tf to an initial struct Trapframe for the child.
	//     Hint: The sys_exofork() system call has already created
	//     a good basis, in envs[ENVX(child)].env_tf.
	//     Hint: You must do something with the program's entry point.
	//     What?  (See load_icode!)
	//
	//   - Call the init_stack() function above to set up
	//     the initial stack page for the child environment.
	//
	//   - Map all of the program's segments that are of p_type
	//     ELF_PROG_LOAD into the new environment's address space.
	//     Use the p_flags field in the Proghdr for each segment
	//     to determine how to map the segment:
	//
	//	* If the ELF flags do not include ELF_PROG_FLAG_WRITE,
	//	  then the segment contains text and read-only data.
	//	  Use read_map() to read the contents of this segment,
	//	  and map the pages it returns directly into the child
	//        so that multiple instances of the same program
	//	  will share the same copy of the program text.
	//        Be sure to map the program text read-only in the child.
	//        Read_map is like read but returns a pointer to the data in
	//        *blk rather than copying the data into another buffer.
	//
	//	* If the ELF segment flags DO include ELF_PROG_FLAG_WRITE,
	//	  then the segment contains read/write data and bss.
	//	  As with load_icode() in Lab 3, such an ELF segment
	//	  occupies p_memsz bytes in memory, but only the FIRST
	//	  p_filesz bytes of the segment are actually loaded
	//	  from the executable file - you must clear the rest to zero.
	//        For each page to be mapped for a read/write segment,
	//        allocate a page in the parent temporarily at UTEMP,
	//        read() the appropriate portion of the file into that page
	//	  and/or use memset() to zero non-loaded portions.
	//	  (You can avoid calling memset(), if you like, if
	//	  page_alloc() returns zeroed pages already.)
	//        Then insert the page mapping into the child.
	//        Look at init_stack() for inspiration.
	//        Be sure you understand why you can't use read_map() here.
	//
	//     Note: None of the segment addresses or lengths above
	//     are guaranteed to be page-aligned, so you must deal with
	//     these non-page-aligned values appropriately.
	//     The ELF linker does, however, guarantee that no two segments
	//     will overlap on the same page; and it guarantees that
	//     PGOFF(ph->p_offset) == PGOFF(ph->p_va).
	//
	//   - Call sys_env_set_trapframe(child, &child_tf) to set up the
	//     correct initial eip and esp values in the child.
	//
	//   - Start the child process running with sys_env_set_status().

	// LAB 5: Your code here.
	
	
	int fdnum;
	struct Elf *elf;
	char elfbuf[512];
	uintptr_t init_esp;
	int r;
	struct Proghdr *ph, *eph;
	uint32_t pageva,pageoff;
	void *blk;
	uint32_t i;
	uint32_t left;
	uint32_t pteno,pdeno;
	uint32_t pn = 0;
	uintptr_t addr;
	pte_t pte;
	//cprintf("spawn:%s\n",prog);
	
	if((fdnum = open(prog, O_RDWR)) < 0)
		return fdnum;

	read(fdnum, elfbuf, 512);
	elf = (struct Elf *) elfbuf;
	if(elf->e_magic != ELF_MAGIC)
		return -E_NOT_EXEC;
	if((child = sys_exofork()) < 0)
		return child;
	else if(child == 0)
	{
		//cprintf("child\n");
		env = &envs[ENVX(sys_getenvid())];
		return 0;
	}
	child_tf = envs[ENVX(child)].env_tf;
	child_tf.tf_eip = elf->e_entry;
	if((r = init_stack(child, argv, &init_esp)) < 0)
		return r;
	child_tf.tf_esp = init_esp;

	ph = (struct Proghdr *) ((uint8_t*)elf + elf->e_phoff);
	eph = ph + elf->e_phnum;
	for (; ph != eph; ph++)
	{
		if(ph->p_type == ELF_PROG_LOAD)
		{
			pageva = ROUNDDOWN(ph->p_va, PGSIZE);
		        pageoff = ROUNDDOWN(ph->p_offset, PGSIZE);
			if(!(ph->p_flags & ELF_PROG_FLAG_WRITE))
			{
				for(i = 0; i< ph->p_memsz; i += PGSIZE)
				{
					if((r = read_map(fdnum, pageoff + i,&blk)) < 0)
						return r;
					if((r = sys_page_map(0, blk, child, (void *)(pageva + i),PTE_U|PTE_P)) < 0)
						return r;			
				}
			}
			else
			{
				for(i = 0; i < ph->p_memsz; i += PGSIZE)
				{
					sys_page_alloc(0, (void*)UTEMP, PTE_U|PTE_P|PTE_W);	
					if( i < ph->p_filesz)
					{
						
						seek(fdnum, pageoff + i);
						left = ph->p_filesz - i; 

						if(left > PGSIZE)
							read(fdnum, (void *)UTEMP, PGSIZE);
						else
						{
							read(fdnum,(void *)UTEMP, left);
							memset((void*)(UTEMP + left),0x0,PGSIZE - left);
						}
					}
					else
						memset((void*)UTEMP, 0x0,PGSIZE);
					sys_page_map(0, UTEMP, child,(void *)(pageva + i),PTE_U|PTE_W|PTE_P);
					sys_page_unmap(0,UTEMP);
				}
			}
		}

	}
	close(fdnum);
	if((r = sys_env_set_trapframe(child, &child_tf)) < 0)
		return r;

	for(pdeno = PDX(0);pdeno < PDX(UTOP);pdeno++)
	{
		if(!(vpd[pdeno] & (PTE_P)))
			continue;
		else
		{
			for(pteno = 0;pteno < NPTENTRIES;pteno++)
			{
				pn = (pdeno<<10) + pteno;
			
				if((vpt[pn] & PTE_P) && (vpt[pn] & PTE_SHARE))
				{
					//remember not to modify vpt[pn]
					pte = vpt[pn] & PTE_USER;
					addr = (uintptr_t)PGADDR(pdeno, pteno, 0);
					sys_page_map(0,(void*)addr,child,(void*)addr,pte);
				}

			}
		}
	}

	if((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0)
		return r;
	return child;
		

	//panic("spawn unimplemented!");
}
Esempio n. 15
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	switch(syscallno) {
	case SYS_cputs:
		sys_cputs((char *) a1, (size_t) a2);
		break;
	case SYS_cgetc:
		return sys_cgetc();
	case SYS_getenvid:
		return sys_getenvid();
	case SYS_env_destroy:
		return sys_env_destroy((envid_t) a1);
	case SYS_yield:
		sys_yield();
		break;
	case SYS_exofork:
		return sys_exofork();
	case SYS_env_set_status:
		return sys_env_set_status((envid_t) a1, (int) a2);
	case SYS_env_set_trapframe:
		return sys_env_set_trapframe((envid_t) a1, (struct Trapframe *) a2);
	case SYS_page_alloc:
		return sys_page_alloc((envid_t) a1, (void *) a2, (int) a3);
	case SYS_page_map:
		return sys_page_map((envid_t) a1, (void *) a2,
				(envid_t) a3, (void *) a4, (int) a5);
	case SYS_page_unmap:
		return sys_page_unmap((envid_t) a1, (void *) a2);
	case SYS_env_set_pgfault_upcall:
		return sys_env_set_pgfault_upcall((envid_t) a1, (void *) a2);
	case SYS_ipc_try_send:
		return sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (unsigned) a4);
	case SYS_ipc_recv:
		return sys_ipc_recv((void *) a1);
	case SYS_env_swap:
		return sys_env_swap((envid_t) a1);
	case SYS_time_msec:
		return sys_time_msec();
	case SYS_net_try_send:
		return sys_net_try_send((char *) a1, (int) a2);
	case SYS_net_try_receive:
		return sys_net_try_receive((char *) a1, (int *) a2);
	case SYS_get_mac:
		return sys_get_mac((uint32_t *) a1, (uint32_t *) a2);
	case SYS_env_lease:
		return sys_env_lease((struct Env*) a1, (envid_t *) a2);
	case SYS_copy_mem:
		return sys_copy_mem((envid_t) a1, (void *) a2, (void *) a3, 
				    (int) a4, (bool) a5);
	case SYS_get_perms:
		return sys_get_perms((envid_t) a1, (void *) a2, (int *) a3);
	case SYS_env_unsuspend:
		return sys_env_unsuspend((envid_t) a1, (uint32_t) a2, (uint32_t) a3);
	case SYS_env_set_thisenv:
		return sys_env_set_thisenv((envid_t) a1, (void *) a2);
	case SYS_migrate:
		return sys_migrate((void *) a1);
	case SYS_lease_complete:
		return sys_lease_complete();
	default:
		return -E_INVAL;
	}

	return 0; // for syscall that return void
}
Esempio n. 16
0
File: spawn.c Progetto: ichaos/jos
// Spawn a child process from a program image loaded from the file system.
// prog: the pathname of the program to run.
// argv: pointer to null-terminated array of pointers to strings,
// 	 which will be passed to the child as its command-line arguments.
// Returns child envid on success, < 0 on failure.
int
spawn(const char *prog, const char **argv)
{
	unsigned char elf_buf[512];
	struct Trapframe child_tf;
	envid_t child;

	int fd, i, r;
	struct Elf *elf;
	struct Proghdr *ph;
	int perm;

	if ((r = open(prog, O_RDONLY)) < 0)
		return r;
	fd = r;

	// Read elf header
	elf = (struct Elf*) elf_buf;
	if (read(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf)
	    || elf->e_magic != ELF_MAGIC) {
		close(fd);
		cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC);
		return -E_NOT_EXEC;
	}

	// Create new child environment
	if ((r = sys_exofork()) < 0)
		return r;
	child = r;

	// Set up trap frame, including initial stack.
	child_tf = envs[ENVX(child)].env_tf;
	child_tf.tf_eip = elf->e_entry;

	if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0)
		return r;

	// Set up program segments as defined in ELF header.
	ph = (struct Proghdr*) (elf_buf + elf->e_phoff);
	for (i = 0; i < elf->e_phnum; i++, ph++) {
		if (ph->p_type != ELF_PROG_LOAD)
			continue;
		perm = PTE_P | PTE_U;
		if (ph->p_flags & ELF_PROG_FLAG_WRITE)
			perm |= PTE_W;
		if ((r = map_segment(child, ph->p_va,
                                     ph->p_memsz,fd, ph->p_filesz,
                                     ph->p_offset, perm)) < 0)
			goto error;
                //memset((void *)(ph->p_va+ph->p_filesz), 0,
                //(ph->p_memsz-ph->p_filesz));
	}
	close(fd);
	fd = -1;

	if ((r = sys_env_set_trapframe(child, &child_tf)) < 0)
		panic("sys_env_set_trapframe: %e", r);

	if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0)
		panic("sys_env_set_status: %e", r);

	return child;

  error:
	sys_env_destroy(child);
	close(fd);
	return r;
}
Esempio n. 17
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	switch (syscallno) {
		case SYS_cputs :
			sys_cputs((const char*) a1, (size_t) a2);
			return 0;
		case SYS_env_set_trapframe:
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*) a2);
		case SYS_cgetc :
			return sys_cgetc();
		case SYS_getenvid:
			return sys_getenvid();
		case SYS_env_destroy:
			return sys_env_destroy((envid_t) a1);
		case SYS_yield:
			sys_yield();
			return 0;
 		case SYS_exofork:
                	return sys_exofork();
		case SYS_env_set_status:
		        return sys_env_set_status((envid_t)a1,(int)a2);
		case SYS_page_alloc:
		        return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
		case SYS_page_map:
		        return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);
		case SYS_page_unmap:
                	return sys_page_unmap((envid_t)a1, (void *)a2);
		case SYS_env_set_pgfault_upcall:
                	return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
		case SYS_ipc_try_send:
			//cprintf("Sending ipc..\n\n\n");
                	return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4);
        	case SYS_ipc_recv:
                	return sys_ipc_recv((void *)a1);
        	case SYS_clear_block_access_bit:
        		return sys_clear_block_access_bit((envid_t)a1, (void*) a2);
        	case SYS_time_msec:
        		return sys_time_msec();
		case SYS_send_packet:
			return sys_send_packet((void *)a1, (unsigned)a2);
		case SYS_receive_packet:
			return sys_receive_packet((void *)a1);
		case SYS_get_mac_address:
			return sys_get_mac_address((uint8_t *) a1);
		case SYS_get_logged_user_name:
			return sys_get_logged_user_name((char *)a1);
		case SYS_get_current_path:
			return sys_get_current_path((char *)a1);
		case SYS_update_current_path:
			return sys_update_current_path((char *)a1);
		case SYS_get_home_dir:
			return sys_get_home_dir((char *)a1);
		default:
			return -E_INVAL;
	}
		
	
	//panic("syscall not implemented");
}
Esempio n. 18
0
// Dispatches to the correct kernel function, passing the arguments.
int64_t
syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	int64_t returnVal = -E_INVAL;

	if(syscallno == SYS_cputs){
		sys_cputs((char *)a1,(size_t)a2);
		returnVal = 0;
	}
	if(syscallno == SYS_cgetc){
		returnVal = (uint64_t)sys_cgetc();
	}
	if(syscallno == SYS_getenvid){
		returnVal = (uint64_t)sys_getenvid();
	}
	if(syscallno == SYS_env_destroy){
		returnVal = (uint64_t)sys_env_destroy((envid_t)a1);
	}
	if(syscallno == SYS_yield){
		sys_yield();
		returnVal = 0;
	} 
	if(syscallno == SYS_exofork){
		returnVal = (uint64_t)sys_exofork();
	}
	if(syscallno == SYS_env_set_status){
		returnVal = (uint64_t)sys_env_set_status((envid_t)a1,(uint64_t)a2);
	}
	if(syscallno == SYS_page_alloc){
		returnVal = (uint64_t)sys_page_alloc((envid_t)a1,(uint64_t *)a2,(int)a3);
	}
	if(syscallno == SYS_page_map){
		returnVal = (uint64_t)sys_page_map((envid_t)a1,(uint64_t *)a2,(envid_t)a3,(uint64_t *)a4,(int)a5);
	}
	if(syscallno == SYS_page_unmap){
		returnVal = (uint64_t)sys_page_unmap((envid_t)a1,(uint64_t *)a2);
	}
	if(syscallno == SYS_env_set_pgfault_upcall){
		returnVal = (uint64_t)sys_env_set_pgfault_upcall((envid_t)a1,(void *)a2);
	}
	if(syscallno == SYS_ipc_try_send){
		returnVal = (uint64_t)sys_ipc_try_send((envid_t)a1,(uint32_t)a2,(void *)a3,(unsigned)a4);
	}
	if(syscallno == SYS_ipc_recv){
		returnVal = (uint64_t)sys_ipc_recv((void *)a1);
	}
	if(syscallno == SYS_env_set_trapframe){
		returnVal = (uint64_t)sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
	}
	if(syscallno == SYS_env_set_transaction){
		returnVal = (uint64_t)sys_set_transaction((envid_t)a1,(void *)a2);
	}
	if(syscallno == SYS_init_journ){
		returnVal = (uint64_t)sys_init_journ();
	}
	return returnVal;

}
Esempio n. 19
0
// Spawn a child process from a program image.
// In Lab 4, the image is loaded from the kernel.
// In Lab 5, you will allow images to be loaded from the file system.
// prog: the name of the program to run.
// argv: pointer to null-terminated array of pointers to strings,
// 	 which will be passed to the child as its command-line arguments.
// Returns child envid on success, < 0 on failure.
envid_t
spawn(const char* progname, const char** argv)
{
	uint8_t elf_header_buf[512];
	ssize_t elf_size;
	struct Trapframe child_tf; 	/* Hint!! */

	// Insert your code, following approximately this procedure:
	//
	//   - Look up the program using sys_program_lookup.
	//     Return an error code if no such program exists.
	//
	envid_t child, envid;
	int pid, err;
	pid = sys_program_lookup(progname,sizeof(progname)); 
	if(pid < 0)
		return pid;
	//   - Set 'elf_size' to the program's ELF binary size using
	//     sys_program_size.
	//
	elf_size = sys_program_size(pid);
	//   - Map the program's first page at UTEMP using the map_page helper.
	//
	envid = sys_getenvid();
	map_page(envid, pid, 0, (void *)UTEMP, PTE_U|PTE_P);

	//   - Copy the 512-byte ELF header from UTEMP into elf_header_buf.
	//
	memcpy(elf_header_buf, (void *)UTEMP, 512);
	//   - Read the ELF header, as you have before, and sanity check its
	//     magic number.  (Check out your load_elf for hints!)
	//
	struct Elf *elfbin = (struct Elf *)elf_header_buf;
    if (elfbin->e_magic != ELF_MAGIC)
    	return -E_INVAL;
	//   - Use sys_exofork() to create a new environment.
	//
	child = sys_exofork();
	if (child < 0)
		panic("sys_exofork: %e", child);
	if (child == 0) {
		return 0;
	}

	//   - Set child_tf to an initial struct Trapframe for the child.
	//     Hint: The sys_exofork() system call has already created
	//     a good starting point.  It is accessible at
	//     envs[ENVX(child)].env_tf.
	//     Hint: You must do something with the program's entry point.
	//     What?  (See load_elf!)
	//
	child_tf = envs[ENVX(child)].env_tf;
	//child_tf.tf_regs = envs[ENVX(child)].env_tf.tf_regs;
	child_tf.tf_eip = elfbin->e_entry;
	//sys_env_set_trapframe(child, &child_tf);
	
	//   - Call the init_stack() function to set up the initial stack
	//     page for the child environment.
	//
	if((err = init_stack(child,argv,&(child_tf.tf_esp))) < 0){
	sys_env_destroy(child);
	return err;
	}
	//   - Map all of the program's segments that are of p_type
	//     ELF_PROG_LOAD into the new environment's address space.
	//     Use the load_segment() helper function below.
	//     All the 'struct Proghdr' structures will be accessible
	//     within the first 512 bytes of the ELF.
	//
	// load each program segment (ignores ph flags)
	struct Proghdr *ph, *eph;
    ph = (struct Proghdr *) ((uint8_t *) elfbin + elfbin->e_phoff);
	eph = ph + elfbin->e_phnum;
	for(; ph < eph; ph++){
		if(ph->p_type != ELF_PROG_LOAD){
			continue;
		}
		assert(ph->p_filesz <= ph->p_memsz);
		load_segment(child, pid, ph, elfbin, elf_size);
	}
	//   - Call sys_env_set_trapframe(child, &child_tf) to set up the
	//     correct initial eip and esp values in the child.
	//
	if((err = sys_env_set_trapframe(child, &child_tf)) < 0){
		sys_env_destroy(child);
		return err;
	}
	//   - Start the child process running with sys_env_set_status().
	///
	if((err = sys_env_set_status(child,ENV_RUNNABLE)) < 0){
		sys_env_destroy(child);
		return err;
	}
	//panic("spawn unimplemented!");
	return 0;
}
Esempio n. 20
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

	int32_t ret = 0;

	switch (syscallno) {
	case SYS_cputs:
		sys_cputs((char *)a1, (size_t)a2);
		break;
	case SYS_cgetc:
		ret = sys_cgetc();
		break;
	case SYS_getenvid:
		ret = sys_getenvid();
		break;
	case SYS_env_destroy:
		ret = sys_env_destroy((envid_t)a1);
		break;
	case SYS_yield:
		sys_yield();
		break;
	case SYS_exofork:
		ret = sys_exofork();
		break;
	case SYS_env_set_status:
		ret = sys_env_set_status((envid_t)a1, a2);
		break;
	case SYS_page_alloc:
		ret = sys_page_alloc((envid_t)a1, (void *)a2, a3);
		break;
	case SYS_page_map:
		ret = sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, a5);
		break;
	case SYS_page_unmap:
		ret = sys_page_unmap((envid_t)a1, (void *)a2);
		break;
	case SYS_env_set_pgfault_upcall:
		ret = sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
		break;
	case SYS_ipc_recv:
		ret = sys_ipc_recv((void *)a1);
		break;
	case SYS_ipc_try_send:
		ret = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4);
		break;
	case SYS_env_set_trapframe:
		ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
		break;
	case SYS_time_msec:
		ret = sys_time_msec();
		break;
	case SYS_transmit_packet:
		ret = sys_transmit_packet((void *)a1, a2);
		break;
	case SYS_receive_packet:
		ret = sys_receive_packet((void *)a1);
		break;
	default:
		return -E_INVAL;
	}

	return ret;
}
Esempio n. 21
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.

  int32_t ret=0;
  /* if(syscallno==SYS_cputs||syscallno==SYS_getenvid||syscallno==SYS_env_destroy||syscallno==SYS_cgetc)
{
         if(syscallno==SYS_cputs)
               sys_cputs((char *)a1,a2);

                  if(syscallno==SYS_getenvid)
                        return sys_getenvid();

                  if(syscallno==SYS_env_destroy)
                        return sys_env_destroy(a1);

               if(syscallno==SYS_cgetc)
                     return sys_cgetc();
   return ret;
}*/
//cprintf("\nNO----%d\n",syscallno);
 switch (syscallno) {  
     case SYS_cputs:  
         sys_cputs((const char *)a1, (size_t)a2);  
         break;  
     case SYS_cgetc:  
         ret = sys_cgetc();  
         break;  
     case SYS_getenvid:  
         ret = sys_getenvid();  
         break;  
     case SYS_env_destroy:  
         ret = sys_env_destroy((envid_t)a1);  
         break;
    case SYS_yield:
           sys_yield();
       break;
    case SYS_exofork:
        ret=sys_exofork();
       break;
    case SYS_env_set_status:
         ret = sys_env_set_status(a1,a2);
        break;
    case SYS_page_alloc:
         ret = sys_page_alloc(a1,(void *)a2,a3);
        break;
    case SYS_page_map:
         ret = sys_page_map(a1,(void *)a2,a3,(void *)a4,a5);
        break;
    case SYS_page_unmap:
         ret = sys_page_unmap(a1,(void *)a2);
        break;
    case SYS_env_set_pgfault_upcall:
         ret = sys_env_set_pgfault_upcall(a1,(void *)a2);
    case SYS_ipc_try_send:
          ret=sys_ipc_try_send(a1,a2,(void *)a3,a4);
          break;
    case SYS_ipc_recv:
          ret=sys_ipc_recv((void *)a1);
           break;
   case SYS_env_set_trapframe:
         ret=sys_env_set_trapframe(a1,(struct Trapframe *)a2);
    break;
   case SYS_time_msec:
         ret=sys_time_msec();
    break;
   case SYS_call_packet_send:
         ret=sys_call_packet_send((void *)a1,a2);
   break;
   case SYS_call_receive_packet:
         ret=sys_call_receive_packet((void *)a1,(void *)a2);
       break;
     default:  
         // NSYSCALLS  
         ret = -E_INVAL;  
         break;  
    }
  return ret;
}
Esempio n. 22
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	switch (syscallno) {
	case SYS_cputs:
		sys_cputs((char *)a1, a2);
		return 0;	/* Sys_cputs is of no interest in return-value */

	case SYS_cgetc:
		return sys_cgetc();

	case SYS_reboot:
		sys_reboot();
		return 0;

	case SYS_env_destroy:
		return sys_env_destroy(a1);

	case SYS_getenvid:
		return sys_getenvid();

	case SYS_yield:
		sys_yield();	/* Never return */

	case SYS_page_alloc:
		return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);

	case SYS_page_map:
		return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);

	case SYS_page_unmap:
		return sys_page_unmap((envid_t)a1, (void *)a2);

	case SYS_exofork:
		return sys_exofork();

	case SYS_env_set_status:
		return sys_env_set_status((envid_t)a1, (int)a2);

	case SYS_env_set_trapframe:
		return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);

	case SYS_env_set_pgfault_upcall:
		return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);

	case SYS_ipc_try_send:
		return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4);

	case SYS_ipc_recv:
		return sys_ipc_recv((void *)a1); /* Never return */

	case SYS_time_msec:
		return sys_time_msec();

	case SYS_nic_send:
		return sys_nic_send((char *)a1, (int)a2);

	case SYS_nic_recv:
		return sys_nic_recv((char *)a1, (int *)a2);

	default:
		panic("Unknown system call!");
	}
}