[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:
@ -21,113 +21,113 @@ global Irq_15
|
||||
; 32: IRQ0
|
||||
Irq_0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32; Note that these don't push an error code on the stack:
|
||||
push dword 0
|
||||
push dword 32; Note that these don't push an error code on the stack:
|
||||
; We need to push a dummy error code
|
||||
jmp irq_common_stub
|
||||
|
||||
; 33: IRQ1
|
||||
Irq_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
push dword 0
|
||||
push dword 33
|
||||
jmp irq_common_stub
|
||||
|
||||
; 34: IRQ2
|
||||
Irq_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
push dword 0
|
||||
push dword 34
|
||||
jmp irq_common_stub
|
||||
|
||||
; 35: IRQ3
|
||||
Irq_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
push dword 0
|
||||
push dword 35
|
||||
jmp irq_common_stub
|
||||
|
||||
; 36: IRQ4
|
||||
Irq_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
push dword 0
|
||||
push dword 36
|
||||
jmp irq_common_stub
|
||||
|
||||
; 37: IRQ5
|
||||
Irq_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
push dword 0
|
||||
push dword 37
|
||||
jmp irq_common_stub
|
||||
|
||||
; 38: IRQ6
|
||||
Irq_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
push dword 0
|
||||
push dword 38
|
||||
jmp irq_common_stub
|
||||
|
||||
; 39: IRQ7
|
||||
Irq_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
push dword 0
|
||||
push dword 39
|
||||
jmp irq_common_stub
|
||||
|
||||
; 40: IRQ8
|
||||
Irq_8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
push dword 0
|
||||
push dword 40
|
||||
jmp irq_common_stub
|
||||
; 41: IRQ9
|
||||
Irq_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
push dword 0
|
||||
push dword 41
|
||||
jmp irq_common_stub
|
||||
|
||||
; 42: IRQ10
|
||||
Irq_10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
push dword 0
|
||||
push dword 42
|
||||
jmp irq_common_stub
|
||||
|
||||
; 43: IRQ11
|
||||
Irq_11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
push dword 0
|
||||
push dword 43
|
||||
jmp irq_common_stub
|
||||
|
||||
; 44: IRQ12
|
||||
Irq_12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
push dword 0
|
||||
push dword 44
|
||||
jmp irq_common_stub
|
||||
|
||||
; 45: IRQ13
|
||||
Irq_13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
push dword 0
|
||||
push dword 45
|
||||
jmp irq_common_stub
|
||||
|
||||
; 46: IRQ14
|
||||
Irq_14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
push dword 0
|
||||
push dword 46
|
||||
jmp irq_common_stub
|
||||
|
||||
; 47: IRQ15
|
||||
Irq_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
push dword 0
|
||||
push dword 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern IrqHandler
|
||||
|
@ -36,158 +36,158 @@ global isr_exception_31
|
||||
|
||||
isr_exception_0:
|
||||
cli
|
||||
push byte 0; A normal ISR stub that pops a dummy error code to keep a
|
||||
push dword 0; A normal ISR stub that pops a dummy error code to keep a
|
||||
; uniform stack frame
|
||||
push byte 0
|
||||
push dword 0
|
||||
jmp isr_common_stub
|
||||
isr_exception_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
push dword 0
|
||||
push dword 1
|
||||
jmp isr_common_stub
|
||||
isr_exception_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
push dword 0
|
||||
push dword 2
|
||||
jmp isr_common_stub
|
||||
isr_exception_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
push dword 0
|
||||
push dword 3
|
||||
jmp isr_common_stub
|
||||
isr_exception_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
push dword 0
|
||||
push dword 4
|
||||
jmp isr_common_stub
|
||||
isr_exception_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
push dword 0
|
||||
push dword 5
|
||||
jmp isr_common_stub
|
||||
isr_exception_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
push dword 0
|
||||
push dword 6
|
||||
jmp isr_common_stub
|
||||
isr_exception_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
push dword 0
|
||||
push dword 7
|
||||
jmp isr_common_stub
|
||||
isr_exception_8:
|
||||
cli
|
||||
push byte 8
|
||||
push dword 8
|
||||
jmp isr_common_stub
|
||||
isr_exception_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
push dword 0
|
||||
push dword 9
|
||||
jmp isr_common_stub
|
||||
isr_exception_10:
|
||||
cli
|
||||
push byte 10
|
||||
push dword 10
|
||||
jmp isr_common_stub
|
||||
isr_exception_11:
|
||||
cli
|
||||
push byte 11
|
||||
push dword 11
|
||||
jmp isr_common_stub
|
||||
isr_exception_12:
|
||||
cli
|
||||
push byte 12
|
||||
push dword 12
|
||||
jmp isr_common_stub
|
||||
isr_exception_13:
|
||||
cli
|
||||
push byte 13
|
||||
push dword 13
|
||||
jmp isr_common_stub
|
||||
isr_exception_14:
|
||||
cli
|
||||
push byte 14
|
||||
push dword 14
|
||||
jmp isr_common_stub
|
||||
isr_exception_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
push dword 0
|
||||
push dword 15
|
||||
jmp isr_common_stub
|
||||
isr_exception_16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
push dword 0
|
||||
push dword 16
|
||||
jmp isr_common_stub
|
||||
isr_exception_17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
push dword 0
|
||||
push dword 17
|
||||
jmp isr_common_stub
|
||||
isr_exception_18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
push dword 0
|
||||
push dword 18
|
||||
jmp isr_common_stub
|
||||
isr_exception_19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
push dword 0
|
||||
push dword 19
|
||||
jmp isr_common_stub
|
||||
isr_exception_20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
push dword 0
|
||||
push dword 20
|
||||
jmp isr_common_stub
|
||||
isr_exception_21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
push dword 0
|
||||
push dword 21
|
||||
jmp isr_common_stub
|
||||
isr_exception_22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
push dword 0
|
||||
push dword 22
|
||||
jmp isr_common_stub
|
||||
isr_exception_23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
push dword 0
|
||||
push dword 23
|
||||
jmp isr_common_stub
|
||||
isr_exception_24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
push dword 0
|
||||
push dword 24
|
||||
jmp isr_common_stub
|
||||
isr_exception_25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
push dword 0
|
||||
push dword 25
|
||||
jmp isr_common_stub
|
||||
isr_exception_26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
push dword 0
|
||||
push dword 26
|
||||
jmp isr_common_stub
|
||||
isr_exception_27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
push dword 0
|
||||
push dword 27
|
||||
jmp isr_common_stub
|
||||
isr_exception_28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
push dword 0
|
||||
push dword 28
|
||||
jmp isr_common_stub
|
||||
isr_exception_29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
push dword 0
|
||||
push dword 29
|
||||
jmp isr_common_stub
|
||||
isr_exception_30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
push dword 0
|
||||
push dword 30
|
||||
jmp isr_common_stub
|
||||
isr_exception_31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
push dword 0
|
||||
push dword 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern IsrsFaultHandler
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#if NEVER
|
||||
#include <fileio.h>
|
||||
#include <debugio.h>
|
||||
#include "fat.h"
|
||||
@ -78,3 +79,5 @@ void FatInstall()
|
||||
|
||||
VfsInstallFs(&fat12); VfsInstallFs(&fat16); VfsInstallFs(&fat32);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifdef NEVER
|
||||
#ifndef FAT_H_
|
||||
#define FAT_H_
|
||||
|
||||
@ -133,3 +134,4 @@ extern uint32 Fat16Detect (DevReadRoutine r, uint32 blocksz);
|
||||
extern uint32 Fat32Detect (DevReadRoutine r, uint32 blocksz);
|
||||
|
||||
#endif /* FAT_H_ */
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Created on: Aug 29, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#if NEVER
|
||||
#include <fileio.h>
|
||||
#include <memory.h>
|
||||
#include "fat.h"
|
||||
@ -23,3 +24,4 @@ uint32 Fat12Detect (DevReadRoutine r, uint32 blocksz)
|
||||
kfree(buffer);
|
||||
return (res == 12);
|
||||
}
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Created on: Aug 31, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#ifdef NEVER
|
||||
#include <fileio.h>
|
||||
#include <memory.h>
|
||||
#include "fat.h"
|
||||
@ -23,4 +24,4 @@ uint32 Fat16Detect (DevReadRoutine r, uint32 blocksz)
|
||||
kfree(buffer);
|
||||
return (res == 16);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Created on: Aug 31, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#if NEVER
|
||||
#include <fileio.h>
|
||||
#include <memory.h>
|
||||
#include "fat.h"
|
||||
@ -24,3 +25,4 @@ uint32 Fat32Detect (DevReadRoutine r, uint32 blocksz)
|
||||
return (res == 32);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "keyboard/keyboard.h"
|
||||
#include "mouse/mouse.h"
|
||||
|
||||
#include "filesys/fat/fat.h"
|
||||
//#include "filesys/fat/fat.h"
|
||||
|
||||
#include <fileio.h>
|
||||
#include <debugio.h>
|
||||
@ -38,5 +38,5 @@ void HalInitialize()
|
||||
|
||||
// Install VFS
|
||||
VfsInstall();
|
||||
FatInstall();
|
||||
//FatInstall();
|
||||
}
|
||||
|
257
Kernel/hal/vfs.c
257
Kernel/hal/vfs.c
@ -1,152 +1,169 @@
|
||||
#include <array.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <fileio.h>
|
||||
#include <debugio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_FS_COUNT 64
|
||||
#define BAD 0xffffffff
|
||||
|
||||
FileSystem* fsArray;
|
||||
uint32 fsCount;
|
||||
DynamicArray fsList;
|
||||
DynamicArray mpList;
|
||||
|
||||
FileSystem* fsArray;
|
||||
MountPoint* mpArray;
|
||||
uint32 mpCount;
|
||||
uint32 mpAllocated;
|
||||
|
||||
void VfsInstall ()
|
||||
{
|
||||
fsArray = (FileSystem*) kmalloc(MAX_FS_COUNT * sizeof(FileSystem));
|
||||
fsCount = 0;
|
||||
DynamicArrayCreate(sizeof(FileSystem), &fsList);
|
||||
DynamicArrayCreate(sizeof(MountPoint), &mpList);
|
||||
|
||||
mpArray = (MountPoint*) kmalloc(32 * sizeof(MountPoint));
|
||||
mpCount = 0;
|
||||
mpAllocated = 32;
|
||||
fsArray = (FileSystem*) fsList.Data;
|
||||
mpArray = (MountPoint*) mpList.Data;
|
||||
|
||||
Log("VFS", "%#VFS now in business.\n", ColorLightGreen);
|
||||
Log("VFS", "%#Vfs now in business.\n", ColorLightGreen);
|
||||
}
|
||||
|
||||
uint8 VfsInstallFs (FileSystem* fs)
|
||||
void VfsInstallFs (FileSystem* fs)
|
||||
{
|
||||
if (fsCount >= MAX_FS_COUNT) {
|
||||
Error("VFS", "%#Failed to install file system '%s': FS count reached.\n", ColorLightRed, fs->Name);
|
||||
return 0;
|
||||
fs->Id = fsList.Size;
|
||||
DynamicArrayPush(fs, &fsList);
|
||||
|
||||
Log("VFS", "Installed file system %#%s%# (id=%u).\n", ColorWhite, fs->Name,
|
||||
ColorLightGray, fs->Id);
|
||||
}
|
||||
|
||||
int32 _VfsFindDevice (string name)
|
||||
{
|
||||
int32 i;
|
||||
for (i = 0; (uint32)i < mpList.Size; i++)
|
||||
if (mpArray[i].Id != BAD && strcmp (name, mpArray[i].Name) == 0) return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
string _VfsGetDevice (string path, int32* dev)
|
||||
{
|
||||
// Make sure path is valid
|
||||
if (!path || *path != '/') {
|
||||
*dev = -1; return NULL;
|
||||
}
|
||||
|
||||
memcpy(&fsArray[fsCount], fs, sizeof(FileSystem));
|
||||
fsArray[fsCount].Id = fsCount;
|
||||
// Do we need to return root?
|
||||
path++;
|
||||
if (*path == '\0') return NULL; // Yes, but not implemented yet
|
||||
|
||||
++fsCount;
|
||||
Log("VFS", "Installed file system %#%s.\n", ColorWhite, fs->Name);
|
||||
return 1;
|
||||
// Find the next '/'
|
||||
int32 i, index = -1, len = strlen(path);
|
||||
for (i = 0; i < len && index == -1; i++)
|
||||
if (path[i] == '/') index = i;
|
||||
|
||||
if (index == -1) index = len;
|
||||
|
||||
// Find the device
|
||||
*dev = -1;
|
||||
for (i = 0; (uint32)i < mpList.Size && *dev == -1; i++)
|
||||
if (mpArray[i].Id != BAD && strncmp(path, mpArray[i].Name, index) == 0)
|
||||
*dev = i;
|
||||
|
||||
return &path[index];
|
||||
}
|
||||
|
||||
uint32 VfsFindDevice (string dev)
|
||||
int32 _VfsDetectFs (MountPoint* mp)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < mpCount; i++)
|
||||
if (mpArray[i].Id != BAD && strcmp(dev, mpArray[i].Name) == 0)
|
||||
return i;
|
||||
int32 i;
|
||||
for (i = 0; (uint32)i < fsList.Size; i++)
|
||||
if (fsArray[i].Detect && fsArray[i].Detect(mp)) return i;
|
||||
|
||||
return BAD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Returns mount point index, removes dev name from path
|
||||
uint32 VfsParsePath (string* path)
|
||||
int32 VfsTestDevname (string name)
|
||||
{
|
||||
// Sanity check
|
||||
if (!path || !(*path)) return BAD;
|
||||
// Check if name exists
|
||||
uint8 success = (_VfsFindDevice(name) == -1);
|
||||
|
||||
string dev = *path, p = strchr(*path, ':');
|
||||
if (p == NULL) return BAD; // invalid path
|
||||
// Set up for search
|
||||
char find;
|
||||
uint32 len = strlen(name);
|
||||
name[len+1] = '\0';
|
||||
|
||||
// Split string
|
||||
*path = p+1; *p = '\0';
|
||||
|
||||
return VfsFindDevice(dev);
|
||||
}
|
||||
|
||||
uint8 VfsMount (string Name, DevReadRoutine R, DevWriteRoutine W, uint32 BlockSize)
|
||||
{
|
||||
uint32 i, fsId = BAD, mpIndex = BAD;
|
||||
|
||||
// Try to figure out the file system
|
||||
for (i = 0; i < fsCount && fsId == BAD; i++)
|
||||
if (fsArray[i].Detect && fsArray[i].Detect(R, BlockSize))
|
||||
fsId = i;
|
||||
|
||||
if (fsId == BAD) {
|
||||
Error("VFS", "%#Failed to mount device %s: no file system found.\n", ColorLightRed, Name)
|
||||
return 0; // No file system, no good
|
||||
}
|
||||
|
||||
// Try to find an empty slot to fill
|
||||
for (i = 0; i < mpCount && mpIndex == BAD; i++)
|
||||
if (mpArray[i].Id == BAD) mpIndex = i;
|
||||
|
||||
// No empty slots?
|
||||
if (mpIndex == BAD)
|
||||
// Name exists? Try a number
|
||||
for (find = '0'; find <= '9' && !success; find++)
|
||||
{
|
||||
// Make sure we have enough space
|
||||
if (mpCount == mpAllocated) {
|
||||
mpAllocated += 4;
|
||||
mpArray = kmrealloc(mpArray, mpAllocated * sizeof(MountPoint));
|
||||
}
|
||||
|
||||
mpIndex = mpCount++;
|
||||
name[len] = find;
|
||||
success = (_VfsFindDevice(name) == -1);
|
||||
}
|
||||
|
||||
// Add to mount point list, set up data
|
||||
mpArray[mpIndex].Id = mpIndex;
|
||||
mpArray[mpIndex].FsId = fsId;
|
||||
mpArray[mpIndex].BlockSize = BlockSize;
|
||||
mpArray[mpIndex].Read = R;
|
||||
mpArray[mpIndex].Write = W;
|
||||
|
||||
// Change name if it already exists
|
||||
uint32 find = VfsFindDevice(Name);
|
||||
if (find != BAD)
|
||||
// Whoa... nothing? Try the alphabet.
|
||||
for (find = 'a'; find <= 'z' && !success; find++)
|
||||
{
|
||||
uint32 len = strlen(Name);
|
||||
uint8 success = 0;
|
||||
Name[len+1] = '\0';
|
||||
|
||||
// Try to find a number index
|
||||
for (find = '0'; find <= '9' && !success; find++)
|
||||
{
|
||||
Name[len] = find;
|
||||
if (VfsFindDevice(Name) == BAD) success = 1;
|
||||
}
|
||||
|
||||
// What? Haven't found anything yet? Try the alphabet
|
||||
for (find = 'a'; find <= 'z' && !success; find++)
|
||||
{
|
||||
Name[len] = find;
|
||||
if (VfsFindDevice(Name) == BAD) success = 1;
|
||||
}
|
||||
|
||||
// Still nothing? How in the world is this even possible ?!?!?!
|
||||
if (!success) return 0;
|
||||
name[len] = find;
|
||||
success = (_VfsFindDevice(name) == -1);
|
||||
}
|
||||
|
||||
memcpy(mpArray[mpIndex].Name, Name, sizeof(char) * MAX_MOUNTPOINTNAME_LEN);
|
||||
|
||||
// Tell file system to mount the device
|
||||
if (fsArray[mpArray[mpIndex].FsId].MountDevice)
|
||||
fsArray[mpArray[mpIndex].FsId].MountDevice(&mpArray[mpIndex]);
|
||||
|
||||
Log("VFS", "Mounted device %#%s%# using the %#%s%# file system.\n", ColorWhite, Name,
|
||||
ColorLightGray, ColorWhite, fsArray[fsId].Name, ColorLightGray);
|
||||
return 1;
|
||||
return success;
|
||||
}
|
||||
|
||||
void VfsUnmount (uint32 dev_id)
|
||||
MountPoint* VfsMount (string devname, DevReadRoutine R, DevWriteRoutine W, uint32 bs)
|
||||
{
|
||||
if (fsArray[mpArray[dev_id].FsId].UnmountDevice)
|
||||
fsArray[mpArray[dev_id].FsId].UnmountDevice(&mpArray[dev_id]);
|
||||
// Create a mount point
|
||||
MountPoint mp ;
|
||||
strcpy(mp.Name, devname);
|
||||
mp.BlockSize = bs;
|
||||
mp.Read = R;
|
||||
mp.Write = W;
|
||||
|
||||
mpArray[dev_id].Id = BAD;
|
||||
mpCount--;
|
||||
// Detect file system
|
||||
int32 fsid = _VfsDetectFs(&mp);
|
||||
if (fsid == -1) {
|
||||
Error("VFS", "%#Failed to mount device %s: could not find a file system.\n", ColorLightRed, devname);
|
||||
return NULL;
|
||||
}
|
||||
mp.FsId = (uint32) fsid;
|
||||
|
||||
// Rename if it has problems
|
||||
if (!VfsTestDevname(mp.Name)) {
|
||||
Error("VFS", "%#Failed to mount device %s: bad name.\n", ColorLightRed, devname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find an empty slot
|
||||
uint32 empty = BAD, i;
|
||||
for (i = 0; i < mpList.Size && empty == BAD; i++)
|
||||
if (mpArray[i].Id == BAD) empty = i;
|
||||
|
||||
// Mount it
|
||||
if (empty == BAD) {
|
||||
mp.Id = mpList.Size;
|
||||
DynamicArrayPush(&mp, &mpList);
|
||||
}
|
||||
|
||||
else {
|
||||
mp.Id = empty;
|
||||
memcpy ( &mpArray[empty], &mp, sizeof(MountPoint));
|
||||
}
|
||||
|
||||
// Tell the FS to mount the device
|
||||
if (fsArray[fsid].MountDevice)
|
||||
fsArray[fsid].MountDevice(&mpArray[mp.Id]);
|
||||
|
||||
// Log
|
||||
Log("VFS", "Mounted device %#%s%# using the %#%s%# file system.\n", ColorWhite, mp.Name,
|
||||
ColorLightGray, ColorWhite, fsArray[fsid].Name, ColorLightGray);
|
||||
|
||||
return &mpArray[mp.Id];
|
||||
}
|
||||
|
||||
void VfsUnmount (uint32 devid)
|
||||
{
|
||||
if (fsArray[mpArray[devid].FsId].UnmountDevice)
|
||||
fsArray[mpArray[devid].FsId].UnmountDevice(&mpArray[devid],0);
|
||||
|
||||
// Invalidate ID
|
||||
mpArray[devid].Id = BAD;
|
||||
|
||||
// We shouldn't remove it from the array, because it will invalidate
|
||||
// all other devices' IDs.
|
||||
}
|
||||
|
||||
// Returns pointer to FILE structure that was inputed if success, null otherwise
|
||||
@ -155,23 +172,25 @@ FILE* VfsOpen (FILE* file, string path)
|
||||
if (!file) return NULL;
|
||||
|
||||
// Parse string
|
||||
uint32 dev = VfsParsePath(&path);
|
||||
int32 dev; string temp;
|
||||
temp = _VfsGetDevice(path, &dev);
|
||||
file->DeviceId = dev;
|
||||
|
||||
// Device not found, or Open routine doesn't exist
|
||||
if (dev == BAD || !fsArray[mpArray[dev].FsId].Open) return NULL;
|
||||
if (dev == -1 || !fsArray[mpArray[dev].FsId].Open) return NULL;
|
||||
|
||||
// Ask the FS to do the 'opening'
|
||||
return fsArray[mpArray[dev].FsId].Open(&mpArray[dev],file,path);
|
||||
return fsArray[mpArray[dev].FsId].Open(&mpArray[dev],file,temp);
|
||||
}
|
||||
|
||||
DirectoryEntry* VfsTest (string path)
|
||||
{
|
||||
// Parse string
|
||||
uint32 dev = VfsParsePath(&path);
|
||||
int32 dev;
|
||||
path = _VfsGetDevice(path, &dev);
|
||||
|
||||
// Device not found, or Open routine doesn't exist
|
||||
if (dev == BAD || !fsArray[mpArray[dev].FsId].Test) return NULL;
|
||||
if (dev == -1 || !fsArray[mpArray[dev].FsId].Test) return NULL;
|
||||
|
||||
// Ask the FS to do the 'opening'
|
||||
return fsArray[mpArray[dev].FsId].Test(&mpArray[dev],path);
|
||||
@ -212,3 +231,9 @@ DirectoryEntry* VfsReadDirectory (FILE* handle, uint32 index)
|
||||
if (!fsArray[mp->FsId].ReadDirectory) return NULL;
|
||||
return fsArray[mp->FsId].ReadDirectory(mp, handle, index);
|
||||
}
|
||||
|
||||
MountPoint* VfsGetMountPoint (uint32 dev_id)
|
||||
{
|
||||
if (dev_id < mpList.Size) return &mpArray[dev_id];
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user