Skip to content
Snippets Groups Projects
Commit d82586ec authored by John Hodge's avatar John Hodge
Browse files

Kernel - Fixing binary loader and MMap

- Still some issues with what seems to be nodes going out of scope
parent 5114cd4c
No related merge requests found
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Acess2 * Acess2
* Common Binary Loader * Common Binary Loader
*/ */
#define DEBUG 1 #define DEBUG 0
#include <acess.h> #include <acess.h>
#include <binary.h> #include <binary.h>
#include <mm_virt.h> #include <mm_virt.h>
...@@ -28,6 +28,7 @@ extern char *Threads_GetName(int ID); ...@@ -28,6 +28,7 @@ extern char *Threads_GetName(int ID);
extern tKernelSymbol gKernelSymbols[]; extern tKernelSymbol gKernelSymbols[];
extern tKernelSymbol gKernelSymbolsEnd[]; extern tKernelSymbol gKernelSymbolsEnd[];
extern tBinaryType gELF_Info; extern tBinaryType gELF_Info;
extern void MM_DumpTables(tVAddr, tVAddr);
// === PROTOTYPES === // === PROTOTYPES ===
int Proc_Execve(const char *File, const char **ArgV, const char **EnvP); int Proc_Execve(const char *File, const char **ArgV, const char **EnvP);
...@@ -169,6 +170,9 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP) ...@@ -169,6 +170,9 @@ int Proc_Execve(const char *File, const char **ArgV, const char **EnvP)
} }
LOG("entry = 0x%x, bases[0] = 0x%x", entry, bases[0]); LOG("entry = 0x%x, bases[0] = 0x%x", entry, bases[0]);
MM_DumpTables(0, KERNEL_BASE);
LEAVE('-'); LEAVE('-');
// --- And... Jump to it // --- And... Jump to it
Proc_StartUser(entry, bases, argc, argvSaved, envpSaved, argenvBytes); Proc_StartUser(entry, bases, argc, argvSaved, envpSaved, argenvBytes);
...@@ -293,6 +297,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo ...@@ -293,6 +297,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
// Check if base is free // Check if base is free
if(base != 0) if(base != 0)
{ {
LOG("Checking base %p", base);
for(i=0;i<Binary->NumSections;i++) for(i=0;i<Binary->NumSections;i++)
{ {
if( Binary_int_CheckMemFree( Binary->LoadSections[i].Virtual, Binary->LoadSections[i].MemSize ) ) if( Binary_int_CheckMemFree( Binary->LoadSections[i].Virtual, Binary->LoadSections[i].MemSize ) )
...@@ -322,6 +327,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo ...@@ -322,6 +327,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
// Else decrement pointer and try again // Else decrement pointer and try again
base -= BIN_GRANUALITY; base -= BIN_GRANUALITY;
} }
LOG("Allocated base %p", base);
} }
// Error Check // Error Check
...@@ -338,7 +344,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo ...@@ -338,7 +344,7 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
tBinarySection *sect = &Binary->LoadSections[i]; tBinarySection *sect = &Binary->LoadSections[i];
Uint protflags, mapflags; Uint protflags, mapflags;
tVAddr addr = sect->Virtual - Binary->Base + base; tVAddr addr = sect->Virtual - Binary->Base + base;
LOG("%i - 0x%x to 0x%x", i, addr, sect->Offset); LOG("%i - %p to 0x%llx (%x)", i, addr, sect->Offset, sect->Flags);
protflags = MMAP_PROT_READ; protflags = MMAP_PROT_READ;
mapflags = MMAP_MAP_FIXED; mapflags = MMAP_MAP_FIXED;
...@@ -761,6 +767,7 @@ Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val) ...@@ -761,6 +767,7 @@ Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val)
int Binary_int_CheckMemFree( tVAddr _start, size_t _len ) int Binary_int_CheckMemFree( tVAddr _start, size_t _len )
{ {
_len += _start & (PAGE_SIZE-1); _len += _start & (PAGE_SIZE-1);
_len = (_len + PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
_start &= ~(PAGE_SIZE-1); _start &= ~(PAGE_SIZE-1);
for( ; _len > PAGE_SIZE; _len -= PAGE_SIZE, _start += PAGE_SIZE ) { for( ; _len > PAGE_SIZE; _len -= PAGE_SIZE, _start += PAGE_SIZE ) {
if( MM_GetPhysAddr(_start) != 0 ) if( MM_GetPhysAddr(_start) != 0 )
......
...@@ -280,25 +280,23 @@ extern void MM_DerefPhys(tPAddr PAddr); ...@@ -280,25 +280,23 @@ extern void MM_DerefPhys(tPAddr PAddr);
*/ */
extern int MM_GetRefCount(tPAddr PAddr); extern int MM_GetRefCount(tPAddr PAddr);
/** /**
* \brief Set the node/offset associated with a page * \brief Set the node associated with a page
* \param PAddr Physical address of page * \param PAddr Physical address of page
* \param Node Node pointer (tVFS_Node) * \param Node Node pointer (tVFS_Node)
* \param Offset File offset
* \return Boolean failure * \return Boolean failure
* \retval 0 Success * \retval 0 Success
* \retval 1 Page not allocated * \retval 1 Page not allocated
*/ */
extern int MM_SetPageInfo(tPAddr PAddr, void *Node, Uint64 Offset); extern int MM_SetPageNode(tPAddr PAddr, void *Node);
/** /**
* \brief Get the node/offset associated with a page * \brief Get the node associated with a page
* \param PAddr Physical address of page * \param PAddr Physical address of page
* \param Node Node pointer (tVFS_Node) destination * \param Node Node pointer (tVFS_Node) destination
* \param Offset File offset destination (pointer)
* \return Boolean failure * \return Boolean failure
* \retval 0 Success * \retval 0 Success
* \retval 1 Page not allocated * \retval 1 Page not allocated
*/ */
extern int MM_GetPageInfo(tPAddr PAddr, void **Node, Uint64 *Offset); extern int MM_GetPageNode(tPAddr PAddr, void **Node);
/** /**
* \} * \}
*/ */
......
...@@ -23,36 +23,45 @@ struct sVFS_MMapPageBlock ...@@ -23,36 +23,45 @@ struct sVFS_MMapPageBlock
void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset) void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset)
{ {
tVFS_Handle *h; tVFS_Handle *h;
tVAddr mapping_dest; tVAddr mapping_dest, mapping_base;
int npages, pagenum; int npages, pagenum;
tVFS_MMapPageBlock *pb, *prev; tVFS_MMapPageBlock *pb, *prev;
ENTER("pDestHint iLength xProtection xFlags xFD XOffset", DestHint, Length, Protection, Flags, FD, Offset); ENTER("pDestHint iLength xProtection xFlags xFD XOffset", DestHint, Length, Protection, Flags, FD, Offset);
npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE; npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
pagenum = Offset / PAGE_SIZE; pagenum = Offset / PAGE_SIZE;
mapping_dest = (tVAddr)DestHint; mapping_base = (tVAddr)DestHint;
mapping_dest = mapping_base & ~(PAGE_SIZE-1);
// TODO: Locate space for the allocation // TODO: Locate space for the allocation
// Handle anonymous mappings // Handle anonymous mappings
if( Flags & MMAP_MAP_ANONYMOUS ) if( Flags & MMAP_MAP_ANONYMOUS )
{ {
int i; for( ; npages --; mapping_dest += PAGE_SIZE )
for( i = 0; i < npages; i ++ ) { {
tPAddr rv = MM_Allocate(mapping_dest + i * PAGE_SIZE); if( MM_GetPhysAddr(mapping_dest) ) {
if( !rv ) { // TODO: Set flags to COW if needed (well, if shared)
// TODO: Error }
else {
if( !MM_Allocate(mapping_dest) ) {
// TODO: Error
Log_Warning("VFS", "VFS_MMap: Anon alloc to %p failed", mapping_dest);
}
LOG("Anon map to %p", mapping_dest);
} }
} }
LEAVE_RET('p', (void*)mapping_dest); LEAVE_RET('p', (void*)mapping_base);
} }
h = VFS_GetHandle(FD); h = VFS_GetHandle(FD);
if( !h || !h->Node ) LEAVE_RET('n', NULL); if( !h || !h->Node ) LEAVE_RET('n', NULL);
LOG("h = %p", h); LOG("h = %p", h);
Mutex_Acquire( &h->Node->Lock );
// Search for existing mapping for each page // Search for existing mapping for each page
// - Sorted list of 16 page blocks // - Sorted list of 16 page blocks
...@@ -62,12 +71,17 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, ...@@ -62,12 +71,17 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
prev = pb, pb = pb->Next prev = pb, pb = pb->Next
); );
LOG("pb = %p, pb->BaseOffset = %X", pb, pb ? pb->BaseOffset : 0);
// - Allocate a block if needed // - Allocate a block if needed
if( !pb || pb->BaseOffset > pagenum ) if( !pb || pb->BaseOffset > pagenum )
{ {
void *old_pb = pb; void *old_pb = pb;
pb = malloc( sizeof(tVFS_MMapPageBlock) ); pb = malloc( sizeof(tVFS_MMapPageBlock) );
if(!pb) LEAVE_RET('n', NULL); if(!pb) {
Mutex_Release( &h->Node->Lock );
LEAVE_RET('n', NULL);
}
pb->Next = old_pb; pb->Next = old_pb;
pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK; pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK;
memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs)); memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
...@@ -80,29 +94,57 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, ...@@ -80,29 +94,57 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
// - Map (and allocate) pages // - Map (and allocate) pages
while( npages -- ) while( npages -- )
{ {
if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 ) if( MM_GetPhysAddr(mapping_dest) == 0 )
{ {
if( h->Node->MMap ) if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 )
h->Node->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
else
{ {
// Allocate pages and read data if( h->Node->MMap )
if( MM_Allocate(mapping_dest) == 0 ) { h->Node->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
// TODO: Unwrap else
return NULL; {
// Allocate pages and read data
if( MM_Allocate(mapping_dest) == 0 ) {
// TODO: Unwrap
Mutex_Release( &h->Node->Lock );
LEAVE('n');
return NULL;
}
h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
} }
h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest); pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
MM_SetPageNode( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node );
LOG("Read and map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
pb->PhysAddrs[pagenum - pb->BaseOffset]);
}
else
{
MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
LOG("Cached map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
pb->PhysAddrs[pagenum - pb->BaseOffset]);
}
h->Node->ReferenceCount ++;
// Set flags
if( !(Protection & MMAP_PROT_WRITE) ) {
MM_SetFlags(mapping_dest, MM_PFLAG_RO, MM_PFLAG_RO);
}
else {
MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
} }
pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
// MM_SetPageInfo( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node, pagenum*PAGE_SIZE );
} }
else else
{ {
MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] ); LOG("Flag update on %p", mapping_dest);
if( (MM_GetFlags(mapping_dest) & MM_PFLAG_RO) && (Protection & MMAP_PROT_WRITE) )
{
MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
}
} }
if( Flags & MMAP_MAP_PRIVATE )
MM_SetFlags(mapping_dest, MM_PFLAG_COW, MM_PFLAG_COW);
pagenum ++; pagenum ++;
mapping_dest += PAGE_SIZE; mapping_dest += PAGE_SIZE;
// Roll on to next block if needed // Roll on to next block if needed
if(pagenum - pb->BaseOffset == MMAP_PAGES_PER_BLOCK) if(pagenum - pb->BaseOffset == MMAP_PAGES_PER_BLOCK)
{ {
...@@ -120,9 +162,11 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, ...@@ -120,9 +162,11 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
pagenum = 0; pagenum = 0;
} }
} }
Mutex_Release( &h->Node->Lock );
LEAVE('n'); LEAVE('p', mapping_base);
return NULL; return (void*)mapping_base;
} }
int VFS_MUnmap(void *Addr, size_t Length) int VFS_MUnmap(void *Addr, size_t Length)
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment