Ejemplo n.º 1
0
void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, const char **ArgV, int DataSize)
{
    int	i;
    const char	**envp;
    tVAddr	delta;

//	Log_Debug("Proc", "Proc_StartUser: (Entrypoint=%p, Base=%p, ArgC=%i, ArgV=%p, DataSize=0x%x)",
//		Entrypoint, Base, ArgC, ArgV, DataSize);

    // Write data to the user's stack
    Uint32 *usr_sp = (void*)MM_NewUserStack();
    if( !usr_sp ) {
        Log_KernelPanic("Proc", "Creation of user stack failed");
    }
    usr_sp -= (DataSize+3)/4;
    memcpy(usr_sp, ArgV, DataSize);
    free(ArgV);

    // Adjust user's copy of the arguments
    delta = (tVAddr)usr_sp -  (tVAddr)ArgV;
    ArgV = (void*)usr_sp;
    for(i = 0; ArgV[i]; i ++)	ArgV[i] += delta;
    envp = &ArgV[i+1];
    for(i = 0; envp[i]; i ++)	envp[i] += delta;

    *--usr_sp = (Uint32)envp;
    *--usr_sp = (Uint32)ArgV;
    *--usr_sp = (Uint32)ArgC;
    *--usr_sp = Base;

    // Drop to user code
    Log_Debug("Proc", "Proc_int_DropToUser(%p, %p)", Entrypoint, usr_sp);
    Proc_int_DropToUser(Entrypoint, (Uint32)usr_sp);
}
Ejemplo n.º 2
0
/**
 * \fn int VFS_Init(void)
 * \brief Initialises the VFS for use by the kernel and user
 */
int VFS_Init(void)
{
	// Core Drivers
	gVFS_Drivers = &gRootFS_Info;
	gVFS_Drivers->Next = &gDevFS_Info;
	VFS_UpdateDriverFile();
	
	// Register with SysFS
	giVFS_MountFileID = SysFS_RegisterFile("VFS/Mounts", NULL, 0);
	giVFS_DriverFileID = SysFS_RegisterFile("VFS/Drivers", NULL, 0);
	
	if( VFS_Mount("root", "/", "rootfs", "") != 0 ) {
		Log_KernelPanic("VFS", "Unable to mount root (Where the **** is rootfs?)");
		return -1;
	}
	VFS_MkDir("/Devices");
	VFS_MkDir("/Mount");
	VFS_Mount("dev", "/Devices", "devfs", "");
	
	// Set default max user file count
	// - Applies to PID0, but propagated to all children
	*Threads_GetMaxFD(NULL) = 32;
	return 0;
}
Ejemplo n.º 3
0
/**
 * \brief Clone a page from an entry
 * \param Ent	Pointer to the entry in the PML4/PDP/PD/PT
 * \param NextLevel	Pointer to contents of the entry
 * \param Addr	Dest address
 * \note Used in COW
 */
void MM_int_ClonePageEnt( Uint64 *Ent, void *NextLevel, tVAddr Addr, int bTable )
{
	tPAddr	curpage = *Ent & PADDR_MASK; 
	 int	bCopied = 0;
	
	if( MM_GetRefCount( curpage ) <= 0 ) {
		Log_KernelPanic("MMVirt", "Page %P still marked COW, but unreferenced", curpage);
	}
	if( MM_GetRefCount( curpage ) == 1 )
	{
		*Ent &= ~PF_COW;
		*Ent |= PF_PRESENT|PF_WRITE;
		#if TRACE_COW
		Log_Debug("MMVirt", "COW ent at %p (%p) only %P", Ent, NextLevel, curpage);
		#endif
	}
	else
	{
		void	*tmp;
		tPAddr	paddr;
		
		if( !(paddr = MM_AllocPhys()) ) {
			Threads_SegFault(Addr);
			return ;
		}

		ASSERT(paddr != curpage);
			
		tmp = MM_MapTemp(paddr);
		memcpy( tmp, NextLevel, 0x1000 );
		MM_FreeTemp( tmp );
		
		#if TRACE_COW
		Log_Debug("MMVirt", "COW ent at %p (%p) from %P to %P", Ent, NextLevel, curpage, paddr);
		#endif

		MM_DerefPhys( curpage );
		*Ent &= PF_USER;
		*Ent |= paddr|PF_PRESENT|PF_WRITE;
		
		bCopied = 1;
	}
	INVLPG( (tVAddr)NextLevel );
	
	// Mark COW on contents if it's a PDPT, Dir or Table
	if(bTable) 
	{
		Uint64	*dp = NextLevel;
		 int	i;
		for( i = 0; i < 512; i ++ )
		{
			if( !(dp[i] & PF_PRESENT) )
				continue;
			
			if( bCopied )
				MM_RefPhys( dp[i] & PADDR_MASK );
			if( dp[i] & PF_WRITE ) {
				dp[i] &= ~PF_WRITE;
				dp[i] |= PF_COW;
			}
		}
	}
}
Ejemplo n.º 4
0
// === CODE ===
int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
{
	 int	nPMemMapEnts = 0;
	
	ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
		MBInfo, MapOffset, Map, MapSize, KStart, KEnd);

	// Check that the memory map is present
	if( MBInfo->Flags & (1 << 6) )
	{
		tMBoot_MMapEnt	*ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
		tMBoot_MMapEnt	*last = (void*)((tVAddr)ent + MBInfo->MMapLength);
		// Build up memory map
		nPMemMapEnts = 0;
		while( ent < last && nPMemMapEnts < MapSize )
		{
			tPMemMapEnt	*nent = &Map[nPMemMapEnts];
			if( !MM_GetPhysAddr(ent) )
				Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
					nPMemMapEnts, ent);
			LOG("%llx+%llx", ent->Base, ent->Length);
	
			nent->Start = ent->Base;
			nent->Length = ent->Length;
			switch(ent->Type)
			{
			case 1:
				nent->Type = PMEMTYPE_FREE;
				break;
			default:
				nent->Type = PMEMTYPE_RESERVED;
				break;
			}
			nent->NUMADomain = 0;
			
			nPMemMapEnts ++;
			ent = (void*)( (tVAddr)ent + ent->Size + 4 );
		}
		if( ent < last )
		{
			Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated",
				MapSize);
		}
	}
	else if( MBInfo->Flags & (1 << 0) )
	{
		Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
		ASSERT(MapSize >= 2);
		nPMemMapEnts = 2;
		Map[0].Start = 0;
		Map[0].Length = MBInfo->LowMem * 1024;
		Map[0].Type = PMEMTYPE_FREE;
		Map[0].NUMADomain = 0;

		Map[1].Start = 0x100000;
		Map[1].Length = MBInfo->HighMem * 1024;
		Map[1].Type = PMEMTYPE_FREE;
		Map[1].NUMADomain = 0;
	}
	else
	{
		Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
	}

	// Ensure it's valid
	LOG("Validating");
	nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
	// TODO: Error handling

	// Replace kernel with PMEMTYPE_USED
	LOG("Marking kernel");
	nPMemMapEnts = PMemMap_MarkRangeUsed(
		Map, nPMemMapEnts, MapSize,
		KStart, KEnd - KStart
		);

	LOG("Dumping");
	PMemMap_DumpBlocks(Map, nPMemMapEnts);

	// Check if boot modules were passed
	if( MBInfo->Flags & (1 << 3) )
	{
		// Replace modules with PMEMTYPE_USED
		nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
			MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
			);
		LOG("MBInfo->Modules = %x", MBInfo->Modules);
		tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
		for( int i = 0; i < MBInfo->ModuleCount; i ++ )
		{
			LOG("&mods[%i] = %p", i, &mods[i]);
			LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
			nPMemMapEnts = PMemMap_MarkRangeUsed(
				Map, nPMemMapEnts, MapSize,
				mods[i].Start, mods[i].End - mods[i].Start
				);
		}
	}
		
	// Debug - Output map
	PMemMap_DumpBlocks(Map, nPMemMapEnts);

	LEAVE('i', nPMemMapEnts);
	return nPMemMapEnts;
}