Exemplo n.º 1
0
// Allocate and initialize a new proc as child 'cn' of parent 'p'.
// Returns NULL if no physical memory available.
proc *
proc_alloc(proc *p, uint32_t cn)
{
	pageinfo *pi = mem_alloc();
	if (!pi)
		return NULL;
	mem_incref(pi);

	proc *cp = (proc*)mem_pi2ptr(pi);
	memset(cp, 0, sizeof(proc));
	spinlock_init(&cp->lock);
	cp->parent = p;
	cp->state = PROC_STOP;

	// Integer register state
	cp->sv.tf.eflags = (FL_IOPL_MASK & FL_IOPL_3) | FL_IF;
	cp->sv.tf.cs = CPU_GDT_UCODE | 3;
	cp->sv.tf.ds = CPU_GDT_UDATA | 3;
	cp->sv.tf.es = CPU_GDT_UDATA | 3;
	cp->sv.tf.cs = CPU_GDT_UCODE | 3;
	cp->sv.tf.ss = CPU_GDT_UDATA | 3;


	if (p)
		p->child[cn] = cp;
	return cp;
}
Exemplo n.º 2
0
// Allocate and initialize a new proc as child 'cn' of parent 'p'.
// Returns NULL if no physical memory available.
proc *
proc_alloc(proc *p, uint32_t cn)
{
	pageinfo *pi = mem_alloc();
	if (!pi)
		return NULL;
	mem_incref(pi);
	
	proc *cp = (proc*)mem_pi2ptr(pi);
	memset(cp, 0, sizeof(proc));
	spinlock_init(&cp->lock);
	cp->parent = p;
	cp->state = PROC_STOP;


	cp->home = RRCONS(net_node, mem_phys(cp), 0);
	
	//Page directories - we might need this stuff, idk, merge conflict
	// cp->pdir = pmap_newpdir();
	// cp->rpdir = pmap_newpdir();

	// Integer register state
	cp->sv.tf.ds = CPU_GDT_UDATA | 3;
	cp->sv.tf.es = CPU_GDT_UDATA | 3;
	cp->sv.tf.cs = CPU_GDT_UCODE | 3;
	cp->sv.tf.ss = CPU_GDT_UDATA | 3;

	cp->pdir = pmap_newpdir();
	if (!cp->pdir)
		return NULL;

	cp->rpdir = pmap_newpdir();
	if (!cp->rpdir)
	{
		pmap_freepdir(mem_ptr2pi(cp->pdir));
		return NULL;
	}

	if (p)
		p->child[cn] = cp;
	return cp;
}
Exemplo n.º 3
0
Arquivo: mem.c Projeto: bhup99/PIOS
//
// Check the physical page allocator (mem_alloc(), mem_free())
// for correct operation after initialization via mem_init().
//
void
mem_check()
{
	pageinfo *pp, *pp0, *pp1, *pp2;
	pageinfo *fl;
	int i;

        // if there's a page that shouldn't be on
        // the free list, try to make sure it
        // eventually causes trouble.
	int freepages = 0;
	for (pp = mem_freelist; pp != 0; pp = pp->free_next) {
		memset(mem_pi2ptr(pp), 0x97, 128);
		freepages++;
	}
	cprintf("mem_check: %d free pages\n", freepages);
	assert(freepages < mem_npage);	// can't have more free than total!
	assert(freepages > 16000);	// make sure it's in the right ballpark

	// should be able to allocate three pages
	pp0 = pp1 = pp2 = 0;
	pp0 = mem_alloc(); assert(pp0 != 0);
	pp1 = mem_alloc(); assert(pp1 != 0);
	pp2 = mem_alloc(); assert(pp2 != 0);

	assert(pp0);
	assert(pp1 && pp1 != pp0);
	assert(pp2 && pp2 != pp1 && pp2 != pp0);
        assert(mem_pi2phys(pp0) < mem_npage*PAGESIZE);
        assert(mem_pi2phys(pp1) < mem_npage*PAGESIZE);
        assert(mem_pi2phys(pp2) < mem_npage*PAGESIZE);

	// temporarily steal the rest of the free pages
	fl = mem_freelist;
	mem_freelist = 0;

	// should be no free memory
	assert(mem_alloc() == 0);

        // free and re-allocate?
        mem_free(pp0);
        mem_free(pp1);
        mem_free(pp2);
	pp0 = pp1 = pp2 = 0;
	pp0 = mem_alloc(); assert(pp0 != 0);
	pp1 = mem_alloc(); assert(pp1 != 0);
	pp2 = mem_alloc(); assert(pp2 != 0);
	assert(pp0);
	assert(pp1 && pp1 != pp0);
	assert(pp2 && pp2 != pp1 && pp2 != pp0);
	assert(mem_alloc() == 0);

	// give free list back
	mem_freelist = fl;

	// free the pages we took
	mem_free(pp0);
	mem_free(pp1);
	mem_free(pp2);

	cprintf("mem_check() succeeded!\n");
}
Exemplo n.º 4
0
// Called first from entry.S on the bootstrap processor,
// and later from boot/bootother.S on all other processors.
// As a rule, "init" functions in PIOS are called once on EACH processor.
void
init(void)
{
	extern char start[], edata[], end[];

	// Before anything else, complete the ELF loading process.
	// Clear all uninitialized global data (BSS) in our program,
	// ensuring that all static/global variables start out zero.
	if (cpu_onboot())
		memset(edata, 0, end - edata);

	// Initialize the console.
	// Can't call cprintf until after we do this!
	cons_init();

  	extern uint8_t _binary_obj_boot_bootother_start[],
    	_binary_obj_boot_bootother_size[];

  	uint8_t *code = (uint8_t*)lowmem_bootother_vec;
  	memmove(code, _binary_obj_boot_bootother_start, (uint32_t) _binary_obj_boot_bootother_size);

	// Lab 1: test cprintf and debug_trace
	cprintf("1234 decimal is %o octal!\n", 1234);
	debug_check();

	// Initialize and load the bootstrap CPU's GDT, TSS, and IDT.
	cpu_init();
	trap_init();

	// Physical memory detection/initialization.
	// Can't call mem_alloc until after we do this!
	mem_init();

	// Lab 2: check spinlock implementation
	if (cpu_onboot())
		spinlock_check();

	// Initialize the paged virtual memory system.
	pmap_init();

	// Find and start other processors in a multiprocessor system
	mp_init();		// Find info about processors in system
	pic_init();		// setup the legacy PIC (mainly to disable it)
	ioapic_init();		// prepare to handle external device interrupts
	lapic_init();		// setup this CPU's local APIC
	cpu_bootothers();	// Get other processors started
//	cprintf("CPU %d (%s) has booted\n", cpu_cur()->id,
//		cpu_onboot() ? "BP" : "AP");

	file_init();		// Create root directory and console I/O files

	// Lab 4: uncomment this when you can handle IRQ_SERIAL and IRQ_KBD.
	//cons_intenable();	// Let the console start producing interrupts

	// Initialize the process management code.
	proc_init();
	// Initialize the process management code.
	proc_init();


	if(!cpu_onboot())
		proc_sched();
 	proc *root = proc_root = proc_alloc(NULL,0);
  
  	elfhdr *ehs = (elfhdr *)ROOTEXE_START;
  	assert(ehs->e_magic == ELF_MAGIC);

  	proghdr *phs = (proghdr *) ((void *) ehs + ehs->e_phoff);
  	proghdr *ep = phs + ehs->e_phnum;

  	for (; phs < ep; phs++)
	{
    		if (phs->p_type != ELF_PROG_LOAD)
      		continue;

    		void *fa = (void *) ehs + ROUNDDOWN(phs->p_offset, PAGESIZE);
    		uint32_t va = ROUNDDOWN(phs->p_va, PAGESIZE);
    		uint32_t zva = phs->p_va + phs->p_filesz;
    		uint32_t eva = ROUNDUP(phs->p_va + phs->p_memsz, PAGESIZE);

    		uint32_t perm = SYS_READ | PTE_P | PTE_U;
    		if(phs->p_flags & ELF_PROG_FLAG_WRITE) perm |= SYS_WRITE | PTE_W;

    		for (; va < eva; va += PAGESIZE, fa += PAGESIZE) 
		{
    			pageinfo *pi = mem_alloc(); assert(pi != NULL);
      			if(va < ROUNDDOWN(zva, PAGESIZE))
        			memmove(mem_pi2ptr(pi), fa, PAGESIZE);
      			else if (va < zva && phs->p_filesz)
			{
      				memset(mem_pi2ptr(pi),0, PAGESIZE);
      				memmove(mem_pi2ptr(pi), fa, zva-va);
      			} 
			else
        			memset(mem_pi2ptr(pi), 0, PAGESIZE);

      			pte_t *pte = pmap_insert(root->pdir, pi, va, perm);
      			assert(pte != NULL);
      		}
      }

      root->sv.tf.eip = ehs->e_entry;
      root->sv.tf.eflags |= FL_IF;

      pageinfo *pi = mem_alloc(); assert(pi != NULL);
      pte_t *pte = pmap_insert(root->pdir, pi, VM_STACKHI-PAGESIZE,
      SYS_READ | SYS_WRITE | PTE_P | PTE_U | PTE_W);

      assert(pte != NULL);
      root->sv.tf.esp = VM_STACKHI;

      proc_ready(root);
      proc_sched();
	// Initialize the I/O system.

	// Lab 1: change this so it enters user() in user mode,
	// running on the user_stack declared above,
	// instead of just calling user() directly.
	user(); // FIXME: Maybe get rid of this
}