This commit is contained in:
Aaron Hance 2022-01-29 20:05:11 +00:00
parent da36f6fabb
commit e791edb02a
7 changed files with 334 additions and 63 deletions

2
.vscode/launch.json vendored
View File

@ -10,7 +10,7 @@
"--comment", "--comment",
"Asuro", "Asuro",
"--startvm", "--startvm",
"7d395c96-891c-4139-b77d-9b6b144b0b93" "0c971fec-6de7-42c0-a377-de11bb1cafa2"
], ],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"console": "internalConsole", "console": "internalConsole",

33
doc/flatfs.md Normal file
View File

@ -0,0 +1,33 @@
#Flat filesystem
A super simple filesystem for asuro. Folders are emulated in filenames.
Starts with disk info sector, sector 0 of volume
---
#### disk info
jmp2boot : ubit24;
OEMName : array[0..7] of char;
version : uint16 // numerical version of filesystem
sectorCount : uint16;
fileCount : uint16
signature : uint32 = 0xABAB1F1E
the Rest of the sector is reserved
---
Starting from sector 1 is the file table. Table size is determined by entry size (512) * fileCount
---
####File entry
name : array[0..59] of char //file name max 60 chars
fileStart : 16bit // start sector of data
fileSize : 16bit // data size in sectors
---

View File

@ -28,10 +28,7 @@ type
bootstrap : array[0..439] of uint8; bootstrap : array[0..439] of uint8;
signature : uint32; signature : uint32;
rsv : uint16; rsv : uint16;
partition_0 : TPartition_table; partition : array[0..3] of TPartition_table;
partition_1 : TPartition_table;
partition_2 : TPartition_table;
partition_3 : TPartition_table;
boot_sector : uint16; boot_sector : uint16;
end; end;

View File

@ -905,7 +905,7 @@ begin
if (puint32(buffer)[127] = $55AA) and (PBootRecord(buffer)^.bsignature = $29) then begin //TODO partition table if (puint32(buffer)[127] = $55AA) and (PBootRecord(buffer)^.bsignature = $29) then begin //TODO partition table
console.writestringln('FAT32: volume found!'); console.writestringln('FAT32: volume found!');
volume^.device:= disk; volume^.device:= disk;
volume^.sectorStart:= 1; volume^.sectorStart:= 1; //THIS MAKE SURE IF NOT FUCKY, cos im getting info from 2
volume^.sectorSize:= PBootRecord(buffer)^.sectorSize; volume^.sectorSize:= PBootRecord(buffer)^.sectorSize;
volume^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first volume^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first
volume^.filesystem := @filesystem; volume^.filesystem := @filesystem;
@ -919,13 +919,14 @@ procedure init();
begin begin
push_trace('fat32.init()'); push_trace('fat32.init()');
filesystem.sName:= 'FAT32'; filesystem.sName:= 'FAT32';
filesystem.system_id:= $00; filesystem.system_id:= $01;
filesystem.readDirCallback:= @readDirectoryGen; filesystem.readDirCallback:= @readDirectoryGen;
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;
volumemanager.register_filesystem(@filesystem); volumemanager.register_filesystem(@filesystem);
end; end;

View File

@ -0,0 +1,109 @@
// Copyright 2021 Aaron Hance
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Driver->Storage->flatfs super simple flat filesystem
@author(Aaron Hance ah@aaronhance.me)
}
unit flatfs;
interface
uses
tracer,
strings,
volumemanager;
type
TDisk_Info = bitpacked record
jmp2boot: ubit24;
OEMName: array[0..7] of char;
version: uint16;
sectorCount : uint16;
fileCount : uint16;
signature : uint32 = $0B00B1E5;
end;
PDisk_Info = ^TDisk_Info;
TFile_Entry = packed record
name: array[0..59] of char;
size: uint16;
start : uint16;
end;
PFile_Entry = ^TFile_Entry;
var
filesystem : TFilesystem;
procedure init;
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
procedure detect_volumes(disk : PStorage_Device);
implementation
procedure detect_volumes(disk : PStorage_Device);
var
buffer : puint32;
volume : PStorage_volume;
begin
push_trace('flatfs.detectVolumes()');
volume:= PStorage_volume(kalloc(sizeof(TStorage_Volume)));
//check first address for MBR
//if found then add volume and use info to see if there is another volume
buffer := puint32(kalloc(512));
memset(uint32(buffer), 0, 512);
disk^.readcallback(disk, 2, 1, buffer);
if (PDisk_Info(buffer)^.signature = $0B00B1E5) then begin
console.writestringln('FlatFS: volume found!');
volume^.device:= disk;
volume^.sectorStart:= 2;
volume^.sectorSize:= 512;
volume^.sectorCount:= PDisk_Info(buffer)^.sectorCount;
volume^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first
volume^.filesystem := @filesystem;
volume^.isBootDrive := false;
// storagemanagement.register_volume(disk, volume); TODO repalce with new thing
end;
kfree(buffer);
end;
procedure init();
begin
push_trace('flatfs.init()');
filesystem.sName:= 'FlatFS';
filesystem.system_id:= $02;
filesystem.readDirCallback:= @readDirectoryGen;
filesystem.createDirCallback:= @writeDirectoryGen;
filesystem.createcallback:= @create_volume;
filesystem.detectcallback:= @detect_volumes;
filesystem.writecallback:= @writeFile;
filesystem.readcallback := @readFile;
filesystem.formatVolumeCallback := @create_volume;
volumemanager.register_filesystem(@filesystem);
end;
end.

View File

@ -31,7 +31,9 @@ uses
strings, strings,
lists, lists,
tracer, tracer,
rtc; rtc,
MBR,
volumemanager;
type type
@ -54,26 +56,26 @@ type
PPHIOHook_ = procedure; PPHIOHook_ = procedure;
TFilesystem = record // TFilesystem = record
sName : pchar; // sName : pchar;
writeCallback : PPWriteHook; // writeCallback : PPWriteHook;
readCallback : PPReadHook; // readCallback : PPReadHook;
createCallback : PPCreateHook; // createCallback : PPCreateHook;
detectCallback : PPDetectHook; // detectCallback : PPDetectHook;
createDirCallback : PPCreateDirHook; // createDirCallback : PPCreateDirHook;
readDirCallback : PPReadDirHook; // readDirCallback : PPReadDirHook;
end; // end;
PFileSystem = ^TFilesystem; // PFileSystem = ^TFilesystem;
TStorage_Volume = record // TStorage_Volume = record
device : PStorage_device; // device : PStorage_device;
sectorStart : uint32; // sectorStart : uint32;
sectorSize : uint32; // sectorSize : uint32;
freeSectors : uint32; // freeSectors : uint32;
filesystem : PFilesystem; // filesystem : PFilesystem;
{ True if this drive contains the loaded OS } // { True if this drive contains the loaded OS }
isBootDrive : boolean; // isBootDrive : boolean;
end; // end;
{ Generic storage device } { Generic storage device }
TStorage_Device = record TStorage_Device = record
@ -89,6 +91,7 @@ type
hpc : uint16; hpc : uint16;
spt : uint16; spt : uint16;
end; end;
APStorage_Device = array[0..255] of PStorage_device; APStorage_Device = array[0..255] of PStorage_device;
{ Generic directory entry } { Generic directory entry }
@ -112,7 +115,7 @@ function get_device_list() : PLinkedListBase;
procedure register_filesystem(filesystem : PFilesystem); procedure register_filesystem(filesystem : PFilesystem);
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume); // procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
//function writeNewFile(fileName : pchar; extension : pchar; buffer : puint32; size : uint32) : uint32; //function writeNewFile(fileName : pchar; extension : pchar; buffer : puint32; size : uint32) : uint32;
//function readFile(fileName : pchar; extension : pchar; buffer : puint32; byteCount : puint32) : puint32; //function readFile(fileName : pchar; extension : pchar; buffer : puint32; byteCount : puint32) : puint32;
@ -171,16 +174,57 @@ var
filesystemString : pchar; filesystemString : pchar;
filesystem : PFileSystem; filesystem : PFileSystem;
spc : puint32; spc : puint32;
sectorCount : uint32;
volumeId : uint8;
mb : PMaster_Boot_Record;
i : uint32 = 0;
begin begin
//format <DRIVE_ID> <FILESYSTEM> <size>
spc:= puint32(kalloc(4)); spc:= puint32(kalloc(4));
spc^:= 4; spc^:= 1;
driveIndex:= stringToInt( getParam(1, params) ); driveIndex:= stringToInt( getParam(1, params) );
drive:= PStorage_Device(LL_Get(storageDevices, driveIndex)); drive:= PStorage_Device(LL_Get(storageDevices, driveIndex));
sectorCount := stringToInt( getParam(4, params) );
// if sector count is 0, use full drive
if sectorCount = 0 then begin
sectorCount = drive^.maxSectorCount - 10;
end;
//create MBR if none, and partition table
mb := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)));
mb := drive^.readCallback(drive, 0, 1);
//check if MBR exists
if not mb^.boot_sector = $55AA then begin
//create MBR
mb^.signature := $A570 + drive^.idx;
mb^.boot_sector := $55AA;
//create partition table
mbr.setup_partition(@mb^.partition[0], 2, sectorCount);
//write MBR
disk^.writeCallback(drive, 0, 1, mb);
end;
kfree(mb);
//setup volume
//todo change b4 adding in aniother filesytem //todo change b4 adding in aniother filesytem
PFilesystem(LL_Get(filesystems, 0))^.createCallback(drive, drive^.maxSectorCount-1, 1, spc); // PFilesystem(LL_Get(filesystems, 0))^.createCallback(drive, drive^.maxSectorCount-1, 1, spc);
writestringWnd('Drive ', getTerminalHWND); writestringWnd('Drive ', getTerminalHWND);
writeintWnd(driveIndex, getTerminalHWND); writeintWnd(driveIndex, getTerminalHWND);
@ -217,10 +261,6 @@ begin
format_command(params); format_command(params);
end; end;
//lsfs command for listing filesystems
if stringEquals(subcmd, 'lsfs') then begin
end;
pop_trace(); pop_trace();
end; end;
@ -231,11 +271,8 @@ begin
setworkingdirectory('.'); setworkingdirectory('.');
storageDevices:= ll_new(sizeof(TStorage_Device)); storageDevices:= ll_new(sizeof(TStorage_Device));
fileSystems:= ll_New(sizeof(TFilesystem));
terminal.registerCommand('DISK', @disk_command, 'Disk utility'); terminal.registerCommand('DISK', @disk_command, 'Disk utility');
end; end;
{ Register a new drive with the storage manager } { Register a new drive with the storage manager }
@ -254,9 +291,7 @@ begin
PStorage_Device(LL_Get(storageDevices, LL_Size(storageDevices) - 1))^.volumes := LL_New(sizeof(TStorage_Volume)); PStorage_Device(LL_Get(storageDevices, LL_Size(storageDevices) - 1))^.volumes := LL_New(sizeof(TStorage_Volume));
//check for volumes //check for volumes
for i:=0 to ll_size(filesystems) - 1 do begin
PFileSystem(LL_Get(filesystems, i))^.detectCallback(PStorage_Device(LL_Get(storageDevices, LL_Size(storageDevices) - 1)));
end;
pop_trace(); pop_trace();
end; end;
@ -266,23 +301,4 @@ begin
get_device_list:= storageDevices; get_device_list:= storageDevices;
end; end;
procedure register_filesystem(filesystem : PFilesystem);
var
elm : void;
begin
elm:= LL_Add(fileSystems);
PFileSystem(elm)^ := filesystem^;
end;
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
var
elm : void;
begin
push_trace('storagemanagement.register_volume');
elm := LL_Add(device^.volumes);
PStorage_volume(elm)^:= volume^;
if rootVolume = PStorage_Volume(0) then rootVolume:= volume;
end;
end. end.

View File

@ -48,6 +48,7 @@ type
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
PPFormatVolumeHook = procedure(disk : PStorage_device; sectorCount : uint32; start : uint32; config : puint32);
PPHIOHook_ = procedure; PPHIOHook_ = procedure;
@ -60,6 +61,7 @@ type
detectCallback : PPDetectHook; detectCallback : PPDetectHook;
createDirCallback : PPCreateDirHook; createDirCallback : PPCreateDirHook;
readDirCallback : PPReadDirHook; readDirCallback : PPReadDirHook;
formatVolumeCallback : PPFormatVolumeHook;
end; end;
TStorage_Volume = record TStorage_Volume = record
@ -96,6 +98,58 @@ var
implementation implementation
procedure format_volume_command(params : PParamList);
var
volume : PStorage_Volume;
filesystem : PFilesystem;
config : puint32;
begin
push_trace('VolumeManager.format_volume_command');
if paramCount(params) < 3 then begin
console.writestringlnWND('Invalid arguments', getTerminalHWND());
end;
push_trace('VolumeManager.format_volume_command.1');
volume := PStorage_volume(LL_get(storageVolumes, stringToInt(getParam(1, params))));
filesystem := PFilesystem(LL_get(filesystems, stringToInt(getParam(2, params))));
push_trace('VolumeManager.format_volume_command.2');
config := PuInt32(kalloc(sizeof(uInt32)));
config^ := 4;
push_trace('VolumeManager.format_volume_command.3');
//TODO check things exsist
console.writestringlnWND('Staring volume formatting...', getTerminalHWND());
filesystem^.formatVolumeCallback(volume^.device, volume^.sectorSize, volume^.sectorStart, config);
console.writestringlnWND('Volume format finished.', getTerminalHWND());
end;
procedure list_filesystems_command();
var
i : uint32;
filesystem : PFilesystem;
begin
push_trace('VolumeManager.list_filesystems_command');
if LL_Size(filesystems) < 1 then begin
console.writestringlnWnd('ERROR: no filesystems found!', getTerminalHWND());
exit;
end;
console.writestringlnWnd('Filesystems: ', getTerminalHWND());
for i:=0 to LL_Size(filesystems) - 1 do begin
filesystem := PFilesystem(LL_Get(filesystems, i));
console.writestringWnd(' ', getTerminalHWND());
console.writestringWnd(filesystem^.sName, getTerminalHWND());
console.writestringWnd(' - ', getTerminalHWND());
console.writehexlnWND(filesystem^.system_id, getTerminalHWND());
end;
end;
procedure list_volume_command(); procedure list_volume_command();
var var
i : uint32; i : uint32;
@ -116,9 +170,15 @@ begin
console.writestringWnd(' ', getTerminalHWND()); console.writestringWnd(' ', getTerminalHWND());
console.writeintWnd(i, getTerminalHWND()); console.writeintWnd(i, getTerminalHWND());
console.writestringWnd(' - Capacity: ', getTerminalHWND()); console.writestringWnd(' - Capacity: ', getTerminalHWND());
console.writeintWnd(uint32(volume^.sectorSize * volume^.sectorCount DIV 1024 DIV 1024), getTerminalHWND()); console.writeintWnd(uint32((volume^.sectorSize * volume^.sectorCount) DIV 1024 DIV 1024), getTerminalHWND());
console.writestringWnd('MB System: ', getTerminalHWND()); console.writestringWnd('MB, Filesystem: ', getTerminalHWND());
if volume^.filesystem <> nil then begin
console.writestringlnWnd(volume^.filesystem^.sName, getTerminalHWND()); console.writestringlnWnd(volume^.filesystem^.sName, getTerminalHWND());
end else begin
console.writestringlnWnd('None', getTerminalHWND());
end;
end; end;
end; end;
@ -143,6 +203,16 @@ begin
list_volume_command(); list_volume_command();
exit; exit;
end; end;
if( stringEquals(subcmd, 'lsfs') ) then begin
list_filesystems_command();
exit;
end;
if( stringEquals(subcmd, 'format') ) then begin
format_volume_command(params);
exit;
end;
end; end;
{ Initialise volume manager } { Initialise volume manager }
@ -189,8 +259,9 @@ begin
storageVolume.device := drive; storageVolume.device := drive;
storageVolume.sectorStart := bootrecord^.partition_0.LBA_start; storageVolume.sectorStart := bootrecord^.partition_0.LBA_start;
storageVolume.sectorCount := bootrecord^.partition_0.sector_count; storageVolume.sectorCount := bootrecord^.partition_0.sector_count;
storageVolume.sectorSize := drive^.sectorSize;
storageVolume.freeSectors := 0; //TODO impliment storageVolume.freeSectors := 0; //TODO impliment
push_trace('VolumeManager.init2'); storageVolume.filesystem := nil;
if LL_Size(filesystems) < 1 then begin if LL_Size(filesystems) < 1 then begin
console.writestringln('Failed to initalise storage system, no filesystems found, stopping!'); console.writestringln('Failed to initalise storage system, no filesystems found, stopping!');
@ -218,4 +289,48 @@ begin
end; end;
procedure create_volume(disk : PStorage_device; filesystem : PChar; sectorStart : uint32; sectorCount : uint32);
var
volume : PStorage_Volume;
elm : void;
begin
volume := PStorage_Volume(kalloc(SizeOf(TStorage_Volume)));
volume^.device := disk;
volume^.sectorStart := sectorStart;
volume^.sectorCount := sectorCount;
volume^.sectorSize := disk^.sectorSize;
volume^.freeSectors := 0; //TODO impliment
//find filesystem
for i:=0 to LL_Size(filesystems) - 1 do begin
if stringEquals(filesystem, PFilesystem(LL_Get(filesystems, i))^.sName) then begin
volume^.filesystem := PFilesystem(LL_Get(filesystems, i));
end;
end;
//format volume
volume^.filesystem^.formatVolumeCallback(disk, sectorStart, sectorCount, 0);
//add volume to list
elm := LL_Add(storageVolumes);
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
//add volume to device
elm := LL_Add(disk^.volumes);
memcpy(uint32(volume), uint32(elm), SizeOf(TStorage_Volume));
end;
procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
var
elm : void;
begin
push_trace('storagemanagement.register_volume');
elm := LL_Add(device^.volumes);
PStorage_volume(elm)^:= volume^;
if rootVolume = PStorage_Volume(0) then rootVolume:= volume;
end;
end. end.