Example #1
0
void
input(envid_t ns_envid)
{
	binaryname = "ns_input";

	// LAB 6: Your code here:
	// 	- read a packet from the device driver
	//	- send it to the network server
	// Hint: When you IPC a page to the network server, it will be
	// reading from it for a while, so don't immediately receive
	// another packet in to the same physical page.
	int i, r;
	int32_t length;
	struct jif_pkt *cpkt = pkt;
	
	for(i = 0; i < 10; i++)
		if ((r = sys_page_alloc(0, (void*)((uintptr_t)pkt + i * PGSIZE), PTE_P | PTE_U | PTE_W)) < 0)
			panic("sys_page_alloc: %e", r);
	
	i = 0;
	while(1) {
		while((length = sys_netpacket_recv((void*)((uintptr_t)cpkt + sizeof(cpkt->jp_len)), PGSIZE - sizeof(cpkt->jp_len))) < 0) {
			// cprintf("len: %d\n", length);
			sys_yield();
		}

		cpkt->jp_len = length;
		ipc_send(ns_envid, NSREQ_INPUT, cpkt, PTE_P | PTE_U);
		i = (i + 1) % 10;
		cpkt = (struct jif_pkt*)((uintptr_t)pkt + i * PGSIZE);
		sys_yield();
	}	
}
Example #2
0
static void
announce(void)
{
	// We need to pre-announce our IP so we don't have to deal
	// with ARP requests.  Ideally, we would use gratuitous ARP
	// for this, but QEMU's ARP implementation is dumb and only
	// listens for very specific ARP requests, such as requests
	// for the gateway IP.

	uint8_t mac[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
	uint32_t myip = inet_addr(IP);
	uint32_t gwip = inet_addr(DEFAULT);
	int r;

	if ((r = sys_page_alloc(0, pkt, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_map: %e", r);

	struct etharp_hdr *arp = (struct etharp_hdr*)pkt->jp_data;
	pkt->jp_len = sizeof(*arp);

	memset(arp->ethhdr.dest.addr, 0xff, ETHARP_HWADDR_LEN);
	memcpy(arp->ethhdr.src.addr,  mac,  ETHARP_HWADDR_LEN);
	arp->ethhdr.type = htons(ETHTYPE_ARP);
	arp->hwtype = htons(1); // Ethernet
	arp->proto = htons(ETHTYPE_IP);
	arp->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | 4);
	arp->opcode = htons(ARP_REQUEST);
	memcpy(arp->shwaddr.addr,  mac,   ETHARP_HWADDR_LEN);
	memcpy(arp->sipaddr.addrw, &myip, 4);
	memset(arp->dhwaddr.addr,  0x00,  ETHARP_HWADDR_LEN);
	memcpy(arp->dipaddr.addrw, &gwip, 4);

	ipc_send(output_envid, NSREQ_OUTPUT, pkt, PTE_P|PTE_W|PTE_U);
	sys_page_unmap(0, pkt);
}
Example #3
0
File: fork.c Project: zbh24/JosLab
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at uvpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.
	if ((err & FEC_WR) == 0 || (vpd[VPD(addr)] & PTE_P) == 0 || (vpt[VPN(addr)] & PTE_COW) == 0)
		panic ("pgfault: not a write or attempting to access a non-COW page");
	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.
	if ((r = sys_page_alloc (0, (void *)PFTEMP, PTE_U|PTE_P|PTE_W)) < 0)
		panic ("pgfault: page allocation failed : %e", r);
	addr = ROUNDDOWN (addr, PGSIZE);
	memmove (PFTEMP, addr, PGSIZE);
	if ((r = sys_page_map (0, PFTEMP, 0, addr, PTE_U|PTE_P|PTE_W)) < 0)
		panic ("pgfault: page mapping failed : %e", r);
	//panic("pgfault not implemented");
}
Example #4
0
File: fork.c Project: zbh24/JosLab
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use uvpd, uvpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	set_pgfault_handler (pgfault);
	envid_t envid;
	uint32_t addr;
	int r;
	envid = sys_exofork();
	if (envid < 0)
		panic("sys_exofork: %e", envid);
	// We’re the child
	if (envid == 0) {
		env = &envs[ENVX(sys_getenvid())];
		return 0;
	}
	// We’re the parent.
	for (addr = UTEXT; addr < UXSTACKTOP - PGSIZE; addr += PGSIZE) {
	if ((vpd[VPD(addr)] & PTE_P) > 0 && (vpt[VPN(addr)] & PTE_P) > 0 && (vpt[
		VPN(addr)] & PTE_U) > 0)
		duppage (envid, VPN(addr));
	}

	if ((r = sys_page_alloc (envid, (void *)(UXSTACKTOP - PGSIZE), PTE_U|PTE_W|PTE_P)) < 0)
		panic ("fork: page allocation failed : %e", r);
	extern void _pgfault_upcall (void);
	sys_env_set_pgfault_upcall (envid, _pgfault_upcall);
	// Start the child environment running
	if ((r = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
		panic("fork: set child env status failed : %e", r);
	return envid;
	//panic("fork not implemented");
}
void
umain(int argc, char **argv)
{
  envid_t who;

  if ((who = fork()) == 0) {
    // Child
    ipc_recv(&who, TEMP_ADDR_CHILD, 0);
    cprintf("%x got message: %s\n", who, TEMP_ADDR_CHILD);
    if (strncmp(TEMP_ADDR_CHILD, str1, strlen(str1)) == 0)
      cprintf("child received correct message\n");

    memcpy(TEMP_ADDR_CHILD, str2, strlen(str2) + 1);
    ipc_send(who, 0, TEMP_ADDR_CHILD, PTE_P | PTE_W | PTE_U);
    return;
  }

  // Parent
  sys_page_alloc(thisenv->env_id, TEMP_ADDR, PTE_P | PTE_W | PTE_U);
  memcpy(TEMP_ADDR, str1, strlen(str1) + 1);
  ipc_send(who, 0, TEMP_ADDR, PTE_P | PTE_W | PTE_U);

  ipc_recv(&who, TEMP_ADDR, 0);
  cprintf("%x got message: %s\n", who, TEMP_ADDR);
  if (strncmp(TEMP_ADDR, str2, strlen(str2)) == 0)
    cprintf("parent received correct message\n");
  return;
}
Example #6
0
File: pgfault.c Project: yahu/JOS
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
	int r;
    int re;
    envid_t envid = sys_getenvid();

	if (_pgfault_handler == 0) {
		// First time through!
		// LAB 4: Your code here.

		sys_env_set_pgfault_upcall(envid, _pgfault_upcall);
		re = sys_page_alloc(envid, (void *)(UXSTACKTOP - PGSIZE),PTE_U | PTE_P |PTE_W);
        if( re < 0){
            cprintf("process %x,sys_page_alloc fail\n",envid);
            sys_env_destroy(envid);
        }

		//panic("set_pgfault_handler not implemented");
	}

	// Save handler pointer for assembly to call.

	_pgfault_handler = handler;
	//cprintf("_pgfault_handler = %x\n",(uint32_t)_pgfault_handler);
}
Example #7
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;
	}
}
Example #8
0
/*
 * low_level_output():
 *
 * Should do the actual transmission of the packet. The packet is
 * contained in the pbuf that is passed to the function. This pbuf
 * might be chained.
 *
 */
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
    int r = sys_page_alloc(0, (void *)PKTMAP, PTE_U|PTE_W|PTE_P);
    if (r < 0)
	panic("jif: could not allocate page of memory");
    struct jif_pkt *pkt = (struct jif_pkt *)PKTMAP;

    struct jif *jif;
    jif = netif->state;

    char *txbuf = pkt->jp_data;
    int txsize = 0;
    struct pbuf *q;
    for (q = p; q != NULL; q = q->next) {
	/* Send the data from the pbuf to the interface, one pbuf at a
	   time. The size of the data in each pbuf is kept in the ->len
	   variable. */

	if (txsize + q->len > 2000)
	    panic("oversized packet, fragment %d txsize %d\n", q->len, txsize);
	memcpy(&txbuf[txsize], q->payload, q->len);
	txsize += q->len;
    }

    pkt->jp_len = txsize;

    ipc_send(jif->envid, NSREQ_OUTPUT, (void *)pkt, PTE_P|PTE_W|PTE_U);
    sys_page_unmap(0, (void *)pkt);

    return ERR_OK;
}
Example #9
0
void
fs_test(void)
{
	struct File *f;
	int r;
	char *blk;
	uint32_t *bits;

	// back up bitmap
	if ((r = sys_page_alloc(0, (void*) PGSIZE, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_alloc: %e", r);
	bits = (uint32_t*) PGSIZE;
	memmove(bits, bitmap, PGSIZE);
	// allocate block
	if ((r = alloc_block()) < 0)
		panic("alloc_block: %e", r);
	// check that block was free
	assert(bits[r/32] & (1 << (r%32)));
	// and is not free any more
	assert(!(bitmap[r/32] & (1 << (r%32))));
	cprintf("alloc_block is good\n");

	if ((r = file_open("/not-found", &f)) < 0 && r != -E_NOT_FOUND)
		panic("file_open /not-found: %e", r);
	else if (r == 0)
		panic("file_open /not-found succeeded!");
	if ((r = file_open("/newmotd", &f)) < 0)
		panic("file_open /newmotd: %e", r);
	cprintf("file_open is good\n");

	if ((r = file_get_block(f, 0, &blk)) < 0)
		panic("file_get_block: %e", r);
	if (strcmp(blk, msg) != 0)
		panic("file_get_block returned wrong data");
	cprintf("file_get_block is good\n");

	*(volatile char*)blk = *(volatile char*)blk;
	assert((vpt[PPN(blk)] & PTE_D));
	file_flush(f);
	assert(!(vpt[PPN(blk)] & PTE_D));
	cprintf("file_flush is good\n");

	if ((r = file_set_size(f, 0)) < 0)
		panic("file_set_size: %e", r);
	assert(f->f_direct[0] == 0);
	assert(!(vpt[PPN(f)] & PTE_D));
	cprintf("file_truncate is good\n");

	if ((r = file_set_size(f, strlen(msg))) < 0)
		panic("file_set_size 2: %e", r);
	assert(!(vpt[PPN(f)] & PTE_D));
	if ((r = file_get_block(f, 0, &blk)) < 0)
		panic("file_get_block 2: %e", r);
	strcpy(blk, msg);
	assert((vpt[PPN(blk)] & PTE_D));
	file_flush(f);
	assert(!(vpt[PPN(blk)] & PTE_D));
	assert(!(vpt[PPN(f)] & PTE_D));
	cprintf("file rewrite is good\n");
}
Example #10
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use uvpd, uvpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
  extern void _pgfault_upcall();
  // LAB 4: Your code here.
  set_pgfault_handler(pgfault);

  envid_t envid = sys_exofork();
  if (envid == 0) {
    thisenv = &envs[ENVX(sys_getenvid())];
    return 0;
  }
  if (envid < 0) {
    panic("sys_exofork failed: %e", envid);
  }

  uint32_t addr;
  for (addr = 0; addr < USTACKTOP; addr += PGSIZE) {
    if ((uvpd[PDX(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_U)) {
      duppage(envid, PGNUM(addr));
    }
  }
  int alloc_err = sys_page_alloc(envid, (void *)(UXSTACKTOP-PGSIZE), PTE_U|PTE_W|PTE_P);
  if (alloc_err) {
    panic("sys_page_alloc failed with error: %e", alloc_err);
  }
  sys_env_set_pgfault_upcall(envid, _pgfault_upcall);
  int set_status_err = sys_env_set_status(envid, ENV_RUNNABLE);
  if (set_status_err) {
    panic("sys_env_set_status");
  }
  return envid;
}
Example #11
0
void
umain(void)
{
	sys_page_alloc(0, (void*) (UXSTACKTOP - PGSIZE), PTE_P|PTE_U|PTE_W);
	sys_env_set_pgfault_upcall(0, (void*) 0xDeadBeef);
	*(int*)0 = 0;
}
Example #12
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	//panic("fork not implemented");
	extern void _pgfault_upcall(void);
	set_pgfault_handler(pgfault);
	envid_t id = sys_exofork();
	int r;
	if (id < 0)
		panic("exofork: child");
	if (id == 0)
	{
		thisenv = envs + ENVX(sys_getenvid());
		return 0;
	}
//	cprintf("fork id: %x",id);
	if ((r=sys_page_alloc(id, (void*)(UXSTACKTOP-PGSIZE), PTE_U | PTE_W | PTE_P))<0)
		return r;
	int i;
	for (i=0;i<UTOP-PGSIZE;i+=PGSIZE)
		if ((vpd[PDX(i)] & PTE_P) && (vpt[PGNUM(i)] & PTE_P))
		{
//			cprintf("i:%x ",i);
			if ((r=duppage(id,PGNUM(i)))<0)
				return r;
		}
	if ((r=sys_env_set_pgfault_upcall(id,(void*)_pgfault_upcall))<0)
		return r;
	if ((r=sys_env_set_status(id, ENV_RUNNABLE))<0)
		return r;
	return id;
}
Example #13
0
void
input(envid_t ns_envid)
{
	binaryname = "ns_input";

	// LAB 6: Your code here:
	// 	- read a packet from the device driver
	//	- send it to the network server
	// Hint: When you IPC a page to the network server, it will be
	// reading from it for a while, so don't immediately receive
	// another packet in to the same physical page.
    uint8_t data[2048];
    int length, r;

    for (;;) {
        while ((length = sys_pkt_receive(data)) < 0)
            sys_yield();

        while (sys_page_alloc(0, &nsipcbuf, PTE_P | PTE_W | PTE_U) < 0)
            sys_yield();

        nsipcbuf.pkt.jp_len = length;
        memmove(nsipcbuf.pkt.jp_data, data, length);

        while (sys_ipc_try_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_P | PTE_W | PTE_U) < 0)
            sys_yield();
    }
}
Example #14
0
void
input(envid_t ns_envid)
{
	binaryname = "ns_input";

	// LAB 6: Your code here:
	// 	- read a packet from the device driver
	//	- send it to the network server
	// Hint: When you IPC a page to the network server, it will be
	// reading from it for a while, so don't immediately receive
	// another packet in to the same physical page.
	int RPKT_SIZE = 2048;
	
	int lengthOfPacket = RPKT_SIZE - 1;
	int r = 0;
	char buffer[RPKT_SIZE];
	
	while(1){
		while((r = sys_receive(buffer,&lengthOfPacket))<0){
		sys_yield();
	     }	
	
	while((r = sys_page_alloc(0, &nsipcbuf, PTE_P|PTE_U|PTE_W))<0);

	nsipcbuf.pkt.jp_len = lengthOfPacket;
	memmove(nsipcbuf.pkt.jp_data, buffer, lengthOfPacket);

	while((r = sys_ipc_try_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_P|PTE_U|PTE_W)) < 0);
	
	}
}
Example #15
0
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
	int r;

	if (_pgfault_handler == 0) {
		r = sys_page_alloc(sys_getenvid(), (void*)(UXSTACKTOP - PGSIZE), PTE_W | PTE_U | PTE_P);

		if(r)
		{
			panic("pgfault.c:40: Error %e when allocating User Exception Stack\n", r);
		} 	
	}

	// Save handler pointer for assembly to call.
	_pgfault_handler = handler;

	/*
	* We register with the kernel the assembly routine to return to execution.
	*/
	r = sys_env_set_pgfault_upcall(sys_getenvid(), _pgfault_upcall);
	
	if(r)
	{
		panic("pgfault.c:55: Error %e when setting the pgfault upcall\n", r);
	} 	
}
Example #16
0
File: fs.c Project: darfux/jos
// Allocate a page to hold the disk block
int
map_block(uint32_t blockno)
{
	if (block_is_mapped(blockno))
		return 0;
	return sys_page_alloc(0, diskaddr(blockno), PTE_U|PTE_P|PTE_W);
}
Example #17
0
void
umain(int argc, char **argv)
{
	int r;

	if (argc != 0)
		childofspawn();

	if ((r = sys_page_alloc(0, VA, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		panic("sys_page_alloc: %e", r);

	// check fork
	if ((r = fork()) < 0)
		panic("fork: %e", r);
	if (r == 0) {
		strcpy(VA, msg);
		exit();
	}
	wait(r);
	cprintf("fork handles PTE_SHARE %s\n", strcmp(VA, msg) == 0 ? "right" : "wrong");

	// check spawn
	if ((r = spawnl("/testptelibrary", "testptelibrary", "arg", 0)) < 0)
		panic("spawn: %e", r);
	wait(r);
	cprintf("spawn handles PTE_SHARE %s\n", strcmp(VA, msg2) == 0 ? "right" : "wrong");
}
Example #18
0
File: syscall.c Project: 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");
}
Example #19
0
File: bc.c Project: evilzone/CSE506
// Fault any disk block that is read or written in to memory by
// loading it from disk.
// Hint: Use ide_read and BLKSECTS.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_rip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page, and mark the
	// page not-dirty (since reading the data from disk will mark
	// the page dirty).
	//
	// LAB 5: Your code here

	void *dst_addr = (void *) ROUNDDOWN(addr, BLKSIZE);
	r = sys_page_alloc(thisenv->env_id, dst_addr, PTE_U | PTE_P | PTE_W);

	// Project addition --> Transparent disk decryption (called only if disk block
	// is encrypted). Bitmap block has been left out of encryption, bitmap block data is tightly
	// bound in other routines, so can't encrypt.
	 if(blockno == 2)
	     ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS);
	else if (blockno == 1) /* || (blockno == 2)) */
	 {
		 if(!s_encrypted)
			 ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS);
		 else
		 {
			 r = transparent_disk_decrypt(blockno, dst_addr);
			 if(r)
				 return;

		 }

	 }
	 else 
	 { 
		 r = transparent_disk_decrypt(blockno, dst_addr);
		 if(r)
			 return;
	 }

	// panic("bc_pgfault not implemented");

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
Example #20
0
File: spawn.c Project: ichaos/jos
// Set up the initial stack page for the new child process with envid 'child'
// using the arguments array pointed to by 'argv',
// which is a null-terminated array of pointers to null-terminated strings.
//
// On success, returns 0 and sets *init_esp
// to the initial stack pointer with which the child should start.
// Returns < 0 on failure.
static int
init_stack(envid_t child, const char **argv, uintptr_t *init_esp)
{
	size_t string_size;
	int argc, i, r;
	char *string_store;
	uintptr_t *argv_store;

	// Count the number of arguments (argc)
	// and the total amount of space needed for strings (string_size).
	string_size = 0;
	for (argc = 0; argv[argc] != 0; argc++)
		string_size += strlen(argv[argc]) + 1;

	// Determine where to place the strings and the argv array.
	// Set up pointers into the temporary page 'UTEMP'; we'll map a page
	// there later, then remap that page into the child environment
	// at (USTACKTOP - PGSIZE).
	// strings is the topmost thing on the stack.
	string_store = (char*) UTEMP + PGSIZE - string_size;
	// argv is below that.  There's one argument pointer per argument, plus
	// a null pointer.
	argv_store = (uintptr_t*) (ROUNDDOWN(string_store, 4) - 4 * (argc + 1));

	// Make sure that argv, strings, and the 2 words that hold 'argc'
	// and 'argv' themselves will all fit in a single stack page.
	if ((void*) (argv_store - 2) < (void*) UTEMP)
		return -E_NO_MEM;

	// Allocate the single stack page at UTEMP.
	if ((r = sys_page_alloc(0, (void*) UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
		return r;

	for (i = 0; i < argc; i++) {
		argv_store[i] = UTEMP2USTACK(string_store);
		strcpy(string_store, argv[i]);
		string_store += strlen(argv[i]) + 1;
	}
	argv_store[argc] = 0;
	assert(string_store == (char*)UTEMP + PGSIZE);

	argv_store[-1] = UTEMP2USTACK(argv_store);
	argv_store[-2] = argc;

	*init_esp = UTEMP2USTACK(&argv_store[-2]);

	// After completing the stack, map it into the child's address space
	// and unmap it from ours!
	if ((r = sys_page_map(0, UTEMP, child, (void*) (USTACKTOP - PGSIZE), PTE_P | PTE_U | PTE_W)) < 0)
		goto error;
	if ((r = sys_page_unmap(0, UTEMP)) < 0)
		goto error;

	return 0;

error:
	sys_page_unmap(0, UTEMP);
	return r;
}
Example #21
0
int
pipe(int pfd[2])
{
	int r;
	struct Fd *fd0, *fd1;
	void *va;

	// allocate the file descriptor table entries
	if ((r = fd_alloc(&fd0)) < 0
	    || (r = sys_page_alloc(0, fd0, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err;

	if ((r = fd_alloc(&fd1)) < 0
	    || (r = sys_page_alloc(0, fd1, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err1;

	// allocate the pipe structure as first data page in both
	va = fd2data(fd0);
	if ((r = sys_page_alloc(0, va, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err2;
	if ((r = sys_page_map(0, va, 0, fd2data(fd1), PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err3;

	// set up fd structures
	fd0->fd_dev_id = devpipe.dev_id;
	fd0->fd_omode = O_RDONLY;

	fd1->fd_dev_id = devpipe.dev_id;
	fd1->fd_omode = O_WRONLY;

	if (debug)
		cprintf("[%08x] pipecreate %08x\n", env->env_id, vpt[VPN(va)]);

	pfd[0] = fd2num(fd0);
	pfd[1] = fd2num(fd1);
	return 0;

    err3:
	sys_page_unmap(0, va);
    err2:
	sys_page_unmap(0, fd1);
    err1:
	sys_page_unmap(0, fd0);
    err:
	return r;
}
Example #22
0
File: fork.c Project: wuxy/mitjos
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t err = utf->utf_err;
	int r;

	// Check that the faulting access was (1) a write, and (2) to a
	// copy-on-write page.  If not, panic.
	// Hint:
	//   Use the read-only page table mappings at vpt
	//   (see <inc/memlayout.h>).

	// LAB 4: Your code here.
	pde_t *pde;
	pte_t *pte;
	uint32_t *va,*srcva,*dstva;
	pde =(pde_t*) &vpd[VPD(addr)];
	if(*pde&PTE_P)
	{
		pte=(pte_t*)&vpt[VPN(addr)];
	}
	else{
		cprintf("addr=%x err=%x *pde=%x utf_eip=%x\n",(uint32_t)addr,err,*pde,utf->utf_eip);	
		panic("page table for fault va is not exist");
	}
	//cprintf("addr=%x err=%x *pte=%x utf_eip=%x\n",(uint32_t)addr,err,*pte,utf->utf_eip);
	if(!(err&FEC_WR)||!(*pte&PTE_COW))
	{	
		cprintf("envid=%x addr=%x err=%x *pte=%x utf_eip=%x\n",env->env_id,(uint32_t)addr,err,*pte,utf->utf_eip);
		panic("faulting access is illegle");
	}
	// Allocate a new page, map it at a temporary location (PFTEMP),
	// copy the data from the old page to the new page, then move the new
	// page to the old page's address.
	// Hint:
	//   You should make three system calls.
	//   No need to explicitly delete the old page's mapping.

	// LAB 4: Your code here.
	//cprintf("pgfault:env_id=%x\n",env->env_id);
	if((r=sys_page_alloc(0,PFTEMP,PTE_W|PTE_U|PTE_P))<0)
			//输入id=0表示当前环境id(curenv->env_id),这个时候不能用env->env-id,子环境中env的修改会缺页
		panic("alloc a page for PFTEMP failed:%e",r);
	//cprintf("PFTEMP=%x add=%x\n",PFTEMP,(uint32_t)addr&0xfffff000);
	srcva = (uint32_t*)((uint32_t)addr&0xfffff000);
	dstva = (uint32_t*)PFTEMP;
	//strncpy((char*)PFTEMP,(char*)((uint32_t)addr&0xfffff000),PGSIZE);
	for(;srcva<(uint32_t*)(ROUNDUP(addr,PGSIZE));srcva++)//数据拷贝要注意,用strncpy出错了,原因还得分析
	{
		*dstva=*srcva;
		dstva++;
	}
	if((r=sys_page_map(0,(void*)PFTEMP,0,(void*)((uint32_t)addr&0xfffff000),PTE_W|PTE_U|PTE_P))<0)
			//输入id=0表示当前环境id(curenv->env_id),这个时候不能用env->env-id,子环境中env的修改会缺页
		panic("page mapping failed");
	//panic("pgfault not implemented");
}
Example #23
0
File: spawn.c Project: HVNT/6.828
static int
map_segment(envid_t child, uintptr_t va, size_t memsz, 
	int fd, size_t filesz, off_t fileoffset, int perm)
{
	int i, r;
	void *blk;

	//cprintf("map_segment %x+%x\n", va, memsz);

	if ((i = PGOFF(va))) {
		va -= i;
		memsz += i;
		filesz += i;
		fileoffset -= i;
	}

	for (i = 0; i < memsz; i += PGSIZE) {
		if (i >= filesz) {
			// allocate a blank page
			if ((r = sys_page_alloc(child, (void*) (va + i), perm)) < 0)
				return r;
		} else {
			// from file
			if (perm & PTE_W) {
				// must make a copy so it can be writable
				if ((r = sys_page_alloc(0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
					return r;
				if ((r = seek(fd, fileoffset + i)) < 0)
					return r;
				if ((r = read(fd, UTEMP, MIN(PGSIZE, filesz-i))) < 0)
					return r;
				if ((r = sys_page_map(0, UTEMP, child, (void*) (va + i), perm)) < 0)
					panic("spawn: sys_page_map data: %e", r);
				sys_page_unmap(0, UTEMP);
			} else {
				// can map buffer cache read only
				if ((r = read_map(fd, fileoffset + i, &blk)) < 0)
					return r;
				if ((r = sys_page_map(0, blk, child, (void*) (va + i), perm)) < 0)
					panic("spawn: sys_page_map text: %e", r);
			}
		}
	}
	return 0;
}
Example #24
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 = -E_INVAL;
	switch(syscallno) {
		case SYS_cputs:
			sys_cputs((char *)a1, a2);
			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_yield:
			sys_yield();
			ret = 0;
			break;
		case SYS_map_kernel_page:
			ret = sys_map_kernel_page((void *)a1, (void *)a2);
			break;
		case SYS_sbrk:
			ret = sys_sbrk(a1);
			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);
			break;
		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);
	}
	return ret;
//	panic("syscall not implemented");
}
Example #25
0
File: syscall.c Project: dannoy/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.
    /* lj */
    int ret = 0;
    switch(syscallno) {
        case SYS_cputs:
            sys_cputs((const char *)a1, a2);
        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_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_try_send:
            ret = sys_ipc_try_send((envid_t)a1, a2, (void *)a3, a4);
        break;
        case SYS_ipc_recv:
            ret = sys_ipc_recv((void *)a1);
        break;
        default:
            ret = -E_INVAL;
        break;
    }

    //panic("syscall not implemented");
    //cprintf("%d return to user %d\n", syscallno, ret);
    return ret;
}
Example #26
0
void process_main(void) {
    while (1) {
        if (rand() % ALLOC_SLOWDOWN == 0) {
            if (sys_fork() == 0) {
                break;
            }
        } else {
            sys_yield();
        }
    }

    pid_t p = sys_getpid();
    srand(p);

    // The heap starts on the page right after the 'end' symbol,
    // whose address is the first address not allocated to process code
    // or data.
    heap_top = ROUNDUP((uint8_t*) end, PAGESIZE);

    // The bottom of the stack is the first address on the current
    // stack page (this process never needs more than one stack page).
    stack_bottom = ROUNDDOWN((uint8_t*) read_rsp() - 1, PAGESIZE);

    // Allocate heap pages until (1) hit the stack (out of address space)
    // or (2) allocation fails (out of physical memory).
    while (1) {
        int x = rand() % (8 * ALLOC_SLOWDOWN);
        if (x < 8 * p) {
            if (heap_top == stack_bottom || sys_page_alloc(heap_top) < 0) {
                break;
            }
            *heap_top = p;      /* check we have write access to new page */
            heap_top += PAGESIZE;
            if (console[CPOS(24, 0)]) {
                /* clear "Out of physical memory" msg */
                console_printf(CPOS(24, 0), 0, "\n");
            }
        } else if (x == 8 * p) {
            if (sys_fork() == 0) {
                p = sys_getpid();
            }
        } else if (x == 8 * p + 1) {
            sys_exit();
        } else {
            sys_yield();
        }
    }

    // After running out of memory
    while (1) {
        if (rand() % (2 * ALLOC_SLOWDOWN) == 0) {
            sys_exit();
        } else {
            sys_yield();
        }
    }
}
Example #27
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "env" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	//cprintf("In environment %04x\n", sys_getenvid());
	set_pgfault_handler(pgfault);
	envid_t envid;
	int r;
	envid = sys_exofork();
	if(envid < 0)
		panic("sys_exofork: %e", envid);	
	else if(envid == 0)
	{
		env = &envs[ENVX(sys_getenvid())];
		//cprintf("I am the child %04x %04x\n", sys_getenvid(), env->env_id);
		return 0;
	}
	
	//cprintf("In the parent process %04x\n", sys_getenvid());
	if((r = sys_page_alloc(envid, (void *)(UXSTACKTOP - PGSIZE), PTE_W | PTE_U | PTE_P))<0)
		panic("sys_page_alloc: %e", r);
	if((r = sys_env_set_pgfault_upcall(envid, env->env_pgfault_upcall))<0)
		panic("sys_env_set_pgfault_upcall: %e", r);
	
	uint32_t va;
	for(va = UTEXT; va < UTOP; va += PGSIZE)
		if(va == UXSTACKTOP - PGSIZE) 
		{
			if((r = sys_page_alloc(envid, (void *)(UXSTACKTOP - PGSIZE), PTE_P | PTE_W | PTE_U))<0)
				panic("sys_page_alloc: %e", r);
		}
		else if((vpd[VPN(va)/NPTENTRIES] & PTE_P) && (vpt[VPN(va)] & PTE_P))
			duppage(envid, va>>PGSHIFT);

	//cprintf("Done with the copying in environment %04x\n", env->env_id);
	if((r = sys_env_set_pgfault_upcall(envid, env->env_pgfault_upcall))<0)
		panic("sys_env_set_pgfault_upcall: %e", r);

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

	// Returning the child's envid to the parent
	return envid;
}
Example #28
0
// Page fault handler
void
handler(struct UTrapframe *utf)
{
	int r;
	void *addr = (void*)utf->utf_fault_va;

	if ((r = sys_page_alloc(0, ROUNDDOWN(addr, PGSIZE),
				PTE_P|PTE_U|PTE_W)) < 0)
		panic("allocating at %x in page fault handler: %e", addr, r);
}
Example #29
0
File: fork.c Project: ren85/jos2006
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "env" and the user exception stack in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	
	// Assembly language pgfault entrypoint defined in lib/pgfaultentry.S.
	extern void _pgfault_upcall(void);
	
	envid_t chenvid;	
	void *addr;
	void *addr2;
	unsigned pn;	
	pte_t pte, pde;
	int count, r, entries;

	set_pgfault_handler(pgfault);

	if ( (chenvid = sys_exofork()) < 0)
		panic("fork() - no free env!");
	else if (chenvid == 0){					//we are in child - ren
		env = &envs[ENVX(sys_getenvid())];	
		return 0;
	     }
	
	//we are in parent - ren

	//copy mappings - ren
	entries = NPDENTRIES;
	for(addr = 0; entries--; addr+=NPTENTRIES*PGSIZE){	//walk through page directory - ren
		pde = vpd[PDX(addr)];
		if (pde & PTE_P) {				
								//walk through page table - ren
			for(addr2 = addr, count = NPTENTRIES; ((uintptr_t)addr2 < (uintptr_t)UTOP - PGSIZE) && (count);
							       addr2+=PGSIZE, count--){	
				pte = vpt[VPN(addr2)];
				if (pte & PTE_P){
					duppage(chenvid, (uintptr_t)addr2/PGSIZE);				
				}
			}
			if (count)			
				break;				//reached exception stack - ren				
		}	
	}
	
	if( (r = sys_page_alloc(chenvid, (void *) UXSTACKTOP-PGSIZE, PTE_U | PTE_P | PTE_W)) < 0)
			panic("fork() - could not allocate exception stack for the child!");	

	if( (r = sys_env_set_pgfault_upcall(chenvid, (void *) _pgfault_upcall)) < 0)
			panic("fork() - could not set page fault entrypoint for the child!");

	if( (r = sys_env_set_status(chenvid, ENV_RUNNABLE)) < 0)
			panic("fork() - could not set child ENV_RUNNABLE!");

	return chenvid;
}		
Example #30
0
File: fork.c Project: HVNT/6.828
envid_t
fork(void)
{
    // LAB 4: Your code here.
    // seanyliu
    int r;
    int pdidx = 0;
    int peidx = 0;
    envid_t childid;
    set_pgfault_handler(pgfault);

    // create child environment
    childid = sys_exofork();
    if (childid < 0) {
        panic("fork: failed to create child %d", childid);
    }
    if (childid == 0) {
        env = &envs[ENVX(sys_getenvid())];
        return 0;
    }

    // loop through pg dir, avoid user exception stack (which is immediately below UTOP
    for (pdidx = 0; pdidx < PDX(UTOP); pdidx++) {
        // check if the pg is present
        if (!(vpd[pdidx] & PTE_P)) continue;

        // loop through pg table entries
        for (peidx = 0; (peidx < NPTENTRIES) && (pdidx*NPDENTRIES+peidx < (UXSTACKTOP - PGSIZE)/PGSIZE); peidx++) {
            if (vpt[pdidx * NPTENTRIES + peidx] & PTE_P) {
                if ((r = duppage(childid, pdidx * NPTENTRIES + peidx)) < 0) {
                    panic("fork: duppage failed: %d", r);
                }
            }
        }
    }

    // allocate fresh page in the child for exception stack.
    if ((r = sys_page_alloc(childid, (void *)(UXSTACKTOP - PGSIZE), PTE_U | PTE_P | PTE_W)) < 0) {
        panic("fork: %d", r);
    }

    // parent sets the user page fault entrypoint for the child to look like its own.
    if ((r = sys_env_set_pgfault_upcall(childid, env->env_pgfault_upcall)) < 0) {
        panic("fork: %d", r);
    }

    // parent marks child runnable
    if ((r = sys_env_set_status(childid, ENV_RUNNABLE)) < 0) {
        panic("fork: %d", r);
    }

    return childid;

    //panic("fork not implemented");
}