working storage system
This commit is contained in:
1 parent
84b589c856
commit
81d1b97cd0
24 files changed
+1930
-2049
No files matched your search
@@ -0,0 +1 @@
|
||||
Hello from the Asuro ISO!
|
||||
+237
-216
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File renamed without changes.
File diff suppressed because it is too large.
Load diff
File renamed without changes.
@@ -768,7 +768,6 @@ begin
|
||||
elm := LL_Add(entries);
|
||||
dirEntry := PDirectory_Entry(elm);
|
||||
dirEntry^.fileName := stringCopy(afterString);
|
||||
dirEntry^.extension := nil;
|
||||
if fileEntrys[i].attribues and $10 = $10 then
|
||||
dirEntry^.entryType := TDirectory_Entry_Type.directoryEntry
|
||||
else
|
||||
File diff suppressed because it is too large.
Load diff
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -44,8 +44,27 @@ implementation
|
||||
function LBA_2_CHS(lba : uint32) : T24bit;
|
||||
var
|
||||
dat : T24bit;
|
||||
cylinder, head, sector : uint16;
|
||||
sectors_per_track : uint16;
|
||||
heads_per_cylinder : uint16;
|
||||
begin
|
||||
//TODO impliment procedure
|
||||
// Standard CHS geometry values
|
||||
sectors_per_track := 63;
|
||||
heads_per_cylinder := 255;
|
||||
|
||||
// Calculate CHS values from LBA
|
||||
sector := (lba mod sectors_per_track) + 1; // Sectors are 1-indexed
|
||||
head := (lba div sectors_per_track) mod heads_per_cylinder;
|
||||
cylinder := (lba div sectors_per_track) div heads_per_cylinder;
|
||||
|
||||
// Pack into MBR CHS format (3 bytes):
|
||||
// Byte 0: Head (8 bits)
|
||||
// Byte 1: Sector (bits 0-5) | Cylinder high 2 bits (bits 6-7)
|
||||
// Byte 2: Cylinder low 8 bits
|
||||
dat[0] := head;
|
||||
dat[1] := (sector and $3F) or ((cylinder shr 8) shl 6);
|
||||
dat[2] := (cylinder and $FF);
|
||||
|
||||
LBA_2_CHS := dat;
|
||||
end;
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,66 @@
|
||||
{
|
||||
Driver->Storage->IOBuffer - Safe IO buffer allocation helpers.
|
||||
|
||||
Provides correct-size buffer allocation tied to a volume's sector
|
||||
geometry so that callers never have to compute sizes by hand.
|
||||
|
||||
@author(Aaron Hance <[email protected]>)
|
||||
}
|
||||
unit iobuffer;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
lmemorymanager,
|
||||
storagetypes,
|
||||
tracer;
|
||||
|
||||
{ Allocate a buffer of at least `size` bytes.
|
||||
Returns a pointer to the allocated buffer, or nil on failure. }
|
||||
function AllocateIOBuffer(volume : PStorage_Volume; size : uint32) : puint32;
|
||||
|
||||
{ Free a buffer previously allocated by AllocateIOBuffer.
|
||||
Returns true if the buffer was freed successfully. }
|
||||
function FreeIOBuffer(buf : puint32) : boolean;
|
||||
|
||||
implementation
|
||||
|
||||
function AllocateIOBuffer(volume : PStorage_Volume; size : uint32) : puint32;
|
||||
var
|
||||
sectorSize : uint32;
|
||||
alignedSize : uint32;
|
||||
buf : puint32;
|
||||
begin
|
||||
tracer.push_trace('iobuffer.AllocateIOBuffer');
|
||||
AllocateIOBuffer := nil;
|
||||
|
||||
if volume = nil then exit;
|
||||
if size = 0 then exit;
|
||||
|
||||
{ Round up to a whole number of sectors so DMA / block I/O is safe }
|
||||
sectorSize := volume^.device^.sectorSize; //TODO need fileystsem function to get thing size, like cluster size, for file-level IO buffer allocation. For now we just assume sector size.
|
||||
if sectorSize = 0 then
|
||||
sectorSize := 512;
|
||||
|
||||
sectorSize := 512*4; { safe default } //TODO
|
||||
|
||||
alignedSize := ((size + sectorSize - 1) div sectorSize) * sectorSize;
|
||||
|
||||
buf := puint32(kalloc(alignedSize));
|
||||
if buf = nil then exit;
|
||||
|
||||
AllocateIOBuffer := buf;
|
||||
end;
|
||||
|
||||
function FreeIOBuffer(buf : puint32) : boolean;
|
||||
begin
|
||||
tracer.push_trace('iobuffer.FreeIOBuffer');
|
||||
FreeIOBuffer := false;
|
||||
|
||||
if buf = nil then exit;
|
||||
|
||||
kfree(void(buf));
|
||||
FreeIOBuffer := true;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -52,6 +52,13 @@ type
|
||||
{ Directory entry types }
|
||||
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
|
||||
|
||||
{ Storage error codes — shared between VFS and filesystem drivers }
|
||||
TError = (eNone, eUnknown, eFileInUse, eWriteOnly, eReadOnly, eFileDoesNotExist,
|
||||
eDirectoryDoesNotExist, eDirectoryAlreadyExists, eNotADirectory,
|
||||
eDiskFull, eFilenameTooLong, eDirectoryFull, eInvalidPath, ePermissionDenied,
|
||||
eInvalidFileName, eInvalidFileExtension, eTooManyOpenFiles, eDirectoryNotEmpty);
|
||||
PError = ^TError;
|
||||
|
||||
{ Forward declarations }
|
||||
PStorage_device = ^TStorage_Device;
|
||||
PStorage_Volume = ^TStorage_Volume;
|
||||
@@ -65,7 +72,7 @@ type
|
||||
|
||||
{ Filesystem callback types }
|
||||
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; buffer : puint32; bytecount : puint32) : uint32;
|
||||
PPCreateHook = procedure(volume : PStorage_volume; start : uint32; size : uint32; config : puint32);
|
||||
PPDetectHook = procedure(disk : PStorage_Device);
|
||||
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32);
|
||||
@@ -121,7 +128,6 @@ type
|
||||
{ Generic directory entry }
|
||||
TDirectory_Entry = record
|
||||
fileName : pchar;
|
||||
extension : pchar;
|
||||
entryType : TDirectory_Entry_Type;
|
||||
end;
|
||||
|
||||
|
||||
+403
-177
File diff suppressed because it is too large.
Load diff
@@ -64,6 +64,7 @@ var
|
||||
volume : PStorage_Volume;
|
||||
begin
|
||||
volume := PStorage_Volume(kalloc(sizeof(TStorage_Volume)));
|
||||
if volume = nil then exit;
|
||||
volume^.device := device;
|
||||
volume^.sectorStart := sectorStart;
|
||||
volume^.sectorCount := sectorCount;
|
||||
@@ -130,7 +131,7 @@ begin
|
||||
i := i + 1;
|
||||
end;
|
||||
|
||||
if device^.volumes <> nil then
|
||||
if (device <> nil) and (device^.volumes <> nil) then
|
||||
DL_Clear(device^.volumes);
|
||||
end;
|
||||
|
||||
@@ -149,6 +150,7 @@ var
|
||||
volPtr : PStorage_Volume;
|
||||
begin
|
||||
push_trace('VolumeManager.register_volume');
|
||||
if device = nil then exit;
|
||||
volPtr := volume;
|
||||
DL_Add(volumes);
|
||||
DL_Set(volumes, DL_Size(volumes) - 1, puint32(@volPtr));
|
||||
@@ -193,6 +195,7 @@ begin
|
||||
memset(uint32(@get_partition), 0, sizeof(TPartition_table));
|
||||
if (device = nil) or (index > 3) then exit;
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
get_partition := bootrecord^.partition[index];
|
||||
kfree(puint32(bootrecord));
|
||||
end;
|
||||
@@ -207,12 +210,13 @@ begin
|
||||
|
||||
{ Write to MBR }
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
bootrecord^.partition[slot] := partition;
|
||||
storagemanager.write_mbr(device, bootrecord);
|
||||
kfree(puint32(bootrecord));
|
||||
|
||||
{ Create volume in memory }
|
||||
if (partition.LBA_start <> 0) or (partition.sector_count <> 0) then
|
||||
if (partition.LBA_start <> 0) and (partition.sector_count <> 0) then
|
||||
create_volume_from_partition(device, partition.LBA_start, partition.sector_count);
|
||||
end;
|
||||
|
||||
@@ -228,6 +232,7 @@ begin
|
||||
|
||||
{ Read old entry so we know which volume to remove }
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
oldPart := bootrecord^.partition[slot];
|
||||
|
||||
{ Zero the slot }
|
||||
@@ -237,7 +242,7 @@ begin
|
||||
kfree(puint32(bootrecord));
|
||||
|
||||
{ Remove the corresponding volume }
|
||||
if (oldPart.LBA_start <> 0) or (oldPart.sector_count <> 0) then
|
||||
if (oldPart.LBA_start <> 0) and (oldPart.sector_count <> 0) then
|
||||
remove_volume_by_start(device, oldPart.LBA_start);
|
||||
end;
|
||||
|
||||
@@ -255,28 +260,62 @@ begin
|
||||
|
||||
{ Write clean MBR }
|
||||
bootrecord := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)));
|
||||
if bootrecord = nil then exit;
|
||||
memset(uint32(bootrecord), 0, sizeof(TMaster_Boot_Record));
|
||||
bootrecord^.boot_sector := $AA55;
|
||||
storagemanager.write_mbr(device, bootrecord);
|
||||
kfree(puint32(bootrecord));
|
||||
end;
|
||||
|
||||
{ Read MBR and create volumes for all non-empty partitions }
|
||||
{ Read MBR and create volumes for all non-empty partitions.
|
||||
If the MBR contains no partitions, or no partition was identified
|
||||
by any filesystem, fall back to asking each registered filesystem's
|
||||
detectCallback to probe the raw disk (e.g. ISO 9660 media may have
|
||||
a hybrid MBR with dummy partitions that don't match any FS). }
|
||||
procedure discover_volumes(device : PStorage_Device);
|
||||
var
|
||||
bootrecord : PMaster_Boot_Record;
|
||||
i : uint32;
|
||||
found : uint32;
|
||||
identified : uint32;
|
||||
fsCount : uint32;
|
||||
fs : PFilesystem;
|
||||
v : PStorage_Volume;
|
||||
begin
|
||||
push_trace('VolumeManager.discover_volumes');
|
||||
if device = nil then exit;
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
|
||||
found := 0;
|
||||
for i := 0 to 3 do begin
|
||||
if bootrecord^.partition[i].LBA_start <> 0 then
|
||||
if bootrecord^.partition[i].LBA_start <> 0 then begin
|
||||
create_volume_from_partition(device, bootrecord^.partition[i].LBA_start, bootrecord^.partition[i].sector_count);
|
||||
found := found + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
kfree(puint32(bootrecord));
|
||||
|
||||
{ Check whether any MBR volume was actually identified }
|
||||
identified := 0;
|
||||
if (found > 0) and (device^.volumes <> nil) then begin
|
||||
for i := 0 to DL_Size(device^.volumes) - 1 do begin
|
||||
v := PStorage_Volume(Void(DL_Get(device^.volumes, i))^);
|
||||
if v^.filesystem <> nil then
|
||||
identified := identified + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ No identified volumes — let filesystem drivers probe the raw disk }
|
||||
if identified = 0 then begin
|
||||
fsCount := filesystemmanager.get_filesystem_count();
|
||||
for i := 0 to fsCount - 1 do begin
|
||||
fs := filesystemmanager.get_filesystem(i);
|
||||
if (fs <> nil) and (fs^.detectCallback <> nil) then
|
||||
fs^.detectCallback(device);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Find the first LBA after all existing partitions.
|
||||
@@ -292,6 +331,7 @@ begin
|
||||
find_free_space := 0;
|
||||
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
nextLBA := 1;
|
||||
|
||||
for i := 0 to 3 do begin
|
||||
@@ -318,6 +358,7 @@ begin
|
||||
find_free_slot := -1;
|
||||
|
||||
bootrecord := storagemanager.read_mbr(device);
|
||||
if bootrecord = nil then exit;
|
||||
|
||||
for i := 0 to 3 do begin
|
||||
if (bootrecord^.partition[i].LBA_start = 0) and
|
||||
|
||||
Loaded 20 of 24 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user