/** * Once we're inside of idleproc_run(), we are executing in the context of the * first process-- a real context, so we can finally begin running * meaningful code. * * This is the body of process 0. It should initialize all that we didn't * already initialize in kmain(), launch the init process (initproc_run), * wait for the init process to exit, then halt the machine. * * @param arg1 the first argument (unused) * @param arg2 the second argument (unused) */ static void * idleproc_run(int arg1, void *arg2) { int status; pid_t child; dbg_print("Made it to idleproc_run\n"); /* create init proc */ kthread_t *initthr = initproc_create(); init_call_all(); GDB_CALL_HOOK(initialized); /* Create other kernel threads (in order) */ #ifdef __VFS__ /* Once you have VFS remember to set the current working directory * of the idle and init processes */ /* Here you need to make the null, zero, and tty devices using mknod */ /* You can't do this until you have VFS, check the include/drivers/dev.h * file for macros with the device ID's you will need to pass to mknod */ #endif /* Finally, enable interrupts (we want to make sure interrupts * are enabled AFTER all drivers are initialized) */ intr_enable(); /* Run initproc */ sched_make_runnable(initthr); /* Now wait for it */ child = do_waitpid(-1, 0, &status); KASSERT(PID_INIT == child); #ifdef __MTP__ kthread_reapd_shutdown(); #endif #ifdef __VFS__ /* Shutdown the vfs: */ dbg_print("weenix: vfs shutdown...\n"); vput(curproc->p_cwd); if (vfs_shutdown()) panic("vfs shutdown FAILED!!\n"); #endif /* Shutdown the pframe system */ #ifdef __S5FS__ pframe_shutdown(); #endif dbg_print("\nweenix: halted cleanly!\n"); GDB_CALL_HOOK(shutdown); hard_shutdown(); return NULL; }
/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); /* This little loop gives gdb a place to synch up with weenix. In the * past the weenix command started qemu was started with -S which * allowed gdb to connect and start before the boot loader ran, but * since then a bug has appeared where breakpoints fail if gdb connects * before the boot loader runs. See * * https://bugs.launchpad.net/qemu/+bug/526653 * * This loop (along with an additional command in init.gdb setting * gdb_wait to 0) sticks weenix at a known place so gdb can join a * running weenix, set gdb_wait to zero and catch the breakpoint in * bootstrap below. See Config.mk for how to set GDBWAIT correctly. * * DANGER: if GDBWAIT != 0, and gdb is not running, this loop will never * exit and weenix will not run. Make SURE the GDBWAIT is set the way * you expect. */ while (gdb_wait) ; context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
/** * Once we're inside of idleproc_run(), we are executing in the context of the * first process-- a real context, so we can finally begin running * meaningful code. * * This is the body of process 0. It should initialize all that we didn't * already initialize in kmain(), launch the init process (initproc_run), * wait for the init process to exit, then halt the machine. * * @param arg1 the first argument (unused) * @param arg2 the second argument (unused) */ static void * idleproc_run(int arg1, void *arg2) { int status; pid_t child; /* create init proc */ kthread_t *initthr = initproc_create(); /* dbg(DBG_INIT,"created initproc"); dbg(DBG_INIT,"%d",curproc->p_pid);*/ init_call_all(); GDB_CALL_HOOK(initialized); /* Create other kernel threads (in order) */ #ifdef __VFS__ /* Once you have VFS remember to set the current working directory * of the idle and init processes */ curproc->p_cwd = vfs_root_vn; initthr->kt_proc->p_cwd = vfs_root_vn; vref(vfs_root_vn); vref(vfs_root_vn); /* Here you need to make the null, zero, and tty devices using mknod */ /* You can't do this until you have VFS, check the include/drivers/dev.h * file for macros with the device ID's you will need to pass to mknod */ /*NOT_YET_IMPLEMENTED("VFS: idleproc_run");*/ /*TODO Dont know When VFS will be formed*/ if(do_mkdir("/dev") >= 0) { dbg(DBG_PRINT,"(GRADING2C) Creating null, zero and tty0\n"); /*do_mkdir("/dev");*/ /*Block devices*/ int status1=do_mknod("/dev/null", S_IFCHR, MEM_NULL_DEVID); int status2=do_mknod("/dev/zero", S_IFCHR, MEM_ZERO_DEVID); int status3=do_mknod("/dev/tty0", S_IFCHR, MKDEVID(2, 0)); } #endif /* Finally, enable interrupts (we want to make sure interrupts * are enabled AFTER all drivers are initialized) */ intr_enable(); /* Run initproc */ sched_make_runnable(initthr); /* Now wait for it */ child = do_waitpid(-1, 0, &status); KASSERT(PID_INIT == child); #ifdef __MTP__ kthread_reapd_shutdown(); #endif #ifdef __VFS__ /* Shutdown the vfs: */ dbg_print("weenix: vfs shutdown...\n"); vput(curproc->p_cwd); if (vfs_shutdown()) panic("vfs shutdown FAILED!!\n"); #endif /* Shutdown the pframe system */ #ifdef __S5FS__ pframe_shutdown(); #endif dbg_print("\nweenix: halted cleanly!\n"); GDB_CALL_HOOK(shutdown); hard_shutdown(); return NULL; }
/** * Once we're inside of idleproc_run(), we are executing in the context of the * first process-- a real context, so we can finally begin running * meaningful code. * * This is the body of process 0. It should initialize all that we didn't * already initialize in kmain(), launch the init process (initproc_run), * wait for the init process to exit, then halt the machine. * * @param arg1 the first argument (unused) * @param arg2 the second argument (unused) */ static void * idleproc_run(int arg1, void *arg2) { int status; pid_t child; /* create init proc */ kthread_t *initthr = initproc_create(); init_call_all(); GDB_CALL_HOOK(initialized); /* Create other kernel threads (in order) */ /* PROCS BLANK {{{ */ #ifdef __SHADOWD__ /* TODO port this - alvin */ #endif /* PROCS BLANK }}} */ #ifdef __VFS__ /* Once you have VFS remember to set the current working directory * of the idle and init processes */ /* PROCS BLANK {{{ */ proc_t *idle = proc_lookup(PID_IDLE); proc_t *init = proc_lookup(PID_INIT); KASSERT(NULL != idle); KASSERT(NULL != init); idle->p_cwd = vfs_root_vn; init->p_cwd = vfs_root_vn; vref(vfs_root_vn); vref(vfs_root_vn); /* PROCS BLANK }}} */ /* Here you need to make the null, zero, and tty devices using mknod */ /* You can't do this until you have VFS, check the include/drivers/dev.h * file for macros with the device ID's you will need to pass to mknod */ /* PROCS BLANK {{{ */ int fd, ii; char path[32]; struct stat statbuf; if (do_stat("/dev", &statbuf) < 0) { KASSERT(!(status = do_mkdir("/dev"))); } if ((fd = do_open("/dev/null", O_RDONLY)) < 0) { KASSERT(!(status = do_mknod("/dev/null", S_IFCHR, MEM_NULL_DEVID))); } else { do_close(fd); } if ((fd = do_open("/dev/zero", O_RDONLY)) < 0) { KASSERT(!(status = do_mknod("/dev/zero", S_IFCHR, MEM_ZERO_DEVID))); } else { do_close(fd); } memset(path, '\0', 32); for (ii = 0; ii < __NTERMS__; ii++) { sprintf(path, "/dev/tty%d", ii); dbg(DBG_INIT, "Creating tty mknod with path %s\n", path); if ((fd = do_open(path, O_RDONLY)) < 0) { KASSERT(!do_mknod(path, S_IFCHR, MKDEVID(2, ii))); } else { do_close(fd); } } for (ii = 0; ii < __NDISKS__; ii++) { sprintf(path, "/dev/hda%d", ii); dbg(DBG_INIT, "Creating disk mknod with path %s\n", path); if ((fd = do_open(path, O_RDONLY)) < 0) { KASSERT(!do_mknod(path, S_IFBLK, MKDEVID(1, ii))); } else { do_close(fd); } } /* PROCS BLANK }}} */ #endif /* Finally, enable interrupts (we want to make sure interrupts * are enabled AFTER all drivers are initialized) */ intr_enable(); /* Run initproc */ sched_make_runnable(initthr); /* Now wait for it */ child = do_waitpid(-1, 0, &status); KASSERT(PID_INIT == child); #ifdef __MTP__ kthread_reapd_shutdown(); #endif #ifdef __SHADOWD__ /* wait for shadowd to shutdown */ shadowd_shutdown(); #endif #ifdef __VFS__ /* Shutdown the vfs: */ dbg_print("weenix: vfs shutdown...\n"); vput(curproc->p_cwd); if (vfs_shutdown()) panic("vfs shutdown FAILED!!\n"); #endif /* Shutdown the pframe system */ #ifdef __S5FS__ pframe_shutdown(); #endif dbg_print("\nweenix: halted cleanly!\n"); GDB_CALL_HOOK(shutdown); hard_shutdown(); return NULL; }