mirror of
https://github.com/drasko/codezero.git
synced 2026-07-20 06:05:24 +02:00
Brought mm0 initialization up to init_execve()
Changes: It is now possible to use do_mmap() from within mm0. - pager_new_virtual()/delete_virtual() return addresses that are disjoint from find_unmapped_area() used by mmap() interface for anonymous or not-fixed areas. - find_unmapped_area() now uses task->map_start task->map_end instead of task->start and task->end. task->start/end are still valid task space addresses for mmap(), but finding a new address is limited to map_start/map_end. - We have both interfaces because mmap() is only useful for backed-files. When the pager needs to access a user memory range for example, that is not backed by a file and thus we need to use pager_new_virtual() instead of mmap() for mapping.
This commit is contained in:
@@ -42,7 +42,7 @@
|
|||||||
#define MEMFS_TOTAL_SIZE SZ_4MB
|
#define MEMFS_TOTAL_SIZE SZ_4MB
|
||||||
#define MEMFS_TOTAL_INODES 128
|
#define MEMFS_TOTAL_INODES 128
|
||||||
#define MEMFS_TOTAL_BLOCKS 2000
|
#define MEMFS_TOTAL_BLOCKS 2000
|
||||||
#define MEMFS_FMAX_BLOCKS 40
|
#define MEMFS_FMAX_BLOCKS 60
|
||||||
#define MEMFS_BLOCK_SIZE PAGE_SIZE
|
#define MEMFS_BLOCK_SIZE PAGE_SIZE
|
||||||
#define MEMFS_MAGIC 0xB
|
#define MEMFS_MAGIC 0xB
|
||||||
#define MEMFS_NAME "memfs"
|
#define MEMFS_NAME "memfs"
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <physmem.h>
|
#include <physmem.h>
|
||||||
|
#include <linker.h>
|
||||||
|
|
||||||
|
#define PAGER_MMAP_SEGMENT SZ_4MB
|
||||||
|
#define PAGER_MMAP_START (page_align_up(__stack))
|
||||||
|
#define PAGER_MMAP_END (PAGER_MMAP_START + PAGER_MMAP_SEGMENT)
|
||||||
|
|
||||||
void init_mm_descriptors(struct page_bitmap *page_map,
|
void init_mm_descriptors(struct page_bitmap *page_map,
|
||||||
struct bootdesc *bootdesc, struct membank *membank);
|
struct bootdesc *bootdesc, struct membank *membank);
|
||||||
|
|||||||
@@ -166,4 +166,7 @@ struct tcb *task_create(struct tcb *orig,
|
|||||||
unsigned int ctrl_flags,
|
unsigned int ctrl_flags,
|
||||||
unsigned int alloc_flags);
|
unsigned int alloc_flags);
|
||||||
|
|
||||||
|
int prefault_range(struct tcb *task, unsigned long start,
|
||||||
|
unsigned long end, unsigned int vm_flags);
|
||||||
|
|
||||||
#endif /* __TASK_H__ */
|
#endif /* __TASK_H__ */
|
||||||
|
|||||||
@@ -970,7 +970,7 @@ int prefault_page(struct tcb *task, unsigned long address,
|
|||||||
.address = address,
|
.address = address,
|
||||||
};
|
};
|
||||||
|
|
||||||
dprintf("Pre-faulting address 0x%x, on task %d, with flags: 0x%x\n",
|
dprintf("Pre-faulting address 0x%lx, on task %d, with flags: 0x%x\n",
|
||||||
address, task->tid, vmflags);
|
address, task->tid, vmflags);
|
||||||
|
|
||||||
/* Find the vma */
|
/* Find the vma */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Initialise the system.
|
* Initialise the system.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
* Copyright (C) 2007 - 2009 Bahadir Balban
|
||||||
*/
|
*/
|
||||||
#include <l4lib/arch/syscalls.h>
|
#include <l4lib/arch/syscalls.h>
|
||||||
#include <l4lib/arch/syslib.h>
|
#include <l4lib/arch/syslib.h>
|
||||||
@@ -58,6 +58,7 @@ void print_pfn_range(int pfn, int size)
|
|||||||
printf("Used: 0x%x - 0x%x\n", addr, end);
|
printf("Used: 0x%x - 0x%x\n", addr, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This sets up the mm0 task struct and memory environment but omits
|
* This sets up the mm0 task struct and memory environment but omits
|
||||||
* bits that are already done such as creating a new thread, setting
|
* bits that are already done such as creating a new thread, setting
|
||||||
@@ -105,9 +106,9 @@ int pager_setup_task(void)
|
|||||||
task->bss_start = (unsigned long)__start_bss;
|
task->bss_start = (unsigned long)__start_bss;
|
||||||
task->bss_end = (unsigned long)__end_bss;
|
task->bss_end = (unsigned long)__end_bss;
|
||||||
|
|
||||||
/* Task's region available for mmap */
|
/* Task's region available for mmap as */
|
||||||
task->map_start = page_align_up((unsigned long)__stack);
|
task->map_start = PAGER_MMAP_START;
|
||||||
task->map_end = 0xF0000000; /* FIXME: Fix this */
|
task->map_end = PAGER_MMAP_END;
|
||||||
|
|
||||||
/* Task's total map boundaries */
|
/* Task's total map boundaries */
|
||||||
task->start = task->text_start;
|
task->start = task->text_start;
|
||||||
@@ -124,8 +125,8 @@ int pager_setup_task(void)
|
|||||||
VM_WRITE | VM_EXEC | VMA_PRIVATE,
|
VM_WRITE | VM_EXEC | VMA_PRIVATE,
|
||||||
__pfn(page_align_up(task->map_start) -
|
__pfn(page_align_up(task->map_start) -
|
||||||
task->start)))) {
|
task->start)))) {
|
||||||
printf("do_mmap: failed with %d.\n", (int)mapped);
|
printf("FATAL: do_mmap: failed with %d.\n", (int)mapped);
|
||||||
return (int)mapped;
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
task_setup_utcb(task);
|
task_setup_utcb(task);
|
||||||
@@ -453,25 +454,61 @@ void copy_init_process(void)
|
|||||||
struct svc_image *init_img;
|
struct svc_image *init_img;
|
||||||
unsigned long img_size;
|
unsigned long img_size;
|
||||||
void *init_img_start, *init_img_end;
|
void *init_img_start, *init_img_end;
|
||||||
|
struct tcb *self = find_task(self_tid());
|
||||||
|
void *mapped;
|
||||||
|
int err;
|
||||||
|
|
||||||
if ((fd = sys_open(find_task(self_tid()),
|
if ((fd = sys_open(self, "/test0", O_TRUNC |
|
||||||
"/test0", O_TRUNC | O_RDWR | O_CREAT,
|
O_RDWR | O_CREAT, 0)) < 0) {
|
||||||
0)) < 0) {
|
|
||||||
printf("FATAL: Could not open file "
|
printf("FATAL: Could not open file "
|
||||||
"to write initial task.\n");
|
"to write initial task.\n");
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_img = bootdesc_get_image_byname("test0");
|
init_img = bootdesc_get_image_byname("test0");
|
||||||
img_size = init_img->phys_end - init_img->phys_start;
|
img_size = page_align_up(init_img->phys_end) -
|
||||||
|
page_align(init_img->phys_start);
|
||||||
|
|
||||||
init_img_start = l4_map_helper((void *)init_img->phys_start, __pfn(img_size));
|
init_img_start = l4_map_helper((void *)init_img->phys_start,
|
||||||
|
__pfn(img_size));
|
||||||
init_img_end = init_img_start + img_size;
|
init_img_end = init_img_start + img_size;
|
||||||
|
|
||||||
sys_write(find_task(self_tid()), fd, init_img_start, img_size);
|
/*
|
||||||
|
* Map an anonymous region and prefault it.
|
||||||
|
*/
|
||||||
|
if (IS_ERR(mapped =
|
||||||
|
do_mmap(0, 0, self, 0,
|
||||||
|
VMA_ANONYMOUS | VM_READ |
|
||||||
|
VM_WRITE | VM_EXEC | VMA_PRIVATE,
|
||||||
|
__pfn(img_size)))) {
|
||||||
|
printf("FATAL: do_mmap: failed with %d.\n",
|
||||||
|
(int)mapped);
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prefault it */
|
||||||
|
if ((err = prefault_range(self, (unsigned long)mapped,
|
||||||
|
img_size,
|
||||||
|
VM_READ | VM_WRITE)) < 0) {
|
||||||
|
printf("FATAL: Prefaulting init image failed.\n");
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the raw image to anon region */
|
||||||
|
memcpy(mapped, init_img_start, img_size);
|
||||||
|
|
||||||
|
/* Write it to real file from anon region */
|
||||||
|
sys_write(find_task(self_tid()), fd, mapped, img_size);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
sys_close(find_task(self_tid()), fd);
|
sys_close(find_task(self_tid()), fd);
|
||||||
|
|
||||||
|
/* Unmap anon region */
|
||||||
|
do_munmap(self, (unsigned long)mapped, img_size);
|
||||||
|
|
||||||
|
/* Unmap raw virtual range for image memory */
|
||||||
|
l4_unmap_helper(init_img_start,__pfn(img_size));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_init_process(void)
|
void start_init_process(void)
|
||||||
|
|||||||
@@ -40,21 +40,27 @@ static struct pager_virtual_address_id_pool {
|
|||||||
.bitlimit = ADDRESS_POOL_256MB * 32,
|
.bitlimit = ADDRESS_POOL_256MB * 32,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For supplying contiguous virtual addresses to pager */
|
/* For supplying contiguous virtual addresses to pager
|
||||||
|
*
|
||||||
|
* MM0:
|
||||||
|
* task->start
|
||||||
|
* Text
|
||||||
|
* Data
|
||||||
|
* Bss
|
||||||
|
* Stack
|
||||||
|
* mmap area start
|
||||||
|
* mmap area end
|
||||||
|
*
|
||||||
|
* pager address pool
|
||||||
|
*
|
||||||
|
* task->end
|
||||||
|
*/
|
||||||
int pager_address_pool_init(void)
|
int pager_address_pool_init(void)
|
||||||
{
|
{
|
||||||
/*
|
address_pool_init_with_idpool(&pager_vaddr_pool,
|
||||||
* Initialise id pool for pager virtual address
|
|
||||||
* allocation. This spans from end of pager image
|
|
||||||
* until the end of the virtual address range
|
|
||||||
* allocated for the pager
|
|
||||||
*/
|
|
||||||
address_pool_init_with_idpool(&pager_vaddr_pool,
|
|
||||||
(struct id_pool *)
|
(struct id_pool *)
|
||||||
&pager_virtual_address_id_pool,
|
&pager_virtual_address_id_pool,
|
||||||
page_align_up((unsigned long)__end + PAGE_SIZE),
|
PAGER_MMAP_END, 0xF0000000);
|
||||||
/* FIXME: Fix this! Same as mm0's map_start and map_end */
|
|
||||||
(unsigned long)0xF0000000);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,22 +110,22 @@ int task_insert_vma(struct vm_area *this, struct link *vma_list)
|
|||||||
*/
|
*/
|
||||||
unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
||||||
{
|
{
|
||||||
unsigned long pfn_start = __pfn(task->start);
|
unsigned long pfn_start = __pfn(task->map_start);
|
||||||
unsigned long pfn_end = pfn_start + npages;
|
unsigned long pfn_end = pfn_start + npages;
|
||||||
struct vm_area *vma;
|
struct vm_area *vma;
|
||||||
|
|
||||||
if (npages > __pfn(task->end - task->start))
|
if (npages > __pfn(task->map_end - task->map_start))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If no vmas, first map slot is available. */
|
/* If no vmas, first map slot is available. */
|
||||||
if (list_empty(&task->vm_area_head->list))
|
if (list_empty(&task->vm_area_head->list))
|
||||||
return task->start;
|
return task->map_start;
|
||||||
|
|
||||||
/* First vma to check our range against */
|
/* First vma to check our range against */
|
||||||
vma = link_to_struct(task->vm_area_head->list.next, struct vm_area, list);
|
vma = link_to_struct(task->vm_area_head->list.next, struct vm_area, list);
|
||||||
|
|
||||||
/* Start searching from task's end of data to start of stack */
|
/* Start searching from task's end of data to start of stack */
|
||||||
while (pfn_end <= __pfn(task->end)) {
|
while (pfn_end <= __pfn(task->map_end)) {
|
||||||
|
|
||||||
/* If intersection, skip the vma and fast-forward to next */
|
/* If intersection, skip the vma and fast-forward to next */
|
||||||
if (set_intersection(pfn_start, pfn_end,
|
if (set_intersection(pfn_start, pfn_end,
|
||||||
@@ -140,7 +140,7 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
|||||||
* Are we out of task map area?
|
* Are we out of task map area?
|
||||||
*/
|
*/
|
||||||
if (vma->list.next == &task->vm_area_head->list) {
|
if (vma->list.next == &task->vm_area_head->list) {
|
||||||
if (pfn_end > __pfn(task->end))
|
if (pfn_end > __pfn(task->map_end))
|
||||||
break; /* Yes, fail */
|
break; /* Yes, fail */
|
||||||
else /* No, success */
|
else /* No, success */
|
||||||
return __pfn_to_addr(pfn_start);
|
return __pfn_to_addr(pfn_start);
|
||||||
@@ -151,7 +151,7 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task)
|
|||||||
struct vm_area, list);
|
struct vm_area, list);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BUG_ON(pfn_start + npages > __pfn(task->end));
|
BUG_ON(pfn_start + npages > __pfn(task->map_end));
|
||||||
return __pfn_to_addr(pfn_start);
|
return __pfn_to_addr(pfn_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Finished initialising the vma, add it to task */
|
/* Finished initialising the vma, add it to task */
|
||||||
dprintf("%s: Mapping 0x%x - 0x%x\n", __FUNCTION__,
|
dprintf("%s: Mapping 0x%lx - 0x%lx\n", __FUNCTION__,
|
||||||
map_address, map_address + __pfn_to_addr(npages));
|
map_address, map_address + __pfn_to_addr(npages));
|
||||||
task_insert_vma(new, &task->vm_area_head->list);
|
task_insert_vma(new, &task->vm_area_head->list);
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,12 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset)
|
|||||||
paddr = (void *)page_to_phys(page);
|
paddr = (void *)page_to_phys(page);
|
||||||
vaddr = l4_new_virtual(1);
|
vaddr = l4_new_virtual(1);
|
||||||
|
|
||||||
/* FIXME: Are we sure that pages need to be mapped to self one-by-one? */
|
/* FIXME:
|
||||||
BUG();
|
* Are we sure that pages need
|
||||||
|
* to be mapped to self one-by-one?
|
||||||
|
*
|
||||||
|
* This needs fixing.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Map the page to self */
|
/* Map the page to self */
|
||||||
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
|
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
|
||||||
|
|||||||
@@ -713,3 +713,13 @@ int task_prefault_regions(struct tcb *task, struct vm_file *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int prefault_range(struct tcb *task, unsigned long start,
|
||||||
|
unsigned long end, unsigned int vm_flags)
|
||||||
|
{
|
||||||
|
for (unsigned long i = start; i < start + end; i += PAGE_SIZE)
|
||||||
|
prefault_page(task, i, vm_flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void print_cache_pages(struct vm_object *vmo)
|
|||||||
printf("Pages:\n======\n");
|
printf("Pages:\n======\n");
|
||||||
|
|
||||||
list_foreach_struct(p, &vmo->page_cache, list) {
|
list_foreach_struct(p, &vmo->page_cache, list) {
|
||||||
dprintf("Page offset: 0x%x, virtual: 0x%x, refcnt: %d\n", p->offset,
|
dprintf("Page offset: 0x%lx, virtual: 0x%lx, refcnt: %d\n", p->offset,
|
||||||
p->virtual, p->refcnt);
|
p->virtual, p->refcnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include INC_SUBARCH(mm.h)
|
#include INC_SUBARCH(mm.h)
|
||||||
|
|
||||||
/* Abort debugging conditions */
|
/* Abort debugging conditions */
|
||||||
// #define DEBUG_ABORTS
|
#define DEBUG_ABORTS
|
||||||
#if defined (DEBUG_ABORTS)
|
#if defined (DEBUG_ABORTS)
|
||||||
#define dbg_abort(...) dprintk(__VA_ARGS__)
|
#define dbg_abort(...) dprintk(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user