[GOOD] BUILD 0.1.0.590 DATE 9/05/2011 AT 2:40 PM

====================================================
Mainly changed: FS.Initrd
+ (kind of) refractored VFS, bugfixed
+ Rewrote 'initrd' file system, fixed many problems
+ Working 'cat' and 'dir' console commands
+ Wrote 'initrd' image write application (for windows), however it may
be bugged
This commit is contained in:
2021-09-14 18:52:47 +03:00
parent caa7718af9
commit 852cf1bb17
71 changed files with 1979 additions and 659 deletions

View File

@ -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 &current->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;
}
}

View File

@ -5,6 +5,7 @@
* Author: Tiberiu
*/
#ifndef INITDR_H_
#define INITDR_H_
@ -12,45 +13,15 @@
#include <fileio.h>
typedef struct {
char Name[256];
uint32 Flags, OwnerId, GroupId, Size;
TimeSystem TimeCreated, TimeModified, TimeAccessed;
DirectoryEntry De;
uint32 Offset;
} luxDirectoryEntry;
typedef struct {
uint32 Count;
luxDirectoryEntry* Entries;
} luxDirectory;
} __attribute__((packed)) luxDirectoryEntry;
typedef struct {
uint32 Magic;
char Oem[6];
luxDirectory* Root;
} luxHeader;
typedef struct {
uint32 DeviceId;
uint32 Size;
void* Data;
} luxDEVICE;
typedef struct {
uint32 Id;
uint32 Size;
void* Start;
void* Pos;
} luxFILE;
extern uint32 luxDevRead (uint32 offset, void* buffer);
extern void luxInitrdInstall (MultibootInfo* info);
extern uint32 luxDetect (DevReadRoutine rd, uint32 blocksz);
extern uint32 luxRead (const MountPoint* mp, FILE* f, uint32 elemsz, uint32 n, uint8* buffer);
extern FILE* luxOpen (const MountPoint* mp, FILE* f, string path);
extern DirectoryEntry* luxTest (const MountPoint* mp, string path);
extern FILE* luxClose (const MountPoint* mp, FILE* f);
extern DirectoryEntry* luxReadDir (const MountPoint* mp, FILE* f, uint32 index);
uint32 RootSize;
// After RootSize is the root content
} __attribute__((packed)) luxHeader;
#endif /* INITDR_H_ */