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
void fb_init(void)
{
    SUBSYS_INIT();
    void ** p;

    SET_FOREACH(p, fb_init_funcs) {
        fbi_t fbi;
        fbi = *(fbi_t *)p;
        fbi();
    }
Beispiel #3
0
int bcm_jtag_init(void)
{
    SUBSYS_INIT("BCM2835 JTAG");

    bcm2835_set_gpio_func(22, GPIO_FSEL_ALTFN4);
    bcm2835_set_gpio_func(4, GPIO_FSEL_ALTFN5);
    bcm2835_set_gpio_func(27, GPIO_FSEL_ALTFN4);
    bcm2835_set_gpio_func(25, GPIO_FSEL_ALTFN4);
    bcm2835_set_gpio_func(23, GPIO_FSEL_ALTFN4);
    bcm2835_set_gpio_func(24, GPIO_FSEL_ALTFN4);

    return 0;
}
Beispiel #4
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 #5
0
void vralloc_init(void)
{
    SUBSYS_INIT();
    struct vregion * reg;

    vrlist = dllist_create(struct vregion, node);
    reg = vreg_alloc_node(256);
    if (!(vrlist && reg)) {
        panic("Can't initialize vralloc.");
    }

    last_vreg = reg;

    _bio_init();

    SUBSYS_INITFINI("vralloc OK");
}
Beispiel #6
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 #7
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 #8
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 #9
0
/**
 * Page table mapper init function.
 * @note This function should be called by mmu init.
 */
void ptmapper_init(void)
{
    SUBSYS_INIT();
    KERROR(KERROR_INFO, "ptmapper init started");

    /* Allocate memory for mmu_pagetable_master */
    if (ptmapper_alloc(&mmu_pagetable_master)) {
        panic("Can't allocate memory for master page table.");
    }

    mmu_pagetable_system.master_pt_addr = mmu_pagetable_master.master_pt_addr;
    if (ptmapper_alloc(&mmu_pagetable_system)) {
        panic("Can't allocate memory for system page table.");
    }

    /* Initialize system page tables */
    mmu_init_pagetable(&mmu_pagetable_master);
    mmu_init_pagetable(&mmu_pagetable_system);

    /* Init regions */
    /* Kernel ro region */
    mmu_region_kernel.num_pages  = MMU_PAGE_CNT_BY_RANGE(
            MMU_VADDR_KERNEL_START, (intptr_t)(&_rodata_end) - 1,
            MMU_PGSIZE_COARSE);
    /* Kernel rw data region */
    mmu_region_kdata.vaddr      = (intptr_t)(&_data_start);
    mmu_region_kdata.num_pages  = MMU_PAGE_CNT_BY_RANGE(
            (intptr_t)(&_data_start), MMU_VADDR_KERNEL_END,
            MMU_PGSIZE_COARSE);
    mmu_region_kdata.paddr      = (intptr_t)(&_data_start);

    /* Fill page tables with translations & attributes */
    {
#if configDEBUG >= KERROR_DEBUG
        char buf[80];
        const char str_type[2][9] = {"sections", "pages"};
#define PRINTMAPREG(region) \
        ksprintf(buf, sizeof(buf), "Mapped %s: %u %s", \
            #region, region.num_pages, \
            (region.pt->type == MMU_PTT_MASTER) ? \
                str_type[0] : str_type[1]); \
        KERROR(KERROR_DEBUG, buf);
#else
#define PRINTMAPREG(region)
#endif
#define MAP_REGION(reg) \
        mmu_map_region(&reg); \
        PRINTMAPREG(reg)

        //MAP_REGION(mmu_region_tkstack);
        MAP_REGION(mmu_region_kstack);
        MAP_REGION(mmu_region_kernel);
        MAP_REGION(mmu_region_kdata);
        MAP_REGION(mmu_region_page_tables);
        MAP_REGION(mmu_region_rpihw);
#undef MAP_REGION
#undef PRINTMAPREG
    }

    /* Copy system page table to vm version of it, this is the only easy way to
     * solve some issues now. TODO Maybe we'd like to do some major refactoring
     * some day. */
    vm_pagetable_system.pt = mmu_pagetable_system;
    vm_pagetable_system.linkcount = 1;

    /* Activate page tables */
    mmu_attach_pagetable(&mmu_pagetable_master); /* Load L1 TTB */
#if configDEBUG >= KERROR_DEBUG
    KERROR(KERROR_DEBUG, "Attached TTB mmu_pagetable_master");
#endif
    mmu_attach_pagetable(&mmu_pagetable_system); /* Add L2 pte into L1 mpt */
#if configDEBUG >= KERROR_DEBUG
    KERROR(KERROR_DEBUG, "Attached mmu_pagetable_system");
#endif

    SUBSYS_INITFINI("ptmapper OK");
}
Beispiel #10
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;
}
Beispiel #11
0
/**
 * Page table mapper init function.
 * @note This function should be called by mmu init.
 */
int ptmapper_init(void)
{
    SUBSYS_INIT("ptmapper");
#if defined(configPTMAPPER_DEBUG)
    kputs("\n");
#endif

    /* Allocate memory for mmu_pagetable_master */
    if (ptmapper_alloc(&mmu_pagetable_master)) {
        /* Critical failure */
        panic("Can't allocate memory for master page table.\n");
    }

    mmu_pagetable_system.master_pt_addr = mmu_pagetable_master.master_pt_addr;
    mmu_pagetable_system.nr_tables =
        (MMU_VADDR_KERNEL_END + 1) / MMU_PGSIZE_SECTION;
    if (ptmapper_alloc(&mmu_pagetable_system)) {
        /* Critical failure */
        panic("Can't allocate memory for system page table.\n");
    }

    /* Initialize system page tables */
    mmu_init_pagetable(&mmu_pagetable_master);
    mmu_init_pagetable(&mmu_pagetable_system);

    /*
     * Init regions
     */

    /* Kernel ro region */
    mmu_region_kernel.num_pages  = MMU_PAGE_CNT_BY_RANGE(
            MMU_VADDR_KERNEL_START, (intptr_t)(&_rodata_end) - 1,
            MMU_PGSIZE_COARSE);
    /* Kernel rw data region */
    mmu_region_kdata.vaddr      = (intptr_t)(&_data_start);
    mmu_region_kdata.num_pages  = MMU_PAGE_CNT_BY_RANGE(
            (intptr_t)(&_data_start), MMU_VADDR_KERNEL_END,
            MMU_PGSIZE_COARSE);
    mmu_region_kdata.paddr      = (intptr_t)(&_data_start);

    /* Fill page tables with translations & attributes */
    {
        mmu_region_t ** regp;
#if defined(configPTMAPPER_DEBUG)
        const char str_type[2][9] = {"sections", "pages"};
#define PRINTMAPREG(region)                             \
        KERROR(KERROR_DEBUG, "Mapped %s: %u %s\n",      \
            #region, region.num_pages,                  \
            (region.pt->pt_type == MMU_PTT_MASTER) ?    \
                str_type[0] : str_type[1]);
#else
#define PRINTMAPREG(region)
#endif
#define MAP_REGION(reg)         \
        mmu_map_region(&reg);   \
        PRINTMAPREG(reg)

        MAP_REGION(mmu_region_kstack);
        MAP_REGION(mmu_region_kernel);
        MAP_REGION(mmu_region_kdata);
        MAP_REGION(mmu_region_page_tables);
#undef MAP_REGION
#undef PRINTMAPREG
        SET_FOREACH(regp, ptmapper_fixed_regions) {
            mmu_map_region(*regp);
        }
    }