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; }
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; }
// 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; }
// 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); }
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; } }