[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:
		@@ -258,41 +258,45 @@ void CommandRead(string argv[], int32 argc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern MountPoint* mpArray;
 | 
			
		||||
extern uint32 mpCount;
 | 
			
		||||
void CommandDir (string argv[], int32 argc)
 | 
			
		||||
{
 | 
			
		||||
	if (argc < 2)
 | 
			
		||||
	{
 | 
			
		||||
	// No parameters? Display root content
 | 
			
		||||
	if (argc < 2) 	{
 | 
			
		||||
		ConsoleWrite ("Content of root: \n\n");
 | 
			
		||||
		uint32 i = 0;
 | 
			
		||||
		MountPoint* mp = VfsGetMountPoint(0);
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < mpCount; i++)
 | 
			
		||||
			ConsoleWrite ("\t\t[DEV] %s\n", mpArray[i].Name);
 | 
			
		||||
		for (i = 1; mp != NULL; i++)
 | 
			
		||||
		{
 | 
			
		||||
			ConsoleWrite ("\t[DEV] %s\n", mp->Name);
 | 
			
		||||
			mp = VfsGetMountPoint(i);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Make sure directory exists
 | 
			
		||||
	DirectoryEntry* temp = VfsTest(argv[1]);
 | 
			
		||||
 | 
			
		||||
	if (temp == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		ConsoleWrite("%#! Invalid path!\n", ColorLightRed);
 | 
			
		||||
		return;
 | 
			
		||||
	if (temp == NULL) 	{
 | 
			
		||||
		ConsoleWrite("%#! Invalid path!\n", ColorLightRed); return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Write contents
 | 
			
		||||
	ConsoleWrite ("Content of directory %#%s:\n\n", ColorWhite, argv[1]);
 | 
			
		||||
 | 
			
		||||
	FILE dir; VfsOpen(&dir, argv[1]);
 | 
			
		||||
	uint32 i;
 | 
			
		||||
 | 
			
		||||
	temp = VfsReadDirectory(&dir,0);
 | 
			
		||||
	for (i = 1; temp != NULL; i++, temp = VfsReadDirectory(&dir, 0))
 | 
			
		||||
	for (i = 1; temp != NULL; i++)
 | 
			
		||||
	{
 | 
			
		||||
		ConsoleWrite ("\t\t[%s] ", (temp->Flags & 0x1) ? "FIL" : "DIR" );
 | 
			
		||||
		ConsoleWrite ("\t[%s] ", (temp->Flags & 0x1) ? "FIL" : "DIR" );
 | 
			
		||||
		ConsoleWrite ("%s", temp->Name);
 | 
			
		||||
		Point p = {60, -1}; ConsoleCursorGoto(p);
 | 
			
		||||
		ConsoleWrite ("%u bytes\n", temp->Size);
 | 
			
		||||
 | 
			
		||||
		temp = VfsReadDirectory(&dir, i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VfsClose(&dir);
 | 
			
		||||
@@ -305,18 +309,25 @@ void CommandCat (string argv[], int32 argc)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("Contents of file %s:\n--------------------------\n");
 | 
			
		||||
	FILE f;
 | 
			
		||||
	VfsOpen(&f, argv[1]);
 | 
			
		||||
	uint8* buffer = kmalloc(0x1000);
 | 
			
		||||
	uint32 sz, i;
 | 
			
		||||
 | 
			
		||||
	while ((sz = VfsRead(&f, 1, 0x1000, buffer)))
 | 
			
		||||
	{
 | 
			
		||||
		for (i = 0; i < sz; i++) ConsoleWrite("%c", buffer[i]);
 | 
			
		||||
	// Try to open
 | 
			
		||||
	if (!VfsOpen(&f, argv[1])) {
 | 
			
		||||
		ConsoleWrite ("%#! Invalid file: %s\n.", ColorLightRed, argv[1]);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("\n--------------------------\n");
 | 
			
		||||
	uint8* buffer = kmalloc(0x100);
 | 
			
		||||
	uint32 sz, i;
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("----[%s]------\n", argv[1]);
 | 
			
		||||
 | 
			
		||||
	while ((sz = VfsRead(&f, 1, 0x100, buffer)))
 | 
			
		||||
	{
 | 
			
		||||
		for (i = 0; i < sz; i++) ConsoleWrite("%#%c", ColorLightGray, buffer[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("\n------------[EOF]------------\n");
 | 
			
		||||
	kfree(buffer);
 | 
			
		||||
	VfsClose(&f);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								Kernel/include/array.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Kernel/include/array.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * array.h
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Sep 3, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ARRAY_H_
 | 
			
		||||
#define ARRAY_H_
 | 
			
		||||
 | 
			
		||||
#include <types.h>
 | 
			
		||||
 | 
			
		||||
/*******************************************
 | 
			
		||||
 * Dynamically expanding array             *
 | 
			
		||||
 *******************************************/
 | 
			
		||||
typedef struct {
 | 
			
		||||
	//   You can cast the Data to any type of array
 | 
			
		||||
	// because it contains the actual data, not pointers
 | 
			
		||||
	void* Data;
 | 
			
		||||
	uint32 ElemSize;
 | 
			
		||||
	uint32 Size;
 | 
			
		||||
	uint32 Allocated;
 | 
			
		||||
} DynamicArray;
 | 
			
		||||
 | 
			
		||||
extern void DynamicArrayCreate (uint32 ElemSize, DynamicArray* arr);
 | 
			
		||||
extern void DynamicArrayPush (void* item, DynamicArray* arr);
 | 
			
		||||
extern void DynamicArrayPop (DynamicArray* arr);
 | 
			
		||||
extern void DynamicArrayInsert (void* item, uint32 index, DynamicArray* arr);
 | 
			
		||||
extern void DynamicArrayRemove (uint32 index, DynamicArray* arr);
 | 
			
		||||
extern void DynamicArraySwap (uint32 a, uint32 b, DynamicArray* arr);
 | 
			
		||||
extern void DynamicArrayDispose (DynamicArray* arr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*******************************************
 | 
			
		||||
 * Ordered array                           *
 | 
			
		||||
 *******************************************/
 | 
			
		||||
typedef int (*ComparePredicate) (uint32, uint32);
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint32* Data;
 | 
			
		||||
	uint32 Size;
 | 
			
		||||
	uint32 SizeLimit;
 | 
			
		||||
	ComparePredicate Compare;
 | 
			
		||||
} OrderedArray;
 | 
			
		||||
 | 
			
		||||
extern OrderedArray OrderedArrayCreate 		(uint32 maxSize, ComparePredicate p);
 | 
			
		||||
extern OrderedArray OrderedArrayPlace 		(uint32 addr, uint32 maxSize, ComparePredicate p);
 | 
			
		||||
extern void 		OrderedArrayDispose 	(OrderedArray* arr);
 | 
			
		||||
extern uint32 		OrderedArraySearch 		(uint32 key, OrderedArray* arr, ComparePredicate predicate);
 | 
			
		||||
extern void 		OrderedArrayInsert 		(uint32 item, OrderedArray* arr);
 | 
			
		||||
extern uint32 		OrderedArrayLookup 		(uint32 index, OrderedArray* arr);
 | 
			
		||||
extern void 		OrderedArrayDeleteIndex (uint32 index, OrderedArray* arr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* ARRAY_H_ */
 | 
			
		||||
@@ -43,24 +43,23 @@ enum FileFlags
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	uint32 DeviceId;	// The VFS identifies the mounted device that uses this
 | 
			
		||||
	uint32 Id;			// The FS idenitifies files using this field
 | 
			
		||||
	//char Name[MAX_FILENAME_LEN];
 | 
			
		||||
	uint32 Id;			// The FS identifies files using this field
 | 
			
		||||
	char* Name;
 | 
			
		||||
 | 
			
		||||
	/*** Looks like this:
 | 
			
		||||
	 *	bits  description
 | 
			
		||||
	 *	0-2   file type
 | 
			
		||||
	 *  3-5   owner permissions (rwx)
 | 
			
		||||
	 *  6-8   group permissions (rwx)
 | 
			
		||||
	 *  9-11  other permissions (rwx)
 | 
			
		||||
	 *  12    hidden
 | 
			
		||||
	 *  13-31 (unassigned yet)
 | 
			
		||||
	/*** Flags look like this:
 | 
			
		||||
	 *
 | 
			
		||||
	 *  Note: In windows FS, the readonly and system
 | 
			
		||||
	* attributes are set using permissions and owner id */
 | 
			
		||||
	uint32 Flags;
 | 
			
		||||
	uint32 OwnerId, GroupId;
 | 
			
		||||
	 *	bits 31 ... 13 |     12 | 11 10  9 | 8  7  6 | 5  4  3 | 2  1  0
 | 
			
		||||
	 *	    unassigned | Hidden |  x  w  r | x  w  r | x  w  r | file type (enum above)
 | 
			
		||||
	 *	                        |  others  |  group  |  owner  |
 | 
			
		||||
	 * Note: In windows FSs, the readonly and system attributes are set
 | 
			
		||||
	 * using permissions mask and owner id (0 = system) */
 | 
			
		||||
	uint32 Flags, OwnerId, GroupId;
 | 
			
		||||
	uint32 Size;
 | 
			
		||||
 | 
			
		||||
	// Useful for file systems
 | 
			
		||||
	void *BufStart, *BufPos, *BufEnd ;
 | 
			
		||||
	uint32 FsData[8];	// Can store info such as current cluster, etc
 | 
			
		||||
 | 
			
		||||
} FILE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -70,31 +69,32 @@ typedef struct _DirectoryEntry
 | 
			
		||||
	uint32 Flags, OwnerId, GroupId, Size;
 | 
			
		||||
	TimeSystem TimeCreated, TimeModified, TimeAccessed;
 | 
			
		||||
 | 
			
		||||
} DirectoryEntry;
 | 
			
		||||
}  __attribute__((packed)) DirectoryEntry;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint32 Id;
 | 
			
		||||
	uint32 FsId;
 | 
			
		||||
	uint32 Id, FsId;
 | 
			
		||||
	char Name[MAX_MOUNTPOINTNAME_LEN];
 | 
			
		||||
 | 
			
		||||
	uint32 BlockSize;
 | 
			
		||||
	DevReadRoutine Read;
 | 
			
		||||
	DevWriteRoutine Write;
 | 
			
		||||
 | 
			
		||||
	uint32 FsData[8];
 | 
			
		||||
} MountPoint;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// File system routines
 | 
			
		||||
typedef uint32 (*FsReadRoutine)(const MountPoint*, FILE*, uint32, uint32, uint8*);
 | 
			
		||||
typedef uint32 (*FsWriteRoutine)(const MountPoint*, FILE*, uint32, uint32, uint8*);
 | 
			
		||||
typedef FILE* (*FsOpenRoutine)(const MountPoint*, FILE*,string);
 | 
			
		||||
typedef DirectoryEntry* (*FsTestRoutine)(const MountPoint*, string);	// Test if a file exists, and returns info
 | 
			
		||||
typedef FILE* (*FsCloseRoutine)(const MountPoint*, FILE*);
 | 
			
		||||
typedef DirectoryEntry* (*FsReadDirRoutine)(const MountPoint*,FILE*,uint32);
 | 
			
		||||
typedef uint32 			(*FsReadRoutine)	(MountPoint*, FILE*, uint32, uint32, uint8*);
 | 
			
		||||
typedef uint32 			(*FsWriteRoutine)	(MountPoint*, FILE*, uint32, uint32, uint8*);
 | 
			
		||||
typedef FILE* 			(*FsOpenRoutine)	(MountPoint*, FILE*, string);
 | 
			
		||||
typedef DirectoryEntry* (*FsTestRoutine)	(MountPoint*, string);	// Test if a file exists, and returns info
 | 
			
		||||
typedef FILE* 			(*FsCloseRoutine)	(MountPoint*, FILE*);
 | 
			
		||||
typedef DirectoryEntry* (*FsReadDirRoutine)	(MountPoint*, FILE*, uint32);
 | 
			
		||||
 | 
			
		||||
typedef uint32 (*FsDetectRoutine) (DevReadRoutine, uint32 blocksz);
 | 
			
		||||
typedef void (*FsMountRoutine) (const MountPoint*);
 | 
			
		||||
typedef void (*FsUnmountRoutine) (const MountPoint*);
 | 
			
		||||
typedef uint32 			(*FsDetectRoutine) 	(MountPoint*);
 | 
			
		||||
typedef void 			(*FsMountRoutine) 	(MountPoint*);
 | 
			
		||||
typedef void 			(*FsUnmountRoutine) (MountPoint*, uint8 Forced); // If forced, the FS shouldn't try to write to device
 | 
			
		||||
 | 
			
		||||
// File system structure
 | 
			
		||||
typedef struct {
 | 
			
		||||
@@ -115,18 +115,16 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Vfs routines
 | 
			
		||||
extern void   VfsInstall ();
 | 
			
		||||
extern uint8  VfsInstallFs (FileSystem* fs);
 | 
			
		||||
extern uint32 VfsFindDevice (string dev);
 | 
			
		||||
extern uint32 VfsParsePath (string* path);
 | 
			
		||||
extern uint8  VfsMount (string Name, DevReadRoutine R, DevWriteRoutine W, uint32 BlockSize);
 | 
			
		||||
extern void VfsUnmount (uint32 dev_id);
 | 
			
		||||
extern FILE* VfsOpen (FILE* file, string path);
 | 
			
		||||
extern void			VfsInstall ();
 | 
			
		||||
extern void			VfsInstallFs (FileSystem* fs);
 | 
			
		||||
extern MountPoint* 	VfsMount (string devname, DevReadRoutine R, DevWriteRoutine W, uint32 bs);
 | 
			
		||||
extern void			VfsUnmount (uint32 dev_id);
 | 
			
		||||
extern FILE*		VfsOpen (FILE* file, string path);
 | 
			
		||||
extern DirectoryEntry* VfsTest (string path);
 | 
			
		||||
extern FILE* VfsClose (FILE* file);
 | 
			
		||||
extern uint32 VfsRead (FILE* file, uint32 bsz, uint32 n, uint8* buffer);
 | 
			
		||||
extern uint32 VfsWrite (FILE* file, uint32 bsz, uint32 n, uint8* buffer);
 | 
			
		||||
extern FILE*		VfsClose (FILE* file);
 | 
			
		||||
extern uint32		VfsRead (FILE* file, uint32 bsz, uint32 n, uint8* buffer);
 | 
			
		||||
extern uint32 		VfsWrite (FILE* file, uint32 bsz, uint32 n, uint8* buffer);
 | 
			
		||||
extern DirectoryEntry* VfsReadDirectory (FILE* handle, uint32 index);
 | 
			
		||||
 | 
			
		||||
extern MountPoint* 	VfsGetMountPoint (uint32 dev_id);
 | 
			
		||||
 | 
			
		||||
#endif /* FILEIO_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
#include <memory.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
#include <array.h>
 | 
			
		||||
 | 
			
		||||
/***************************************************
 | 
			
		||||
 * Paging                                          *
 | 
			
		||||
 
 | 
			
		||||
@@ -23,10 +23,11 @@
 | 
			
		||||
 ***************************************************/
 | 
			
		||||
extern uint32 strlen (string s);
 | 
			
		||||
extern int32  strcmp (string a, string b);
 | 
			
		||||
extern int32 strcasecmp (string a, string b);
 | 
			
		||||
extern int32  strncmp (string a, string b, uint32 n);
 | 
			
		||||
extern int32  strcasecmp (string a, string b);
 | 
			
		||||
extern string strcpy (string s1, const string s2);
 | 
			
		||||
extern char* strchr (string s, int c);
 | 
			
		||||
extern char* strrchr (string s, int c);
 | 
			
		||||
extern char*  strchr (string s, int c);
 | 
			
		||||
extern char*  strrchr (string s, int c);
 | 
			
		||||
 | 
			
		||||
/***************************************************
 | 
			
		||||
 * Number operations: len                          *
 | 
			
		||||
@@ -50,23 +51,5 @@ extern int32 	ConvertStringToInt 		(string buffer);
 | 
			
		||||
extern uint32	ConvertStringToUInt 	(string buffer);
 | 
			
		||||
extern uint32 	ConvertStringToIntHex 	(string buffer);
 | 
			
		||||
 | 
			
		||||
/***************************************************
 | 
			
		||||
 * Ordered array implementation                    *
 | 
			
		||||
 ***************************************************/
 | 
			
		||||
typedef int (*ComparePredicate) (uint32, uint32);
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint32* Data;
 | 
			
		||||
	uint32 Size;
 | 
			
		||||
	uint32 SizeLimit;
 | 
			
		||||
	ComparePredicate Compare;
 | 
			
		||||
} OrderedArray;
 | 
			
		||||
 | 
			
		||||
extern OrderedArray OrderedArrayCreate 		(uint32 maxSize, ComparePredicate p);
 | 
			
		||||
extern OrderedArray OrderedArrayPlace 		(uint32 addr, uint32 maxSize, ComparePredicate p);
 | 
			
		||||
extern void 		OrderedArrayDispose 	(OrderedArray* arr);
 | 
			
		||||
extern uint32 		OrderedArraySearch 		(uint32 key, OrderedArray* arr, ComparePredicate predicate);
 | 
			
		||||
extern void 		OrderedArrayInsert 		(uint32 item, OrderedArray* arr);
 | 
			
		||||
extern uint32 		OrderedArrayLookup 		(uint32 index, OrderedArray* arr);
 | 
			
		||||
extern void 		OrderedArrayDeleteIndex (uint32 index, OrderedArray* arr);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
#define OS_BUILD "0.1.0.551"
 | 
			
		||||
#define OS_BUILD "0.1.0.590"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										103
									
								
								Kernel/library/array/dynamic_arr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								Kernel/library/array/dynamic_arr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
/*
 | 
			
		||||
 * dynamic-arr.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Sep 3, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <memory.h>
 | 
			
		||||
#include <array.h>
 | 
			
		||||
 | 
			
		||||
void DynamicArrayCreate (uint32 ElemSize, DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	// Create a simple array. Allocate 16 elems for start
 | 
			
		||||
	arr->ElemSize = ElemSize;
 | 
			
		||||
	arr->Size = 0;
 | 
			
		||||
	arr->Allocated = 0x10;
 | 
			
		||||
	arr->Data = kmalloc(0x10 * ElemSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArrayPush (void* item, DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	// Make sure we have enough space
 | 
			
		||||
	if (arr->Allocated <= arr->Size)
 | 
			
		||||
	{
 | 
			
		||||
		arr->Allocated += 0x10;
 | 
			
		||||
		arr->Data = kmrealloc(arr->Data, arr->Allocated * arr->ElemSize);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Calculate the address of next item
 | 
			
		||||
	uint32 addr = (uint32)arr->Data + arr->Size * arr->ElemSize;
 | 
			
		||||
 | 
			
		||||
	// Copy data
 | 
			
		||||
	memcpy((void*)addr, item, arr->ElemSize);
 | 
			
		||||
	++arr->Size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArrayPop (DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	// Decrease size
 | 
			
		||||
	--arr->Size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArrayInsert (void* item, uint32 index, DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	// Make sure we have enough space
 | 
			
		||||
	if (arr->Allocated <= arr->Size)
 | 
			
		||||
	{
 | 
			
		||||
		arr->Allocated += 0x10;
 | 
			
		||||
		arr->Data = kmrealloc(arr->Data, arr->Allocated * arr->ElemSize);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Move the data out of the way
 | 
			
		||||
	uint8* buffer = (uint8*) arr->Data;
 | 
			
		||||
	uint32 start = index * arr->ElemSize;
 | 
			
		||||
	uint32 end = arr->Size * arr->ElemSize;
 | 
			
		||||
 | 
			
		||||
	for (--end; end >= start; end--)
 | 
			
		||||
		buffer[end + arr->ElemSize] = buffer[end];
 | 
			
		||||
 | 
			
		||||
	// Insert item
 | 
			
		||||
	memcpy((void*)((uint32)arr->Data + start), item, arr->ElemSize);
 | 
			
		||||
	++ arr->Size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArrayRemove (uint32 index, DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	uint8* buffer = (uint8*) arr->Data;
 | 
			
		||||
	uint32 start = index * arr->ElemSize;
 | 
			
		||||
	uint32 end = (arr->Size-1) * arr->ElemSize;
 | 
			
		||||
 | 
			
		||||
	for (; start < end; start++)
 | 
			
		||||
		buffer[start] = buffer[start + arr->ElemSize];
 | 
			
		||||
 | 
			
		||||
	-- arr->Size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArraySwap (uint32 a, uint32 b, DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	uint8 temp, *buffer = (uint8*) arr->Data;
 | 
			
		||||
	uint32 addra = a * arr->ElemSize;
 | 
			
		||||
	uint32 addrb = b * arr->ElemSize;
 | 
			
		||||
	uint32 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < arr->ElemSize; i++)
 | 
			
		||||
	{
 | 
			
		||||
		// Swap byte i from elem A with byte i from elem B
 | 
			
		||||
		temp = buffer[addra + i];
 | 
			
		||||
		buffer[addra + i] = buffer[addrb + i];
 | 
			
		||||
		buffer[addrb + i] = temp;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicArrayDispose (DynamicArray* arr)
 | 
			
		||||
{
 | 
			
		||||
	// Free used data
 | 
			
		||||
	kfree(arr->Data);
 | 
			
		||||
 | 
			
		||||
	// Set everything to 0 so we don't attempt to add more items and stuff
 | 
			
		||||
	arr->Allocated = 0;
 | 
			
		||||
	arr->Size = 0;
 | 
			
		||||
	arr->ElemSize = 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <memory.h>
 | 
			
		||||
#include <array.h>
 | 
			
		||||
 | 
			
		||||
int StandardComparePredicate (uint32 a, uint32 b)
 | 
			
		||||
{
 | 
			
		||||
@@ -29,6 +29,21 @@ int32 strcmp (string a, string b)
 | 
			
		||||
	return ((c1 < c2) ? -1 : (c1 > c2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32 strncmp (string a, string b, uint32 n)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char uc1, uc2;
 | 
			
		||||
	if (!n) return 0;
 | 
			
		||||
 | 
			
		||||
	while (n-- > 0 && *a == *b) {
 | 
			
		||||
		if (n == 0 || (*a == *b  && *a == '\0')) return 0;
 | 
			
		||||
		a++; b++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uc1 = (* (unsigned char*)a);
 | 
			
		||||
	uc2 = (* (unsigned char*)b);
 | 
			
		||||
	return ((uc1 < uc2) ? -1 : (uc1 > uc2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32 strcasecmp (string a, string b)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char c1, c2;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,75 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * memory-vi.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Aug 23, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
#include <memory-add.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
/*******************************
 | 
			
		||||
 * Data						   *
 | 
			
		||||
 *******************************/
 | 
			
		||||
PageDirectory* CurrentDirectory;
 | 
			
		||||
PageDirectory* KernelDirectory;
 | 
			
		||||
 | 
			
		||||
/*******************************
 | 
			
		||||
 * Useful routines			   *
 | 
			
		||||
 *******************************/
 | 
			
		||||
void PagingInitialize(uint32 kernel_used)
 | 
			
		||||
{
 | 
			
		||||
	LogMem("Virtual memory manager initialization started. End of kernel = 0x%x\n", kernel_used);
 | 
			
		||||
	PageDirectory* kernelPd = (PageDirectory*) kmalloc_a(sizeof(PageDirectory));
 | 
			
		||||
	memset(kernelPd, 0, sizeof(PageDirectory));
 | 
			
		||||
 | 
			
		||||
	CurrentDirectory = kernelPd;
 | 
			
		||||
	KernelDirectory = kernelPd;
 | 
			
		||||
 | 
			
		||||
	uint32 i;
 | 
			
		||||
	for (i = 0; i < kernel_used; i+=0x1000)
 | 
			
		||||
		MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0);
 | 
			
		||||
 | 
			
		||||
	LogMem("Identity mapped first 0x%x bytes.\n", kernel_used);
 | 
			
		||||
 | 
			
		||||
	for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
 | 
			
		||||
		MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 1, 1);
 | 
			
		||||
 | 
			
		||||
	LogMem("Mapped kernel space.\n");
 | 
			
		||||
 | 
			
		||||
	PagingSwitchPageDirectory (kernelPd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PagingSwitchPageDirectory (PageDirectory* dir)
 | 
			
		||||
{
 | 
			
		||||
	CurrentDirectory = dir;
 | 
			
		||||
	asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical));
 | 
			
		||||
	LogMem("Switched page directory to 0x%x.\n", (uint32)(&dir->TablesPhysical));
 | 
			
		||||
 | 
			
		||||
	uint32 cr0;
 | 
			
		||||
	asm volatile ("mov %%cr0, %0": "=r"(cr0));
 | 
			
		||||
	cr0 |= 0x80000000;
 | 
			
		||||
	asm volatile ("mov %0, %%cr0":: "r"(cr0));
 | 
			
		||||
 | 
			
		||||
	LogMem("Enabled paging.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir)
 | 
			
		||||
{
 | 
			
		||||
	addr >>= 12;
 | 
			
		||||
 | 
			
		||||
	uint32 tableIndex = addr >> 10;
 | 
			
		||||
 | 
			
		||||
	if (dir->Tables[tableIndex])
 | 
			
		||||
		return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
 | 
			
		||||
 | 
			
		||||
	else if (make)
 | 
			
		||||
	{
 | 
			
		||||
		uint32 temp;
 | 
			
		||||
		dir->Tables[tableIndex] = (PageTable*)kmalloc_ap(sizeof(PageTable), &temp);
 | 
			
		||||
		memset (dir->Tables[tableIndex], 0, 0x1000);
 | 
			
		||||
		dir->TablesPhysical[tableIndex] = temp | 0x7;
 | 
			
		||||
		return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	else return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,109 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * mem-phys.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Aug 27, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
#include <memory-add.h>
 | 
			
		||||
 | 
			
		||||
uint32* FrameMap;
 | 
			
		||||
uint32 TotalFrames;
 | 
			
		||||
uint32 TotalMemory;
 | 
			
		||||
uint32 UsedFrames;
 | 
			
		||||
 | 
			
		||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
 | 
			
		||||
{
 | 
			
		||||
	*address = (index >> 5);
 | 
			
		||||
	*offset = index & 0x1f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
 | 
			
		||||
{
 | 
			
		||||
	return (address<<5) | offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemPhSetFrame (uint32 frame, uint8 value)
 | 
			
		||||
{
 | 
			
		||||
	uint32 addr, off;
 | 
			
		||||
	ConvertIndexToFrame(frame, &addr, &off);
 | 
			
		||||
 | 
			
		||||
	if (value) {
 | 
			
		||||
		if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
 | 
			
		||||
		FrameMap[addr] |= 1<<off;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	else {
 | 
			
		||||
		if (FrameMap[addr] & (1<<off)) UsedFrames--;
 | 
			
		||||
		FrameMap[addr] &= ~(1<<off);	
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32 MemPhGetFrame (uint32 frame)
 | 
			
		||||
{
 | 
			
		||||
	uint32 addr, off;
 | 
			
		||||
	ConvertIndexToFrame(frame, &addr, &off);
 | 
			
		||||
 | 
			
		||||
	return FrameMap[addr] & (1<<off);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32 MemPhFindFreeFrame()
 | 
			
		||||
{
 | 
			
		||||
	uint32 addr, pos;
 | 
			
		||||
 | 
			
		||||
	for (addr = 0; addr < TotalFrames >> 5; addr++)
 | 
			
		||||
		if (FrameMap[addr] != 0xffffffff)
 | 
			
		||||
		{
 | 
			
		||||
			for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
 | 
			
		||||
 | 
			
		||||
			return ConvertFrameToIndex(addr, pos);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	return 0xffffffff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
 | 
			
		||||
{
 | 
			
		||||
	if ((*page & PageFrame) != 0) return;
 | 
			
		||||
 | 
			
		||||
	uint32 free = MemPhFindFreeFrame();
 | 
			
		||||
	if (free == 0xffffffff) {
 | 
			
		||||
		Panic("%#Failed allocation free=0x%x page=0x%x\n", ColorRed, free, *page);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	MemPhSetFrame(free, 1);
 | 
			
		||||
	*page |= PagePresent;
 | 
			
		||||
	*page |= (isKernel) ? 0 : PageUser;
 | 
			
		||||
	*page |= (isWriteable) ? PageWriteable : 0;
 | 
			
		||||
	*page |= (free<<12) & PageFrame;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemPhFreeFrame(Page* page)
 | 
			
		||||
{
 | 
			
		||||
	uint32 frame = *page & PageFrame;
 | 
			
		||||
	if (!frame) return;
 | 
			
		||||
 | 
			
		||||
	MemPhSetFrame(frame, 0);
 | 
			
		||||
	*page &= ~PageFrame;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemPhInitialize(uint32 SystemMemoryKb)
 | 
			
		||||
{
 | 
			
		||||
	LogMem("Starting physical memory manager...\n");
 | 
			
		||||
	TotalFrames = SystemMemoryKb >> 2;
 | 
			
		||||
	TotalMemory = SystemMemoryKb;
 | 
			
		||||
 | 
			
		||||
	FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
 | 
			
		||||
	memset(FrameMap, 0,  sizeof(uint32) * (1 + (TotalFrames>>5)));
 | 
			
		||||
	LogMem("%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemPhReserveFrames (uint32 address, uint32 length)
 | 
			
		||||
{
 | 
			
		||||
	address >>= 12;
 | 
			
		||||
	length = (length>>12) + ((length & 0xfff) > 0);
 | 
			
		||||
	uint32 end = address + length;
 | 
			
		||||
 | 
			
		||||
	for (; address < end ; address++)
 | 
			
		||||
		MemPhSetFrame(address, 1);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user