Beispiel #1
0
void
file_initroot(proc *root)
{
	// Only one root process may perform external I/O directly -
	// all other processes do I/O indirectly via the process hierarchy.
	assert(root == proc_root);

	// Make sure the root process's page directory is loaded,
	// so that we can write into the root process's file area directly.
	cpu_cur()->proc = root;
	lcr3(mem_phys(root->pdir));

	// Enable read/write access on the file metadata area
	pmap_setperm(root->pdir, FILESVA, ROUNDUP(sizeof(filestate), PAGESIZE),
				SYS_READ | SYS_WRITE);
	memset(files, 0, sizeof(*files));

	// Set up the standard I/O descriptors for console I/O
	files->fd[0].ino = FILEINO_CONSIN;
	files->fd[0].flags = O_RDONLY;
	files->fd[1].ino = FILEINO_CONSOUT;
	files->fd[1].flags = O_WRONLY | O_APPEND;
	files->fd[2].ino = FILEINO_CONSOUT;
	files->fd[2].flags = O_WRONLY | O_APPEND;

	// Setup the inodes for the console I/O files and root directory
	strcpy(files->fi[FILEINO_CONSIN].de.d_name, "consin");
	strcpy(files->fi[FILEINO_CONSOUT].de.d_name, "consout");
	strcpy(files->fi[FILEINO_ROOTDIR].de.d_name, "/");
	files->fi[FILEINO_CONSIN].dino = FILEINO_ROOTDIR;
	files->fi[FILEINO_CONSOUT].dino = FILEINO_ROOTDIR;
	files->fi[FILEINO_ROOTDIR].dino = FILEINO_ROOTDIR;
	files->fi[FILEINO_CONSIN].mode = S_IFREG | S_IFPART;
	files->fi[FILEINO_CONSOUT].mode = S_IFREG;
	files->fi[FILEINO_ROOTDIR].mode = S_IFDIR;

	// Set the whole console input area to be read/write,
	// so we won't have to worry about perms in cons_io().
	pmap_setperm(root->pdir, (uintptr_t)FILEDATA(FILEINO_CONSIN),
				PTSIZE, SYS_READ | SYS_WRITE);

	// Set up the initial files in the root process's file system.
	// Some script magic in kern/Makefrag creates obj/kern/initfiles.h,
	// which gets included above (twice) to create the 'initfiles' array.
	// For each initial file numbered 0 <= i < ninitfiles,
	// initfiles[i][0] is a pointer to the filename string for that file,
	// initfiles[i][1] is a pointer to the start of the file's content, and
	// initfiles[i][2] is a pointer to the end of the file's content
	// (i.e., a pointer to the first byte after the file's last byte).
	int ninitfiles = sizeof(initfiles)/sizeof(initfiles[0]);
	// Lab 4: your file system initialization code here.
	warn("file_initroot: file system initialization not done\n");

	// Set root process's current working directory
	files->cwd = FILEINO_ROOTDIR;

	// Child process state - reserve PID 0 as a "scratch" child process.
	files->child[0].state = PROC_RESERVED;
}
Beispiel #2
0
static bool
madt_scan(struct acpi_madt *madt)
{
	int pc_count = 0;
	int32_t length = madt->header.length;
	if (memcmp(madt, "APIC", 4) != 0 || sum(madt, length) != 0)
		return false;
	lapic = mem_ptr(madt->lapicaddr);
	cprintf("lapic addr %p\n", mem_phys(lapic));
	length -= sizeof(struct acpi_sdt_hdr) + 8;
	uint8_t *p = madt->ent;
	bool ret = false;
	while (length > 0) {
#ifdef DEBUG
		cprintf("MADT type %u length %u\n", p[0], p[1]);
#endif
		switch (p[0]) {
		case MADT_LAPIC:
			if ( p[4] ) {
				/* The first entry is always the BSP, else AP */
				cpu *c = !pc_count ? &cpu_boot : cpu_alloc();
				c->id = p[3];
				c->num = pc_count++;
				break;
			}
		case MADT_IOAPIC:
			ioapicid = ((struct acpi_madt_ioapic *)p)->ioapicid;
			ioapic = mem_ptr(((struct acpi_madt_ioapic *)p)->ioapicaddr);
			cprintf("ioapic %u addr %p\n", ioapicid,
				mem_phys(ioapic));
			ret = true;
		default:
			break;
		}
		length -= p[1];
		p += p[1];
	}
	return ret;
}
Beispiel #3
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;
}
Beispiel #4
0
// Switch to and run a specified process, which must already be locked.
void gcc_noreturn
proc_run(proc *p)
{
	if (!spinlock_holding(&p->lock)) panic("proc_run without lock");

	//if (p->parent) cprintf("running child\n");
	//	else cprintf("running root\n");
	
	p->state = PROC_RUN;
	p->runcpu = cpu_cur();
	cpu_cur()->proc = p;
	
	// Enable interrupts (for preemption)
	p->sv.tf.eflags |= (1 << 9);
	p->sv.tf.ds = CPU_GDT_UDATA | 3;
	p->sv.tf.es = CPU_GDT_UDATA | 3;
	p->sv.tf.cs = CPU_GDT_UCODE | 3;
	p->sv.tf.ss = CPU_GDT_UDATA | 3;
	lcr3 (mem_phys(p->pdir));
	
	spinlock_release(&p->lock);
	
	trap_return(&p->sv.tf);
}
Beispiel #5
0
void
acpi_init(void)
{
	if (!cpu_onboot())
		return;

	int rev = 0;
	void *p = rsdpsearch(&rev);
	if (!p)
		return;
#ifdef DEBUG
	cprintf("rsdp %p rev %u\n", p, rev);
#endif
	ismp = 1;
	if (rev == 1) {
		struct acpi_rsdp *rsdp = p;
		struct acpi_rsdt *rsdt = mem_ptr(rsdp->rsdtaddr);
#ifdef DEBUG
		cprintf("rsdp %p rsdt %p size %u\n", mem_phys(rsdp),
			mem_phys(rsdt), sizeof (struct acpi2_rsdp));
#endif
		rsdt_scan(rsdt);
	} else if (rev == 2) {
		struct acpi2_rsdp *rsdp = p;
#ifdef DEBUG
		cprintf("rsdp %p rev %u\n", mem_phys(rsdp), rsdp->revision);
#endif

		struct acpi_rsdt *rsdt = mem_ptr(rsdp->rsdtaddr);
		struct acpi2_xsdt *xsdt = mem_ptr(rsdp->xsdtaddr);
#ifdef DEBUG
		cprintf("rsdp %p rsdt %p xsdt %p len %u size %u\n",
			mem_phys(rsdp), mem_phys(rsdt), mem_phys(xsdt),
			rsdp->length, sizeof (struct acpi2_rsdp));
#endif
		if (rsdt_scan(rsdt))
			return;
		xsdt_scan(xsdt);
	} else {
		return;
	}
}