PE loader. "C" version

git-svn-id: svn://kolibrios.org@889 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-10-30 06:30:13 +00:00
parent b7083f5742
commit cb4549795b
14 changed files with 265 additions and 511 deletions

View File

@ -562,6 +562,7 @@ endp
; loaded by the load_file() function ; loaded by the load_file() function
align 4 align 4
_load_file@4:
proc load_file stdcall, file_name:dword proc load_file stdcall, file_name:dword
locals locals
attr dd ? attr dd ?

View File

@ -132,13 +132,13 @@ kernel_export:
dd szSelectHwCursor , select_hw_cursor ;import stdcall dd szSelectHwCursor , select_hw_cursor ;import stdcall
dd szSetHwCursor , set_hw_cursor ;import stdcall dd szSetHwCursor , set_hw_cursor ;import stdcall
dd szHwCursorRestore , hw_restore ;import dd szHwCursorRestore , hw_restore ;import
dd szHwCursorCreate , create_cursor ;import dd szHwCursorCreate , create_cursor ;import
dd szSysMsgBoardStr , sys_msg_board_str dd szSysMsgBoardStr , sys_msg_board_str
dd szSysMsgBoardChar , sys_msg_board dd szSysMsgBoardChar , sys_msg_board
dd szGetCurrentTask , get_curr_task dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event dd szSendEvent , send_event
dd szSetMouseData , set_mouse_data ;stdcall dd szSetMouseData , set_mouse_data ;stdcall
dd szSleep , delay_ms dd szSleep , delay_ms

View File

@ -8,18 +8,9 @@
#define page_tabs 0xDF800000 #define page_tabs 0xDF800000
typedef struct
{
link_t link;
link_t adj;
addr_t base;
size_t size;
void *parent;
u32_t state;
}md_t;
#define MD_FREE 1 #define MD_FREE 1
#define MD_USED 2 #define MD_USED 2
typedef struct { typedef struct {
u32_t av_mapped; u32_t av_mapped;
@ -63,36 +54,35 @@ static inline void _reset_savu(count_t idx)
int __fastcall init_heap(addr_t base, size_t size) int __fastcall init_heap(addr_t base, size_t size)
{ {
md_t *md; md_t *md;
u32_t i; u32_t i;
ASSERT(base != 0); ASSERT(base != 0);
ASSERT(size != 0) ASSERT(size != 0)
ASSERT((base & 0x3FFFFF) == 0); ASSERT((base & 0x3FFFFF) == 0);
ASSERT((size & 0x3FFFFF) == 0); ASSERT((size & 0x3FFFFF) == 0);
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
{ {
list_initialize(&lheap.mapped[i]); list_initialize(&lheap.mapped[i]);
list_initialize(&lheap.unmapped[i]); list_initialize(&lheap.unmapped[i]);
list_initialize(&sheap.mapped[i]); list_initialize(&sheap.mapped[i]);
list_initialize(&sheap.unmapped[i]); list_initialize(&sheap.unmapped[i]);
}; };
list_initialize(&lheap.used); list_initialize(&lheap.used);
list_initialize(&sheap.used); list_initialize(&sheap.used);
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED); md = (md_t*)slab_alloc(md_slab,0);
md = (md_t*)slab_alloc(md_slab,0); list_initialize(&md->adj);
md->base = base;
list_initialize(&md->adj); md->size = size;
md->base = base; md->parent = NULL;
md->size = size; md->state = MD_FREE;
md->parent = NULL;
md->state = MD_FREE;
list_prepend(&md->link, &lheap.unmapped[31]); list_prepend(&md->link, &lheap.unmapped[31]);
lheap.av_mapped = 0x00000000; lheap.av_mapped = 0x00000000;
@ -100,82 +90,82 @@ int __fastcall init_heap(addr_t base, size_t size)
sheap.av_mapped = 0x00000000; sheap.av_mapped = 0x00000000;
sheap.av_unmapped = 0x00000000; sheap.av_unmapped = 0x00000000;
return 1; return 1;
}; };
md_t* __fastcall find_large_md(size_t size) md_t* __fastcall find_large_md(size_t size)
{ {
md_t *md = NULL; md_t *md = NULL;
count_t idx0; count_t idx0;
u32_t mask; u32_t mask;
ASSERT((size & 0x3FFFFF) == 0); ASSERT((size & 0x3FFFFF) == 0);
idx0 = (size>>22) - 1 < 32 ? (size>>22) - 1 : 31; idx0 = (size>>22) - 1 < 32 ? (size>>22) - 1 : 31;
mask = lheap.av_unmapped & ( -1<<idx0 ); mask = lheap.av_unmapped & ( -1<<idx0 );
if(mask) if(mask)
{ {
if(idx0 == 31) if(idx0 == 31)
{ {
md_t *tmp = (md_t*)lheap.unmapped[31].next; md_t *tmp = (md_t*)lheap.unmapped[31].next;
while((link_t*)tmp != &lheap.unmapped[31]) while((link_t*)tmp != &lheap.unmapped[31])
{ {
if(tmp->size >= size) if(tmp->size >= size)
{ {
DBG("remove large tmp %x\n", tmp); DBG("remove large tmp %x\n", tmp);
md = tmp; md = tmp;
break; break;
}; };
}; };
tmp = (md_t*)tmp->link.next; tmp = (md_t*)tmp->link.next;
} }
else else
{ {
idx0 = _bsf(mask); idx0 = _bsf(mask);
ASSERT( !list_empty(&lheap.unmapped[idx0])) ASSERT( !list_empty(&lheap.unmapped[idx0]))
md = (md_t*)lheap.unmapped[idx0].next; md = (md_t*)lheap.unmapped[idx0].next;
}; };
} }
else else
return NULL; return NULL;
ASSERT(md->state == MD_FREE); ASSERT(md->state == MD_FREE);
list_remove((link_t*)md); list_remove((link_t*)md);
if(list_empty(&lheap.unmapped[idx0])) if(list_empty(&lheap.unmapped[idx0]))
_reset_lavu(idx0); _reset_lavu(idx0);
if(md->size > size) if(md->size > size)
{ {
count_t idx1; count_t idx1;
md_t *new_md = (md_t*)slab_alloc(md_slab,0); /* FIXME check */ md_t *new_md = (md_t*)slab_alloc(md_slab,0); /* FIXME check */
link_initialize(&new_md->link); link_initialize(&new_md->link);
list_insert(&new_md->adj, &md->adj); list_insert(&new_md->adj, &md->adj);
new_md->base = md->base; new_md->base = md->base;
new_md->size = size; new_md->size = size;
new_md->parent = NULL; new_md->parent = NULL;
new_md->state = MD_USED; new_md->state = MD_USED;
md->base+= size; md->base+= size;
md->size-= size; md->size-= size;
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31; idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
list_prepend(&md->link, &lheap.unmapped[idx1]); list_prepend(&md->link, &lheap.unmapped[idx1]);
_set_lavu(idx1); _set_lavu(idx1);
return new_md; return new_md;
}; };
md->state = MD_USED; md->state = MD_USED;
return md; return md;
} }
md_t* __fastcall find_unmapped_md(size_t size) md_t* __fastcall find_unmapped_md(size_t size)
@ -564,7 +554,7 @@ void __fastcall free_mapped_md(md_t *md)
fd = (md_t*)md->adj.next; fd = (md_t*)md->adj.next;
if(fd->state == MD_FREE) if(fd->state == MD_FREE)
{ {
idx = (fd->size>>12) - 1 < 32 ? (fd->size>>12) - 1 : 31; idx = (fd->size>>12) - 1 < 32 ? (fd->size>>12) - 1 : 31;
list_remove((link_t*)fd); list_remove((link_t*)fd);
@ -590,7 +580,7 @@ void __fastcall free_mapped_md(md_t *md)
slab_free(md_slab, md); slab_free(md_slab, md);
md = fd; md = fd;
}; };
}; };
md->state = MD_FREE; md->state = MD_FREE;
@ -605,15 +595,15 @@ void __fastcall free_mapped_md(md_t *md)
if( list_empty(&sheap.mapped[31])) if( list_empty(&sheap.mapped[31]))
list_prepend(&md->link, &sheap.mapped[31]); list_prepend(&md->link, &sheap.mapped[31]);
else else
{ {
md_t *tmp = (md_t*)sheap.mapped[31].next; md_t *tmp = (md_t*)sheap.mapped[31].next;
while((link_t*)tmp != &sheap.mapped[31]) while((link_t*)tmp != &sheap.mapped[31])
{ {
if(md->base < tmp->base) if(md->base < tmp->base)
break; break;
tmp = (md_t*)tmp->link.next; tmp = (md_t*)tmp->link.next;
} }
list_insert(&md->link, &tmp->link); list_insert(&md->link, &tmp->link);
}; };
}; };
@ -622,16 +612,12 @@ void __fastcall free_mapped_md(md_t *md)
}; };
void * __fastcall mem_alloc(size_t size, u32_t flags) md_t* __fastcall md_alloc(size_t size, u32_t flags)
{ {
eflags_t efl; eflags_t efl;
md_t *md; md_t *md;
DBG("\nmem_alloc: %x bytes\n", size);
ASSERT(size != 0);
size = (size+4095)&~4095; size = (size+4095)&~4095;
if( flags & PG_MAP ) if( flags & PG_MAP )
@ -641,6 +627,9 @@ void * __fastcall mem_alloc(size_t size, u32_t flags)
if( !md ) if( !md )
return NULL; return NULL;
ASSERT(md->state == MD_USED);
ASSERT(md->parent != NULL);
md_t *lmd = (md_t*)md->parent; md_t *lmd = (md_t*)md->parent;
ASSERT( lmd != NULL); ASSERT( lmd != NULL);
@ -655,44 +644,63 @@ void * __fastcall mem_alloc(size_t size, u32_t flags)
addr_t *pte = &((addr_t*)page_tabs)[md->base>>12]; addr_t *pte = &((addr_t*)page_tabs)[md->base>>12];
while(tmp--) while(tmp--)
{ {
*pte++ = frame; *pte++ = frame;
frame+= 4096; frame+= 4096;
}; };
} }
else else
{
md = find_unmapped_md(size); md = find_unmapped_md(size);
if( !md )
return NULL;
ASSERT(md->parent != NULL);
ASSERT(md->state == MD_USED);
}
return md;
};
void * __fastcall mem_alloc(size_t size, u32_t flags)
{
eflags_t efl;
md_t *md;
DBG("\nmem_alloc: %x bytes\n", size);
ASSERT(size != 0);
md = md_alloc(size, flags);
if( !md ) if( !md )
return NULL; return NULL;
ASSERT(md->parent != NULL); efl = safe_cli();
ASSERT(md->state == MD_USED); spinlock_lock(&sheap.lock);
if( list_empty(&sheap.used) )
list_prepend(&md->link, &sheap.used);
else
{
md_t *tmp = (md_t*)sheap.used.next;
efl = safe_cli(); while((link_t*)tmp != &sheap.used)
spinlock_lock(&sheap.lock);
if( list_empty(&sheap.used) )
list_prepend(&md->link, &sheap.used);
else
{ {
md_t *tmp = (md_t*)sheap.used.next; if(md->base < tmp->base)
break;
tmp = (md_t*)tmp->link.next;
}
list_insert(&md->link, &tmp->link);
};
while((link_t*)tmp != &sheap.used) spinlock_unlock(&sheap.lock);
{ safe_sti(efl);
if(md->base < tmp->base)
break;
tmp = (md_t*)tmp->link.next;
}
list_insert(&md->link, &tmp->link);
};
spinlock_unlock(&sheap.lock); DBG("allocate: %x size %x\n\n",md->base, size);
safe_sti(efl); return (void*)md->base;
DBG("allocate: %x size %x\n\n",md->base, size);
return (void*)md->base;
}; };
void __fastcall mem_free(void *mem) void __fastcall mem_free(void *mem)
@ -738,17 +746,17 @@ void __fastcall mem_free(void *mem)
if(lmd->parent != 0) if(lmd->parent != 0)
{ {
count_t tmp = md->size >> 12; count_t tmp = md->size >> 12;
addr_t *pte = &((addr_t*)page_tabs)[md->base>>12]; addr_t *pte = &((addr_t*)page_tabs)[md->base>>12];
while(tmp--) while(tmp--)
{ {
*pte++ = 0; *pte++ = 0;
asm volatile ( asm volatile (
"invlpg (%0)" "invlpg (%0)"
::"r" (mem) ); ::"r" (mem) );
mem+= 4096; mem+= 4096;
}; };
free_mapped_md( md ); free_mapped_md( md );
} }

View File

@ -146,6 +146,7 @@ proc user_free stdcall, base:dword
mov eax, [page_tabs+(esi-1)*4] mov eax, [page_tabs+(esi-1)*4]
test al, USED_BLOCK test al, USED_BLOCK
jz .cantfree jz .cantfree
test al, DONT_FREE_BLOCK test al, DONT_FREE_BLOCK
jnz .cantfree jnz .cantfree
@ -159,6 +160,7 @@ proc user_free stdcall, base:dword
mov ebx, edi mov ebx, edi
shr edi, 12 shr edi, 12
jz .released jz .released
.release: .release:
xor ecx, ecx xor ecx, ecx
xchg ecx, [page_tabs+esi*4] xchg ecx, [page_tabs+esi*4]

View File

@ -243,6 +243,7 @@ proc new_mem_resize stdcall, new_size:dword
mov ecx, [app_page_tabs+edi*4] mov ecx, [app_page_tabs+edi*4]
test ecx, 1 test ecx, 1
jz .next jz .next
mov dword [app_page_tabs+edi*4], 2 mov dword [app_page_tabs+edi*4], 2
mov ebx, edi mov ebx, edi
shl ebx, 12 shl ebx, 12
@ -986,50 +987,16 @@ new_services:
cmp ebx, OS_BASE cmp ebx, OS_BASE
jae .fail jae .fail
stdcall load_PE, ebx mov ecx, ebx
call @load_pe_driver@4
test eax, eax
jz @F
mov esi, eax
stdcall eax, DRV_ENTRY
test eax, eax
jz @F
mov [eax+SRV.entry], esi
@@:
mov [esp+36], eax mov [esp+36], eax
ret ret
.fail: .fail:
xor eax, eax xor eax, eax
mov [esp+36], eax mov [esp+36], eax
ret ret
align 4
proc load_pe_driver stdcall, file:dword
stdcall load_PE, [file]
test eax, eax
jz .fail
mov esi, eax
stdcall eax, DRV_ENTRY
test eax, eax
jz .fail
mov [eax+SRV.entry], esi
ret
.fail:
xor eax, eax
ret
endp
align 4 align 4
proc init_mtrr proc init_mtrr

View File

@ -162,23 +162,23 @@ static void zone_reserve(zone_t *z, pfn_t base, count_t count)
static void zone_release(zone_t *z, pfn_t base, count_t count) static void zone_release(zone_t *z, pfn_t base, count_t count)
{ {
int i; int i;
pfn_t top = base+count; pfn_t top = base+count;
if( (base+count < z->base)||(base > z->base+z->count)) if( (base+count < z->base)||(base > z->base+z->count))
return; return;
if(base < z->base) if(base < z->base)
base = z->base; base = z->base;
if(top > z->base+z->count) if(top > z->base+z->count)
top = z->base+z->count; top = z->base+z->count;
DBG("zone release base %x top %x\n", base, top); DBG("zone release base %x top %x\n", base, top);
for (i = base; i < top; i++) { for (i = base; i < top; i++) {
z->frames[i-z->base].refcount = 0; z->frames[i-z->base].refcount = 0;
buddy_system_free(z, &z->frames[i-z->base].buddy_link); buddy_system_free(z, &z->frames[i-z->base].buddy_link);
} }
}; };
@ -260,12 +260,12 @@ static link_t *buddy_coalesce(zone_t *z, link_t *block_1,
} }
static inline void buddy_mark_busy(zone_t *z, link_t * block) { static inline void buddy_mark_busy(zone_t *z, link_t * block) {
frame_t * frame = (frame_t*)block; frame_t * frame = (frame_t*)block;
frame->refcount = 1; frame->refcount = 1;
} }
static inline void buddy_mark_available(zone_t *z, link_t *block) { static inline void buddy_mark_available(zone_t *z, link_t *block) {
frame_t *frame = (frame_t*)block; frame_t *frame = (frame_t*)block;
frame->refcount = 0; frame->refcount = 0;
} }
@ -281,15 +281,15 @@ static link_t *find_buddy(zone_t *zone, link_t *block)
{ {
frame_t *frame; frame_t *frame;
index_t index; index_t index;
u32_t is_left, is_right; u32_t is_left, is_right;
frame = (frame_t*)block; frame = (frame_t*)block;
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order)); ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order));
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame); is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
ASSERT(is_left ^ is_right); ASSERT(is_left ^ is_right);
if (is_left) { if (is_left) {
index = (frame_index(zone, frame)) + (1 << frame->buddy_order); index = (frame_index(zone, frame)) + (1 << frame->buddy_order);
} else { /* if (is_right) */ } else { /* if (is_right) */
@ -309,56 +309,56 @@ static link_t *find_buddy(zone_t *zone, link_t *block)
static link_t* __fastcall buddy_system_alloc_block(zone_t *z, link_t *block) static link_t* __fastcall buddy_system_alloc_block(zone_t *z, link_t *block)
{ {
link_t *left,*right, *tmp; link_t *left,*right, *tmp;
u32_t order; u32_t order;
left = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK); left = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK);
ASSERT(left); ASSERT(left);
list_remove(left); list_remove(left);
while (1) { while (1) {
if (! buddy_get_order(z,left)) { if (! buddy_get_order(z,left)) {
buddy_mark_busy(z, left); buddy_mark_busy(z, left);
return left; return left;
} }
order = buddy_get_order(z, left); order = buddy_get_order(z, left);
right = buddy_bisect(z, left); right = buddy_bisect(z, left);
buddy_set_order(z, left, order-1); buddy_set_order(z, left, order-1);
buddy_set_order(z, right, order-1); buddy_set_order(z, right, order-1);
tmp = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK); tmp = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK);
if (tmp == right) { if (tmp == right) {
right = left; right = left;
left = tmp; left = tmp;
} }
ASSERT(tmp == left); ASSERT(tmp == left);
buddy_mark_busy(z, left); buddy_mark_busy(z, left);
buddy_system_free(z, right); buddy_system_free(z, right);
buddy_mark_available(z, left); buddy_mark_available(z, left);
} }
} }
static void __fastcall buddy_system_free(zone_t *z, link_t *block) static void __fastcall buddy_system_free(zone_t *z, link_t *block)
{ {
link_t *buddy, *hlp; link_t *buddy, *hlp;
u8_t i; u8_t i;
/* /*
* Determine block's order. * Determine block's order.
*/ */
i = buddy_get_order(z, block); i = buddy_get_order(z, block);
ASSERT(i <= z->max_order); ASSERT(i <= z->max_order);
if (i != z->max_order) { if (i != z->max_order) {
/* /*
* See if there is any buddy in the list of order i. * See if there is any buddy in the list of order i.
*/ */
buddy = find_buddy(z, block); buddy = find_buddy(z, block);
if (buddy) { if (buddy) {
ASSERT(buddy_get_order(z, buddy) == i); ASSERT(buddy_get_order(z, buddy) == i);
/* /*
* Remove buddy from the list of order i. * Remove buddy from the list of order i.
*/ */
@ -367,37 +367,35 @@ static void __fastcall buddy_system_free(zone_t *z, link_t *block)
/* /*
* Invalidate order of both block and buddy. * Invalidate order of both block and buddy.
*/ */
buddy_set_order(z, block, BUDDY_SYSTEM_INNER_BLOCK); buddy_set_order(z, block, BUDDY_SYSTEM_INNER_BLOCK);
buddy_set_order(z, buddy, BUDDY_SYSTEM_INNER_BLOCK); buddy_set_order(z, buddy, BUDDY_SYSTEM_INNER_BLOCK);
/* /*
* Coalesce block and buddy into one block. * Coalesce block and buddy into one block.
*/ */
hlp = buddy_coalesce(z, block, buddy); hlp = buddy_coalesce(z, block, buddy);
/* /*
* Set order of the coalesced block to i + 1. * Set order of the coalesced block to i + 1.
*/ */
buddy_set_order(z, hlp, i + 1); buddy_set_order(z, hlp, i + 1);
/* /*
* Recursively add the coalesced block to the list of order i + 1. * Recursively add the coalesced block to the list of order i + 1.
*/ */
buddy_system_free(z, hlp); buddy_system_free(z, hlp);
return; return;
} }
} }
/* /*
* Insert block into the list of order i. * Insert block into the list of order i.
*/ */
list_append(block, &z->order[i]); list_append(block, &z->order[i]);
} }
static inline frame_t * zone_get_frame(zone_t *zone, index_t frame_idx) static inline frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
{ {
ASSERT(frame_idx < zone->count); ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx]; return &zone->frames[frame_idx];
} }
@ -409,8 +407,8 @@ static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
frame = zone_get_frame(zone, frame_idx); frame = zone_get_frame(zone, frame_idx);
if (frame->refcount) if (frame->refcount)
return; return;
link = buddy_system_alloc_block(zone, &frame->buddy_link); link = buddy_system_alloc_block(zone, &frame->buddy_link);
ASSERT(link); ASSERT(link);
zone->free_count--; zone->free_count--;
} }
@ -418,7 +416,7 @@ static link_t* __fastcall buddy_system_alloc(zone_t *z, u32_t i)
{ {
link_t *res, *hlp; link_t *res, *hlp;
ASSERT(i <= z->max_order); ASSERT(i <= z->max_order);
/* /*
* If the list of order i is not empty, * If the list of order i is not empty,
@ -480,7 +478,7 @@ static __fastcall pfn_t zone_frame_alloc(zone_t *zone, u32_t order)
/* Allocate frames from zone buddy system */ /* Allocate frames from zone buddy system */
tmp = buddy_system_alloc(zone, order); tmp = buddy_system_alloc(zone, order);
ASSERT(tmp); ASSERT(tmp);
/* Update zone information. */ /* Update zone information. */
zone->free_count -= (1 << order); zone->free_count -= (1 << order);
@ -602,14 +600,14 @@ addr_t alloc_page() //obsolete
void __fastcall zone_free(zone_t *zone, pfn_t frame_idx) void __fastcall zone_free(zone_t *zone, pfn_t frame_idx)
{ {
frame_t *frame; frame_t *frame;
u32_t order; u32_t order;
frame = &zone->frames[frame_idx]; frame = &zone->frames[frame_idx];
/* remember frame order */ /* remember frame order */
order = frame->buddy_order; order = frame->buddy_order;
ASSERT(frame->refcount); ASSERT(frame->refcount);
if (!--frame->refcount) if (!--frame->refcount)
{ {

View File

@ -11,279 +11,11 @@ include 'export.inc'
align 4 align 4
proc load_PE stdcall, file_name:dword
locals
image dd ?
entry dd ?
base dd ?
endl
stdcall load_file, [file_name] align 16
test eax, eax _kernel_exports:
jz .fail export 'KERNEL', \
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
mov [image], eax
mov ebx, [eax+60]
mov ecx, [eax+80+edx]
mov edx, PG_SW
call @mem_alloc@8
test eax, eax
mov [base], eax
jz .cleanup
stdcall map_PE, eax, [image]
mov [entry], eax
test eax, eax
jnz .cleanup
mov ecx, [base]
call @mem_free@4
.cleanup:
mov ecx, [image]
call @mem_free@4
mov eax, [entry]
ret
.fail:
xor eax, eax
ret
endp
DWORD equ dword
PTR equ
align 4
map_PE: ;stdcall base:dword, image:dword
cld
push ebp
push edi
push esi
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
shr ecx, 2
rep movsd
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
L3:
mov eax, DWORD PTR [edx+264]
test eax, eax
je L4
mov esi, ebx
mov edi, ebp
add esi, DWORD PTR [edx+268]
mov ecx, eax
add edi, DWORD PTR [edx+260]
shr ecx, 2
rep movsd
L4:
mov ecx, DWORD PTR [edx+256]
add ecx, 4095
and ecx, -4096
cmp ecx, eax
jbe L6
sub ecx, eax
add eax, DWORD PTR [edx+260]
lea edi, [eax+ebp]
xor eax, eax
rep stosb
L6:
inc DWORD PTR [esp+36]
add edx, 40
L2:
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
mov esi, ebp
mov ecx, ebp
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+12], eax
jmp L11
L12:
lea ebx, [eax-8]
xor edi, edi
shr ebx,1
jmp L13
L14:
movzx eax, WORD PTR [ecx+8+edi*2]
mov edx, eax
shr eax, 12
and edx, 4095
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+12]
add WORD PTR [edx+ebp], ax
L17:
add WORD PTR [edx+ebp], si
L18:
add DWORD PTR [edx+ebp], esi
L15:
inc edi
L13:
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
L11:
mov eax, DWORD PTR [ecx+4]
test eax, eax
jne L12
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
mov DWORD PTR [esp+52], 0
add ecx, ebp
add edx, ebp
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
L26:
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
test eax, eax
je L27
test eax, eax
js L27
lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
lea esi, [edi+2]
push eax
push 32
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop ebx
xor ebx, ebx
test eax, eax
jne L32
jmp L30
L33:
push ecx
push 32
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop edx
test eax, eax
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
inc ebx
L32:
cmp ebx, DWORD PTR [__exports+24]
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
mov esi, msg_unresolved
call sys_msg_board_str
lea esi, [edi+2]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov DWORD PTR [esp+40], 1
jmp L37
L30:
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
add eax, OS_BASE
mov DWORD PTR [edx+edi*4], eax
L37:
inc DWORD PTR [esp+52]
jmp L26
L27:
add DWORD PTR [esp+56], 20
jmp L22
L25:
xor eax, eax
cmp DWORD PTR [esp+40], 0
jne L40
L20:
mov ecx, DWORD PTR [esp+32]
mov eax, ebp
add eax, DWORD PTR [ecx+40]
L40:
add esp, 60
pop ebx
pop esi
pop edi
pop ebp
ret 8
align 16
__exports:
export 'KERNEL', \
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
create_kernel_object, 'CreateObject', \ create_kernel_object, 'CreateObject', \
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
destroy_kernel_object, 'DestroyObject', \ destroy_kernel_object, 'DestroyObject', \
@ -292,6 +24,8 @@ __exports:
free, 'Kfree', \ free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall map_io_mem, 'MapIoMem', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax get_pg_addr, 'GetPgAddr', \ ; eax
@mem_alloc@8, 'mem_alloc', \ ; fastcall
@mem_free@4, 'mem_free', \ ; fastcall
\ \
select_hw_cursor, 'SelectHwCursor', \ ; stdcall select_hw_cursor, 'SelectHwCursor', \ ; stdcall
set_hw_cursor, 'SetHwCursor', \ ; stdcall set_hw_cursor, 'SetHwCursor', \ ; stdcall

View File

@ -57,6 +57,7 @@ proc strncat stdcall, s1:dword, s2:dword, n:dword
endp endp
align 4 align 4
_strncmp@12:
proc strncmp stdcall, s1:dword, s2:dword, n:dword proc strncmp stdcall, s1:dword, s2:dword, n:dword
push esi push esi

View File

@ -623,11 +623,11 @@ term9:
pop ecx pop ecx
pop ecx pop ecx
.nodebug: .nodebug:
popad popad
mov edi, [.slot] mov edi, [.slot]
shl edi, 8 shl edi, 8
add edi,SLOT_BASE add edi,SLOT_BASE
mov ecx,[edi+APPDATA.pl0_stack] mov ecx,[edi+APPDATA.pl0_stack]
sub ecx, OS_BASE sub ecx, OS_BASE
@ -639,12 +639,14 @@ term9:
mov ecx, [edi+APPDATA.io_map] mov ecx, [edi+APPDATA.io_map]
cmp ecx, (tss._io_map_0-OS_BASE+PG_MAP) cmp ecx, (tss._io_map_0-OS_BASE+PG_MAP)
je @F je @F
call @core_free@4 call @core_free@4
@@: @@:
mov ecx, [edi+APPDATA.io_map+4] mov ecx, [edi+APPDATA.io_map+4]
cmp ecx, (tss._io_map_1-OS_BASE+PG_MAP) cmp ecx, (tss._io_map_1-OS_BASE+PG_MAP)
je @F je @F
call @core_free@4 call @core_free@4
@@: @@:
mov eax, 0x20202020 mov eax, 0x20202020

View File

@ -208,7 +208,7 @@ proc fs_execute
jna @F jna @F
xor eax, eax xor eax, eax
cld cld
rep stosb rep stosb
@@: @@:
mov ecx, [file_base] mov ecx, [file_base]
@ -416,7 +416,6 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
jnz @B jnz @B
mov edi, page_tabs mov edi, page_tabs
mov ecx, [app_tabs] mov ecx, [app_tabs]
shl ecx, 10 shl ecx, 10
xor eax, eax xor eax, eax
@ -624,7 +623,6 @@ check_process_region:
mov eax,1 mov eax,1
ret ret
; call MEM_Get_Linear_Address ; call MEM_Get_Linear_Address
; push ebx ; push ebx
; push ecx ; push ecx

View File

@ -92,7 +92,7 @@ static inline void _bts(u32_t *data, count_t val)
); );
} }
static inline void _btr(u32_t *data, count_t val) extern inline void _btr(u32_t *data, count_t val)
{ {
asm volatile ("btr %0, %1 \n\t" asm volatile ("btr %0, %1 \n\t"
: :
@ -100,3 +100,22 @@ static inline void _btr(u32_t *data, count_t val)
:"cc" :"cc"
); );
} }
extern inline void* load_file(const char *path, size_t *size)
{
void* retval;
size_t tmp;
__asm__ __volatile__ (
"pushl %%eax \n\t"
"call _load_file@4 \n\t"
:"=eax" (retval), "=ebx"(tmp)
:"a" (path) );
if(size)
*size = tmp;
return retval;
};
//extern __fastcall void* load_file(const char *path, size_t *size);

View File

@ -22,14 +22,25 @@ typedef struct {
int flags; int flags;
} zone_t; } zone_t;
typedef struct typedef struct
{ {
count_t count; link_t link;
addr_t frames[18]; link_t adj;
}phismem_t; addr_t base;
size_t size;
void *parent;
u32_t state;
}md_t;
#define PG_MAP 1 #define PG_MAP 1
#define PG_WRITE 2
#define PG_USER 4
#define PG_SW 3
#define PG_UW 7
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
@ -60,15 +71,19 @@ static inline pfn_t ADDR2PFN(addr_t addr)
void init_mm(); void init_mm();
addr_t __fastcall core_alloc(u32_t order); void* __fastcall frame_get_parent(pfn_t pfn);
void __fastcall core_free(addr_t frame); void __fastcall frame_set_parent(pfn_t pfn, void *data);
pfn_t alloc_page() __attribute__ ((deprecated));
pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated));
void frame_free(pfn_t frame); void frame_free(pfn_t frame);
void __fastcall frame_set_parent(pfn_t pfn, void *data);
void* __fastcall frame_get_parent(pfn_t pfn);
void* __fastcall mem_alloc(size_t size, u32_t flags) ; addr_t __fastcall core_alloc(u32_t order);
void __fastcall core_free(addr_t frame);
pfn_t alloc_page() __attribute__ ((deprecated));
md_t* __fastcall md_alloc(size_t size, u32_t flags);
void* __fastcall mem_alloc(size_t size, u32_t flags);
void __fastcall mem_free(void *mem);

View File

@ -129,6 +129,11 @@ public _rd_fat_end
public _rd_root public _rd_root
public _rd_root_end public _rd_root_end
public _load_file@4
public _kernel_exports
public _strncmp@12
extrn __edata extrn __edata
@ -146,11 +151,13 @@ extrn @core_free@4
extrn @init_heap@8 extrn @init_heap@8
extrn @find_large_md@4 extrn @find_large_md@4
extrn @phis_alloc@4
extrn @mem_alloc@8 extrn @mem_alloc@8
extrn @mem_free@4 extrn @mem_free@4
extrn @load_pe@4
extrn @load_pe_driver@4
extrn _slab_cache_init extrn _slab_cache_init
extrn _alloc_page extrn _alloc_page
@ -779,7 +786,8 @@ include 'detect/disks.inc'
mov [SLOT_BASE+APPDATA.cursor],eax mov [SLOT_BASE+APPDATA.cursor],eax
mov [SLOT_BASE+APPDATA.cursor+256],eax mov [SLOT_BASE+APPDATA.cursor+256],eax
; stdcall load_pe_driver, szAtiHW ;mov ecx, szAtiHW
;call @load_pe_driver@4
; READ TSC / SECOND ; READ TSC / SECOND

View File

@ -6,7 +6,7 @@ INCLUDE = include/
DEFS = -DUSE_SMP -DCONFIG_DEBUG DEFS = -DUSE_SMP -DCONFIG_DEBUG
CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32 LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
KERNEL_SRC:= \ KERNEL_SRC:= \
@ -30,6 +30,7 @@ PE_SRC:= \
mm.c \ mm.c \
slab.c \ slab.c \
heap.c \ heap.c \
dll.c \
spinlock.c \ spinlock.c \
boot/boot.asm \ boot/boot.asm \
boot/start.asm boot/start.asm