mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-11-28 11:43:09 +03:00
kernel heap: use on demand mapping
git-svn-id: svn://kolibrios.org@1066 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
692d85ec0c
commit
4ad5e0815b
@ -191,8 +191,10 @@ HEAP_BASE equ 0x80000000
|
||||
|
||||
HEAP_MIN_SIZE equ 0x01000000
|
||||
|
||||
page_tabs equ 0xDDC00000
|
||||
app_page_tabs equ 0xDDC00000
|
||||
page_tabs equ 0xDD800000
|
||||
app_page_tabs equ 0xDD800000
|
||||
|
||||
shared_tabs equ 0xDDC00000
|
||||
|
||||
heap_tabs equ (page_tabs+ (HEAP_BASE shr 10))
|
||||
kernel_tabs equ (page_tabs+ (OS_BASE shr 10))
|
||||
|
368
kernel/branches/kolibri_pe/core/buddy.inc
Normal file
368
kernel/branches/kolibri_pe/core/buddy.inc
Normal file
@ -0,0 +1,368 @@
|
||||
|
||||
#define BUDDY_SYSTEM_INNER_BLOCK 0xff
|
||||
|
||||
#define frame_index( frame ) \
|
||||
(index_t)( (frame) - z_core.frames)
|
||||
|
||||
#define frame_initialize( frame ) \
|
||||
(frame)->refcount = 1; \
|
||||
(frame)->buddy_order = 0
|
||||
|
||||
#define buddy_get_order( block) \
|
||||
((frame_t*)(block))->buddy_order
|
||||
|
||||
#define buddy_set_order( block, order) \
|
||||
((frame_t*)(block))->buddy_order = (order)
|
||||
|
||||
#define buddy_mark_busy( block ) \
|
||||
((frame_t*)(block))->refcount = 1
|
||||
|
||||
#define IS_BUDDY_LEFT_BLOCK(frame) \
|
||||
(((frame_index((frame)) >> (frame)->buddy_order) & 0x1) == 0)
|
||||
|
||||
#define IS_BUDDY_RIGHT_BLOCK(frame) \
|
||||
(((frame_index((frame)) >> (frame)->buddy_order) & 0x1) == 1)
|
||||
|
||||
#define buddy_mark_available( block ) \
|
||||
((frame_t*)(block))->refcount = 0
|
||||
|
||||
|
||||
static __inline link_t * buddy_bisect(link_t *block)
|
||||
{
|
||||
frame_t *frame_l, *frame_r;
|
||||
|
||||
frame_l = (frame_t*)block;
|
||||
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
|
||||
|
||||
return &frame_r->buddy_link;
|
||||
}
|
||||
|
||||
static __inline link_t *buddy_coalesce(link_t *block_1, link_t *block_2)
|
||||
{
|
||||
frame_t *frame1, *frame2;
|
||||
|
||||
frame1 = (frame_t*)block_1;
|
||||
frame2 = (frame_t*)block_2;
|
||||
|
||||
return frame1 < frame2 ? block_1 : block_2;
|
||||
}
|
||||
|
||||
static link_t *find_buddy(link_t *block)
|
||||
{
|
||||
frame_t *frame;
|
||||
index_t index;
|
||||
u32_t is_left, is_right;
|
||||
|
||||
frame = (frame_t*)block;
|
||||
// ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order));
|
||||
|
||||
is_left = IS_BUDDY_LEFT_BLOCK( frame);
|
||||
is_right = IS_BUDDY_RIGHT_BLOCK( frame);
|
||||
|
||||
// ASSERT(is_left ^ is_right);
|
||||
if (is_left) {
|
||||
index = (frame_index(frame)) + (1 << frame->buddy_order);
|
||||
} else { /* if (is_right) */
|
||||
index = (frame_index(frame)) - (1 << frame->buddy_order);
|
||||
}
|
||||
|
||||
if ( index < z_core.count)
|
||||
{
|
||||
if (z_core.frames[index].buddy_order == frame->buddy_order &&
|
||||
z_core.frames[index].refcount == 0) {
|
||||
return &z_core.frames[index].buddy_link;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static link_t *buddy_find_block(link_t *child, u32_t order)
|
||||
{
|
||||
frame_t *frame;
|
||||
index_t index;
|
||||
|
||||
frame = (frame_t*)child;
|
||||
|
||||
index = frame_index(frame);
|
||||
do {
|
||||
if (z_core.frames[index].buddy_order != order)
|
||||
return &z_core.frames[index].buddy_link;
|
||||
|
||||
} while(index-- > 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void buddy_system_free(link_t *block)
|
||||
{
|
||||
link_t *buddy, *hlp;
|
||||
u32_t i;
|
||||
|
||||
/*
|
||||
* Determine block's order.
|
||||
*/
|
||||
i = buddy_get_order(block);
|
||||
|
||||
// ASSERT(i <= z->max_order);
|
||||
|
||||
if (i != z_core.max_order)
|
||||
{
|
||||
/*
|
||||
* See if there is any buddy in the list of order i.
|
||||
*/
|
||||
buddy = find_buddy( block );
|
||||
if (buddy)
|
||||
{
|
||||
|
||||
// ASSERT(buddy_get_order(z, buddy) == i);
|
||||
/*
|
||||
* Remove buddy from the list of order i.
|
||||
*/
|
||||
list_remove(buddy);
|
||||
|
||||
/*
|
||||
* Invalidate order of both block and buddy.
|
||||
*/
|
||||
buddy_set_order(block, BUDDY_SYSTEM_INNER_BLOCK);
|
||||
buddy_set_order(buddy, BUDDY_SYSTEM_INNER_BLOCK);
|
||||
|
||||
/*
|
||||
* Coalesce block and buddy into one block.
|
||||
*/
|
||||
hlp = buddy_coalesce( block, buddy );
|
||||
|
||||
/*
|
||||
* Set order of the coalesced block to i + 1.
|
||||
*/
|
||||
buddy_set_order(hlp, i + 1);
|
||||
|
||||
/*
|
||||
* Recursively add the coalesced block to the list of order i + 1.
|
||||
*/
|
||||
buddy_system_free( hlp );
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Insert block into the list of order i.
|
||||
*/
|
||||
list_append(block, &z_core.order[i]);
|
||||
}
|
||||
|
||||
|
||||
static link_t* buddy_alloc( u32_t i)
|
||||
{
|
||||
link_t *res, *hlp;
|
||||
|
||||
ASSERT(i <= z_core.max_order);
|
||||
|
||||
/*
|
||||
* If the list of order i is not empty,
|
||||
* the request can be immediatelly satisfied.
|
||||
*/
|
||||
if (!list_empty(&z_core.order[i])) {
|
||||
res = z_core.order[i].next;
|
||||
list_remove(res);
|
||||
buddy_mark_busy(res);
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
* If order i is already the maximal order,
|
||||
* the request cannot be satisfied.
|
||||
*/
|
||||
if (i == z_core.max_order)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Try to recursively satisfy the request from higher order lists.
|
||||
*/
|
||||
hlp = buddy_alloc( i + 1 );
|
||||
|
||||
/*
|
||||
* The request could not be satisfied
|
||||
* from higher order lists.
|
||||
*/
|
||||
if (!hlp)
|
||||
return NULL;
|
||||
|
||||
res = hlp;
|
||||
|
||||
/*
|
||||
* Bisect the block and set order of both of its parts to i.
|
||||
*/
|
||||
hlp = buddy_bisect( res );
|
||||
|
||||
buddy_set_order(res, i);
|
||||
buddy_set_order(hlp, i);
|
||||
|
||||
/*
|
||||
* Return the other half to buddy system. Mark the first part
|
||||
* full, so that it won't coalesce again.
|
||||
*/
|
||||
buddy_mark_busy(res);
|
||||
buddy_system_free( hlp );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static link_t* buddy_alloc_block(link_t *block)
|
||||
{
|
||||
link_t *left,*right, *tmp;
|
||||
u32_t order;
|
||||
|
||||
left = buddy_find_block(block, BUDDY_SYSTEM_INNER_BLOCK);
|
||||
ASSERT(left);
|
||||
list_remove(left);
|
||||
while (1)
|
||||
{
|
||||
if ( !buddy_get_order(left))
|
||||
{
|
||||
buddy_mark_busy(left);
|
||||
return left;
|
||||
}
|
||||
|
||||
order = buddy_get_order(left);
|
||||
|
||||
right = buddy_bisect(left);
|
||||
buddy_set_order(left, order-1);
|
||||
buddy_set_order(right, order-1);
|
||||
|
||||
tmp = buddy_find_block( block, BUDDY_SYSTEM_INNER_BLOCK);
|
||||
|
||||
if (tmp == right) {
|
||||
right = left;
|
||||
left = tmp;
|
||||
}
|
||||
ASSERT(tmp == left);
|
||||
buddy_mark_busy(left);
|
||||
buddy_system_free(right);
|
||||
buddy_mark_available(left);
|
||||
}
|
||||
}
|
||||
|
||||
static void zone_create(zone_t *z, pfn_t start, count_t count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
spinlock_initialize(&z->lock);
|
||||
|
||||
z->base = start;
|
||||
z->count = count;
|
||||
z->free_count = count;
|
||||
z->busy_count = 0;
|
||||
|
||||
z->max_order = fnzb(count);
|
||||
|
||||
ASSERT(z->max_order < BUDDY_SYSTEM_INNER_BLOCK);
|
||||
|
||||
for (i = 0; i <= z->max_order; i++)
|
||||
list_initialize(&z->order[i]);
|
||||
|
||||
z->frames = (frame_t *)balloc(count*sizeof(frame_t));
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
frame_initialize(&z->frames[i]);
|
||||
|
||||
/*
|
||||
for (i = 0; i < count; i++) {
|
||||
z_core.frames[i].buddy_order=0;
|
||||
z_core.frames[i].parent = NULL;
|
||||
z_core.frames[i].refcount=1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
z_core.frames[i].refcount = 0;
|
||||
buddy_system_free(&z_core.frames[i].buddy_link);
|
||||
}
|
||||
*/
|
||||
|
||||
DBG("create zone: base %x count %x order %d\n",
|
||||
start, count, z->max_order);
|
||||
|
||||
}
|
||||
|
||||
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
|
||||
{
|
||||
frame_t *frame;
|
||||
link_t *link;
|
||||
|
||||
ASSERT(frame_idx < zone->count);
|
||||
|
||||
frame = &zone->frames[frame_idx];
|
||||
|
||||
if (frame->refcount)
|
||||
return;
|
||||
link = buddy_alloc_block( &frame->buddy_link);
|
||||
ASSERT(link);
|
||||
zone->free_count--;
|
||||
}
|
||||
|
||||
static void zone_reserve(zone_t *z, pfn_t base, count_t count)
|
||||
{
|
||||
int i;
|
||||
pfn_t top = base + count;
|
||||
|
||||
if( (base+count < z->base)||(base > z->base+z->count))
|
||||
return;
|
||||
|
||||
if(base < z->base)
|
||||
base = z->base;
|
||||
|
||||
if(top > z->base+z->count)
|
||||
top = z->base+z->count;
|
||||
|
||||
DBG("zone reserve base %x top %x\n", base, top);
|
||||
|
||||
for (i = base; i < top; i++)
|
||||
zone_mark_unavailable(z, i - z->base);
|
||||
|
||||
};
|
||||
|
||||
static void zone_release(zone_t *z, pfn_t base, count_t count)
|
||||
{
|
||||
int i;
|
||||
pfn_t top = base+count;
|
||||
|
||||
if( (base+count < z->base)||(base > z->base+z->count))
|
||||
return;
|
||||
|
||||
if(base < z->base)
|
||||
base = z->base;
|
||||
|
||||
if(top > z->base+z->count)
|
||||
top = z->base+z->count;
|
||||
|
||||
DBG("zone release base %x top %x\n", base, top);
|
||||
|
||||
for (i = base; i < top; i++) {
|
||||
z->frames[i-z->base].refcount = 0;
|
||||
buddy_system_free(&z->frames[i-z->base].buddy_link);
|
||||
}
|
||||
};
|
||||
|
||||
static inline frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
|
||||
{
|
||||
ASSERT(frame_idx < zone->count);
|
||||
return &zone->frames[frame_idx];
|
||||
}
|
||||
|
||||
void __fastcall frame_set_parent(pfn_t pfn, void *data)
|
||||
{
|
||||
spinlock_lock(&z_core.lock);
|
||||
zone_get_frame(&z_core, pfn-z_core.base)->parent = data;
|
||||
spinlock_unlock(&z_core.lock);
|
||||
}
|
||||
|
||||
void* __fastcall frame_get_parent(pfn_t pfn)
|
||||
{
|
||||
void *res;
|
||||
|
||||
spinlock_lock(&z_core.lock);
|
||||
res = zone_get_frame(&z_core, pfn)->parent;
|
||||
spinlock_unlock(&z_core.lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -173,32 +173,32 @@ srv_t* __fastcall load_pe_driver(const char *path)
|
||||
PIMAGE_NT_HEADERS32 nt;
|
||||
|
||||
drv_entry_t *drv_entry;
|
||||
md_t *md;
|
||||
addr_t *img_base ;
|
||||
srv_t *srv;
|
||||
|
||||
md = load_image(path);
|
||||
img_base = load_image(path);
|
||||
|
||||
if( ! md )
|
||||
if( ! img_base )
|
||||
return 0;
|
||||
|
||||
if( link_image( md->base ) )
|
||||
if( link_image( img_base ) )
|
||||
{
|
||||
dos = (PIMAGE_DOS_HEADER)md->base;
|
||||
dos = (PIMAGE_DOS_HEADER)img_base;
|
||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||
|
||||
drv_entry = MakePtr(drv_entry_t*, md->base,
|
||||
drv_entry = MakePtr(drv_entry_t*, img_base,
|
||||
nt->OptionalHeader.AddressOfEntryPoint);
|
||||
|
||||
srv = drv_entry(1);
|
||||
|
||||
if(srv != NULL)
|
||||
srv->entry = nt->OptionalHeader.AddressOfEntryPoint + md->base;
|
||||
srv->entry = nt->OptionalHeader.AddressOfEntryPoint + img_base;
|
||||
|
||||
return srv;
|
||||
}
|
||||
else
|
||||
{
|
||||
md_free( md );
|
||||
mem_free( img_base );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -277,9 +277,9 @@ int sys_exec(char *path, char *cmdline, u32_t flags)
|
||||
( raw[1] == 0x30305445) ) )
|
||||
|
||||
{
|
||||
DBG("leagacy Kolibri application");
|
||||
DBG("leagacy Kolibri application\n");
|
||||
int tmp = mnt_exec(raw, raw_size, path, cmdline, flags);
|
||||
DBG(" pid %x\n",tmp);
|
||||
DBG("pid %x\n",tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ int sys_exec(char *path, char *cmdline, u32_t flags)
|
||||
return -30;
|
||||
}
|
||||
|
||||
ex_stack_page = core_alloc(0); /* 2^0 = 1 page */
|
||||
ex_stack_page = alloc_page(); /* 2^0 = 1 page */
|
||||
if( ! ex_stack_page )
|
||||
{
|
||||
mem_free(raw);
|
||||
@ -327,7 +327,7 @@ int sys_exec(char *path, char *cmdline, u32_t flags)
|
||||
|
||||
if( !ex_pg_dir )
|
||||
{
|
||||
core_free(ex_stack_page);
|
||||
frame_free(ex_stack_page);
|
||||
mem_free(raw);
|
||||
return -30; /* FIXME */
|
||||
};
|
||||
|
442
kernel/branches/kolibri_pe/core/frame.c
Normal file
442
kernel/branches/kolibri_pe/core/frame.c
Normal file
@ -0,0 +1,442 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <core.h>
|
||||
#include <spinlock.h>
|
||||
#include <link.h>
|
||||
#include <mm.h>
|
||||
|
||||
extern u32_t pg_balloc;
|
||||
extern u32_t mem_amount;
|
||||
|
||||
void __fastcall *balloc(size_t size);
|
||||
|
||||
static zone_t z_core;
|
||||
|
||||
#include "buddy.inc"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t link;
|
||||
SPINLOCK_DECLARE(lock);
|
||||
u32_t state;
|
||||
void *parent;
|
||||
count_t avail;
|
||||
addr_t base;
|
||||
index_t next;
|
||||
int list[512];
|
||||
}pslab_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SPINLOCK_DECLARE(lock);
|
||||
|
||||
count_t partial_count;
|
||||
|
||||
link_t full_slabs; /**< List of full slabs */
|
||||
link_t partial_slabs; /**< List of partial slabs */
|
||||
}pcache_t;
|
||||
|
||||
static pcache_t page_cache;
|
||||
|
||||
static pslab_t *create_page_slab();
|
||||
|
||||
|
||||
|
||||
void init_mm()
|
||||
{
|
||||
int i;
|
||||
|
||||
u32_t base;
|
||||
u32_t size;
|
||||
count_t pages;
|
||||
size_t conf_size;
|
||||
size_t core_size;
|
||||
pslab_t *slab;
|
||||
|
||||
pages = mem_amount >> PAGE_WIDTH;
|
||||
DBG("last page = %x total pages = %x\n",mem_amount, pages);
|
||||
|
||||
conf_size = pages*sizeof(frame_t);
|
||||
DBG("conf_size = %x free mem start =%x\n",conf_size, pg_balloc);
|
||||
|
||||
zone_create(&z_core, 0, pages);
|
||||
zone_release(&z_core, 0, pages);
|
||||
zone_reserve(&z_core, 0, pg_balloc >> PAGE_WIDTH);
|
||||
|
||||
list_initialize(&page_cache.full_slabs);
|
||||
list_initialize(&page_cache.partial_slabs);
|
||||
|
||||
slab = create_page_slab();
|
||||
|
||||
ASSERT(slab);
|
||||
|
||||
slab->parent = &page_cache;
|
||||
page_cache.partial_count++;
|
||||
list_prepend(&slab->link, &page_cache.partial_slabs);
|
||||
};
|
||||
|
||||
/** Return wasted space in slab */
|
||||
static unsigned int badness(index_t order, size_t size)
|
||||
{
|
||||
unsigned int objects;
|
||||
unsigned int ssize;
|
||||
|
||||
ssize = PAGE_SIZE << order;
|
||||
objects = (PAGE_SIZE << order) / size;
|
||||
return ssize - objects * size;
|
||||
}
|
||||
|
||||
#define SLAB_MAX_BADNESS(order) (((size_t) PAGE_SIZE << (order)) >> 2)
|
||||
|
||||
|
||||
static pslab_t *create_page_slab()
|
||||
{
|
||||
pslab_t *slab;
|
||||
link_t *tmp;
|
||||
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
tmp = buddy_alloc(9);
|
||||
|
||||
if( tmp != 0 )
|
||||
{
|
||||
frame_t *frame;
|
||||
int i;
|
||||
addr_t v;
|
||||
|
||||
/* Update zone information. */
|
||||
z_core.free_count -= 512;
|
||||
z_core.busy_count += 512;
|
||||
|
||||
spinlock_unlock(&z_core.lock);
|
||||
|
||||
/* Frame will be actually a first frame of the block. */
|
||||
frame = (frame_t*)tmp;
|
||||
|
||||
frame->parent = 0;
|
||||
|
||||
v = (z_core.base + (index_t)(frame - z_core.frames)) << PAGE_WIDTH;
|
||||
|
||||
slab = (pslab_t*)PA2KA(v);
|
||||
|
||||
for(i = 1; i < 512; i++)
|
||||
frame[i].parent = slab;
|
||||
|
||||
slab->base = v + PAGE_SIZE;
|
||||
|
||||
slab->avail = 511;
|
||||
slab->next = 0;
|
||||
|
||||
for(i = 0; i < 511; i++)
|
||||
slab->list[i] = i + 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_unlock(&z_core.lock);
|
||||
slab = NULL;
|
||||
};
|
||||
|
||||
DBG("create page slab at %x\n", slab);
|
||||
|
||||
return slab;
|
||||
}
|
||||
|
||||
static void destroy_page_slab(pslab_t *slab)
|
||||
{
|
||||
u32_t order;
|
||||
count_t idx;
|
||||
frame_t *frame;
|
||||
|
||||
|
||||
idx = (KA2PA(slab) >> PAGE_WIDTH)-z_core.base;
|
||||
|
||||
frame = &z_core.frames[idx];
|
||||
|
||||
/* remember frame order */
|
||||
order = frame->buddy_order;
|
||||
|
||||
ASSERT(frame->refcount);
|
||||
|
||||
if (!--frame->refcount)
|
||||
{
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
buddy_system_free(&frame->buddy_link);
|
||||
|
||||
/* Update zone information. */
|
||||
z_core.free_count += (1 << order);
|
||||
z_core.busy_count -= (1 << order);
|
||||
|
||||
spinlock_unlock(&z_core.lock);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
fslab_t *create_slab(index_t order, size_t size)
|
||||
{
|
||||
fslab_t *slab;
|
||||
|
||||
slab = (fslab_t*)PA2KA(frame_alloc(0));
|
||||
|
||||
if( slab )
|
||||
{
|
||||
link_t *tmp;
|
||||
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
tmp = buddy_alloc(order);
|
||||
ASSERT(tmp);
|
||||
|
||||
if( tmp )
|
||||
{
|
||||
frame_t *frame;
|
||||
count_t objects;
|
||||
count_t i;
|
||||
addr_t v;
|
||||
|
||||
/* Update zone information. */
|
||||
z_core.free_count -= (1 << order);
|
||||
z_core.busy_count += (1 << order);
|
||||
|
||||
spinlock_unlock(&z_heap.lock);
|
||||
|
||||
/* Frame will be actually a first frame of the block. */
|
||||
frame = (frame_t*)tmp;
|
||||
|
||||
for(i = 0; i < (1U<<order); i++)
|
||||
frame[i].parent = slab;
|
||||
|
||||
/* get frame address */
|
||||
v = z_core.base + (index_t)(frame - z_core.frames);
|
||||
|
||||
slab->base = (v << PAGE_WIDTH);
|
||||
|
||||
slab->avail = (PAGE_SIZE << order) / size;
|
||||
slab->next = 0;
|
||||
|
||||
objects = (PAGE_SIZE << order) / size;
|
||||
|
||||
for(i = 0; i < objects; i++)
|
||||
slab->list[i] = i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_unlock(&z_core.lock);
|
||||
frame_free(KA2PA(slab));
|
||||
slab = NULL;
|
||||
};
|
||||
};
|
||||
|
||||
return slab;
|
||||
}
|
||||
|
||||
static void destroy_slab(fslab_t *slab)
|
||||
{
|
||||
u32_t order;
|
||||
count_t idx;
|
||||
frame_t *frame;
|
||||
|
||||
idx = (slab->base >> PAGE_WIDTH)-z_core.base;
|
||||
frame = &z_core.frames[idx];
|
||||
|
||||
/* remember frame order */
|
||||
order = frame->buddy_order;
|
||||
|
||||
ASSERT(frame->refcount);
|
||||
|
||||
if (!--frame->refcount)
|
||||
{
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
buddy_system_free(&frame->buddy_link);
|
||||
|
||||
/* Update zone information. */
|
||||
z_core.free_count += (1 << order);
|
||||
z_core.busy_count -= (1 << order);
|
||||
|
||||
spinlock_unlock(&z_core.lock);
|
||||
}
|
||||
|
||||
// slab_free(fslab, slab);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
addr_t alloc_page(void)
|
||||
{
|
||||
eflags_t efl;
|
||||
pslab_t *slab;
|
||||
addr_t frame;
|
||||
|
||||
efl = safe_cli();
|
||||
|
||||
spinlock_lock(&page_cache.lock);
|
||||
|
||||
if (list_empty(&page_cache.partial_slabs))
|
||||
{
|
||||
slab = create_page_slab();
|
||||
if (!slab)
|
||||
{
|
||||
spinlock_unlock(&page_cache.lock);
|
||||
safe_sti(efl);
|
||||
return 0;
|
||||
}
|
||||
slab->parent = &page_cache;
|
||||
slab->state = 1;
|
||||
page_cache.partial_count++;
|
||||
list_prepend(&slab->link, &page_cache.partial_slabs);
|
||||
}
|
||||
else
|
||||
slab = (pslab_t*)page_cache.partial_slabs.next;
|
||||
|
||||
frame = slab->base + (slab->next << PAGE_WIDTH);
|
||||
slab->next = slab->list[slab->next];
|
||||
|
||||
slab->avail--;
|
||||
if( slab->avail == 0 )
|
||||
{
|
||||
slab->state = 0;
|
||||
list_remove(&slab->link);
|
||||
list_prepend(&slab->link, &page_cache.full_slabs);
|
||||
page_cache.partial_count--;
|
||||
DBG("%s insert empty page slab\n");
|
||||
};
|
||||
spinlock_unlock(&page_cache.lock);
|
||||
|
||||
// DBG("alloc_page: %x remain %d\n", frame, slab->avail);
|
||||
|
||||
safe_sti(efl);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
addr_t __fastcall frame_alloc(count_t count)
|
||||
{
|
||||
addr_t frame;
|
||||
|
||||
if ( count > 1)
|
||||
{
|
||||
eflags_t efl;
|
||||
index_t order;
|
||||
frame_t *tmp;
|
||||
count_t i;
|
||||
|
||||
order = fnzb(count-1)+1;
|
||||
|
||||
efl = safe_cli();
|
||||
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
tmp = (frame_t*)buddy_alloc( order );
|
||||
|
||||
ASSERT(tmp);
|
||||
|
||||
z_core.free_count -= (1 << order);
|
||||
z_core.busy_count += (1 << order);
|
||||
|
||||
for(i = 0; i < (1 << order); i++)
|
||||
tmp[i].parent = NULL;
|
||||
|
||||
spinlock_unlock(&z_core.lock);
|
||||
|
||||
safe_sti(efl);
|
||||
|
||||
frame = (z_core.base +
|
||||
(index_t)(tmp - z_core.frames)) << PAGE_WIDTH;
|
||||
|
||||
|
||||
DBG("%s %x order %d remain %d\n", __FUNCTION__,
|
||||
frame, order, z_core.free_count);
|
||||
}
|
||||
else
|
||||
frame = alloc_page();
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
size_t __fastcall frame_free(addr_t addr)
|
||||
{
|
||||
eflags_t efl;
|
||||
index_t idx;
|
||||
frame_t *frame;
|
||||
size_t frame_size;
|
||||
|
||||
idx = addr >> PAGE_WIDTH;
|
||||
|
||||
if( (idx < z_core.base) ||
|
||||
(idx >= z_core.base+z_core.count)) {
|
||||
DBG("%s: invalid address %x\n", __FUNCTION__, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
efl = safe_cli();
|
||||
|
||||
frame = &z_core.frames[idx-z_core.base];
|
||||
|
||||
if( frame->parent != NULL )
|
||||
{
|
||||
pslab_t *slab;
|
||||
|
||||
slab = frame->parent;
|
||||
|
||||
spinlock_lock(&page_cache.lock);
|
||||
|
||||
idx = (addr - slab->base) >> PAGE_WIDTH;
|
||||
|
||||
ASSERT(idx < 512);
|
||||
|
||||
slab->list[idx] = slab->next;
|
||||
slab->next = idx;
|
||||
|
||||
slab->avail++;
|
||||
|
||||
if( (slab->state == 0 ) &&
|
||||
(slab->avail >= 4))
|
||||
{
|
||||
slab->state = 1;
|
||||
// list_remove(&slab->link);
|
||||
// list_prepend(&slab->link, &page_cache.partial_slabs);
|
||||
// page_cache.partial_count++;
|
||||
|
||||
DBG("%s: insert partial page slab\n", __FUNCTION__);
|
||||
}
|
||||
spinlock_unlock(&page_cache.lock);
|
||||
|
||||
frame_size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count_t order;
|
||||
|
||||
order = frame->buddy_order;
|
||||
|
||||
DBG("%s %x order %d\n", __FUNCTION__, addr, order);
|
||||
|
||||
ASSERT(frame->refcount);
|
||||
|
||||
spinlock_lock(&z_core.lock);
|
||||
|
||||
if (!--frame->refcount)
|
||||
{
|
||||
buddy_system_free(&frame->buddy_link);
|
||||
|
||||
/* Update zone information. */
|
||||
z_core.free_count += (1 << order);
|
||||
z_core.busy_count -= (1 << order);
|
||||
}
|
||||
spinlock_unlock(&z_core.lock);
|
||||
|
||||
frame_size = 1 << order;
|
||||
};
|
||||
safe_sti(efl);
|
||||
|
||||
return frame_size;
|
||||
}
|
||||
|
||||
count_t get_free_mem()
|
||||
{
|
||||
return z_core.free_count;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -163,7 +163,7 @@ proc user_free stdcall, base:dword
|
||||
test cl, 1
|
||||
jz @F
|
||||
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
mov eax, esi
|
||||
shl eax, 12
|
||||
invlpg [eax]
|
||||
@ -287,7 +287,7 @@ user_realloc:
|
||||
jz .loop
|
||||
|
||||
push edx
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
pop edx
|
||||
mov eax, edx
|
||||
shl eax, 12
|
||||
|
@ -214,7 +214,7 @@ core_init:
|
||||
call @init_heap@8
|
||||
|
||||
call _init_core_dll
|
||||
call _init_threads
|
||||
; call _init_threads
|
||||
|
||||
; SAVE & CLEAR 0-0xffff
|
||||
|
||||
@ -277,8 +277,8 @@ map_LFB:
|
||||
add eax, 0x00400000
|
||||
mov [_sys_pdbr+4+(LFB_BASE shr 20)], eax
|
||||
if SHADOWFB
|
||||
mov ecx, 11
|
||||
call @core_alloc@4
|
||||
mov ecx, 1 shl 11
|
||||
call @frame_alloc@4
|
||||
or eax, PG_LARGE+PG_UW
|
||||
mov [_sys_pdbr+(SHADOWFB shr 20)], eax
|
||||
add eax, 0x00400000
|
||||
|
@ -987,8 +987,8 @@ malloc_large:
|
||||
align 4
|
||||
init_malloc:
|
||||
|
||||
mov ecx, 6
|
||||
call @core_alloc@4
|
||||
mov ecx, 64
|
||||
call @frame_alloc@4
|
||||
add eax, OS_BASE
|
||||
|
||||
mov [mst.top], eax
|
||||
|
@ -212,7 +212,7 @@ proc new_mem_resize stdcall, new_size:dword
|
||||
mov ebx, edi
|
||||
shl ebx, 12
|
||||
invlpg [ebx]
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
.next:
|
||||
add edi, 1
|
||||
cmp edi, esi
|
||||
@ -220,6 +220,8 @@ proc new_mem_resize stdcall, new_size:dword
|
||||
|
||||
.update_size:
|
||||
mov ebx, [new_size]
|
||||
mov edx, [current_slot]
|
||||
|
||||
call update_mem_size
|
||||
|
||||
xor eax, eax
|
||||
@ -422,12 +424,19 @@ proc page_fault_handler
|
||||
align 4
|
||||
.kernel_heap:
|
||||
|
||||
; xchg bx, bx
|
||||
|
||||
shr ebx, 22
|
||||
mov edx, [master_tab + ebx*4]
|
||||
|
||||
test edx, PG_MAP
|
||||
jz .check_ptab ;òàáëèöà ñòðàíèö íå ñîçäàíà
|
||||
|
||||
mov ecx, [.err_addr]
|
||||
mov edx, [.err_code]
|
||||
|
||||
call @heap_fault@8
|
||||
|
||||
jmp .exit
|
||||
|
||||
.check_ptab:
|
||||
@ -435,8 +444,7 @@ align 4
|
||||
test edx, PG_MAP
|
||||
jnz @F
|
||||
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
@ -546,7 +554,7 @@ align 4
|
||||
popad
|
||||
add esp, 4
|
||||
|
||||
; iretd
|
||||
iretd
|
||||
|
||||
save_ring3_context ;debugger support
|
||||
|
||||
@ -1094,15 +1102,12 @@ proc create_ring_buffer stdcall, size:dword, flags:dword
|
||||
|
||||
push ebx
|
||||
|
||||
xor ecx, ecx
|
||||
mov edx, [size]
|
||||
shr edx, 12
|
||||
mov ebx, edx
|
||||
dec edx
|
||||
bsr ecx, edx
|
||||
inc ecx
|
||||
mov ecx, [size]
|
||||
shr ecx, 12
|
||||
|
||||
call @core_alloc@4
|
||||
mov ebx, ecx
|
||||
|
||||
call @frame_alloc@4
|
||||
test eax, eax
|
||||
jz .mm_fail
|
||||
|
||||
|
@ -13,17 +13,6 @@ void __fastcall *balloc(u32_t size);
|
||||
|
||||
zone_t z_core;
|
||||
|
||||
static inline u32_t save_edx(void)
|
||||
{
|
||||
u32_t val;
|
||||
asm volatile ("movl %%edx, %0":"=r"(val));
|
||||
return val;
|
||||
};
|
||||
|
||||
static inline void restore_edx(u32_t val)
|
||||
{
|
||||
asm volatile (""::"d" (val) );
|
||||
};
|
||||
|
||||
static void buddy_system_create(zone_t *z);
|
||||
static void __fastcall buddy_system_free(zone_t *z, link_t *block);
|
||||
@ -36,8 +25,6 @@ size_t buddy_conf_size(int max_order);
|
||||
|
||||
static inline void frame_initialize(frame_t *frame);
|
||||
|
||||
void init_mm();
|
||||
|
||||
|
||||
static void zone_create(zone_t *z, pfn_t start, count_t count);
|
||||
static void zone_reserve(zone_t *z, pfn_t base, count_t count);
|
||||
@ -558,8 +545,8 @@ addr_t __fastcall core_alloc(u32_t order)
|
||||
spinlock_unlock(&z_core.lock);
|
||||
safe_sti(efl);
|
||||
|
||||
DBG("core alloc: %x, size %x remain %d\n", v << FRAME_WIDTH,
|
||||
((1<<order)<<12), z_core.free_count);
|
||||
DBG("core alloc at: 0x%x, size 0x%x remain %d\n", v << FRAME_WIDTH,
|
||||
((1<<order)<<FRAME_WIDTH), z_core.free_count);
|
||||
|
||||
return (v << FRAME_WIDTH);
|
||||
};
|
||||
@ -568,11 +555,11 @@ void __fastcall core_free(addr_t frame)
|
||||
{
|
||||
eflags_t efl;
|
||||
|
||||
DBG("core free %x", frame);
|
||||
DBG("core free 0x%x", frame);
|
||||
|
||||
efl = safe_cli();
|
||||
spinlock_lock(&z_core.lock);
|
||||
zone_free(&z_core, frame>>12);
|
||||
// zone_free(&z_core, frame>>12);
|
||||
spinlock_unlock(&z_core.lock);
|
||||
safe_sti(efl);
|
||||
|
||||
|
@ -42,7 +42,6 @@ int __stdcall strncmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
bool link_image(addr_t img_base);
|
||||
|
||||
md_t* __fastcall load_image(const char *path);
|
||||
|
||||
/*
|
||||
void* __fastcall load_pe(const char *path)
|
||||
@ -109,12 +108,12 @@ bool validate_pe(void *raw, size_t raw_size, bool is_exec)
|
||||
return true;
|
||||
}
|
||||
|
||||
md_t* __fastcall load_image(const char *path)
|
||||
addr_t __fastcall load_image(const char *path)
|
||||
{
|
||||
PIMAGE_DOS_HEADER dos;
|
||||
PIMAGE_NT_HEADERS32 nt;
|
||||
|
||||
md_t *img_md;
|
||||
// md_t *img_md;
|
||||
|
||||
size_t img_size;
|
||||
addr_t img_base;
|
||||
@ -147,16 +146,17 @@ md_t* __fastcall load_image(const char *path)
|
||||
|
||||
img_size = nt->OptionalHeader.SizeOfImage;
|
||||
|
||||
img_md = md_alloc(img_size, PG_SW);
|
||||
// img_md = md_alloc(img_size, PG_SW);
|
||||
|
||||
img_base = mem_alloc(img_size, PG_SW);
|
||||
|
||||
if( !img_md)
|
||||
if( !img_base)
|
||||
{
|
||||
mem_free(raw);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
img_base = img_md->base;
|
||||
// img_base = img_md->base;
|
||||
|
||||
create_image(img_base, (addr_t)raw, true);
|
||||
|
||||
@ -165,7 +165,7 @@ md_t* __fastcall load_image(const char *path)
|
||||
// dos = (PIMAGE_DOS_HEADER)img_base;
|
||||
// nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||
|
||||
return img_md;
|
||||
return img_base;
|
||||
};
|
||||
|
||||
|
||||
|
@ -33,13 +33,15 @@ static slab_t * slab_space_alloc(slab_cache_t *cache, int flags)
|
||||
unsigned int i;
|
||||
u32_t p;
|
||||
|
||||
data = (void*)PA2KA(core_alloc(cache->order));
|
||||
DBG("%s order %d\n", __FUNCTION__, cache->order);
|
||||
|
||||
data = (void*)PA2KA(frame_alloc(1 << cache->order));
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
slab = (slab_t*)slab_create();
|
||||
if (!slab) {
|
||||
core_free(KA2PA(data));
|
||||
frame_free(KA2PA(data));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -74,12 +76,6 @@ static void * slab_obj_create(slab_cache_t *cache, int flags)
|
||||
spinlock_lock(&cache->slablock);
|
||||
|
||||
if (list_empty(&cache->partial_slabs)) {
|
||||
/* Allow recursion and reclaiming
|
||||
* - this should work, as the slab control structures
|
||||
* are small and do not need to allocate with anything
|
||||
* other than frame_alloc when they are allocating,
|
||||
* that's why we should get recursion at most 1-level deep
|
||||
*/
|
||||
slab = slab_space_alloc(cache, flags);
|
||||
if (!slab)
|
||||
{
|
||||
@ -211,7 +207,7 @@ _slab_cache_create(slab_cache_t *cache,
|
||||
/* Minimum slab order */
|
||||
pages = SIZE2FRAMES(cache->size);
|
||||
/* We need the 2^order >= pages */
|
||||
if (pages == 1)
|
||||
if (pages <= 1)
|
||||
cache->order = 0;
|
||||
else
|
||||
cache->order = fnzb(pages-1)+1;
|
||||
@ -241,6 +237,8 @@ slab_cache_t * slab_cache_create(
|
||||
{
|
||||
slab_cache_t *cache;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
cache = (slab_cache_t*)slab_cache_alloc();
|
||||
_slab_cache_create(cache, size, align, constructor, destructor, flags);
|
||||
return cache;
|
||||
@ -337,22 +335,18 @@ static slab_t *slab_create()
|
||||
void *obj;
|
||||
u32_t p;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
// spinlock_lock(&cache->slablock);
|
||||
|
||||
if (list_empty(&slab_cache->partial_slabs)) {
|
||||
/* Allow recursion and reclaiming
|
||||
* - this should work, as the slab control structures
|
||||
* are small and do not need to allocate with anything
|
||||
* other than frame_alloc when they are allocating,
|
||||
* that's why we should get recursion at most 1-level deep
|
||||
*/
|
||||
// spinlock_unlock(&cache->slablock);
|
||||
// slab = slab_create();
|
||||
|
||||
void *data;
|
||||
unsigned int i;
|
||||
|
||||
data = (void*)PA2KA(core_alloc(0));
|
||||
data = (void*)PA2KA(alloc_page());
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
@ -400,20 +394,17 @@ static slab_cache_t * slab_cache_alloc()
|
||||
void *obj;
|
||||
u32_t *p;
|
||||
|
||||
if (list_empty(&slab_cache_cache.partial_slabs)) {
|
||||
/* Allow recursion and reclaiming
|
||||
* - this should work, as the slab control structures
|
||||
* are small and do not need to allocate with anything
|
||||
* other than frame_alloc when they are allocating,
|
||||
* that's why we should get recursion at most 1-level deep
|
||||
*/
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
if (list_empty(&slab_cache_cache.partial_slabs))
|
||||
{
|
||||
// spinlock_unlock(&cache->slablock);
|
||||
// slab = slab_create();
|
||||
|
||||
void *data;
|
||||
unsigned int i;
|
||||
|
||||
data = (void*)(PA2KA(core_alloc(0)));
|
||||
data = (void*)(PA2KA(alloc_page()));
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
@ -437,7 +428,8 @@ static slab_cache_t * slab_cache_alloc()
|
||||
|
||||
atomic_inc(&slab_cache_cache.allocated_slabs);
|
||||
// spinlock_lock(&cache->slablock);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
slab = list_get_instance(slab_cache_cache.partial_slabs.next, slab_t, link);
|
||||
list_remove(&slab->link);
|
||||
}
|
||||
@ -457,6 +449,7 @@ static slab_cache_t * slab_cache_alloc()
|
||||
|
||||
void slab_cache_init(void)
|
||||
{
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
_slab_cache_create(&slab_cache_cache, sizeof(slab_cache_t),
|
||||
sizeof(void *), NULL, NULL,
|
||||
|
@ -638,23 +638,23 @@ term9:
|
||||
|
||||
mov ecx,[edi+APPDATA.pl0_stack]
|
||||
sub ecx, OS_BASE
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
|
||||
mov ecx,[edi+APPDATA.cur_dir]
|
||||
sub ecx, OS_BASE
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
|
||||
mov ecx, [edi+APPDATA.io_map]
|
||||
cmp ecx, (tss._io_map_0-OS_BASE+PG_MAP)
|
||||
je @F
|
||||
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
@@:
|
||||
mov ecx, [edi+APPDATA.io_map+4]
|
||||
cmp ecx, (tss._io_map_1-OS_BASE+PG_MAP)
|
||||
je @F
|
||||
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
@@:
|
||||
mov eax, 0x20202020
|
||||
stosd
|
||||
|
@ -222,10 +222,9 @@ proc mnt_exec stdcall file_base:dword, file_size:dword, \
|
||||
|
||||
mov ebx,[slot_base]
|
||||
mov [ebx+APPDATA.dir_table],eax
|
||||
mov eax,[hdr_mem]
|
||||
mov [ebx+APPDATA.mem_size],eax
|
||||
mov ecx,[hdr_mem]
|
||||
mov [ebx+APPDATA.mem_size],ecx
|
||||
|
||||
mov ecx, [hdr_mem]
|
||||
mov edi, [file_size]
|
||||
; add edi, 4095
|
||||
; and edi, not 4095
|
||||
@ -337,8 +336,8 @@ proc pe_app_param stdcall path:dword, raw:dword, ex_pg_dir:dword, ex_stack:dword
|
||||
;mov [ebx+APPDATA.mem_size],eax
|
||||
|
||||
|
||||
mov ecx, 1
|
||||
call @core_alloc@4
|
||||
mov ecx, 2
|
||||
call @frame_alloc@4
|
||||
lea edi, [eax+OS_BASE]
|
||||
mov [pl0_stack], edi
|
||||
|
||||
@ -375,8 +374,7 @@ proc pe_app_param stdcall path:dword, raw:dword, ex_pg_dir:dword, ex_stack:dword
|
||||
mov ecx, [def_cursor]
|
||||
mov [ebx+APPDATA.cursor],ecx
|
||||
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
lea edi, [eax+OS_BASE] ; FIXME
|
||||
|
||||
mov esi,[current_slot]
|
||||
@ -542,7 +540,9 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov ecx, 512
|
||||
mov esi, [img_base]
|
||||
|
||||
mov ecx, 512 ; FIX only core tabs
|
||||
mov esi, _sys_pdbr+(HEAP_BASE shr 20)
|
||||
rep movsd
|
||||
|
||||
@ -553,7 +553,9 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
mov eax, edi
|
||||
call set_cr3
|
||||
|
||||
mov edx, [app_tabs]
|
||||
mov esi, [img_base]
|
||||
|
||||
mov ebx, [app_tabs]
|
||||
mov edi, master_tab
|
||||
@@:
|
||||
call _alloc_page
|
||||
@ -562,7 +564,7 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
|
||||
or eax, PG_UW
|
||||
stosd
|
||||
dec edx
|
||||
dec ebx
|
||||
jnz @B
|
||||
|
||||
mov edi, page_tabs
|
||||
@ -571,11 +573,9 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
mov ecx, [app_pages]
|
||||
xor ebx, ebx
|
||||
.alloc:
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
@ -615,8 +615,7 @@ align 4
|
||||
|
||||
lea ebx, [ecx+0x3FFFFF]
|
||||
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
test eax, eax
|
||||
mov [esp], eax
|
||||
jz .fail
|
||||
@ -627,15 +626,14 @@ align 4
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov ecx, 512
|
||||
mov ecx, 512 ; FIX only core tabs
|
||||
mov esi, _sys_pdbr+(HEAP_BASE shr 20)
|
||||
rep movsd
|
||||
|
||||
mov esi, [esp]
|
||||
shr ebx, 22
|
||||
.new_ptab:
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
@ -651,8 +649,7 @@ align 4
|
||||
dec ebx
|
||||
jnz .new_ptab
|
||||
|
||||
xor ecx, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
@ -701,7 +698,7 @@ proc destroy_page_table stdcall, pg_tab:dword
|
||||
test ecx, 1 shl 9
|
||||
jnz .next ;skip shared pages
|
||||
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
.next:
|
||||
add esi, 4
|
||||
dec ebx
|
||||
@ -759,14 +756,14 @@ proc destroy_app_space stdcall, pg_dir:dword
|
||||
stdcall destroy_page_table, eax
|
||||
|
||||
mov ecx, [esi]
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
.next:
|
||||
add esi, 4
|
||||
dec edi
|
||||
jnz .destroy
|
||||
|
||||
mov ecx, [pg_dir]
|
||||
call @core_free@4
|
||||
call @frame_free@4
|
||||
.exit:
|
||||
dec [pg_data.pg_mutex]
|
||||
ret
|
||||
@ -1150,8 +1147,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
||||
pl0_stack dd ?
|
||||
endl
|
||||
|
||||
mov ecx, 1 ;(RING0_STACK_SIZE+512) shr 12
|
||||
call @core_alloc@4
|
||||
mov ecx, 2 ;(RING0_STACK_SIZE+512) shr 12
|
||||
call @frame_alloc@4
|
||||
add eax, OS_BASE
|
||||
mov [pl0_stack], eax
|
||||
|
||||
@ -1196,12 +1193,11 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
||||
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
|
||||
|
||||
call _alloc_page
|
||||
add eax, OS_BASE
|
||||
lea edi, [eax + OS_BASE]
|
||||
mov [ebx+SLOT_BASE+APPDATA.cur_dir], edi
|
||||
mov esi,[current_slot]
|
||||
mov esi,[esi+APPDATA.cur_dir]
|
||||
mov ecx,0x1000/4
|
||||
mov edi,eax
|
||||
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax
|
||||
rep movsd
|
||||
|
||||
shr ebx,3
|
||||
@ -1302,7 +1298,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
||||
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
|
||||
.no_debug:
|
||||
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
|
||||
DEBUGF 1,"%s",new_process_running
|
||||
; DEBUGF 1,"%s",new_process_running
|
||||
ret
|
||||
endp
|
||||
|
||||
|
@ -14,6 +14,8 @@ extern addr_t sys_pdbr;
|
||||
|
||||
void init_threads()
|
||||
{
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
thr_slab = slab_cache_create(sizeof(thr_t), 16,
|
||||
NULL,NULL,SLAB_CACHE_MAGDEFERRED);
|
||||
};
|
||||
@ -27,8 +29,10 @@ thr_t* __fastcall create_systhread(addr_t entry_ptr)
|
||||
thr_t *thr;
|
||||
addr_t thr_stack;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
thr = (thr_t*)slab_alloc(thr_slab,0);
|
||||
thr_stack = PA2KA(core_alloc(1));
|
||||
thr_stack = PA2KA(frame_alloc(2));
|
||||
|
||||
thr_cnt++;
|
||||
|
||||
|
@ -85,8 +85,7 @@ endp
|
||||
|
||||
proc load_file_parse_table
|
||||
|
||||
xor eac, ecx
|
||||
call @core_alloc@4
|
||||
call _alloc_page
|
||||
add eax, OS_BASE
|
||||
mov [tmp_file_name_table],eax
|
||||
mov edi,eax
|
||||
|
@ -4,7 +4,7 @@
|
||||
#define LOAD_BASE 0x00100000
|
||||
|
||||
|
||||
#define page_tabs 0xDDC00000
|
||||
#define page_tabs 0xDD800000
|
||||
|
||||
#define master_tab (page_tabs+(page_tabs>>10))
|
||||
|
||||
@ -20,6 +20,10 @@
|
||||
#define sel_srv_stack 0x39
|
||||
|
||||
|
||||
|
||||
#define __export __attribute__ ((dllexport))
|
||||
|
||||
|
||||
void printf (const char *format, ...);
|
||||
|
||||
#define CALLER ((addr_t) __builtin_return_address(0))
|
||||
@ -74,11 +78,10 @@ static inline void safe_sti(eflags_t efl)
|
||||
asm volatile (
|
||||
"pushl %0\n\t"
|
||||
"popfl\n"
|
||||
: : "r" (efl)
|
||||
);
|
||||
: : "r" (efl));
|
||||
}
|
||||
|
||||
static inline count_t fnzb(u32_t arg)
|
||||
static inline index_t fnzb(u32_t arg)
|
||||
{
|
||||
count_t n;
|
||||
asm volatile (
|
||||
@ -88,7 +91,7 @@ static inline count_t fnzb(u32_t arg)
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline count_t _bsf(u32_t arg)
|
||||
static inline index_t _bsf(u32_t arg)
|
||||
{
|
||||
count_t n;
|
||||
asm volatile (
|
||||
@ -201,7 +204,7 @@ typedef struct
|
||||
}ioctl_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u32_t code;
|
||||
union
|
||||
@ -214,7 +217,7 @@ typedef struct
|
||||
u16_t x; /* cursor x */
|
||||
u16_t y; /* cursor y */
|
||||
u32_t unused;
|
||||
}__attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct /* realtime io */
|
||||
{
|
||||
@ -237,6 +240,7 @@ typedef struct
|
||||
}event_t;
|
||||
|
||||
|
||||
void __fastcall dump_file(addr_t addr, size_t size);
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +1,24 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t link;
|
||||
addr_t base;
|
||||
size_t size;
|
||||
addr_t pte[0];
|
||||
|
||||
}mmap_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t buddy_link; /**< link to the next free block inside one order */
|
||||
count_t refcount; /**< tracking of shared frames */
|
||||
u32_t buddy_order; /**< buddy system block order */
|
||||
u16_t refcount; /**< tracking of shared frames */
|
||||
u16_t buddy_order; /**< buddy system block order */
|
||||
void *parent; /**< If allocated by slab, this points there */
|
||||
} frame_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
|
||||
pfn_t base; /**< frame_no of the first frame in the frames array */
|
||||
count_t count; /**< Size of zone */
|
||||
@ -44,9 +55,7 @@ typedef struct
|
||||
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define FRAME_WIDTH 12
|
||||
|
||||
#define BUDDY_SYSTEM_INNER_BLOCK 0xff
|
||||
#define PAGE_WIDTH 12
|
||||
|
||||
|
||||
# define PA2KA(x) (((addr_t) (x)) + OS_BASE)
|
||||
@ -56,39 +65,39 @@ static inline count_t SIZE2FRAMES(size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return 0;
|
||||
return (count_t) ((size - 1) >> FRAME_WIDTH) + 1;
|
||||
return (count_t) ((size - 1) >> PAGE_WIDTH) + 1;
|
||||
}
|
||||
|
||||
static inline addr_t PFN2ADDR(pfn_t frame)
|
||||
{
|
||||
return (addr_t) (frame << FRAME_WIDTH);
|
||||
return (addr_t) (frame << PAGE_WIDTH);
|
||||
}
|
||||
|
||||
static inline pfn_t ADDR2PFN(addr_t addr)
|
||||
{
|
||||
return (pfn_t) (addr >> FRAME_WIDTH);
|
||||
return (pfn_t) (addr >> PAGE_WIDTH);
|
||||
};
|
||||
|
||||
void init_mm();
|
||||
void init_pg_slab();
|
||||
|
||||
void* __fastcall frame_get_parent(pfn_t pfn);
|
||||
void __fastcall frame_set_parent(pfn_t pfn, void *data);
|
||||
|
||||
void frame_free(pfn_t frame);
|
||||
|
||||
|
||||
addr_t __fastcall core_alloc(u32_t order);
|
||||
void __fastcall core_free(addr_t frame);
|
||||
|
||||
pfn_t alloc_page() __attribute__ ((deprecated));
|
||||
|
||||
|
||||
#define __export __attribute__ ((dllexport))
|
||||
addr_t alloc_page(void);
|
||||
|
||||
|
||||
md_t* __fastcall md_alloc(size_t size, u32_t flags) ;
|
||||
void __fastcall md_free(md_t *md);
|
||||
|
||||
void* __fastcall __export mem_alloc(size_t size, u32_t flags) asm ("MemAlloc");
|
||||
void __fastcall __export mem_free(void *mem) asm ("MemFree");
|
||||
addr_t __fastcall __export mem_alloc(size_t size, u32_t flags) asm ("MemAlloc");
|
||||
void __fastcall __export mem_free(addr_t mem) asm ("MemFree");
|
||||
|
||||
addr_t __fastcall frame_alloc(size_t size);
|
||||
size_t __fastcall frame_free(addr_t addr);
|
||||
|
||||
|
@ -201,7 +201,7 @@ bool validate_pe(void *raw, size_t raw_size, bool is_exec);
|
||||
dll_t * find_dll(link_t *list, const char *name);
|
||||
|
||||
|
||||
md_t* __fastcall load_image(const char *path);
|
||||
addr_t __fastcall load_image(const char *path);
|
||||
|
||||
void create_image(addr_t img_base, addr_t raw, bool force_clear) asm ("CreateImage");
|
||||
|
||||
|
@ -122,6 +122,7 @@ public _gdts
|
||||
public __hlt
|
||||
public _panic_printf
|
||||
public _printf
|
||||
public _dump
|
||||
public _pg_balloc
|
||||
public _mem_amount
|
||||
public @balloc@4
|
||||
@ -215,11 +216,16 @@ extrn _16bit_end
|
||||
|
||||
extrn _poweroff
|
||||
|
||||
extrn @core_alloc@4
|
||||
extrn @core_free@4
|
||||
extrn @pf_dump@8
|
||||
|
||||
extrn @frame_alloc@4
|
||||
extrn @frame_free@4
|
||||
|
||||
extrn @find_large_md@4
|
||||
|
||||
extrn @heap_fault@8
|
||||
|
||||
|
||||
extrn _MemAlloc
|
||||
extrn _MemFree
|
||||
|
||||
@ -486,7 +492,7 @@ no_mode_0x12:
|
||||
call rerouteirqs
|
||||
|
||||
; Initialize system V86 machine
|
||||
call init_sys_v86
|
||||
; call init_sys_v86
|
||||
|
||||
; TIMER SET TO 1/100 S
|
||||
|
||||
@ -587,7 +593,7 @@ include 'detect/disks.inc'
|
||||
call boot_log
|
||||
;call setirqreadports
|
||||
|
||||
; SET UP OS TASK
|
||||
; SETUP OS TASK
|
||||
|
||||
mov esi,boot_setostask
|
||||
call boot_log
|
||||
@ -597,7 +603,7 @@ include 'detect/disks.inc'
|
||||
mov dword [SLOT_BASE+APPDATA.fpu_handler], eax
|
||||
mov dword [SLOT_BASE+APPDATA.sse_handler], eax
|
||||
|
||||
; name for OS/IDLE process
|
||||
; name for OS/IDLE process
|
||||
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
|
||||
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
|
||||
@ -863,14 +869,14 @@ checkidle:
|
||||
jnz idle_exit
|
||||
call _rdtsc
|
||||
mov ecx,eax
|
||||
idle_loop:
|
||||
idle_loop:
|
||||
hlt
|
||||
cmp [check_idle_semaphore],0
|
||||
jne idle_loop_exit
|
||||
mov eax,[timer_ticks] ;[0xfdf0]
|
||||
cmp ebx,eax
|
||||
jz idle_loop
|
||||
idle_loop_exit:
|
||||
idle_loop_exit:
|
||||
mov [idlemem],eax
|
||||
call _rdtsc
|
||||
sub eax,ecx
|
||||
@ -3373,16 +3379,16 @@ redrawscreen:
|
||||
|
||||
;mov ecx,0 ; redraw flags for apps
|
||||
xor ecx,ecx
|
||||
newdw2:
|
||||
newdw2:
|
||||
|
||||
inc ecx
|
||||
push ecx
|
||||
|
||||
mov eax,ecx
|
||||
shl eax,5
|
||||
add eax,window_data
|
||||
add eax, window_data
|
||||
|
||||
cmp eax,[esp+4]
|
||||
cmp eax, [esp+4]
|
||||
je not_this_task
|
||||
; check if window in redraw area
|
||||
mov edi,eax
|
||||
@ -3429,7 +3435,7 @@ bgli:
|
||||
jz newdw8
|
||||
test al,al
|
||||
jz .az
|
||||
lea eax,[edi+draw_data+(0x100000000-OS_BASE)]
|
||||
lea eax,[edi+draw_data-window_data]
|
||||
mov ebx,[dlx]
|
||||
cmp ebx,[eax+RECT.left]
|
||||
jae @f
|
||||
@ -3454,7 +3460,7 @@ bgli:
|
||||
.az:
|
||||
|
||||
mov eax,edi
|
||||
add eax, draw_data+(0x100000000-OS_BASE)
|
||||
add eax, draw_data-window_data
|
||||
|
||||
mov ebx,[dlx] ; set limits
|
||||
mov [eax + RECT.left], ebx
|
||||
@ -3465,7 +3471,7 @@ bgli:
|
||||
mov ebx,[dlye]
|
||||
mov [eax + RECT.bottom], ebx
|
||||
|
||||
sub eax,draw_data+(0x100000000-OS_BASE)
|
||||
sub eax,draw_data - window_data
|
||||
|
||||
cmp dword [esp],1
|
||||
jne nobgrd
|
||||
|
@ -25,9 +25,10 @@ SECTIONS
|
||||
.flat . + 0x00400000:
|
||||
{
|
||||
*(.flat) *(.data)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
.edata ALIGN(32):
|
||||
.edata :
|
||||
{
|
||||
*(.edata)
|
||||
_code_end = .;
|
||||
|
@ -6,7 +6,7 @@ INCLUDE = include/
|
||||
|
||||
DEFS = -DUSE_SMP -DCONFIG_DEBUG
|
||||
|
||||
CFLAGS = -c -O2 -DCONFIG_DEBUG -I $(INCLUDE) -fomit-frame-pointer -fno-builtin
|
||||
CFLAGS = -c -O2 $(DEFS) -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf
|
||||
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
|
||||
|
||||
KERNEL_SRC:= \
|
||||
@ -33,9 +33,9 @@ KERNEL_SRC:= \
|
||||
PE_SRC:= \
|
||||
init.asm \
|
||||
mbi.c \
|
||||
mm.c \
|
||||
heap.c \
|
||||
slab.c \
|
||||
heap.c \
|
||||
frame.c \
|
||||
pe.c \
|
||||
dll.c \
|
||||
spinlock.c \
|
||||
@ -70,6 +70,9 @@ kernel.mnt: kernel.obj bin/export.obj $(PE_OBJS) Makefile ld.x
|
||||
bin/%.obj : core/%.c $(H_SRC) Makefile
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
bin/%.obj : gui/%.c $(H_SRC) Makefile
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
bin/%.obj: core/%.asm Makefile
|
||||
$(FASM) $< $@
|
||||
|
||||
|
@ -5,6 +5,24 @@ BYTE equ byte
|
||||
|
||||
PTR equ
|
||||
|
||||
align 4
|
||||
|
||||
_dump:
|
||||
|
||||
mov ecx, DWORD PTR [esp+4]
|
||||
@@:
|
||||
mov edx, 0x3FD
|
||||
in al, dx
|
||||
test al, 96
|
||||
je @B
|
||||
|
||||
mov dl, -8
|
||||
mov eax, ecx
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
_putc:
|
||||
mov ecx, DWORD PTR [esp+4]
|
||||
.L13:
|
||||
|
@ -28,7 +28,11 @@ unpack:
|
||||
popad
|
||||
ret 8
|
||||
.lzma:
|
||||
pushfd
|
||||
cli
|
||||
call .lzma_unpack
|
||||
popfd
|
||||
|
||||
.common:
|
||||
pop eax
|
||||
test al, 0x80
|
||||
|
Loading…
Reference in New Issue
Block a user