Exemple #1
0
int kshell_ata_write(kshell_t *k, int argc, char **argv){
    if (argc != 3){
        dbg(DBG_DISK | DBG_TERM, "received wrong amount of arguments\n");
        kprintf(k, "Usage: <read_block> <string>\n");
        return -1;
    }

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int blocknum = toint(argv[1]);

    char *input_text = argv[2];
    char *data = (void *) page_alloc();

    if (data == NULL){
        kprintf(k, "not enough memory");
        return -1;
    }

    int i = 0;
    while (input_text[i] != NULL){
        data[i] = input_text[i];
        i++;
    }

    data[i] = '\0';

    int result = bd->bd_ops->write_block(bd, data, blocknum, 1);

    page_free((void *) data);

    return result;
}
Exemple #2
0
int kshell_ata_read(kshell_t *k, int argc, char **argv){
    if (argc != 3){
        dbg(DBG_DISK | DBG_TERM, "received wrong amount of arguments\n");
        kprintf(k, "Usage: <read_block> <num_blocks>\n");
        return -1;
    }

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int blocknum = toint(argv[1]);
    int count = toint(argv[2]);

    char *data = (char *) page_alloc_n(count);

    if (data == NULL){
        kprintf(k, "not enough memory");
        return -1;
    }

    int result = bd->bd_ops->read_block(bd, data, blocknum, count);

    char newline[2] = {'\n', '\0'};

    kprintf(k, data);
    kprintf(k, newline);

    page_free_n((void *) data, count);

    return result;
}
Exemple #3
0
static void test_large_block_reads(){
    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int i;
    for (i = 1; i < 129; i++){
        char *readbuf = (char *) page_alloc_n(i);
        char *writebuf = (char *) page_alloc_n(i);

        int j;
        for (j = 0; j < (i * BLOCK_SIZE); j++){
            writebuf[j] = 'f';
        }

        int write_result = bd->bd_ops->write_block(bd, writebuf, 0, i);
        KASSERT(write_result == 0);

        int read_result = bd->bd_ops->read_block(bd, readbuf, 0, i);
        KASSERT(read_result == 0);

        int k;
        for (k = 0; k < (i * BLOCK_SIZE); k++){
            KASSERT(readbuf[k] == 'f');
        }

        page_free_n((void *) readbuf, i);
        page_free_n((void *) writebuf, i);
    }

    dbg(DBG_TESTPASS, "large read stress tests passed\n");
}
Exemple #4
0
void test_single_rw(){
    dbg(DBG_TEST | DBG_DISK, "testing reading and writing to disk\n");

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    KASSERT(bd != NULL);

    char *writebuf = (char *) page_alloc();
    char *readbuf = (char *) page_alloc();

    KASSERT(readbuf != NULL && writebuf != NULL && "not enough memory");

    unsigned int i;
    for (i = 0; i < BLOCK_SIZE; i++){
        writebuf[i] = 'o';
    }

    int block_to_write = 60;

    rw_args_t read_args = {bd, readbuf, block_to_write, 1};
    rw_args_t write_args = {bd, writebuf, block_to_write, 1};

    simple_write(write_args);
    simple_read(read_args);
 
    unsigned int j;
    for (j = 0; j < BLOCK_SIZE; j++){
        KASSERT(readbuf[j] == 'o');
    }

    page_free((void *) readbuf);
    page_free((void *) writebuf);

    dbg(DBG_TESTPASS, "all simple ata tests passed\n");
}
Exemple #5
0
/*
 * Read fs->fs_dev and set fs_op, fs_root, and fs_i.
 *
 * Point fs->fs_i to an s5fs_t*, and initialize it.  Be sure to
 * verify the superblock (using s5_check_super()).  Use vget() to get
 * the root vnode for fs_root.
 *
 * Return 0 on success, negative on failure.
 */
int
s5fs_mount(struct fs *fs)
{
        int num;
        blockdev_t *dev;
        s5fs_t *s5;
        pframe_t *vp;

        KASSERT(fs);

        if (sscanf(fs->fs_dev, "disk%d", &num) != 1) {
                return -EINVAL;
        }

        if (!(dev = blockdev_lookup(MKDEVID(1, num)))) {
                return -EINVAL;
        }

        /* allocate and initialize an s5fs_t: */
        s5 = (s5fs_t *)kmalloc(sizeof(s5fs_t));

        if (!s5)
                return -ENOMEM;

        /*     init s5f_disk: */
        s5->s5f_bdev  = dev;

        /*     init s5f_super: */
        pframe_get(S5FS_TO_VMOBJ(s5), S5_SUPER_BLOCK, &vp);

        KASSERT(vp);

        s5->s5f_super = (s5_super_t *)(vp->pf_addr);

        if (s5_check_super(s5->s5f_super)) {
                /* corrupt */
                kfree(s5);
                return -EINVAL;
        }

        pframe_pin(vp);

        /*     init s5f_mutex: */
        kmutex_init(&s5->s5f_mutex);

        /*     init s5f_fs: */
        s5->s5f_fs = fs;


        /* Init the members of fs that we (the fs-implementation) are
         * responsible for initializing: */
        fs->fs_i = s5;
        fs->fs_op = &s5fs_fsops;
        fs->fs_root = vget(fs, s5->s5f_super->s5s_root_inode);

        return 0;
}
Exemple #6
0
static void read_many_blocks(){
    dbg(DBG_TEST, "reading from LOTS of blocks, one at a time\n");

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    char *writebuf = (char *) page_alloc();
    char *readbuf = (char *) page_alloc();

    KASSERT(writebuf != NULL && readbuf != NULL);

    unsigned int i;
    for (i = 0; i < BLOCK_SIZE; i++){
        writebuf[i] = 'z';
    }

    dbg(DBG_TEST, "reading from blocks before writing them\n");
    int j;
    for (j = 0; j < 1024; j++){
        int read_result = bd->bd_ops->read_block(bd, readbuf, j, 1);
        KASSERT(read_result == 0);
    }

    dbg(DBG_TEST, "writing to all the blocks\n");

    int k;
    for (k = 0; k < 1024; k++){
        int write_result = bd->bd_ops->write_block(bd, writebuf, k, 1);
        KASSERT(write_result == 0);
    }

    dbg(DBG_TEST, "reading from all the written-to blocks\n");
    int l;
    for (l = 0; l < 1024; l++){
        int read_result = bd->bd_ops->read_block(bd, readbuf, l, 1);
        KASSERT(read_result == 0);

        unsigned int m;
        for (m = 0; m < BLOCK_SIZE; m++){
            KASSERT(readbuf[m] == 'z');
        }
    }

    page_free((void *) writebuf);
    page_free((void *) readbuf);

    dbg(DBG_TESTPASS, "single-block stress tests passed\n");
}
Exemple #7
0
/*
 * Initialize a tty device. The driver should not be NULL, but we don't
 * need a line descriptor yet. To initialize the byte device in the tty
 * struct, use the MKDEVID macro and the correct byte device function
 * table for a tty.
 */
tty_device_t *
tty_create(tty_driver_t *driver, int id)
{
    KASSERT(driver != NULL);
    //slab_allocator_t * device_allocator = slab_allocator_create("device", sizeof(tty_device_t));

    tty_device_t * dev = (tty_device_t *)kmalloc(sizeof(tty_device_t));
    dev->tty_driver = driver;
    dev->tty_id = id;
    dev->tty_cdev = *((bytedev_t *)kmalloc(sizeof(bytedev_t)));
    dev->tty_cdev.cd_id = MKDEVID(2, MINOR(id));
    //dbg_print("%d, %d\n", id, MINOR(1));
    dev->tty_cdev.cd_ops = &tty_bytedev_ops;
    list_link_init(&(dev->tty_cdev.cd_link));
        NOT_YET_IMPLEMENTED("DRIVERS: tty_create");
        return dev;
}
Exemple #8
0
/*
 * Initialize a tty device. The driver should not be NULL, but we don't
 * need a line descriptor yet. To initialize the byte device in the tty
 * struct, use the MKDEVID macro and the correct byte device function
 * table for a tty.
 */
tty_device_t *
tty_create(tty_driver_t *driver, int id)
{
        /* DRIVERS {{{ */
        tty_device_t *tty;
        KASSERT(NULL != driver);

        tty = (tty_device_t *)kmalloc(sizeof(tty_device_t));
        if (NULL == tty) return NULL;

        tty->tty_driver = driver;
        tty->tty_ldisc = NULL;
        tty->tty_id = id;
        tty->tty_cdev.cd_id = MKDEVID(TTY_MAJOR, id);
        tty->tty_cdev.cd_ops = &tty_bytedev_ops;

        return tty;
        /* DRIVERS }}} */
        return 0;
}
Exemple #9
0
int vfs_selftest(kshell_t *kshell, int argc, char **argv)
{
  int fd1,fd2;
  char *y="/ab/fil";
  char x[2];
  int err;
  do_mkdir("/ab");
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  fd1=do_open("/ab/new",2);
  fd2=do_dup2(fd1,NFILES+1);
  if(fd2<0)
    {
      dbg(DBG_PRINT,"File not created\n");
    }
  do_mknod("/ab/notmade",4096,MKDEVID(1,1));
  do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1));
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  do_mknod("", S_IFCHR,MKDEVID(1,1));

  /*do_close(fd1);*/
    for(fd2=1;fd2<35;fd2++)
    {
      sprintf(x,"%d",fd2);
      strcat(y,x);
      do_mknod(y,S_IFCHR,MKDEVID(1,0));
      err=do_open(y,2);
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
      
    }
do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1));
 err=do_dup(fd1);
  do_unlink("/ab/new/ab");
 do_unlink("/ab/new");
 do_close(fd1);
 for(fd2=NFILES-1;fd2>0;fd2--)
   {
     err=do_close(fd2);
     sprintf(x,"%d",fd2);
      strcat(y,x);
      do_unlink(y);  
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
   }
 do_link("/a","/dev");
 do_link("/dev","/a");
 do_link("/dev","/a");
 do_rmdir("/a");
 /* mkdir("/k");
    do_link("/ab","/k");*/
  do_rmdir("/ab");
  /*do_rmdir("/k");*/

 /*GS: SELF TESTS*/
    dbg(DBG_PRINT,"\n*************************************************************\n");
    dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n");

    int retVal = 0;
    int i = 0;

    /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");*/
    char longPath[1024 + 1] = {0};
    for(i = 0; i < 1025; i++)
        longPath[i] = 'a';
    struct stat buf;
    retVal = do_stat(longPath, &buf);
    retVal=do_chdir(longPath);

    /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/
    retVal = do_stat("", &buf);

    /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    struct dirent dirp;
    retVal = do_getdent(-1, &dirp);

    /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    retVal = do_getdent(1, &dirp);

    /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/
    do_mknod("/./file", S_IFCHR,MKDEVID(1,1));
    fd1 = do_open("/./file",2);
    retVal = do_getdent(fd1, &dirp);

    do_unlink("/./file");
    do_close(fd1);
    /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/
    /* and */
    /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/
    retVal = do_rename("/./aaa", "/./bbb");


    dbg(DBG_PRINT,"\n\nretVal=%d",retVal);
    dbg(DBG_PRINT,"\n*************************************************************\n");
  return 0;
}
Exemple #10
0
/**
 * 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) */

#ifdef __VFS__
        curproc->p_cwd=vfs_root_vn;
        vref(vfs_root_vn);
        if(initthr!=NULL)
        {
        initthr->kt_proc->p_cwd=vfs_root_vn;
        vref(vfs_root_vn);
        }

        KASSERT(do_mkdir("/dev") == 0);
        KASSERT(do_mknod("/dev/null", S_IFCHR, MKDEVID(1, 0)) == 0);
        KASSERT(do_mknod("/dev/zero", S_IFCHR, MKDEVID(1, 1)) == 0);
        KASSERT(do_mknod("/dev/tty0", S_IFCHR, MKDEVID(2, 0)) == 0);
        KASSERT(do_mknod("/dev/tty1", S_IFCHR, MKDEVID(2, 1)) == 0);
        KASSERT(do_mknod("/dev/tty2", S_IFCHR, MKDEVID(2, 3)) == 0);

        /* 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);
/*        dbg_print("\nidleproc_run returned from sched_make_rinnable and calling do wait_pid \n");*/
        /* Now wait for it */        
        child = do_waitpid(-1, 0, &status);
        dbg(DBG_INIT,"Process %d cleaned successfully\n", child);
        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
dbg_print("weenix: vfs shutdown...\n");
        /* Shutdown the pframe system */
#ifdef __S5FS__
        
        pframe_shutdown();
        
#endif

        dbg_print("\nweenix: halted cleanly!\n");
        GDB_CALL_HOOK(shutdown);
        hard_shutdown();
        return NULL;
}
Exemple #11
0
/**
 * 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;
}
Exemple #12
0
void test_multiple_threads(){
    dbg(DBG_TEST | DBG_DISK, "testing reading and writing to disk with multiple threads\n");
    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    KASSERT (bd != NULL);

    char *readbuf1 = (char *) page_alloc_n(BLOCKS_TO_READ);
    char *readbuf2 = (char *) page_alloc_n(BLOCKS_TO_READ);
    char *writebuf1 = (char *) page_alloc_n(BLOCKS_TO_WRITE);
    char *writebuf2 = (char *) page_alloc_n(BLOCKS_TO_WRITE);

    KASSERT(readbuf1 != NULL && 
            readbuf2 != NULL &&
            writebuf2 != NULL &&
            writebuf2 != NULL &&
            "not enough memory");

    unsigned int i;
    for (i = 0; i < (BLOCK_SIZE * BLOCKS_TO_WRITE); i++){
        writebuf1[i] = 'a';
        writebuf2[i] = 'b';
    }

    /* create and run procs and threads for writing */
    rw_args_t write_args_1 = {bd, writebuf1, BLOCKNUM_1, BLOCKS_TO_WRITE};
    rw_args_t write_args_2 = {bd, writebuf2, BLOCKNUM_2, BLOCKS_TO_WRITE};

    proc_t *wp1 = proc_create("ata_write_proc_1");
    proc_t *wp2 = proc_create("ata_write_proc_2");

    kthread_t *wt1 = kthread_create(wp1, write_func, 0, (void *) &write_args_1); 
    kthread_t *wt2 = kthread_create(wp2, write_func, 0, (void *) &write_args_2);

    sched_make_runnable(wt1);
    sched_make_runnable(wt2);

    int status;
    do_waitpid(wp1->p_pid, 0, &status);
    do_waitpid(wp2->p_pid, 0, &status);

    /* create and run procs and threads for reading */
    rw_args_t read_args_1 = {bd, readbuf1, BLOCKNUM_1, BLOCKS_TO_READ};
    rw_args_t read_args_2 = {bd, readbuf2, BLOCKNUM_2, BLOCKS_TO_READ};

    proc_t *rp1 = proc_create("ata_read_proc_1");
    proc_t *rp2 = proc_create("ata_read_proc_2");

    kthread_t *rt1 = kthread_create(rp1, read_func, 0, (void *) &read_args_1);
    kthread_t *rt2 = kthread_create(rp2, read_func, 0, (void *) &read_args_2);

    sched_make_runnable(rt1);
    sched_make_runnable(rt2);

    do_waitpid(rp1->p_pid, 0, &status);
    do_waitpid(rp2->p_pid, 0, &status);

    /* make sure that we wrote and read properly */
    unsigned int j;
    for (j = 0; j < BLOCK_SIZE * BLOCKS_TO_READ; j++){
        KASSERT(readbuf1[j] == 'a');
        KASSERT(readbuf2[j] == 'b');
    }

    page_free_n((void *) readbuf1, BLOCKS_TO_READ);
    page_free_n((void *) readbuf2, BLOCKS_TO_READ);
    page_free_n((void *) writebuf1, BLOCKS_TO_WRITE);
    page_free_n((void *) writebuf2, BLOCKS_TO_WRITE);

    dbg(DBG_TESTPASS, "All multi-threaded read/write tests passed\n");
}
Exemple #13
0
/**
 * 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;
}