Restructuring and expanding storage system.

This commit is contained in:
Aaron Hance 2021-06-23 21:22:06 +01:00
parent b18c9384b3
commit ba38f4fd19
6 changed files with 461 additions and 6 deletions

View File

@ -21,7 +21,8 @@ uses
lmemorymanager, lmemorymanager,
storagemanagement, storagemanagement,
strings, strings,
tracer; tracer,
drivemanager;
type type
TPortMode = (P_READ, P_WRITE); TPortMode = (P_READ, P_WRITE);
@ -267,6 +268,7 @@ var
slaveDevice : TStorage_Device; slaveDevice : TStorage_Device;
buffer : puint8; buffer : puint8;
i : uint8; i : uint8;
test : PStorage_device;
begin begin
push_trace('ide.load'); push_trace('ide.load');
console.writestringln('[IDE] (LOAD) BEGIN'); console.writestringln('[IDE] (LOAD) BEGIN');
@ -288,14 +290,15 @@ begin
exit; exit;
end; end;
masterDevice.hpc:= uint32(IDEDevices[0].info[3] DIV IDEDevices[0].info[1]); // masterDevice.hpc:= uint32(IDEDevices[0].info[3] DIV IDEDevices[0].info[1]); //TODO wtf is hpc
masterDevice.sectorSize:= 512; masterDevice.sectorSize:= 512;
if masterDevice.maxSectorCount <> 0 then begin if masterDevice.maxSectorCount <> 0 then begin
IDEDevices[0].exists:= true; IDEDevices[0].exists:= true;
masterDevice.readCallback:= @dread; masterDevice.readCallback:= @dread;
masterDevice.writeCallback:= @dwrite; masterDevice.writeCallback:= @dwrite;
storagemanagement.register_device(@masterDevice); // storagemanagement.register_device(@masterDevice);
drivemanager.register_device(@masterDevice);
end; end;
end; end;

View File

@ -0,0 +1,84 @@
{
Driver->Storage->MBR Master boot record
@author(Aaron Hance ah@aaronhance.me)
}
unit mbr;
interface
uses
tracer;
type
PMaster_Boot_Record = ^TMaster_Boot_Record;
PPartition_table = ^TPartition_table;
TPartition_table = bitpacked record
attributes : uint8;
CHS_start : array[0..2] of uint8;
system_id : uint8;
CHS_end : array[0..2] of uint8;
LBA_start : uInt32;
sector_count : uInt32;
end;
TMaster_Boot_Record = bitpacked record
bootstrap : array[0..439] of uint8;
signature : uint32;
rsv : uint16;
partition_0 : TPartition_table;
partition_1 : TPartition_table;
partition_2 : TPartition_table;
partition_3 : TPartition_table;
boot_sector : uint16;
end;
T24bit = array[0..2] of uint8;
function get_bootable(partition_table : PPartition_table) : boolean;
procedure set_bootable(partition_table : PPartition_table);
procedure setup_partition(partition_table : PPartition_table; address : uint32; sectorSize : uint32);
implementation
{ convert LBA address to CHS address}
function LBA_2_CHS(lba : uint32) : T24bit;
var
dat : T24bit;
begin
//TODO impliment procedure
LBA_2_CHS := dat;
end;
{ Set a partition struct to be bootable}
procedure set_bootable(partition_table : PPartition_table);
begin
push_trace('MBR.set_bootable');
//set the bootble bit in attributes
partition_table^.attributes := (partition_table^.attributes and $80);
end;
{ Check a partitions bootable bit }
function get_bootable(partition_table : PPartition_table) : boolean;
begin
push_trace('MBR.get_bootable');
//get the bootble bit in attributes
get_bootable := (partition_table^.attributes and $80) = $80;
end;
{ Setup a partition table struct }
procedure setup_partition(partition_table : PPartition_table; address : uint32; sectorSize : uint32);
begin
push_trace('MBR.setup_partition');
//set values in both LBA and CHS addressing schemes
partition_table^.LBA_start := address;
partition_table^.sector_count := sectorSize;
partition_table^.CHS_start := LBA_2_CHS(address);
partition_table^.CHS_start := LBA_2_CHS(address + sectorSize);
push_trace('MBR.setup_partition.end');
end;
end.

View File

@ -0,0 +1,226 @@
{
Driver->Storage->DriveManager Physical storage device manager
@author(Aaron Hance ah@aaronhance.me)
}
unit drivemanager;
interface
uses
util,
drivertypes,
console,
terminal,
drivermanagement,
lmemorymanager,
strings,
lists,
tracer,
rtc,
MBR,
serial;
type
TControllerType = (ControllerIDE, ControllerUSB, ControllerAHCI,
ControllerNET, ControllerRAM, rsvctr1, rsvctr2, rsvctr3);
PStorage_device = ^TStorage_Device;
PDrive_Error = ^TDrive_Error;
// 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;
// PPCreateHook = procedure(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
// PPDetectHook = procedure(disk : PStorage_Device);
// 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
PPHIOHook = procedure(drive : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
PPHIOHook_ = procedure;
{ Generic storage device }
TStorage_Device = record
id : uint8;
controller : TControllerType;
controllerId0 : uint32;
writable : boolean;
volumes : PLinkedListBase;
writeCallback : PPHIOHook;
readCallback : PPHIOHook;
maxSectorCount : uint32;
sectorSize : uint32;
end;
TDrive_Error = record
code : uint16;
description : pchar;
recoverable : boolean;
end;
var
storageDevices : PLinkedListBase; //index in this array is global drive id
procedure init();
procedure register_device(device : PStorage_Device);
function get_drive_list() : PLinkedListBase;
function controller_type_2_string(controllerType : TControllerType) : pchar;
implementation
procedure list_drive_command();
var
i : uint32 = 0;
begin
push_trace('DriverManager.list_drive_command');
//if no storage device print none found
if LL_Size(storageDevices) < 1 then begin
console.writestringlnWnd('No storage devices found.', getTerminalHWND());
exit;
end;
//print number of storage devices
console.writeintwnd(LL_Size(storageDevices), getTerminalHWND());
console.writestringlnWnd(' devices found', getTerminalHWND());
for i:=0 to LL_Size(storageDevices)-1 do begin
//print device id and type
console.writeintwnd(i, getTerminalHWND());
console.writestringwnd(' - Device type: ', getTerminalHWND());
console.writestringwnd(controller_type_2_string(PStorage_Device(LL_Get(storageDevices, i))^.controller), getTerminalHWND());
console.writestringwnd(', ', getTerminalHWND());
//print device capcity
console.writestringwnd(' Capacity: ', getTerminalHWND());
console.writeintwnd((( PStorage_Device(LL_Get(storageDevices, i))^.maxSectorCount * PStorage_Device(LL_Get(storageDevices, i))^.sectorSize) DIV 1024) DIV 1024, getTerminalHWND());
console.writestringlnWnd('MB', getTerminalHWND());
end;
end;
{ initalise a drive with a MBR - TODO needs to be expanded for partitioning }
procedure init_drive_command(driveIndex : uint32);
var
bootrecord : PMaster_Boot_Record;
partition : PPartition_table;
drive : PStorage_device;
begin
push_trace('DriverManager.init_drive_command');
//setup MBR and partition table
bootrecord := PMaster_Boot_record(kalloc(SizeOf(TMaster_boot_record)));
partition := PPartition_table(kalloc(SizeOf(TPartition_table)));
drive := PStorage_device(LL_Get(storageDevices, driveIndex));
MBR.setup_partition(partition, 100, drive^.maxSectorCount-300);
bootrecord^.partition_0 := partition^;
//write MBR and partition table to disk
drive^.writeCallback(drive, 0, 1, puint32(bootrecord));
//volume_manager reload partition
//TODO
end;
procedure drive_command(params : PParamList);
var
i : uint16;
drive : uint16;
subcmd : pchar;
begin
push_trace('DriverManager.drive_command');
subcmd:= getParam(0, params);
if ((paramCount(params) = 0)) then begin
console.writestringlnWnd('Please provide valid arguments.', getTerminalHWND());
console.writestringlnWnd(' ls - for listing all drives', getTerminalHWND());
console.writestringlnWnd(' info [drive] - display formation for specified drive', getTerminalHWND());
console.writestringlnWnd(' init [drive] - destructive, formats a drive with a blank partition', getTerminalHWND());
exit;
end;
if( stringEquals(subcmd, 'ls') ) then begin
list_drive_command();
exit;
end;
if( stringEquals(subcmd, 'info') ) then begin
//TODO unimplimented
exit
end;
if( stringEquals(subcmd, 'init') ) then begin
init_drive_command(stringToInt(getParam(1, params) ) );
exit
end;
end;
{ Initialise the drive manager }
procedure init();
begin
push_trace('DriveManager.init');
//setup drive manager
setworkingdirectory('.');
storageDevices:= ll_new(sizeof(TStorage_Device));
serial.sendString('HERE I DID THE INIT WAH DU HEK BRUH!!!!!!');
//register DISK command
terminal.registerCommand('DISK', @drive_command, 'Disk utility');
end;
{ Register a new drive with the drive manager }
procedure register_device(device : PStorage_device);
var
i : uint8;
elm : void;
begin
push_trace('DriveManager.register_device');
//add the drive to the list of storage devices.
elm:= LL_Add(storageDevices);
PStorage_device(elm)^ := device^; //TODO memcopy
//set drive id in struct
PStorage_device(elm)^.id := LL_Size(storageDevices) - 1;
//create empty volume list for drive
// PStorage_Device(LL_Get(storageDevices, LL_Size(storageDevices) - 1))^.volumes := LL_New(sizeof(TStorage_Volume));
//TODO register with volume manager
end;
{ Get the drive list }
function get_drive_list() : PLinkedListBase;
begin
push_trace('DriverManager.get_drive_list');
//return the device list
get_drive_list:= storageDevices;
end;
{ Get string name for controller type }
function controller_type_2_string(controllerType : TControllerType) : pchar;
begin
push_trace('DriverManager.controller_type_2_string');
//return string of controller type
case controllerType of
ControllerIDE : controller_type_2_string:= 'IDE';
ControllerUSB : controller_type_2_string:= 'USB';
ControllerAHCI : controller_type_2_string:= 'ACHI (SATA)';
ControllerNET : controller_type_2_string:= 'Net';
end;
end;
function write_2_drive(drive : uint32; address : uint32; byteSize : uint32; buffer : puint32) : PDrive_Error;
begin
end;
end.

View File

@ -234,7 +234,8 @@ begin
fileSystems:= ll_New(sizeof(TFilesystem)); fileSystems:= ll_New(sizeof(TFilesystem));
terminal.registerCommand('DISK', @disk_command, 'Disk utility'); terminal.registerCommand('DISK', @disk_command, 'Disk utility');
pop_trace();
end; end;
{ Register a new drive with the storage manager } { Register a new drive with the storage manager }

View File

@ -0,0 +1,137 @@
{
Driver->Storage->VolumeManager Drive volume manager
@author(Aaron Hance ah@aaronhance.me)
}
unit volumemanager;
interface
uses
util,
console,
drivemanager,
strings,
lists,
tracer,
vfs,
MBR;
type
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
PDirectory_Entry = ^TDirectory_Entry;
PFilesystem = ^TFilesystem;
PStorage_Volume = ^TStorage_Volume;
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;
PPHIOHook = procedure(volume : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
PPCreateHook = procedure(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
PPDetectHook = procedure(disk : PStorage_Device);
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
PPHIOHook_ = procedure;
TFilesystem = record
sName : pchar;
system_id : uint8;
writeCallback : PPWriteHook;
readCallback : PPReadHook;
createCallback : PPCreateHook;
detectCallback : PPDetectHook;
createDirCallback : PPCreateDirHook;
readDirCallback : PPReadDirHook;
end;
TStorage_Volume = record
device : PStorage_device;
sectorStart : uint32;
sectorSize : uint32;
sectorCount : uint32;
freeSectors : uint32;
filesystem : PFilesystem;
{ True if this drive contains the loaded OS }
isBootDrive : boolean;
end;
{ Generic directory entry }
TDirectory_Entry = record
{ Contains filename and optionally file extension, seperated by the last period.}
fileName : pchar;
entryType : TDirectory_Entry_Type;
// creationT : TDateTime;
// modifiedT : TDateTime;
end;
var
storageVolumes : PLinkedListBase;
filesystems : PlinkedListBase;
procedure init();
procedure register_filesystem(filesystem : PFilesystem);
procedure check_for_volumes(drive : PStorage_device);
//IO functions
implementation
{ Initialise volume manager }
procedure init();
begin
push_trace('VolumeManager.init');
{ setup lists }
storageVolumes:= ll_New(sizeof(TFilesystem));
filesystems:= ll_New(sizeof(TFilesystem));
end;
{ register a new type of filesystem }
procedure register_filesystem(filesystem : PFilesystem); //TODO on init create null filesystem for empty partition
begin
//add filesystem
//check drives for volumes of new type
end;
{ Check for volumes on a physical device }
procedure check_for_volumes(drive : PStorage_device);
var
bootrecord : PMaster_Boot_Record;
storageVolume : TStorage_Volume;
i : uint32 = 0;
elm : void;
begin
drive^.readCallback(drive, 0, 1, puint32(bootrecord));
//TODO multipe partition entries
if bootrecord^.partition_0.LBA_start <> 0 then
begin
//set volume information
storageVolume.device := drive;
storageVolume.sectorStart := bootrecord^.partition_0.LBA_start;
storageVolume.sectorCount := bootrecord^.partition_0.sector_count;
storageVolume.freeSectors := 0; //TODO impliment
//check for filesystem type
for i:=0 to LL_Size(filesystems) - 1 do begin
if bootrecord^.partition_0.system_id = PFilesystem(LL_Get(filesystems, i))^.system_id then
begin
storageVolume.filesystem := PFilesystem(LL_Get(filesystems, i));
end;
end;
//add volume to list
elm := LL_Add(storageVolumes);
memcpy(uint32(@storageVolume), uint32(elm), SizeOf(TStorage_Volume));
end;
end;
end.

View File

@ -41,6 +41,8 @@ uses
E1000, E1000,
IDE, IDE,
storagemanagement, storagemanagement,
drivemanager,
volumemanager,
lists, lists,
net, net,
fat32, fat32,
@ -205,7 +207,9 @@ begin
tracer.push_trace('kmain.DRVMGMT'); tracer.push_trace('kmain.DRVMGMT');
drivermanagement.init(); drivermanagement.init();
tracer.push_trace('kmain.STRMGMT'); tracer.push_trace('kmain.STRMGMT');
storagemanagement.init(); // storagemanagement.init();
drivemanager.init();
volumemanager.init();
{ Hook Timer for Ticks } { Hook Timer for Ticks }
tracer.push_trace('kmain.TMR'); tracer.push_trace('kmain.TMR');
@ -213,7 +217,7 @@ begin
TMR_0_ISR.hook(uint32(@bios_data_area.tick_update)); TMR_0_ISR.hook(uint32(@bios_data_area.tick_update));
{ Filsystems } { Filsystems }
fat32.init(); // fat32.init();
{ Device Drivers } { Device Drivers }
tracer.push_trace('kmain.DEVDRV'); tracer.push_trace('kmain.DEVDRV');