| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -16,124 +16,76 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "initrd.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				luxDEVICE *luxDevices;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxDeviceCount;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				luxFILE *luxFiles;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxFileCount;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxFilesAllocated;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**************************************
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * DEVICE 'FAKE' READ ROUTINE 		  *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 **************************************/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxDevRead (uint32 UNUSED(offset), void* UNUSED(buffer))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxInitrdDevRead (uint32 UNUSED(offset), void* UNUSED(buffer))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return LUXMAGIC;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**************************************
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * INITIALIZATION ROUTINE     		  *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 **************************************/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void luxInitrdInstall (MultibootInfo* info)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Install filesystem
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					FileSystem fs = {0, "luxinitrd", luxDetect, 0, 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							luxOpen, luxClose, luxRead, 0, luxTest, luxReadDir};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					VfsInstallFs(&fs);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// See what modules are loaded in the multiboot info
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if ((info->Flags & 8) == 0 || info->ModulesCount == 0) return;	// nothing was loaded
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					MultibootModule* modules = (MultibootModule*) info->ModulesAddress;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDevices = kmalloc(sizeof(luxDEVICE) * info->ModulesCount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDeviceCount = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (i = 0; i < info->ModulesCount; i++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Check magic number, to make sure module is a initrd image
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxHeader* head = (luxHeader*) modules[i].ModuleStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (head->Magic != LUXMAGIC) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							Log("Initrd", "Magic = 0x%x [bad] ModuleStart = 0x%x\n", head->Magic, modules[i].ModuleStart);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Set up entry
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxDevices[luxDeviceCount].Data = (void*) modules[i].ModuleStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxDevices[luxDeviceCount].Size = modules[i].ModuleEnd - modules[i].ModuleStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Register virtual device. Instead of blocksize, we give the dev no, so we can identify it later
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						VfsMount("initrd", luxDevRead, 0, luxDeviceCount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						++luxDeviceCount;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**************************************
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * OTHER USEFUL ROUTINES      		  *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 **************************************/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxGetFileSlot()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Find an empty slot
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 i = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (i = 0; i < luxFileCount; i++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (luxFiles[i].Id == 0xffffffff) return i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Nothing found? Allocate more slots if necessary
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (luxFileCount >= luxFilesAllocated)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxFilesAllocated += 4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxFiles = kmrealloc(luxFiles, luxFilesAllocated);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Give last slot
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					++luxFileCount;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (luxFileCount-1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Navigates and returns the directory entry that contains the file/folder
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				luxDirectoryEntry* luxGetFile (string path, uint32 dev)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				luxDirectoryEntry rootDirectoryEntry;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				luxDirectoryEntry* luxGetFile (string path, uint32 data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxHeader* root = (luxHeader*) luxDevices[dev].Data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectory* current = root->Root;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectoryEntry rt = {"root", 0xB68, 0, 0, 0, {0,0}, {0,0}, {0,0}, (uint32)&root->Root};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxHeader* head = (luxHeader*)data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 end = strlen(path);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 start, next = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					char* tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (path[0] != '\\')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return &rt;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Remove ending '/' (if any)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (path[end-1] == '/') --end;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					path = path + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Empty string? Return the root
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (end == 0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rootDirectoryEntry.De.Flags = 0xB68; 					// read & execute only
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rootDirectoryEntry.De.GroupId = 0; 						// system group
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rootDirectoryEntry.De.OwnerId = 0; 						// system owner
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rootDirectoryEntry.De.Size = sizeof(uint32) + head->RootSize * sizeof(luxDirectoryEntry);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rootDirectoryEntry.Offset = (uint32)(&head->RootSize) - data; 	// calculate offset
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					while (path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Trim the next path separator
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						string tmp = strchr(path, '\\');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (tmp) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							*tmp = 0; tmp = tmp + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (!*tmp) tmp = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Find the folder/file in current directory
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint32 i, found = 0xffffffff;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (i = 0; i < current->Count && found == 0xffffffff; i++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (strcmp(path, current->Entries[i].Name) == 0) found = i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Check if the file/folder was found
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (found == 0xffffffff) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Return entry pointer if done
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!tmp) return ¤t->Entries[found];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Go inside
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						current = (luxDirectory*) (current->Entries[found].Offset + (uint32)root);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						path = tmp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return &rootDirectoryEntry;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Make sure path is correct
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (path[0] != '/') return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Parse each directory until we find the one containing the file;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 cDir = (uint32)&head->RootSize;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					while (next < end)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Parse string
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						start = next + 1;	// Skip path separator
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						tmp = strchr(&path[start], '/'); // Find next separator
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next = (!tmp) ? end : (uint32)(tmp - path) ; // Mark end of string, or next dir position in path
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// strchr doesn't know when to end
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (next >= end) { tmp = 0; next = end; }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Look for directory
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint32 i, find = 0xffffffff;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint32 size = *(uint32*)cDir;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						luxDirectoryEntry* de = (luxDirectoryEntry*) (cDir + sizeof(uint32));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (i = 0; i < size && find == 0xffffffff; i++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (strncmp(de[i].De.Name, &path[start], strlen(de[i].De.Name)) == 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								find = i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Not found? Nope, not good
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (find == 0xffffffff) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// End of string? Return directory entry
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!tmp) return &de[find];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// make sure we don't try to read a file as a folder
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if ((de[find].De.Flags & 0x7) != FileDirectory) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Not end of string? Continue
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cDir = (uint32) (data + de[find].Offset);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// We shouldn't get here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -141,62 +93,107 @@ luxDirectoryEntry* luxGetFile (string path, uint32 dev)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**************************************
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * FILE SYSTEM INTERFACE ROUTINES	  *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 **************************************/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxDetect (DevReadRoutine rd, uint32 blocksz)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxDetect (MountPoint* mp)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Check magic result, which is returned by our device read function
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					void* buffer = kmalloc(blocksz);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 result = (*rd)(0, buffer);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					kfree(buffer);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					void* buffer = kmalloc(mp->BlockSize);  // must allocate a buffer for non-initrd devices...
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 result = mp->Read(0, buffer);    // read something
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					kfree(buffer);							// get rid of the not needed buffer
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (result == LUXMAGIC);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (result == LUXMAGIC);			// returned magic number? good
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Returns element count read
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxRead (const MountPoint* UNUSED(mp), FILE* f, uint32 elemsz, uint32 n, uint8* buffer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Test if a file exists
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				DirectoryEntry* luxTest (MountPoint* mp, string path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 temp = Min(n*elemsz, luxFiles[f->Id].Size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					memcpy(buffer, luxFiles[f->Id].Pos, temp);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxFiles[f->Id].Size -= temp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return temp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// MountPoint.FsData[0] contains initrd image start address
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// luxDirectoryEntry contains a DirectoryEntry
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (DirectoryEntry*) luxGetFile(path, mp->FsData[0]); // Get a directory and see
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				FILE* luxOpen (const MountPoint* mp, FILE* f, string path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Open a file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				FILE* luxOpen (MountPoint* mp, FILE* f, string path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Id = luxGetFileSlot();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectoryEntry* entry = luxGetFile(path, mp->BlockSize);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Find it first. mp->FsData[0] contains initrd image start address.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectoryEntry* entry = luxGetFile(path, mp->FsData[0]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Name = entry->Name;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Flags = entry->Flags;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->GroupId = entry->GroupId;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->OwnerId = entry->OwnerId;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Size = entry->Size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Invalid entry
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (entry == NULL) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxFiles[f->Id].Id = f->Id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxFiles[f->Id].Pos = luxFiles[f->Id].Start = entry->Offset + luxDevices[mp->BlockSize].Data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxFiles[f->Id].Size = entry->Size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Set some data fields
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Name = entry->De.Name;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Flags = entry->De.Flags;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->GroupId = entry->De.GroupId;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->OwnerId = entry->De.OwnerId;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->Size = entry->De.Size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Set up the buffer info. We will use these to read/write the file.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->BufStart = (void*) (mp->FsData[0] + entry->Offset);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->BufPos = f->BufStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->BufEnd = f->BufStart + entry->De.Size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// And return it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				DirectoryEntry* luxTest (const MountPoint* mp, string path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Close a file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				FILE* luxClose (MountPoint* UNUSED(mp), FILE* f)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (DirectoryEntry*) luxGetFile(path, mp->BlockSize);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				FILE* luxClose (const MountPoint* UNUSED(mp), FILE* f)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxFiles[f->Id].Id = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Just empty buffer info, so we don't attempt to read it again
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->BufStart = f->BufPos = f->BufEnd = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				DirectoryEntry* luxReadDir (const MountPoint* UNUSED(mp), FILE* f, uint32 index)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Read data from a file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Returns byte count read
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32 luxRead (MountPoint* UNUSED(mp), FILE* f, uint32 elemsz, uint32 n, uint8* buffer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectory* dir = luxFiles[f->Id].Start;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Make sure we don't read more than we can
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 total = Min(elemsz * n, (uint32)f->BufEnd - (uint32)f->BufPos);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (index > dir->Count) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (DirectoryEntry*) &dir->Entries[index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					memcpy(buffer, f->BufPos, total);					// Copy data
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f->BufPos = (void*) ((uint32)f->BufPos + total);	// Set new buffer position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return total;										// Return byte count read
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Read contents of a directory
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				DirectoryEntry* luxReadDir (MountPoint* UNUSED(mp), FILE* f, uint32 index)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 size = *(uint32*)f->BufStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					luxDirectoryEntry* de = (luxDirectoryEntry*) ((uint32)f->BufStart + sizeof(uint32));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (index >= size) return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return (DirectoryEntry*) &de[index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**************************************
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * INITIALIZATION ROUTINE     		  *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 **************************************/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void luxInitrdInstall (MultibootInfo* info)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32 i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					MountPoint* mp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Register file system
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					FileSystem fs = {0, "luxinitrd", luxDetect, 0, 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								luxOpen, luxClose, luxRead, 0, luxTest, luxReadDir};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					VfsInstallFs(&fs);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Check for multiboot info flags to see if any modules are loaded
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if ((info->Flags & 8) == 0) return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Loop through each module and if it is an initrd image, mount it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					MultibootModule* modules = (MultibootModule*) info->ModulesAddress;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (i = 0; i < info->ModulesCount; i++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if ((*(uint32*) modules[i].ModuleStart) == LUXMAGIC)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// Mount the device
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							Log("Initrd", "Found initrd image at 0x%x.\n", modules[i].ModuleStart);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							mp = VfsMount("initrd", luxInitrdDevRead, NULL, 0x0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// Set up data fields
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							mp->FsData[0] = modules[i].ModuleStart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							mp->FsData[1] = modules[i].ModuleEnd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				 
 |