Beispiel #1
0
int __kinit__ devfs_init(void)
{
    struct fs_superblock * sb;

    SUBSYS_DEP(ramfs_init);
    SUBSYS_INIT("devfs");

    FS_GIANT_INIT(&devfs_fs.fs_giant);

    /*
     * Inherit ramfs and override what's needed.
     */
    fs_inherit_vnops(&devfs_vnode_ops, &ramfs_vnode_ops);
    vn_devfs = fs_create_pseudofs_root(&devfs_fs, VDEV_MJNR_DEVFS);
    if (!vn_devfs)
        return -ENOMEM;

    /*
     * It's perfectly ok to set a new delete_vnode() function
     * as sb struct is always a fresh struct so altering it
     * doesn't really break functionality for anyone else than us.
     */
    sb = vn_devfs->sb;
    sb->delete_vnode = devfs_delete_vnode;
    sb->umount = devfs_umount;

    /*
     * Finally register our creation with fs subsystem.
     */
    fs_register(&devfs_fs);

    _devfs_create_specials();

    return 0;
}
Beispiel #2
0
int __kinit__ bcm2835_info_init(void)
{
    SUBSYS_DEP(bcm2835_prop_init);
    SUBSYS_INIT("BCM2835_info");

    kputs("\n");
    print_prop("firmware", 0x00000001, 1);
    print_prop("board model", 0x00010001, 1);
    print_prop("board rev", 0x00010002, 1);
    print_prop("board serial", 0x00010004, 2);

    return 0;
}
Beispiel #3
0
int __kinit__ fatfs_init(void)
{
    int err;

    SUBSYS_DEP(fs_init);
    SUBSYS_DEP(proc_init);
    SUBSYS_INIT("fatfs");

    fatfs_sb_arr = kcalloc(configFATFS_MAX_MOUNTS, sizeof(struct fatfs_sb *));
    if (!fatfs_sb_arr)
        return -ENOMEM;

    fs_inherit_vnops(&fatfs_vnode_ops, &nofs_vnode_ops);

    err = ff_init();
    if (err)
        return err;

    FS_GIANT_INIT(&fatfs_fs.fs_giant);
    fs_register(&fatfs_fs);

    return 0;
}
Beispiel #4
0
int __kinit__ procfs_init(void)
{
    SUBSYS_DEP(ramfs_init);
    SUBSYS_INIT("procfs");

    /*
     * This must be static as it's referenced and used in the file system via
     * the fs object system.
     */
    static fs_t procfs_fs = {
        .fsname = PROCFS_FSNAME,
        .mount = procfs_mount,
        .sblist_head = SLIST_HEAD_INITIALIZER(),
    };

    specinfo_pool = mempool_init(MEMPOOL_TYPE_NONBLOCKING,
                                 sizeof(struct procfs_info),
                                 configMAXPROC);
    if (!specinfo_pool)
        return -ENOMEM;

    FS_GIANT_INIT(&procfs_fs.fs_giant);

    /*
     * Inherit unimplemented vnops from ramfs.
     */
    fs_inherit_vnops(&procfs_vnode_ops, &ramfs_vnode_ops);

    vn_procfs = fs_create_pseudofs_root(&procfs_fs, VDEV_MJNR_PROCFS);
    if (!vn_procfs)
        return -ENOMEM;

    struct fs_superblock * sb = vn_procfs->sb;
    sb->delete_vnode = procfs_delete_vnode;

    vn_procfs->sb->umount = procfs_umount;
    fs_register(&procfs_fs);

    int err = init_permanent_files();
    if (err)
        return err;

    procfs_updatedir(vn_procfs);

    return 0;
}
Beispiel #5
0
int __kinit__ devfs_init(void)
{
    SUBSYS_DEP(ramfs_init);
    SUBSYS_INIT("devfs");

    /*
     * This must be static as it's referenced and used in the file system via
     * the fs object system.
     */
    static fs_t devfs_fs = {
        .fsname = DEVFS_FSNAME,
        .mount = devfs_mount,
        .sblist_head = SLIST_HEAD_INITIALIZER(),
    };

    FS_GIANT_INIT(&devfs_fs.fs_giant);

    /*
     * Inherit ramfs and override what's needed.
     */
    fs_inherit_vnops(&devfs_vnode_ops, &ramfs_vnode_ops);
    vn_devfs = fs_create_pseudofs_root(&devfs_fs, VDEV_MJNR_DEVFS);
    if (!vn_devfs)
        return -ENOMEM;

    /*
     * It's perfectly ok to set a new delete_vnode() function
     * as sb struct is always a fresh struct so altering it
     * doesn't really break functionality for anyone else than us.
     */
    struct fs_superblock * sb = vn_devfs->sb;
    sb->delete_vnode = devfs_delete_vnode;
    sb->umount = devfs_umount;

    /*
     * Finally register our creation with fs subsystem.
     */
    fs_register(&devfs_fs);

    _devfs_create_specials();

    return 0;
}
Beispiel #6
0
static pthread_t create_uinit_main(void * stack_addr)
{
    struct _sched_pthread_create_args init_ds = {
        .param.sched_policy = SCHED_OTHER,
        .param.sched_priority = NZERO,
        .stack_addr = stack_addr,
        .stack_size = configUSRINIT_SSIZE,
        .flags      = 0,
        .start      = uinit, /* We have to first get into user space to use exec
                              * and mount the rootfs.
                              */
        .arg1       = (uintptr_t)rootfs,
        .del_thread = (void (*)(void *))uinit_exit,
    };

    return thread_create(&init_ds, THREAD_MODE_PRIV);
}

/**
 * Map vmstack to proc.
 */
static void map_vmstack2proc(struct proc_info * proc, struct buf * vmstack)
{
    struct vm_pt * vpt;

    (*proc->mm.regions)[MM_STACK_REGION] = vmstack;
    vm_updateusr_ap(vmstack);

    vpt = ptlist_get_pt(&proc->mm, vmstack->b_mmu.vaddr,
                        MMU_PGSIZE_COARSE, VM_PT_CREAT);
    if (vpt == 0)
        panic("Couldn't get vpt for init stack");

    vmstack->b_mmu.pt = &(vpt->pt);
    vm_map_region(vmstack, vpt);
}

/**
 * Create init process.
 */
int __kinit__ kinit(void)
{
    SUBSYS_DEP(sched_init);
    SUBSYS_DEP(proc_init);
    SUBSYS_DEP(ramfs_init);
    SUBSYS_DEP(sysctl_init);
    SUBSYS_INIT("kinit");

    char strbuf[80]; /* Buffer for panic messages. */
    struct buf * init_vmstack;
    pthread_t tid;
    pid_t pid;
    struct thread_info * init_thread;
    struct proc_info * init_proc;


    /*
     * FIXME Memory allocation, protection or manipulation bug!
     * There is a critical bug causing random crashes in userland. I suspect
     * something is overwriting user space allocation from the kernel space.
     * Allocating some memory before init is executed seems to fix this issue,
     * however naturally this is not the proper way to fix the bug.
     * Without the allocation here the issue is sometimes seen in init or
     * usually after couple of fork + exec + exit cycles. The usual symptom is
     * that the userland app first calls some 0:0 syscalls and then tries to
     * execute undefined instruction, which probably means that either some
     * jump table in the heap or some part of the executable code is modified
     * by a bad access in kernel mode just before this happens.
     */
    (void)geteblk(MMU_PGSIZE_COARSE * 10);


    mount_tmp_rootfs();

    /*
     * User stack for init
     */
    init_vmstack = create_vmstack();
    if (!init_vmstack)
        panic("Can't allocate a stack for init");

    /*
     * Create a thread for init
     */
    tid = create_uinit_main((void *)(init_vmstack->b_mmu.paddr));
    if (tid < 0) {
        ksprintf(strbuf, sizeof(strbuf), "Can't create a thread for init. %i",
                 tid);
        panic(strbuf);
    }

    /*
     * pid of init
     */
    pid = proc_fork();
    if (pid <= 0) {
        ksprintf(strbuf, sizeof(strbuf), "Can't fork a process for init. %i",
                 pid);
        panic(strbuf);
    }

    init_thread = thread_lookup(tid);
    if (!init_thread) {
        panic("Can't get thread descriptor of init_thread!");
    }

    init_proc = proc_ref(pid);
    if (!init_proc || (init_proc->state == PROC_STATE_INITIAL)) {
        panic("Failed to get proc struct or invalid struct");
    }

    init_thread->pid_owner = pid;
    init_thread->curr_mpt = &init_proc->mm.mpt;

    /*
     * Map the previously created user stack with init process page table.
     */
    map_vmstack2proc(init_proc, init_vmstack);

    /*
     * Map tkstack of init with vm_pagetable_system.
     */
    mmu_map_region(&init_thread->kstack_region->b_mmu);
    init_proc->main_thread = init_thread;

    KERROR_DBG("Init created with pid: %u, tid: %u, stack: %p\n",
               pid, tid, (void *)init_vmstack->b_mmu.vaddr);

    proc_unref(init_proc);

    return 0;
}