Work on storage and flat file system
This commit is contained in:
parent
24c371cab1
commit
ff4c597ff3
@ -12,16 +12,14 @@ OEMName : array[0..7] of char;
|
|||||||
version : uint16 // numerical version of filesystem
|
version : uint16 // numerical version of filesystem
|
||||||
sectorCount : uint16;
|
sectorCount : uint16;
|
||||||
fileCount : uint16
|
fileCount : uint16
|
||||||
signature : uint32 = 0xABAB1F1E
|
signature : uint32 = 0x0B00B1E5
|
||||||
|
|
||||||
|
|
||||||
the Rest of the sector is reserved
|
the Rest of the sector is reserved
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Starting from sector 1 is the file table. Table size is determined by entry size (512) * fileCount
|
Starting from sector 1 is the file table. Table size is determined by entry size (64) * fileCount
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
####File entry
|
####File entry
|
||||||
@ -30,4 +28,5 @@ name : array[0..59] of char //file name max 60 chars
|
|||||||
fileStart : 16bit // start sector of data
|
fileStart : 16bit // start sector of data
|
||||||
fileSize : 16bit // data size in sectors
|
fileSize : 16bit // data size in sectors
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -446,7 +446,8 @@ var
|
|||||||
begin
|
begin
|
||||||
push_trace('IDE.dread');
|
push_trace('IDE.dread');
|
||||||
for i:=0 to sectorCount-1 do begin
|
for i:=0 to sectorCount-1 do begin
|
||||||
readPIO28(device^.controllerId0, LBA, puint8(@buffer[512*i]));
|
readPIO28(device^.controllerId0, LBA + i, puint8(@buffer[512*i]));
|
||||||
|
psleep(100)
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -455,7 +456,8 @@ var
|
|||||||
i : uint16;
|
i : uint16;
|
||||||
begin
|
begin
|
||||||
for i:=0 to sectorCount-1 do begin
|
for i:=0 to sectorCount-1 do begin
|
||||||
writePIO28(device^.controllerId0, LBA, puint8(@buffer[512*i]));
|
writePIO28(device^.controllerId0, LBA + i, puint8(@buffer[512*i]));
|
||||||
|
psleep(100)
|
||||||
end;
|
end;
|
||||||
// writePIO28(device^.controllerId0, LBA, puint8(buffer));
|
// writePIO28(device^.controllerId0, LBA, puint8(buffer));
|
||||||
end;
|
end;
|
||||||
|
@ -95,18 +95,21 @@ var
|
|||||||
i : uint32 = 0;
|
i : uint32 = 0;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
push_trace('DriverManager.format_command');
|
||||||
|
|
||||||
//format <DRIVE_ID> <FILESYSTEM> <size>
|
//format <DRIVE_ID> <FILESYSTEM> <size>
|
||||||
|
|
||||||
spc:= puint32(kalloc(4));
|
spc:= puint32(kalloc(4));
|
||||||
spc^:= 1;
|
spc^:= 1;
|
||||||
|
|
||||||
|
push_trace('DriverManager.format_command.0');
|
||||||
|
|
||||||
//get drive from index/id
|
//get drive from index/id
|
||||||
driveIndex:= stringToInt( getParam(1, params) );
|
driveIndex:= stringToInt( getParam(1, params) );
|
||||||
drive:= PStorage_Device(LL_Get(storageDevices, driveIndex));
|
drive:= PStorage_Device(LL_Get(storageDevices, driveIndex));
|
||||||
|
|
||||||
filesystemString := getParam(2, params);
|
filesystemString := getParam(2, params);
|
||||||
sectorCount := stringToInt( getParam(4, params) );
|
sectorCount := stringToInt( getParam(3, params) );
|
||||||
|
|
||||||
// if sector count is 0, use full drive
|
// if sector count is 0, use full drive
|
||||||
if sectorCount = 0 then begin
|
if sectorCount = 0 then begin
|
||||||
@ -114,11 +117,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
//create MBR if none, and partition table
|
//create MBR if none, and partition table
|
||||||
mb := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)));
|
mb := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)*2));
|
||||||
|
memset(uint32(mb), 0, sizeof(TMaster_Boot_Record));
|
||||||
drive^.readCallback(drive, 0, 1, PuInt32(mb));
|
drive^.readCallback(drive, 0, 1, PuInt32(mb));
|
||||||
|
|
||||||
//check if MBR exists
|
//check if MBR exists
|
||||||
if not mb^.boot_sector = $55AA then begin
|
if (mb^.boot_sector <> $55AA)then begin
|
||||||
|
|
||||||
|
writestringlnWND('Creating MBR', getTerminalHWND());
|
||||||
|
|
||||||
//create MBR
|
//create MBR
|
||||||
mb^.signature := $A570 + drive^.id;
|
mb^.signature := $A570 + drive^.id;
|
||||||
@ -130,6 +136,20 @@ begin
|
|||||||
//write MBR
|
//write MBR
|
||||||
drive^.writeCallback(drive, 0, 1, puint32(mb));
|
drive^.writeCallback(drive, 0, 1, puint32(mb));
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
writestringlnWND('MBR already exists', getTerminalHWND());
|
||||||
|
|
||||||
|
//write first partiton sectorStart and sectorCount
|
||||||
|
writeintlnWND(mb^.partition[0].LBA_start, getTerminalHWND());
|
||||||
|
writeintlnWND(mb^.partition[0].sector_count, getTerminalHWND());
|
||||||
|
|
||||||
|
//create partition table
|
||||||
|
mbr.setup_partition(@mb^.partition[0], 2, sectorCount);
|
||||||
|
|
||||||
|
//write MBR
|
||||||
|
drive^.writeCallback(drive, 0, 1, puint32(mb));
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
kfree(puint32(mb));
|
kfree(puint32(mb));
|
||||||
@ -176,19 +196,23 @@ var
|
|||||||
begin
|
begin
|
||||||
push_trace('DriverManager.drive_command');
|
push_trace('DriverManager.drive_command');
|
||||||
subcmd:= getParam(0, params);
|
subcmd:= getParam(0, params);
|
||||||
|
push_trace('DriverManager.drive_command.0');
|
||||||
|
|
||||||
if ((paramCount(params) = 0)) then begin
|
if ((paramCount(params) = 0)) then begin
|
||||||
console.writestringlnWnd('Please provide valid arguments.', getTerminalHWND());
|
console.writestringlnWnd('Please provide valid arguments.', getTerminalHWND());
|
||||||
console.writestringlnWnd(' ls - for listing all drives', getTerminalHWND());
|
console.writestringlnWnd(' ls - for listing all drives', getTerminalHWND());
|
||||||
console.writestringlnWnd(' info [drive] - display formation for specified drive', getTerminalHWND());
|
console.writestringlnWnd(' info [drive] - display formation for specified drive', getTerminalHWND());
|
||||||
console.writestringlnWnd(' init [drive] - destructive, formats a drive with a blank partition', getTerminalHWND());
|
console.writestringlnWnd(' init [drive] - destructive, formats a drive with a blank partition', getTerminalHWND());
|
||||||
|
console.writestringlnWnd(' format [drive] [filesystem] [size (0 for max)] - destructive, formats a drive with MBR and volume', getTerminalHWND());
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
push_trace('DriverManager.drive_command.1');
|
||||||
|
|
||||||
if( stringEquals(subcmd, 'ls') ) then begin
|
if( stringEquals(subcmd, 'ls') ) then begin
|
||||||
list_drive_command();
|
list_drive_command();
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
push_trace('DriverManager.drive_command.2');
|
||||||
|
|
||||||
if( stringEquals(subcmd, 'info') ) then begin
|
if( stringEquals(subcmd, 'info') ) then begin
|
||||||
console.writestringWnd('Disk: ', getTerminalHWND());
|
console.writestringWnd('Disk: ', getTerminalHWND());
|
||||||
@ -196,14 +220,22 @@ begin
|
|||||||
|
|
||||||
console.writestringWnd('Capacity: ', getTerminalHWND());
|
console.writestringWnd('Capacity: ', getTerminalHWND());
|
||||||
console.writeintlnWND(1, getTerminalHWND());
|
console.writeintlnWND(1, getTerminalHWND());
|
||||||
//TODO impliement
|
//TODO impliment
|
||||||
exit
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if( stringEquals(subcmd, 'init') ) then begin
|
if( stringEquals(subcmd, 'init') ) then begin
|
||||||
init_drive_command(stringToInt(getParam(1, params) ) );
|
init_drive_command(stringToInt(getParam(1, params) ) );
|
||||||
exit
|
exit;
|
||||||
end;
|
end;
|
||||||
|
push_trace('DriverManager.drive_command.3');
|
||||||
|
|
||||||
|
if( stringEquals(subcmd, 'format') ) then begin
|
||||||
|
format_command(params);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
push_trace('DriverManager.drive_command.4');
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Initialise the drive manager }
|
{ Initialise the drive manager }
|
||||||
|
@ -91,7 +91,7 @@ var
|
|||||||
filesystem : TFilesystem;
|
filesystem : TFilesystem;
|
||||||
|
|
||||||
procedure init;
|
procedure init;
|
||||||
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
|
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||||
procedure detect_volumes(disk : PStorage_Device);
|
procedure detect_volumes(disk : PStorage_Device);
|
||||||
//function writeDirectory(volume : PStorage_volume; directory : pchar; attributes : uint32) : uint8; // need to handle parent table cluster overflow, need to take attributes
|
//function writeDirectory(volume : PStorage_volume; directory : pchar; attributes : uint32) : uint8; // need to handle parent table cluster overflow, need to take attributes
|
||||||
//function readDirectory(volume : PStorage_volume; directory : pchar; listPtr : PLinkedListBase) : uint8; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
|
//function readDirectory(volume : PStorage_volume; directory : pchar; listPtr : PLinkedListBase) : uint8; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
|
||||||
@ -753,7 +753,7 @@ end;
|
|||||||
|
|
||||||
//TODO check directory commands for errors with a clean disk
|
//TODO check directory commands for errors with a clean disk
|
||||||
|
|
||||||
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
|
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||||
var
|
var
|
||||||
buffer : puint32;
|
buffer : puint32;
|
||||||
bt: puint32;
|
bt: puint32;
|
||||||
@ -774,9 +774,18 @@ var
|
|||||||
programFileArray : byteArray8 = ('P','R','O','G','R','A','M','S');
|
programFileArray : byteArray8 = ('P','R','O','G','R','A','M','S');
|
||||||
rootCluster : uint32 = 1;
|
rootCluster : uint32 = 1;
|
||||||
|
|
||||||
|
sysArray : byteArray8 = ('S','Y','S','T','E','M',' ',' ');
|
||||||
|
progArray : byteArray8 = ('P','R','O','G','R','A','M','S');
|
||||||
|
userArray : byteArray8 = ('U','S','E','R',' ',' ',' ',' ');
|
||||||
|
|
||||||
|
status : puint32;
|
||||||
|
disk : PStorage_device;
|
||||||
|
|
||||||
begin //maybe increase buffer size by one?
|
begin //maybe increase buffer size by one?
|
||||||
push_trace('fat32.create_volume()');
|
push_trace('fat32.create_volume()');
|
||||||
|
|
||||||
|
disk := volume^.device;
|
||||||
|
|
||||||
// zeroBuffer:= puint32(kalloc( disk^.sectorSize * 4 ));
|
// zeroBuffer:= puint32(kalloc( disk^.sectorSize * 4 ));
|
||||||
// memset(uint32(zeroBuffer), 0, disk^.sectorSize * 4);
|
// memset(uint32(zeroBuffer), 0, disk^.sectorSize * 4);
|
||||||
|
|
||||||
@ -813,7 +822,7 @@ begin //maybe increase buffer size by one?
|
|||||||
bootRecord^.jmp2boot := $0; //TODO impliment boot jump
|
bootRecord^.jmp2boot := $0; //TODO impliment boot jump
|
||||||
bootRecord^.OEMName := asuroArray;
|
bootRecord^.OEMName := asuroArray;
|
||||||
bootRecord^.sectorSize := disk^.sectorsize;
|
bootRecord^.sectorSize := disk^.sectorsize;
|
||||||
bootRecord^.spc := config^;
|
bootRecord^.spc := 1;
|
||||||
bootRecord^.rsvSectors := 32; //32 is standard
|
bootRecord^.rsvSectors := 32; //32 is standard
|
||||||
bootRecord^.numFats := 1;
|
bootRecord^.numFats := 1;
|
||||||
bootRecord^.mediaDescp := $F8;
|
bootRecord^.mediaDescp := $F8;
|
||||||
@ -875,8 +884,16 @@ begin //maybe increase buffer size by one?
|
|||||||
|
|
||||||
disk^.writecallback(disk, dataStart + (config^ * rootCluster), 1, buffer);
|
disk^.writecallback(disk, dataStart + (config^ * rootCluster), 1, buffer);
|
||||||
|
|
||||||
|
memset(uint32(buffer), 0, disk^.sectorsize);
|
||||||
|
|
||||||
|
status := puint32(kalloc(sizeof(uint32)));
|
||||||
|
writeDirectory(volume, '', sysArray, $10, status, '');
|
||||||
|
|
||||||
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure detect_volumes(disk : PStorage_Device);
|
procedure detect_volumes(disk : PStorage_Device);
|
||||||
@ -926,7 +943,6 @@ begin
|
|||||||
filesystem.detectcallback:= @detect_volumes;
|
filesystem.detectcallback:= @detect_volumes;
|
||||||
filesystem.writecallback:= @writeFile;
|
filesystem.writecallback:= @writeFile;
|
||||||
filesystem.readcallback := @readFile;
|
filesystem.readcallback := @readFile;
|
||||||
// filesystem.formatVolumeCallback := @create_volume;
|
|
||||||
|
|
||||||
volumemanager.register_filesystem(@filesystem);
|
volumemanager.register_filesystem(@filesystem);
|
||||||
end;
|
end;
|
||||||
|
@ -25,7 +25,13 @@ interface
|
|||||||
uses
|
uses
|
||||||
tracer,
|
tracer,
|
||||||
strings,
|
strings,
|
||||||
volumemanager;
|
volumemanager,
|
||||||
|
lists,
|
||||||
|
console,
|
||||||
|
terminal,
|
||||||
|
storagetypes,
|
||||||
|
lmemorymanager,
|
||||||
|
util;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -35,14 +41,15 @@ type
|
|||||||
version: uint16;
|
version: uint16;
|
||||||
sectorCount : uint16;
|
sectorCount : uint16;
|
||||||
fileCount : uint16;
|
fileCount : uint16;
|
||||||
signature : uint32 = $0B00B1E5;
|
signature : uint32;
|
||||||
end;
|
end;
|
||||||
PDisk_Info = ^TDisk_Info;
|
PDisk_Info = ^TDisk_Info;
|
||||||
|
|
||||||
TFile_Entry = packed record
|
TFile_Entry = bitpacked record
|
||||||
name: array[0..59] of char;
|
attribues : uint8; // 0x00 = does not exsist, 0x01 = file, 0x02 = hidden, 0x04 = system/read only, 0x10 = directory, 0x20 = archive
|
||||||
size: uint16;
|
name: array[0..54] of char; //max file name length is 55
|
||||||
start : uint16;
|
size: uint32;
|
||||||
|
start : uint32;
|
||||||
end;
|
end;
|
||||||
PFile_Entry = ^TFile_Entry;
|
PFile_Entry = ^TFile_Entry;
|
||||||
|
|
||||||
@ -51,11 +58,344 @@ var
|
|||||||
|
|
||||||
|
|
||||||
procedure init;
|
procedure init;
|
||||||
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
|
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||||
procedure detect_volumes(disk : PStorage_Device);
|
procedure detect_volumes(disk : PStorage_Device);
|
||||||
|
function read_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||||
|
var
|
||||||
|
info : PDisk_Info;
|
||||||
|
entryTable : PFile_Entry;
|
||||||
|
i : uint32;
|
||||||
|
|
||||||
|
directories : PLinkedListBase;
|
||||||
|
status : PuInt32;
|
||||||
|
|
||||||
|
const
|
||||||
|
asuroArray : array[0..7] of char = 'ASURO';
|
||||||
|
systemArray : array[0..6] of char = '/system';
|
||||||
|
programsArray : array[0..8] of char = '/programs';
|
||||||
|
userArray : array[0..4] of char = '/user';
|
||||||
|
begin
|
||||||
|
|
||||||
|
info := PDisk_Info(Kalloc(512));
|
||||||
|
memset(uint32(info), 0, 512);
|
||||||
|
|
||||||
|
info^.jmp2boot := $0;
|
||||||
|
info^.OEMName := asuroArray;
|
||||||
|
info^.version := 1;
|
||||||
|
info^.sectorCount := sectors;
|
||||||
|
info^.fileCount := 1000;
|
||||||
|
info^.signature := $0B00B1E5;
|
||||||
|
|
||||||
|
if config^ <> 0 then begin
|
||||||
|
info^.fileCount := config^;
|
||||||
|
end;
|
||||||
|
|
||||||
|
volume^.device^.writeCallback(volume^.device, start, 1, PuInt32(info));// what happens if buffer is smaller than 512?
|
||||||
|
|
||||||
|
// create file table
|
||||||
|
entryTable := PFile_Entry(Kalloc(126 * 512));
|
||||||
|
memset(uint32(entryTable), 0, 126 * 512);
|
||||||
|
|
||||||
|
//create system folders
|
||||||
|
entryTable[0].attribues := $10;
|
||||||
|
memcpy(uint32(@systemArray), uint32(@entryTable[0].name), 7);
|
||||||
|
entryTable[0].size := 0;
|
||||||
|
entryTable[0].start := 0;
|
||||||
|
|
||||||
|
entryTable[1].attribues := $10;
|
||||||
|
memcpy(uint32(@programsArray), uint32(@entryTable[1].name), 9);
|
||||||
|
entryTable[1].size := 0;
|
||||||
|
entryTable[1].start := 0;
|
||||||
|
|
||||||
|
entryTable[2].attribues := $10;
|
||||||
|
memcpy(uint32(@userArray), uint32(@entryTable[2].name), 5);
|
||||||
|
entryTable[2].size := 0;
|
||||||
|
entryTable[2].start := 0;
|
||||||
|
|
||||||
|
//write file table
|
||||||
|
// volume^.device^.writeCallback(volume^.device, start + 1, ((sizeof(TFile_Entry) * info^.fileCount) div 512), puint32(entryTable));
|
||||||
|
volume^.device^.writeCallback(volume^.device, start + 1, 1, puint32(entryTable));
|
||||||
|
|
||||||
|
//temp read
|
||||||
|
status := PuInt32(Kalloc(sizeof(uint32)));
|
||||||
|
directories := read_directory(volume, '/', status);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure write_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32);
|
||||||
|
var
|
||||||
|
directories : PLinkedListBase;
|
||||||
|
i : uint32;
|
||||||
|
|
||||||
|
fileEntry : PFile_Entry;
|
||||||
|
buffer : PuInt32;
|
||||||
|
|
||||||
|
position : uint32;
|
||||||
|
offset : uint32;
|
||||||
|
|
||||||
|
const
|
||||||
|
fileCount : uint32 = 1000;
|
||||||
|
begin
|
||||||
|
status^ = 0;
|
||||||
|
|
||||||
|
directories := read_directory(volume, directory, status);
|
||||||
|
|
||||||
|
if status^ = 0 then begin
|
||||||
|
for i := 0 to fileCount - 1 do begin
|
||||||
|
fileEntry := PFile_Entry(LL_Get(directories, i));
|
||||||
|
|
||||||
|
if fileEntry^.attribues = 0 then begin
|
||||||
|
fileEntry^.attribues := $10;
|
||||||
|
fileEntry^.size := 0;
|
||||||
|
fileEntry^.start := 0;
|
||||||
|
memcpy(uint32(@fileEntry^.name), uint32(@directory), strlen(directory));
|
||||||
|
|
||||||
|
//write file table
|
||||||
|
buffer := PuInt32(Kalloc(512));
|
||||||
|
memset(uint32(buffer), 0, 512);
|
||||||
|
|
||||||
|
//read file table cointaining entry of interest
|
||||||
|
position := (i * sizeof(TFile_Entry)) div 512;
|
||||||
|
volume^.device^.readCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||||
|
|
||||||
|
//calculate entry offset into sector
|
||||||
|
offset := (i * sizeof(TFile_Entry)) mod 512;
|
||||||
|
offset := offset div sizeof(TFile_Entry);
|
||||||
|
|
||||||
|
//set entry in buffer
|
||||||
|
PFile_Entry(buffer)[offset] := fileEntry^;
|
||||||
|
|
||||||
|
//write updated file table sector
|
||||||
|
volume^.device^.writeCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||||
|
|
||||||
|
Kfree(buffer);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if fileEntry^.attribues = 0 then begin
|
||||||
|
status^ := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
LL_Destroy(directories);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function read_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
|
||||||
|
var
|
||||||
|
directories : PLinkedListBase;
|
||||||
|
fileEntrys : PFile_Entry;
|
||||||
|
i : uint32;
|
||||||
|
|
||||||
|
compString : PChar;
|
||||||
|
afterString : PChar;
|
||||||
|
compStringLength : uint32;
|
||||||
|
|
||||||
|
fileCount : uint32 = 1000;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
compString := pchar(kalloc(60));
|
||||||
|
memset(uint32(compString), 0, 60);
|
||||||
|
|
||||||
|
afterString := pchar(kalloc(60));
|
||||||
|
memset(uint32(afterString), 0, 60);
|
||||||
|
|
||||||
|
directories := STRLL_New();
|
||||||
|
|
||||||
|
fileEntrys := PFile_Entry(Kalloc(sizeof(TFile_Entry) * fileCount));
|
||||||
|
volume^.device^.readCallback(volume^.device, volume^.sectorStart + 1, sizeof(TFile_Entry) * fileCount div 512, puint32(fileEntrys));
|
||||||
|
|
||||||
|
for i := 0 to fileCount - 1 do begin
|
||||||
|
// if fileEntrys[i].attribues and $10 = $10 then begin
|
||||||
|
|
||||||
|
writestringlnWND(fileEntrys[i].name, getterminalhwnd());
|
||||||
|
|
||||||
|
compString := stringSub(fileEntrys[i].name, 0, stringSize(directory));
|
||||||
|
afterString := stringSub(fileEntrys[i].name, stringSize(directory), stringSize(fileEntrys[i].name)-1);
|
||||||
|
|
||||||
|
if stringEquals(compString, directory) and
|
||||||
|
(not stringContains(afterString, '/')) then begin
|
||||||
|
|
||||||
|
console.writestringlnWND(afterString, getTerminalHWND());
|
||||||
|
STRLL_Add(directories, afterString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Kfree(puint32(fileEntrys));
|
||||||
|
|
||||||
|
read_directory := directories;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure quicksort_start(list : PFile_Entry; begining : uint32; stop : uint32);
|
||||||
|
var
|
||||||
|
pivot : uint32;
|
||||||
|
i : uint32;
|
||||||
|
j : uint32;
|
||||||
|
temp : PLinkedListBase;
|
||||||
|
|
||||||
|
tempFileEntry : PFile_Entry;
|
||||||
|
begin
|
||||||
|
|
||||||
|
i:=begining;
|
||||||
|
j:=stop;
|
||||||
|
|
||||||
|
pivot := list[(begining + stop) div 2].start;
|
||||||
|
|
||||||
|
while i <= j do begin
|
||||||
|
while list[i].start < pivot do begin
|
||||||
|
i := i + 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
while list[j].start > pivot do begin
|
||||||
|
j := j - 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if i <= j then begin
|
||||||
|
tempFileEntry := list[i];
|
||||||
|
list[i] := list[j];
|
||||||
|
list[j] := tempFileEntry;
|
||||||
|
|
||||||
|
i := i + 1;
|
||||||
|
j := j - 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if begining < j then begin
|
||||||
|
quicksort_start(list, begining, j);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if i < stop then begin
|
||||||
|
quicksort_start(list, i, stop);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function find_free_space(volume : PStorage_Volume; size : uint32; status : PuInt32) : uint32;
|
||||||
|
var
|
||||||
|
fileEntrys : PFile_Entry;
|
||||||
|
fileEntry : TFile_Entry;
|
||||||
|
i : uint32;
|
||||||
|
fileCount : uint32 = 1000;
|
||||||
|
begin
|
||||||
|
fileEntrys := PFile_Entry(Kalloc(sizeof(TFile_Entry) * fileCount));
|
||||||
|
volume^.device^.readCallback(volume^.device, volume^.sectorStart + 1, sizeof(TFile_Entry) * fileCount div 512, puint32(fileEntrys));
|
||||||
|
|
||||||
|
//sort file table by start address using quicksort
|
||||||
|
quicksort(fileEntrys, 0, fileCount - 1);
|
||||||
|
|
||||||
|
//find free space big enough to fit size
|
||||||
|
for i := 0 to fileCount - 1 do begin
|
||||||
|
if fileEntrys[i+1].start - (fileEntrys[i].start + fileEntrys[i].size) > size+1 then begin
|
||||||
|
find_free_space := fileEntrys[i].start + fileEntrys[i].size;
|
||||||
|
status^ := 0;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Kfree(puint32(fileEntrys));
|
||||||
|
|
||||||
|
find_free_space := freeSpace;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure write_file(volume : PStorage_Volume; fileName : pchar; data : PuInt32; size : uint32; status : PuInt32);
|
||||||
|
var
|
||||||
|
directories : PLinkedListBase;
|
||||||
|
i : uint32;
|
||||||
|
|
||||||
|
fileEntry : PFile_Entry;
|
||||||
|
buffer : PuInt32;
|
||||||
|
|
||||||
|
position : uint32;
|
||||||
|
offset : uint32;
|
||||||
|
|
||||||
|
fileCount : uint32 = 1000;
|
||||||
|
|
||||||
|
exsists : boolean;
|
||||||
|
begin
|
||||||
|
|
||||||
|
//load file table
|
||||||
|
directories := read_directory(volume, '/', status);
|
||||||
|
|
||||||
|
|
||||||
|
//check if file exists else find free entry
|
||||||
|
for i := 0 to fileCount - 1 do begin
|
||||||
|
fileEntry := PFile_Entry(LL_Get(directories, i));
|
||||||
|
|
||||||
|
if stringEquals(fileEntry^.name, fileName) then begin
|
||||||
|
exsists := true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if fileEntry^.attribues = 0 then begin
|
||||||
|
exsists := false;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//if entry is directory then exit
|
||||||
|
if fileEntry^.attribues and $10 = $10 then begin
|
||||||
|
status^ := 1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//allocate file table
|
||||||
|
buffer := PuInt32(Kalloc(512));
|
||||||
|
memset(uint32(buffer), 0, 512);
|
||||||
|
|
||||||
|
//read file table cointaining entry of interest
|
||||||
|
position := (i * sizeof(TFile_Entry)) div 512;
|
||||||
|
volume^.device^.readCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||||
|
|
||||||
|
//calculate entry offset into sector
|
||||||
|
offset := (i * sizeof(TFile_Entry)) mod 512;
|
||||||
|
offset := offset div sizeof(TFile_Entry);
|
||||||
|
|
||||||
|
//if file exists update entry else create new entry
|
||||||
|
if exsists then do begin
|
||||||
|
//check if size is greater than current size
|
||||||
|
if size > fileEntry^.size then begin
|
||||||
|
//find free space
|
||||||
|
fileEntry^.start := find_free_space(volume, size);
|
||||||
|
fileEntry^.size := size;
|
||||||
|
end else begin
|
||||||
|
//update size
|
||||||
|
fileEntry^.size := size;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
//find free space
|
||||||
|
fileEntry^.start := find_free_space(volume, size);
|
||||||
|
fileEntry^.size := size;
|
||||||
|
fileEntry^.attribues := $01;
|
||||||
|
|
||||||
|
//add file name
|
||||||
|
fileEntry^.name := fileName;
|
||||||
|
|
||||||
|
//add file to table
|
||||||
|
LL_Add(directories, fileEntry);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//write file table
|
||||||
|
volume^.device^.writeCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||||
|
|
||||||
|
//write file
|
||||||
|
volume^.device^.writeCallback(volume^.device, fileEntry^.start, size div 512 + 1, data);
|
||||||
|
|
||||||
|
//free buffer
|
||||||
|
Kfree(puint32(buffer));
|
||||||
|
|
||||||
|
//free directories
|
||||||
|
LL_Free(directories);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure detect_volumes(disk : PStorage_Device);
|
procedure detect_volumes(disk : PStorage_Device);
|
||||||
var
|
var
|
||||||
buffer : puint32;
|
buffer : puint32;
|
||||||
@ -92,14 +432,14 @@ end;
|
|||||||
procedure init();
|
procedure init();
|
||||||
begin
|
begin
|
||||||
push_trace('flatfs.init()');
|
push_trace('flatfs.init()');
|
||||||
filesystem.sName:= 'FlatFS';
|
filesystem.sName:= 'flatfs';
|
||||||
filesystem.system_id:= $02;
|
filesystem.system_id:= $02;
|
||||||
filesystem.readDirCallback:= @readDirectoryGen;
|
filesystem.readDirCallback:= @read_directory;
|
||||||
filesystem.createDirCallback:= @writeDirectoryGen;
|
// filesystem.createDirCallback:= @writeDirectoryGen;
|
||||||
filesystem.createcallback:= @create_volume;
|
filesystem.createcallback:= @create_volume;
|
||||||
filesystem.detectcallback:= @detect_volumes;
|
filesystem.detectcallback:= @detect_volumes;
|
||||||
filesystem.writecallback:= @writeFile;
|
// filesystem.writecallback:= @writeFile;
|
||||||
filesystem.readcallback := @readFile;
|
// filesystem.readcallback := @readFile;
|
||||||
// filesystem.formatVolumeCallback := @create_volume;
|
// filesystem.formatVolumeCallback := @create_volume;
|
||||||
|
|
||||||
volumemanager.register_filesystem(@filesystem);
|
volumemanager.register_filesystem(@filesystem);
|
||||||
|
@ -44,7 +44,7 @@ type
|
|||||||
PPWriteHook = procedure(volume : PStorage_volume; directory : pchar; entry : PDirectory_Entry; byteCount : uint32; buffer : puint32; statusOut : puint32);
|
PPWriteHook = procedure(volume : PStorage_volume; directory : pchar; entry : PDirectory_Entry; byteCount : uint32; buffer : puint32; statusOut : puint32);
|
||||||
PPReadHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; fileExtension : pchar; buffer : puint32; bytecount : puint32) : uint32;
|
PPReadHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; fileExtension : pchar; buffer : puint32; bytecount : puint32) : uint32;
|
||||||
PPHIOHook = procedure(volume : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
|
PPHIOHook = procedure(volume : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
|
||||||
PPCreateHook = procedure(disk : PStorage_Device; start : uint32; size : uint32; config : puint32);
|
PPCreateHook = procedure(volume : PStorage_volume; start : uint32; size : uint32; config : puint32);
|
||||||
PPDetectHook = procedure(disk : PStorage_Device);
|
PPDetectHook = procedure(disk : PStorage_Device);
|
||||||
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32);
|
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32);
|
||||||
PPReadDirHook = function(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
|
PPReadDirHook = function(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
|
||||||
@ -290,6 +290,22 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure remove_volume(list : PLinkedListBase; volume : PStorage_Volume);
|
||||||
|
var
|
||||||
|
i : uint32;
|
||||||
|
elm : void;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i:=0 to LL_Size(list) - 1 do begin
|
||||||
|
elm := LL_Get(list, i);
|
||||||
|
if (PStorage_Volume(elm)^.device = volume^.device)
|
||||||
|
and (PStorage_Volume(elm)^.sectorStart = volume^.sectorStart) then begin
|
||||||
|
LL_Delete(list, i);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure create_volume(disk : PStorage_device; filesystem : PChar; sectorStart : uint32; sectorCount : uint32);
|
procedure create_volume(disk : PStorage_device; filesystem : PChar; sectorStart : uint32; sectorCount : uint32);
|
||||||
var
|
var
|
||||||
volume : PStorage_Volume;
|
volume : PStorage_Volume;
|
||||||
@ -298,10 +314,12 @@ var
|
|||||||
config : PuInt32;
|
config : PuInt32;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
push_trace('VolumeManager.create_volume');
|
||||||
|
|
||||||
volume := PStorage_Volume(kalloc(SizeOf(TStorage_Volume)));
|
volume := PStorage_Volume(kalloc(SizeOf(TStorage_Volume)));
|
||||||
volume^.device := disk;
|
volume^.device := disk;
|
||||||
volume^.sectorStart := sectorStart;
|
volume^.sectorStart := sectorStart;
|
||||||
volume^.sectorCount := sectorCount - 10; //-10 is temp also in storagemanager
|
volume^.sectorCount := sectorCount - 10;
|
||||||
volume^.sectorSize := disk^.sectorSize;
|
volume^.sectorSize := disk^.sectorSize;
|
||||||
volume^.freeSectors := 0; //setup by filesystem
|
volume^.freeSectors := 0; //setup by filesystem
|
||||||
|
|
||||||
@ -312,17 +330,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
//format volume
|
//format volume
|
||||||
volume^.filesystem^.createCallback(disk, sectorStart, sectorCount, config);
|
volume^.filesystem^.createCallback(volume, sectorCount, sectorStart, config);
|
||||||
|
|
||||||
|
push_trace('VolumeManager.create_volume.2');
|
||||||
|
|
||||||
|
//remove volume from list of volumes
|
||||||
|
remove_volume(storageVolumes, volume);
|
||||||
|
|
||||||
//add volume to list
|
//add volume to list
|
||||||
elm := LL_Add(storageVolumes);
|
elm := LL_Add(storageVolumes);
|
||||||
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
|
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
|
||||||
|
|
||||||
|
push_trace('VolumeManager.create_volume.3');
|
||||||
|
|
||||||
|
//remove volume from list of volumes on device
|
||||||
|
remove_volume(disk^.volumes, volume);
|
||||||
|
|
||||||
//add volume to device
|
//add volume to device
|
||||||
elm := LL_Add(disk^.volumes);
|
elm := LL_Add(disk^.volumes);
|
||||||
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
|
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
|
||||||
|
|
||||||
|
//free memory
|
||||||
|
kfree(puint32(volume));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
|
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
|
||||||
|
@ -46,6 +46,7 @@ uses
|
|||||||
lists,
|
lists,
|
||||||
net,
|
net,
|
||||||
fat32,
|
fat32,
|
||||||
|
flatfs,
|
||||||
isrmanager,
|
isrmanager,
|
||||||
faults,
|
faults,
|
||||||
fonts,
|
fonts,
|
||||||
@ -218,6 +219,7 @@ begin
|
|||||||
|
|
||||||
{ Filsystems }
|
{ Filsystems }
|
||||||
fat32.init();
|
fat32.init();
|
||||||
|
flatfs.init();
|
||||||
|
|
||||||
{ Device Drivers }
|
{ Device Drivers }
|
||||||
tracer.push_trace('kmain.DEVDRV');
|
tracer.push_trace('kmain.DEVDRV');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user