コード例 #1
0
ファイル: pagetable.c プロジェクト: himaaaatti/himawari
bool init_pagetable(uintptr_t rounded_kernel_memory_end)
{
    kernel_page_directory_num = rounded_kernel_memory_end / 0x200000;
    kernel_pml4               = create_pml4();

    __asm__ volatile(
        "movq %0, %%cr3" ::"r"((uintptr_t)kernel_pml4 - START_KERNEL_MAP)
        : "memory");

    return true;
}
コード例 #2
0
ファイル: process.c プロジェクト: Enerccio/Cthulhu-OS
int create_process_base(uint8_t* image_data, int argc, char** argv,
        char** envp, proc_t** cpt, uint8_t asked_priority, registers_t* r) {
    proc_spinlock_lock(&__thread_modifier);
    uint8_t cpp = get_current_cput()->ct->parent_process->priority;
    proc_spinlock_unlock(&__thread_modifier);

    if (cpp > asked_priority) {
        return EINVAL;
    }

    int envc = 0;
    char** envt = envp;
    while (*envt != NULL) {
        ++envc;
        ++envt;
    }

    int err;
    if ((err = cpy_array(argc, &argv)) != 0)
        return err;
    if ((err = cpy_array(envc, &envp)) != 0) {
        free_array(argc, argv);
        return err;
    }
    // envp and argv are now kernel structures

    proc_t* process = malloc(sizeof(proc_t));
    if (process == NULL) {
        return ENOMEM_INTERNAL;
    }
    memset(process, 0, sizeof(proc_t));

    process->__ob_lock = 0;
    process->process_list.data = process;
    process->pprocess = true;

    process->fds = create_array();
    if (process->fds == NULL) {
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->threads = create_array();
    if (process->fds == NULL) {
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->mem_maps = NULL;
    process->proc_random = rg_create_random_generator(get_unix_time());
    process->parent = NULL;
    process->priority = asked_priority;
    process->pml4 = create_pml4();
    if (process->pml4 == 0) {
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->futexes = create_uint64_table();

    if (process->futexes == NULL) {
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->input_buffer = create_queue_static(__message_getter);

    if (process->input_buffer == NULL) {
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->pq_input_buffer = create_queue_static(__message_getter);

    if (process->input_buffer == NULL) {
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->blocked_wait_messages = create_list_static(__message_getter);
    if (process->blocked_wait_messages == NULL) {
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        return ENOMEM_INTERNAL;
    }

    process->temp_processes = create_list_static(__process_get_function);
	if (process->blocked_wait_messages == NULL) {
		free_list(process->blocked_wait_messages);
		free_queue(process->pq_input_buffer);
		free_queue(process->input_buffer);
		destroy_table(process->futexes);
		destroy_array(process->threads);
		destroy_array(process->fds);
		free(process);
		return ENOMEM_INTERNAL;
	}

    thread_t* main_thread = malloc(sizeof(thread_t));
    if (main_thread == NULL) {
    	free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return ENOMEM_INTERNAL;
    }
    memset(main_thread, 0, sizeof(thread_t));
    main_thread->parent_process = process;
    main_thread->priority = asked_priority;
    main_thread->blocked = false;

    main_thread->continuation = malloc(sizeof(continuation_t));
    if (main_thread->continuation == NULL) {
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return ENOMEM_INTERNAL;
    }
    main_thread->continuation->present = false;

    main_thread->futex_block = create_list_static(__blocked_getter);
    if (main_thread->futex_block == NULL) {
        free(main_thread->continuation);
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return ENOMEM_INTERNAL;
    }

    array_push_data(process->threads, main_thread);

    err = load_elf_exec((uintptr_t)image_data, process);
    if (err == ELF_ERROR_ENOMEM) {
        err = ENOMEM_INTERNAL;
    } else if (err != 0) {
        err = EINVAL;
    }

    if (err != 0) {
        free_list(main_thread->futex_block);
        free(main_thread->continuation);
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return err;
    }

    char** argvu = argv;
    char** envpu = envp;
    if ((err = cpy_array_user(argc, &argvu, process)) != 0) {
        free_list(main_thread->futex_block);
        free(main_thread->continuation);
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return err;
    }
    if ((err = cpy_array_user(envc, &envpu, process)) != 0) {
        free_list(main_thread->futex_block);
        free(main_thread->continuation);
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return err;
    }

    main_thread->local_info = proc_alloc_direct(process, sizeof(tli_t));
    if (main_thread->local_info == NULL) {
        free_list(main_thread->futex_block);
        free(main_thread->continuation);
        free(main_thread);
        free_list(process->temp_processes);
        free_list(process->blocked_wait_messages);
        free_queue(process->pq_input_buffer);
        free_queue(process->input_buffer);
        destroy_table(process->futexes);
        destroy_array(process->threads);
        destroy_array(process->fds);
        free(process);
        // TODO: free process address page
        return ENOMEM_INTERNAL;
    }
    tli_t* li = different_page_mem(process->pml4, main_thread->local_info);
    li->self = main_thread->local_info;

    for (int i=0; i<MESSAGE_BUFFER_CNT; i++) {
        _message_t* m = &process->output_buffer[i];
        m->owner = process;
        m->used = false;
        m->message = proc_alloc_direct(process, 0x200000);
        if (m->message == NULL) {
            free_list(main_thread->futex_block);
            free(main_thread->continuation);
            free(main_thread);
            free_list(process->temp_processes);
            free_list(process->blocked_wait_messages);
            free_queue(process->pq_input_buffer);
            free_queue(process->input_buffer);
            destroy_table(process->futexes);
            destroy_array(process->threads);
            destroy_array(process->fds);
            free(process);
            // TODO: free process address page
            return ENOMEM_INTERNAL;
        }
    }

    process->argc = argc;
    process->argv = argvu;
    process->environ = envpu;

    main_thread->last_r12 = 0;
    main_thread->last_r11 = 0;
    main_thread->last_r10 = 0;
    main_thread->last_r9 = 0;
    main_thread->last_r8 = 0;
    main_thread->last_rax = 0;
    main_thread->last_rbx = 0;
    main_thread->last_rcx = 0;
    main_thread->last_rdx = 0;
    main_thread->last_rdi = 0;
    main_thread->last_rsi = 0;
    main_thread->last_rbp = 0;
    main_thread->last_rflags = 0x200; // enable interrupts

    proc_spinlock_lock(&__proclist_lock);
    main_thread->tId = __atomic_add_fetch(&thread_id_num, 1, __ATOMIC_SEQ_CST);
    process->proc_id = ++process_id_num;
    list_push_right(processes, process);
    proc_spinlock_unlock(&__proclist_lock);

    li->t = main_thread->tId;
    main_thread->last_rdi = (ruint_t)(uintptr_t)process->argc;
    main_thread->last_rsi = (ruint_t)(uintptr_t)process->argv;
    main_thread->last_rdx = (ruint_t)(uintptr_t)process->environ;
    main_thread->blocked_list.data = main_thread;
    main_thread->schedule_list.data = main_thread;

    free_array(argc, argv);
    free_array(envc, envp);

    // TODO: add split option?
    main_thread->last_rax = process->proc_id;
    enschedule_best(main_thread);
    *cpt = process;
    return 0;
}