mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 10:53:16 +01:00
Moved boot-related functions to boot.c
This commit is contained in:
128
tasks/mm0/src/boot.c
Normal file
128
tasks/mm0/src/boot.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Functions used for running initial tasks during boot.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <boot.h>
|
||||
#include <mmap.h>
|
||||
#include <utcb.h>
|
||||
#include <shm.h>
|
||||
#include <l4/api/thread.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
|
||||
int boottask_setup_regions(struct vm_file *file, struct tcb *task,
|
||||
unsigned long task_start, unsigned long task_end)
|
||||
{
|
||||
/*
|
||||
* Set task's main address space boundaries. Not all tasks
|
||||
* run in the default user boundaries, e.g. mm0 pager.
|
||||
*/
|
||||
task->start = task_start;
|
||||
task->end = task_end;
|
||||
|
||||
/* Task stack starts right after the environment. */
|
||||
task->stack_end = task->end;
|
||||
task->stack_start = task->stack_end - DEFAULT_STACK_SIZE;
|
||||
|
||||
/* Prepare environment boundaries. */
|
||||
task->args_end = task->stack_end;
|
||||
task->args_start = task->stack_start - DEFAULT_ENV_SIZE;
|
||||
|
||||
/* Currently RO text and RW data are one region. TODO: Fix this */
|
||||
task->data_start = task->start;
|
||||
task->data_end = task->start + page_align_up(file->length);
|
||||
task->text_start = task->data_start;
|
||||
task->text_end = task->data_end;
|
||||
task->entry = task->text_start;
|
||||
|
||||
/* Task's region available for mmap */
|
||||
task->map_start = task->data_end;
|
||||
task->map_end = task->stack_start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for mmapping boot task regions. These are slightly different
|
||||
* from a vfs executable file.
|
||||
*/
|
||||
int boottask_mmap_regions(struct tcb *task, struct vm_file *file)
|
||||
{
|
||||
void *mapped;
|
||||
struct vm_file *shm;
|
||||
|
||||
/*
|
||||
* mmap each task's physical image to task's address space.
|
||||
* TODO: Map data and text separately when available from bootdesc.
|
||||
*/
|
||||
if (IS_ERR(mapped = do_mmap(file, 0, task, task->text_start,
|
||||
VM_READ | VM_WRITE | VM_EXEC | VMA_PRIVATE,
|
||||
__pfn(page_align_up(task->text_end) -
|
||||
task->text_start)))) {
|
||||
printf("do_mmap: failed with %d.\n", (int)mapped);
|
||||
return (int)mapped;
|
||||
}
|
||||
|
||||
/* mmap each task's stack as anonymous memory. */
|
||||
if (IS_ERR(mapped = do_mmap(0, 0, task, task->stack_start,
|
||||
VM_READ | VM_WRITE |
|
||||
VMA_PRIVATE | VMA_ANONYMOUS,
|
||||
__pfn(task->stack_end -
|
||||
task->stack_start)))) {
|
||||
printf("do_mmap: Mapping stack failed with %d.\n",
|
||||
(int)mapped);
|
||||
return (int)mapped;
|
||||
}
|
||||
|
||||
/* Task's utcb */
|
||||
task->utcb = utcb_new_address();
|
||||
|
||||
/* Create a shared memory segment available for shmat() */
|
||||
if (IS_ERR(shm = shm_new((key_t)task->utcb, __pfn(DEFAULT_UTCB_SIZE))))
|
||||
return (int)shm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main entry point for the creation, initialisation and
|
||||
* execution of a new task.
|
||||
*/
|
||||
struct tcb *boottask_exec(struct vm_file *f, unsigned long task_region_start,
|
||||
unsigned long task_region_end, struct task_ids *ids)
|
||||
{
|
||||
struct tcb *task;
|
||||
int err;
|
||||
|
||||
if (IS_ERR(task = task_create(0, ids, THREAD_NEW_SPACE,
|
||||
TCB_NO_SHARING)))
|
||||
return task;
|
||||
|
||||
if ((err = boottask_setup_regions(f, task, task_region_start,
|
||||
task_region_end)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
if ((err = boottask_mmap_regions(task, f)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
if ((err = task_setup_registers(task, 0, 0, 0)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
/* Add the task to the global task list */
|
||||
global_add_task(task);
|
||||
|
||||
/* Add the file to global vm lists */
|
||||
global_add_vm_file(f);
|
||||
|
||||
/* Prefault all its regions */
|
||||
if (ids->tid == VFS_TID)
|
||||
task_prefault_regions(task, f);
|
||||
|
||||
/* Start the task */
|
||||
if ((err = task_start(task)) < 0)
|
||||
return PTR_ERR(err);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user