Modified task initialisation so that stack now comes beneath the environment

Environment is backed by a special per-task file maintained by mm0 for each task.
This file is filled in by the env pager, by simple copying of env data into the
faulty page upon a fault. UTCB and all anon regions (stack) could use the same
scheme.

Fixed IS_ERR(x) to accept negative values that are above -1000 for errors. This
protects against false positives for pointers such as 0xE0000000.

	modified:   include/l4/generic/scheduler.h
	modified:   include/l4/macros.h
	modified:   src/arch/arm/exception.c
	modified:   tasks/fs0/include/linker.lds
	modified:   tasks/libl4/src/init.c
	modified:   tasks/libposix/shm.c
	new file:   tasks/mm0/include/env.h
	modified:   tasks/mm0/include/file.h
	new file:   tasks/mm0/include/lib/addr.h
	deleted:    tasks/mm0/include/lib/vaddr.h
	modified:   tasks/mm0/include/task.h
	new file:   tasks/mm0/include/utcb.h
	new file:   tasks/mm0/src/env.c
	modified:   tasks/mm0/src/fault.c
	modified:   tasks/mm0/src/file.c
	modified:   tasks/mm0/src/init.c
	new file:   tasks/mm0/src/lib/addr.c
	modified:   tasks/mm0/src/lib/idpool.c
	deleted:    tasks/mm0/src/lib/vaddr.c
	modified:   tasks/mm0/src/mmap.c
	modified:   tasks/mm0/src/shm.c
	modified:   tasks/mm0/src/task.c
	new file:   tasks/mm0/src/utcb.c
	modified:   tasks/test0/include/linker.lds
This commit is contained in:
Bahadir Balban
2008-02-29 01:43:56 +00:00
parent 5b7bb88008
commit 617d24b4f0
24 changed files with 316 additions and 144 deletions

View File

@@ -12,7 +12,7 @@
/* Ticks per second, try ticks = 1000 + timeslice = 1 for regressed preemption test. */
#define HZ 10
#define TASK_TIMESLICE_DEFAULT 100
#define TASK_TIMESLICE_DEFAULT 500
/* #define TASK_TIMESLICE_DEFAULT (HZ/100)*/
static inline struct ktcb *current_task(void)

View File

@@ -77,7 +77,8 @@
/* Functions who may either return a pointer or an error code can use these: */
#define PTR_ERR(x) ((void *)(x))
#define IS_ERR(x) (((int)(x)) < 0)
/* checks up to -1000, the rest might be valid pointers!!! E.g. 0xE0000000 */
#define IS_ERR(x) ((((int)(x)) < 0) && (((int)(x) > -1000)))
/* TEST: Is this type of printk well tested? */
#define BUG() {do { \

View File

@@ -82,22 +82,22 @@ int check_aborts(u32 faulted_pc, u32 fsr, u32 far)
int ret = 0;
if (is_prefetch_abort(fsr)) {
// dprintk("Prefetch abort @ ", faulted_pc);
dprintk("Prefetch abort @ ", faulted_pc);
return 0;
}
switch (fsr & ARM_FSR_MASK) {
/* Aborts that are expected on page faults: */
case DABT_PERM_PAGE:
// dprintk("Page permission fault @ ", far);
dprintk("Page permission fault @ ", far);
ret = 0;
break;
case DABT_XLATE_PAGE:
// dprintk("Page translation fault @ ", far);
dprintk("Page translation fault @ ", far);
ret = 0;
break;
case DABT_XLATE_SECT:
// dprintk("Section translation fault @ ", far);
dprintk("Section translation fault @ ", far);
ret = 0;
break;
@@ -166,7 +166,7 @@ int check_aborts(u32 faulted_pc, u32 fsr, u32 far)
void data_abort_handler(u32 faulted_pc, u32 fsr, u32 far)
{
set_abort_type(fsr, ARM_DABT);
// dprintk("Data abort @ PC: ", faulted_pc);
dprintk("Data abort @ PC: ", faulted_pc);
if (check_aborts(faulted_pc, fsr, far) < 0) {
printascii("This abort can't be handled by any pager.\n");
goto error;

View File

@@ -14,7 +14,7 @@
*/
/* USER_AREA_START, see memlayout.h */
virtual_base = 0x10000000;
__stack = 0x20000000;
__stack = (0x20000000 - 0x1000 - 8); /* First page before env/args page */
INCLUDE "include/physical_base.lds"
/* physical_base = 0x228000; */

View File

@@ -4,6 +4,9 @@
* Copyright (C) 2007 Bahadir Balban
*/
#include <l4lib/kip.h>
#include <l4lib/arch/syslib.h>
#include <l4/macros.h>
#include INC_GLUE(memlayout.h)
__l4_ipc_t __l4_ipc = 0;
__l4_map_t __l4_map = 0;
@@ -22,22 +25,32 @@ struct kip *kip;
/* UTCB address of this task. */
struct utcb *utcb;
#include <stdio.h>
void __l4_init(void)
{
kip = l4_kernel_interface(0, 0, 0);
kip = l4_kernel_interface(0, 0, 0);
__l4_ipc = (__l4_ipc_t)kip->ipc;
__l4_map = (__l4_map_t)kip->map;
__l4_unmap = (__l4_unmap_t)kip->unmap;
__l4_kread = (__l4_kread_t)kip->kread;
__l4_getid = (__l4_getid_t)kip->getid;
__l4_thread_switch = (__l4_thread_switch_t)kip->thread_switch;
__l4_thread_control= (__l4_thread_control_t)kip->thread_control;
__l4_ipc_control= (__l4_ipc_control_t)kip->ipc_control;
__l4_space_control= (__l4_space_control_t)kip->space_control;
__l4_exchange_registers =
(__l4_exchange_registers_t)kip->exchange_registers;
__l4_kmem_grant = (__l4_kmem_grant_t)kip->kmem_grant;
__l4_kmem_reclaim = (__l4_kmem_reclaim_t)kip->kmem_reclaim;
/* Initialise utcb only if we're not the pager */
if (self_tid() != PAGER_TID) {
utcb = *(struct utcb **)(USER_AREA_END - 8);
printf("UTCB Read from userspace as: 0x%x\n",
(unsigned long)utcb);
}
__l4_ipc = (__l4_ipc_t)kip->ipc;
__l4_map = (__l4_map_t)kip->map;
__l4_unmap = (__l4_unmap_t)kip->unmap;
__l4_kread = (__l4_kread_t)kip->kread;
__l4_getid = (__l4_getid_t)kip->getid;
__l4_thread_switch =(__l4_thread_switch_t)kip->thread_switch;
__l4_thread_control=(__l4_thread_control_t)kip->thread_control;
__l4_ipc_control= (__l4_ipc_control_t)kip->ipc_control;
__l4_space_control=(__l4_space_control_t)kip->space_control;
__l4_exchange_registers =(__l4_exchange_registers_t)kip->exchange_registers;
__l4_kmem_grant =(__l4_kmem_grant_t)kip->kmem_grant;
__l4_kmem_reclaim =(__l4_kmem_reclaim_t)kip->kmem_reclaim;
}

View File

@@ -11,9 +11,7 @@
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#define PTR_ERR(x) ((void *)(x))
#define IS_ERR(x) (((int)(x)) < 0)
#include <l4/macros.h>
int l4_shmget(l4id_t key, int size, int shmflg)
{

6
tasks/mm0/include/env.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef __MM0_ENV__
#define __MM0_ENV__
int task_prepare_env_file(struct tcb *t);
#endif

View File

@@ -5,6 +5,7 @@
#include <posix/sys/types.h>
void vmfile_init(void);
struct vm_file *vmfile_alloc_init(void);
int vfs_receive_sys_open(l4id_t sender, l4id_t opener, int fd,
unsigned long vnum, unsigned long size);
@@ -16,4 +17,5 @@ int sys_read(l4id_t sender, int fd, void *buf, int count);
int sys_write(l4id_t sender, int fd, void *buf, int count);
int sys_lseek(l4id_t sender, int fd, off_t offset, int whence);
extern struct list_head vm_file_list;
#endif /* __MM0_FILE_H__ */

View File

@@ -0,0 +1,23 @@
/*
* Address allocation pool
*
* Copyright (C) 2007 Bahadir Balban
*/
#ifndef __ADDR_H__
#define __ADDR_H__
#include <lib/idpool.h>
/* Address pool to allocate from a range of addresses */
struct address_pool {
struct id_pool *idpool;
unsigned long start;
unsigned long end;
};
int address_pool_init(struct address_pool *pool, unsigned long start,
unsigned long end);
void *address_new(struct address_pool *pool, int npages);
int address_del(struct address_pool *, void *addr, int npages);
#endif /* __ADDR_H__ */

View File

@@ -1,17 +0,0 @@
/*
* Virtual address allocation pool (for shm)
*
* Copyright (C) 2007 Bahadir Balban
*/
#ifndef __VADDR_H__
#define __VADDR_H__
#include <lib/idpool.h>
void vaddr_pool_init(struct id_pool *pool, unsigned long start,
unsigned long end);
void *vaddr_new(struct id_pool *pool, int npages);
int vaddr_del(struct id_pool *, void *vaddr, int npages);
#endif /* __VADDR_H__ */

View File

@@ -12,6 +12,7 @@
#include <l4/lib/list.h>
#include <l4lib/types.h>
#include <l4lib/utcb.h>
#include <lib/addr.h>
#define __TASKNAME__ __PAGERNAME__
@@ -43,7 +44,7 @@ struct tcb {
/* Related task ids */
unsigned int pagerid; /* Task's pager */
/* Program segment marks */
/* Program segment marks, ends exclusive as usual */
unsigned long text_start;
unsigned long text_end;
unsigned long data_start;
@@ -51,9 +52,9 @@ struct tcb {
unsigned long bss_start;
unsigned long bss_end;
unsigned long stack_start;
unsigned long stack_end; /* Exclusive of last currently mapped page */
unsigned long stack_end;
unsigned long heap_start;
unsigned long heap_end; /* Exclusive of last currently mapped page */
unsigned long heap_end;
unsigned long env_start;
unsigned long env_end;
unsigned long args_start;
@@ -62,17 +63,24 @@ struct tcb {
/* UTCB address */
unsigned long utcb_address;
/* Temporary storage for environment data */
void *env_data;
unsigned long env_size;
/* Per-task environment file */
struct vm_file *env_file;
/* Virtual memory areas */
struct list_head vm_area_list;
/* Per-task swap file for now */
struct vm_file *swap_file;
/* File descriptors for this task */
struct file_descriptor fd[TASK_OFILES_MAX];
/* Per-task swap file for now */
struct vm_file *swap_file;
/* Pool to generate swap file offsets for fileless anonymous regions */
struct id_pool *swap_file_offset_pool;
struct address_pool swap_file_offset_pool;
};
struct tcb *find_task(int tid);

7
tasks/mm0/include/utcb.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef __MM0_UTCB_H__
#define __MM0_UTCB_H__
void *utcb_vaddr_new(void);
int utcb_pool_init(void);
#endif

80
tasks/mm0/src/env.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* This implements a per-process virtual private file
* server to store environment variables.
*
* Using a per-process private file for the environment
* gives the impression as if a file-backed env/arg area
* is mapped on every process. By this means the env/arg
* pages dont need special processing and are abstracted
* away as files. Same idea can be applied to other
* private regions of a process such as the stack, so
* that debuggers can use file-based process inspection
* methods.
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <l4/lib/list.h>
#include <vm_area.h>
#include <kmalloc/kmalloc.h>
#include <task.h>
#include <l4/api/kip.h>
#include <l4/api/errno.h>
#include <string.h>
#include <file.h>
/* Copies environment data into provided page. */
int task_env_pager_read_page(struct vm_file *f, unsigned long f_off_pfn,
void *dest_page)
{
struct tcb *t = find_task(f->vnum);
if (!t) {
printf("%s: No such task tid: %d, to copy environment for.\n",
__TASKNAME__, f->vnum);
return -EINVAL;
}
if (f_off_pfn != 0) {
printf("%s: Environments currently have a single page.\n");
return -EINVAL;
}
memset(dest_page, 0, PAGE_SIZE);
memcpy(dest_page, t->env_data, t->env_size);
return 0;
}
/* Pager for environment files */
struct vm_pager task_env_pager = {
.ops = {
.read_page = task_env_pager_read_page,
.write_page= 0,
},
};
/*
* For a task that is about to execute, this dynamically
* generates its environment file.
*/
int task_prepare_env_file(struct tcb *t)
{
/* Allocate a new vmfile for this task's environment */
if (IS_ERR(t->env_file = vmfile_alloc_init()))
return (int)t->env_file;
/* Initialise and add it to global vmfile list */
/*
* NOTE: Temporarily we can use tid as the vnum because
* this is the only per-task file.
*/
t->env_file->vnum = t->tid;
t->env_file->length = PAGE_SIZE;
t->env_file->pager = &task_env_pager;
list_add(&t->env_file->list, &vm_file_list);
return 0;
}

View File

@@ -108,8 +108,10 @@ int do_file_page(struct fault_data *fault)
* Read the page. (Simply read into the faulty area that's
* now mapped using a newly allocated page.)
*/
fault->vma->owner->pager->ops.read_page(fault->vma->owner,
f_offset, vaddr);
if (fault->vma->owner->pager->ops.read_page(fault->vma->owner,
f_offset,
vaddr) < 0)
BUG();
/* Remove temporary mapping */
l4_unmap(vaddr, 1, self_tid());
@@ -221,8 +223,10 @@ int do_file_page(struct fault_data *fault)
* Read the page. (Simply read into the faulty area that's
* now mapped using a newly allocated page.)
*/
fault->vma->owner->pager->ops.read_page(fault->vma->owner,
f_offset, vaddr);
if (fault->vma->owner->pager->ops.read_page(fault->vma->owner,
f_offset,
vaddr) < 0)
BUG();
/* Unmap from self */
l4_unmap(vaddr, 1, self_tid());
@@ -252,26 +256,6 @@ int do_file_page(struct fault_data *fault)
return 0;
}
/* Check if faulty page has environment and argument information */
int is_env_arg_page(struct fault_data *fault)
{
return fault->address >= page_align(fault->task->stack_end);
}
int fill_env_arg_info(struct fault_data *fault, void *vaddr)
{
/* Get the env start offset in the page */
unsigned long env_offset = fault->task->env_start & PAGE_MASK;
/* Write the environment information */
*(unsigned long *)(vaddr + env_offset) = fault->task->utcb_address;
printf("%s: Written env value 0x%x, to task address 0x%x\n",
__TASKNAME__, fault->task->utcb_address,
page_align(fault->address) + env_offset);
return 0;
}
/*
* Handles any page allocation or file ownership change for anonymous pages.
* For read accesses initialises a wired-in zero page and for write accesses
@@ -303,7 +287,7 @@ int do_anon_page(struct fault_data *fault)
/* For non-existant pages just map the zero page, unless it is the
* beginning of stack which requires environment and argument data. */
if (fault->reason & VM_READ && is_env_arg_page(fault)) {
if (fault->reason & VM_READ) {
/*
* Zero page is a special wired-in page that is mapped
* many times in many tasks. Just update its count field.
@@ -315,7 +299,7 @@ int do_anon_page(struct fault_data *fault)
}
/* Write faults require a real zero initialised page */
if (fault->reason & VM_WRITE || is_env_arg_page(fault)) {
if (fault->reason & VM_WRITE) {
paddr = alloc_page(1);
vaddr = phys_to_virt(paddr);
page = phys_to_page(paddr);
@@ -333,10 +317,6 @@ int do_anon_page(struct fault_data *fault)
/* Clear the page */
memset((void *)vaddr, 0, PAGE_SIZE);
/* If its the env/arg page on stack, fill that information */
if (is_env_arg_page(fault))
fill_env_arg_info(fault, vaddr);
/* Remove temporary mapping */
l4_unmap((void *)vaddr, 1, self_tid());

View File

@@ -340,5 +340,3 @@ int sys_lseek(l4id_t sender, int fd, off_t offset, int whence)
return 0;
}

View File

@@ -11,22 +11,31 @@
#include <kmalloc/kmalloc.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/utcb.h>
#include <task.h>
#include <shm.h>
#include <file.h>
#include <init.h>
#include <utcb.h>
/* Initialise the utcb virtual address pool and its own utcb */
/*
* Initialise the utcb virtual address pool and its own utcb.
* NOTE: This allocates memory so kmalloc must be initialised first.
*/
void init_utcb(void)
{
void *utcb_virt, *utcb_page;
/* Allocate and map one for self */
if (utcb_pool_init() < 0)
printf("UTCB initialisation failed.\n");
utcb_virt = utcb_vaddr_new();
printf("%s: Mapping 0x%x as utcb to self.\n", __TASKNAME__, utcb_virt);
utcb_page = alloc_page(1);
l4_map(utcb_page, utcb_virt, 1, MAP_USR_RW_FLAGS, self_tid());
/* Also initialise the utcb reference that is used in l4lib. */
utcb = utcb_virt;
}
void init_mm(struct initdata *initdata)
@@ -43,9 +52,6 @@ void init_mm(struct initdata *initdata)
init_devzero();
printf("%s: Initialised devzero.\n", __TASKNAME__);
init_utcb();
printf("%s: Initialised own utcb.\n", __TASKNAME__);
/* Initialise the pager's memory allocator */
kmalloc_init();
printf("%s: Initialised kmalloc.\n", __TASKNAME__);
@@ -53,6 +59,9 @@ void init_mm(struct initdata *initdata)
shm_init();
printf("%s: Initialised shm structures.\n", __TASKNAME__);
init_utcb();
printf("%s: Initialised own utcb.\n", __TASKNAME__);
vmfile_init();
/* Give the kernel some memory to use for its allocators */

44
tasks/mm0/src/lib/addr.c Normal file
View File

@@ -0,0 +1,44 @@
/*
* This module allocates an unused address range from
* a given memory region defined as the pool range.
*
* Copyright (C) 2007 Bahadir Balban
*/
#include <lib/bit.h>
#include <l4/macros.h>
#include <l4/types.h>
#include INC_GLUE(memory.h)
#include <lib/addr.h>
#include <stdio.h>
int address_pool_init(struct address_pool *pool, unsigned long start, unsigned long end)
{
if ((pool->idpool = id_pool_new_init(__pfn(end - start))) < 0)
return (int)pool->idpool;
pool->start = start;
pool->end = end;
return 0;
}
void *address_new(struct address_pool *pool, int npages)
{
unsigned int pfn;
if ((int)(pfn = ids_new_contiguous(pool->idpool, npages)) < 0)
return 0;
return (void *)__pfn_to_addr(pfn) + pool->start;
}
int address_del(struct address_pool *pool, void *addr, int npages)
{
unsigned long pfn = __pfn(page_align(addr) - pool->start);
if (ids_del_contiguous(pool->idpool, pfn, npages) < 0) {
printf("%s: Invalid address range returned to "
"virtual address pool.\n", __FUNCTION__);
return -1;
}
return 0;
}

View File

@@ -7,12 +7,15 @@
#include <kmalloc/kmalloc.h>
#include INC_GLUE(memory.h)
#include <stdio.h>
#include <l4/api/errno.h>
struct id_pool *id_pool_new_init(int totalbits)
{
int nwords = BITWISE_GETWORD(totalbits);
struct id_pool *new = kzalloc((nwords * SZ_WORD)
+ sizeof(struct id_pool));
if (!new)
return PTR_ERR(-ENOMEM);
new->nwords = nwords;
return new;
}

View File

@@ -1,39 +0,0 @@
/*
* This module allocates an unused virtual address range for shm segments.
*
* Copyright (C) 2007 Bahadir Balban
*/
#include <lib/bit.h>
#include <l4/macros.h>
#include <l4/types.h>
#include INC_GLUE(memory.h)
#include <lib/vaddr.h>
#include <stdio.h>
void vaddr_pool_init(struct id_pool *pool, unsigned long start, unsigned long end)
{
pool = id_pool_new_init(__pfn(end - start));
}
void *vaddr_new(struct id_pool *pool, int npages)
{
unsigned int shm_vpfn;
if ((int)(shm_vpfn = ids_new_contiguous(pool, npages)) < 0)
return 0;
return (void *)__pfn_to_addr(shm_vpfn + SHM_AREA_START);
}
int vaddr_del(struct id_pool *pool, void *vaddr, int npages)
{
unsigned long idpfn = __pfn(page_align(vaddr) - SHM_AREA_START);
if (ids_del_contiguous(pool, idpfn, npages) < 0) {
printf("%s: Invalid address range returned to "
"virtual address pool.\n", __FUNCTION__);
return -1;
}
return 0;
}

View File

@@ -361,6 +361,8 @@ pgtable_unmap:
* - If refcount is zero (they could be shared!), either add pages to some page
* cache, or simpler the better, free the actual pages back to the page allocator.
* - l4_unmap() the corresponding virtual region from the page tables.
*
* -- These are all done --
*/
#endif
return 0;

View File

@@ -12,7 +12,7 @@
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <lib/idpool.h>
#include <lib/vaddr.h>
#include <lib/addr.h>
#include <lib/spinlock.h>
#include <l4/api/errno.h>
#include <l4/lib/list.h>
@@ -33,7 +33,7 @@ static struct list_head shm_desc_list;
static struct id_pool *shm_ids;
/* Globally disjoint shm virtual address pool */
static struct id_pool *shm_vaddr_pool;
static struct address_pool shm_vaddr_pool;
void shm_init()
{
@@ -43,7 +43,7 @@ void shm_init()
shm_ids = id_pool_new_init(SHM_AREA_MAX);
/* Initialise the global shm virtual address pool */
vaddr_pool_init(shm_vaddr_pool, SHM_AREA_START, SHM_AREA_END);
address_pool_init(&shm_vaddr_pool, SHM_AREA_START, SHM_AREA_END);
}
/*
@@ -74,7 +74,7 @@ static int do_shmat(struct shm_descriptor *shm, void *shm_addr, int shmflg,
if (shm->shm_addr)
shm_addr = shm->shm_addr;
else
shm_addr = vaddr_new(shm_vaddr_pool, __pfn(shm->size));
shm_addr = address_new(&shm_vaddr_pool, __pfn(shm->size));
BUG_ON(!is_page_aligned(shm_addr));

View File

@@ -13,7 +13,7 @@
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <lib/vaddr.h>
#include <lib/addr.h>
#include <task.h>
#include <kdata.h>
#include <kmalloc/kmalloc.h>
@@ -22,6 +22,7 @@
#include <memory.h>
#include <file.h>
#include <utcb.h>
#include <env.h>
struct tcb_head {
struct list_head list;
@@ -63,8 +64,8 @@ struct tcb *create_init_tcb(struct tcb_head *tcbs)
task->spid = TASK_ID_INVALID;
task->swap_file = kzalloc(sizeof(struct vm_file));
task->swap_file->pager = &swap_pager;
vaddr_pool_init(task->swap_file_offset_pool, 0,
__pfn(TASK_SWAPFILE_MAXSIZE));
address_pool_init(&task->swap_file_offset_pool, 0,
__pfn(TASK_SWAPFILE_MAXSIZE));
INIT_LIST_HEAD(&task->swap_file->page_cache_list);
INIT_LIST_HEAD(&task->list);
INIT_LIST_HEAD(&task->vm_area_list);
@@ -119,26 +120,37 @@ int start_boot_tasks(struct initdata *initdata, struct tcb_head *tcbs)
file->pager = &boot_file_pager;
list_add(&file->list, &initdata->boot_file_list);
/*
* Setup task's regions so that they are taken into account
* during page faults.
*/
task->stack_start = USER_AREA_END - PAGE_SIZE * 4;
/* Next address after 8 spaces, and 8-byte alignment */
task->stack_end = align(USER_AREA_END - 8, 8) + sizeof(int);
/* No argument space, but 8 bytes for utcb address environment */
task->env_start = task->stack_end;
/* Prepare environment boundaries. Posix minimum is 4Kb */
task->env_end = USER_AREA_END;
task->env_start = task->env_end - PAGE_SIZE;
task->args_start = task->env_start;
task->args_end = task->env_start;
/*
* Prepare the task environment file and data.
* Currently it only has the utcb address. The env pager
* when faulted, simply copies the task env data to the
* allocated page.
*/
if (task_prepare_env_file(task) < 0) {
printf("Could not create environment file.\n");
goto error;
}
task->env_data = &task->utcb_address;
task->env_size = sizeof(task->utcb_address);
/*
* Task stack starts right after the environment,
* and is of 4 page size.
*/
task->stack_end = task->env_start;
task->stack_start = task->stack_end - PAGE_SIZE * 4;
/* Only text start is valid */
task->text_start = USER_AREA_START;
/* Set up task's registers */
sp = align(task->stack_end - 1, sizeof(int));
sp = align(task->stack_end - 1, 8);
pc = task->text_start;
/* mmap each task's physical image to task's address space. */
@@ -149,9 +161,19 @@ int start_boot_tasks(struct initdata *initdata, struct tcb_head *tcbs)
goto error;
}
/* mmap each task's environment from its env file. */
if ((err = do_mmap(task->env_file, 0, task, task->env_start,
VM_READ | VM_WRITE,
__pfn(task->env_end - task->env_start)) < 0)) {
printf("do_mmap: Mapping environment failed with %d.\n",
err);
goto error;
}
/* mmap each task's stack as 4-page anonymous memory. */
if ((err = do_mmap(0, 0, task, task->stack_start,
VM_READ | VM_WRITE | VMA_ANON, 4) < 0)) {
VM_READ | VM_WRITE | VMA_ANON,
__pfn(task->stack_end - task->stack_start)) < 0)) {
printf("do_mmap: Mapping stack failed with %d.\n", err);
goto error;
}

32
tasks/mm0/src/utcb.c Normal file
View File

@@ -0,0 +1,32 @@
/*
* Utcb address allocation for user tasks.
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <stdio.h>
#include <utcb.h>
#include <lib/addr.h>
#include <l4/macros.h>
#include INC_GLUE(memlayout.h)
static struct address_pool utcb_vaddr_pool;
int utcb_pool_init()
{
int err;
if ((err = address_pool_init(&utcb_vaddr_pool,
UTCB_AREA_START,
UTCB_AREA_END)) < 0) {
printf("UTCB address pool initialisation failed: %d\n", err);
return err;
}
return 0;
}
void *utcb_vaddr_new(void)
{
return address_new(&utcb_vaddr_pool, 1);
}

View File

@@ -14,7 +14,7 @@
*/
/* USER_AREA_START, see memlayout.h */
virtual_base = 0x10000000;
__stack = 0x20000000;
__stack = (0x20000000 - 0x1000 - 8); /* First page before the env/args */
INCLUDE "include/physical_base.lds"
/* physical_base = 0x228000; */