file io working

This commit is contained in:
Aaron committed 2026-02-28 14:42:30 +00:00
1 parent 8b80b6864b
commit 84b589c856
23 files changed
+4093 -596

No files matched your search

+1 -1
View File
@@ -4,4 +4,4 @@ echo "======================="
echo " " echo " "
echo "Compiling FPC Sources..." echo "Compiling FPC Sources..."
echo " " echo " "
fpc -Aelf -gw -n -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/storage/* -Fusrc/driver/storage/AHCI/* -Fusrc/driver/* -Fusrc/driver/net/* src/kernel.pas fpc -Aelf -gw -n -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/storage/* -Fusrc/driver/storage/AHCI/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/prog/* src/kernel.pas
+185
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -20,15 +20,15 @@
unit AHCITypes; unit AHCITypes;
interface interface
uses uses
util,
PCI,
drivertypes,
drivermanagement,
lmemorymanager,
console, console,
vmemorymanager, drivermanagement,
drivertypes,
idetypes, idetypes,
lists; lists,
lmemorymanager,
PCI,
util,
vmemorymanager;
const const
AHCI_CONTROLLER_MODE = $80000000; AHCI_CONTROLLER_MODE = $80000000;
+1 -1
View File
@@ -140,7 +140,7 @@ begin
writestringlnWND('MBR already exists', getTerminalHWND()); writestringlnWND('MBR already exists', getTerminalHWND());
//write first partiton sectorStart and sectorCount //write first partition sectorStart and sectorCount
writeintlnWND(mb^.partition[0].LBA_start, getTerminalHWND()); writeintlnWND(mb^.partition[0].LBA_start, getTerminalHWND());
writeintlnWND(mb^.partition[0].sector_count, getTerminalHWND()); writeintlnWND(mb^.partition[0].sector_count, getTerminalHWND());
+7 -6
View File
@@ -23,14 +23,15 @@ interface
uses uses
console, console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists, lists,
tracer, lmemorymanager,
rtc,
serial, serial,
rtc; storagemanagement,
strings,
terminal,
tracer,
util;
type type
File diff suppressed because it is too large. Load diff
+120
View File
@@ -0,0 +1,120 @@
{
Driver->Storage->FilesystemManager - Filesystem driver registry and routing.
Filesystem drivers (FAT32, FlatFS, etc.) register themselves here.
When VolumeManager discovers a volume, FilesystemManager probes it
against all registered filesystem drivers to detect the filesystem type.
@author(Aaron Hance <[email protected]>)
}
unit filesystemmanager;
interface
uses
lists,
lmemorymanager,
storagetypes,
strings,
tracer,
util;
var
filesystems : PLinkedListBase;
procedure init();
procedure register_filesystem(filesystem : PFilesystem);
function get_filesystem_count() : uint32;
function get_filesystem(index : uint32) : PFilesystem;
function find_filesystem_by_name(name : pchar) : PFilesystem;
function find_filesystem_by_id(system_id : uint8) : PFilesystem;
procedure probe_volume(volume : PStorage_Volume);
implementation
procedure init();
begin
push_trace('FilesystemManager.init');
filesystems := LL_New(sizeof(TFilesystem));
end;
procedure register_filesystem(filesystem : PFilesystem);
var
elm : void;
begin
push_trace('FilesystemManager.register_filesystem');
elm := LL_Add(filesystems);
memcpy(uint32(filesystem), uint32(elm), sizeof(TFilesystem));
end;
function get_filesystem_count() : uint32;
begin
get_filesystem_count := LL_Size(filesystems);
end;
function get_filesystem(index : uint32) : PFilesystem;
begin
if index < LL_Size(filesystems) then
get_filesystem := PFilesystem(LL_Get(filesystems, index))
else
get_filesystem := nil;
end;
function find_filesystem_by_name(name : pchar) : PFilesystem;
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.find_filesystem_by_name');
find_filesystem_by_name := nil;
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if stringEquals(fs^.sName, name) then begin
find_filesystem_by_name := fs;
exit;
end;
end;
end;
function find_filesystem_by_id(system_id : uint8) : PFilesystem;
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.find_filesystem_by_id');
find_filesystem_by_id := nil;
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if fs^.system_id = system_id then begin
find_filesystem_by_id := fs;
exit;
end;
end;
end;
procedure probe_volume(volume : PStorage_Volume);
var
i : uint32;
fs : PFilesystem;
begin
push_trace('FilesystemManager.probe_volume.enter');
{ Try each registered filesystem's identify callback against this volume }
for i := 0 to LL_Size(filesystems) - 1 do begin
fs := PFilesystem(LL_Get(filesystems, i));
if fs^.identifyCallback <> nil then begin
push_trace('FilesystemManager.probe_volume.tryFS');
if fs^.identifyCallback(volume) then begin
volume^.filesystem := fs;
push_trace('FilesystemManager.probe_volume.found');
exit;
end;
end;
end;
push_trace('FilesystemManager.probe_volume.exit');
end;
end.
File diff suppressed because it is too large. Load diff
+12 -11
View File
@@ -1,6 +1,6 @@
{ ************************************************ { ************************************************
* Asuro * Asuro
* Unit: Drivers/storage/partitontable * Unit: Drivers/storage/partitiontable
* Description: partionTable * Description: partionTable
* *
************************************************ ************************************************
@@ -8,32 +8,33 @@
* Contributors: * Contributors:
************************************************ } ************************************************ }
unit partitontable; unit partitiontable;
interface interface
uses uses
console, console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists, lists,
lmemorymanager,
rtc,
storagemanagement,
strings,
terminal,
tracer, tracer,
rtc; util;
type type
TPartitonTable = record TpartitionTable = record
end; end;
PPartitonTable = ^TPartitonTable; PpartitionTable = ^TpartitionTable;
var var
location = $1BE; location = $1BE;
procedure create_new(device : PStorage_Device); procedure create_new(device : PStorage_Device);
function get_table() : PPartitonTable; function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume); procedure add_volume(volume : TStorage_Volume);
implementation implementation
@@ -45,7 +46,7 @@ begin
end; end;
function get_table() : PPartitonTable; function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume); procedure add_volume(volume : TStorage_Volume);
end. end.
+96
View File
@@ -0,0 +1,96 @@
{
Driver->Storage->StorageManager - Physical storage device registry.
Manages registration of physical storage devices (AHCI, IDE, USB, etc.)
and provides a global device list plus raw MBR read/write.
Device drivers call register_device() when they discover a new device.
@author(Aaron Hance <[email protected]>)
}
unit storagemanager;
interface
uses
lists,
lmemorymanager,
MBR,
storagetypes,
tracer,
util;
var
storageDevices : PDList;
procedure init();
procedure register_device(device : PStorage_Device);
function get_device_list() : PDList;
function get_device_count() : uint32;
function get_device(index : uint32) : PStorage_Device;
function controller_type_2_string(controllerType : TControllerType) : pchar;
function read_mbr(device : PStorage_Device) : PMaster_Boot_Record;
procedure write_mbr(device : PStorage_Device; mbr : PMaster_Boot_Record);
implementation
procedure init();
begin
push_trace('StorageManager.init');
storageDevices := DL_New(sizeof(TStorage_Device));
end;
procedure register_device(device : PStorage_Device);
begin
push_trace('StorageManager.register_device');
DL_Add(storageDevices);
DL_Set(storageDevices, DL_Size(storageDevices) - 1, puint32(device));
end;
function get_device_list() : PDList;
begin
get_device_list := storageDevices;
end;
function get_device_count() : uint32;
begin
get_device_count := DL_Size(storageDevices);
end;
function get_device(index : uint32) : PStorage_Device;
begin
if index < DL_Size(storageDevices) then
get_device := PStorage_Device(DL_Get(storageDevices, index))
else
get_device := nil;
end;
function controller_type_2_string(controllerType : TControllerType) : pchar;
begin
case controllerType of
ControllerATA: controller_type_2_string := 'ATA';
ControllerATAPI: controller_type_2_string := 'ATAPI';
ControllerUSB: controller_type_2_string := 'USB';
ControllerAHCI: controller_type_2_string := 'AHCI';
ControllerAHCI_ATAPI: controller_type_2_string := 'AHCI_ATAPI';
ControllerNVMe: controller_type_2_string := 'NVMe';
ControllerNET: controller_type_2_string := 'NET';
ControllerRAM: controller_type_2_string := 'RAM';
ControllerSCSI: controller_type_2_string := 'SCSI';
end;
end;
function read_mbr(device : PStorage_Device) : PMaster_Boot_Record;
begin
push_trace('StorageManager.read_mbr');
read_mbr := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record)));
device^.readCallback(device, 0, 1, puint32(read_mbr));
end;
procedure write_mbr(device : PStorage_Device; mbr : PMaster_Boot_Record);
begin
push_trace('StorageManager.write_mbr');
if not device^.writable then exit;
device^.writeCallback(device, 0, 1, puint32(mbr));
end;
end.
+48 -5
View File
@@ -26,6 +26,7 @@ uses
type type
{ Controller types }
TControllerType = ( TControllerType = (
ControllerATA, ControllerATA,
ControllerATAPI, ControllerATAPI,
@@ -38,6 +39,7 @@ type
ControllerSCSI ControllerSCSI
); );
{ Filesystem type identifiers }
TFileSystemType = ( TFileSystemType = (
FileSystemFAT32, FileSystemFAT32,
FileSystemExFAT, FileSystemExFAT,
@@ -47,12 +49,31 @@ type
FileSystemOther FileSystemOther
); );
{ Directory entry types }
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
{ Forward declarations }
PStorage_device = ^TStorage_Device; PStorage_device = ^TStorage_Device;
PStorage_Volume = ^TStorage_Volume;
PFilesystem = ^TFilesystem;
PDirectory_Entry = ^TDirectory_Entry;
PDrive_Error = ^TDrive_Error; PDrive_Error = ^TDrive_Error;
{ Block I/O callback for raw device access }
PPHIOHook = procedure(drive : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32); PPHIOHook = procedure(drive : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
PPHIOHook_ = procedure; PPHIOHook_ = procedure;
{ 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;
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);
PPReadDirHook = function(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase;
PPDeleteFileHook = procedure(volume : PStorage_Volume; filePath : pchar; status : puint32);
PPDeleteDirHook = procedure(volume : PStorage_Volume; path : pchar; status : puint32);
PPIdentifyHook = function(volume : PStorage_Volume) : boolean;
byteArray8 = array[0..7] of char; byteArray8 = array[0..7] of char;
PByteArray8 = ^byteArray8; PByteArray8 = ^byteArray8;
@@ -70,17 +91,39 @@ type
start : uint32; //start of device in sectors start : uint32; //start of device in sectors
end; end;
{ Filesystem driver descriptor }
TFilesystem = record
sName : pchar;
system_id : uint8;
writeCallback : PPWriteHook;
readCallback : PPReadHook;
createCallback : PPCreateHook;
detectCallback : PPDetectHook;
createDirCallback : PPCreateDirHook;
readDirCallback : PPReadDirHook;
deleteFileCallback : PPDeleteFileHook;
deleteDirCallback : PPDeleteDirHook;
identifyCallback : PPIdentifyHook;
end;
{ Generic storage volume } { Generic storage volume }
TStorage_Volume = record TStorage_Volume = record
id : uint32; id : uint32;
device : PStorage_device; device : PStorage_device;
name : pchar; sectorStart : uint32;
fileSystem : TFileSystemType; sectorSize : uint32;
size : uint32; //size of volume in sectors sectorCount : uint32;
start : uint32; //start of volume in sectors freeSectors : uint32;
filesystem : PFilesystem;
isBootDrive : boolean;
end; end;
PStorage_Volume = ^TStorage_Volume; { Generic directory entry }
TDirectory_Entry = record
fileName : pchar;
extension : pchar;
entryType : TDirectory_Entry_Type;
end;
TDrive_Error = record TDrive_Error = record
code : uint16; code : uint16;
+898 -145
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+42 -7
View File
@@ -23,9 +23,9 @@ unit strings;
interface interface
uses uses
util, lists,
lmemorymanager, lmemorymanager,
lists; util;
function stringToUpper(str : pchar) : pchar; function stringToUpper(str : pchar) : pchar;
function stringToLower(str : pchar) : pchar; function stringToLower(str : pchar) : pchar;
@@ -116,6 +116,11 @@ var
size : uint32; size : uint32;
begin begin
if str = nil then begin
result := stringNew(0);
stringCopy := result;
exit;
end;
size:= stringSize(str); size:= stringSize(str);
result:= stringNew(size); result:= stringNew(size);
memcpy(uint32(str), uint32(result), size); memcpy(uint32(str), uint32(result), size);
@@ -137,6 +142,10 @@ var
i : uint32; i : uint32;
begin begin
if str = nil then begin
stringSize := 0;
exit;
end;
i:=0; i:=0;
while byte(str[i]) <> 0 do begin while byte(str[i]) <> 0 do begin
inc(i); inc(i);
@@ -300,8 +309,30 @@ begin
end; end;
function intToString(i : uint32) : pchar; function intToString(i : uint32) : pchar;
var
buf : array[0..11] of char;
p : uint32;
tmp : uint32;
begin begin
intToString:= ' '; if i = 0 then begin
intToString := stringNew(1);
intToString[0] := '0';
exit;
end;
for p := 0 to 11 do buf[p] := char(0);
p := 10;
tmp := i;
while tmp > 0 do begin
buf[p] := char(ord('0') + (tmp mod 10));
tmp := tmp div 10;
if (tmp > 0) and (p > 0) then
p := p - 1;
end;
intToString := stringCopy(@buf[p]);
end; end;
function boolToString(b : boolean; ext : boolean) : pchar; function boolToString(b : boolean; ext : boolean) : pchar;
@@ -311,11 +342,15 @@ var
begin begin
if ext then begin if ext then begin
t:= stringCopy('true'); t:= stringNew(4);
f:= stringCopy('false'); t[0]:= 't'; t[1]:= 'r'; t[2]:= 'u'; t[3]:= 'e';
f:= stringNew(5);
f[0]:= 'f'; f[1]:= 'a'; f[2]:= 'l'; f[3]:= 's'; f[4]:= 'e';
end else begin end else begin
t:= stringCopy('1'); t:= stringNew(1);
f:= stringCopy('0'); t[0]:= '1';
f:= stringNew(1);
f[0]:= '0';
end; end;
if b then begin if b then begin
kfree(void(f)); kfree(void(f));
+19 -8
View File
@@ -42,11 +42,13 @@ uses
IDE, IDE,
// storagemanagement, // storagemanagement,
// drivemanager, // drivemanager,
storagemanager,
volumemanager, volumemanager,
filesystemmanager,
lists, lists,
net, net,
// fat32, fat32,
// flatfs, flatfs,
isrmanager, isrmanager,
faults, faults,
fonts, fonts,
@@ -59,7 +61,10 @@ uses
terminal, terminal,
hashmap, vfs, hashmap, vfs,
AHCI, AHCI,
AHCITest; AHCITest,
diskcmd,
partcmd,
volcmd;
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
@@ -210,9 +215,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(); storagemanager.init();
// drivemanager.init(); volumemanager.init();
// volumemanager.init(); filesystemmanager.init();
{ Hook Timer for Ticks } { Hook Timer for Ticks }
tracer.push_trace('kmain.TMR'); tracer.push_trace('kmain.TMR');
@@ -220,8 +225,8 @@ 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();
// flatfs.init(); flatfs.init();
{ Device Drivers } { Device Drivers }
tracer.push_trace('kmain.DEVDRV'); tracer.push_trace('kmain.DEVDRV');
@@ -233,6 +238,9 @@ begin
// IDE.init(); // IDE.init();
AHCI.init(); AHCI.init();
AHCITest.init(); AHCITest.init();
diskcmd.init();
partcmd.init();
volcmd.init();
console.outputln('KERNEL', 'DEVICE DRIVERS: INIT END.'); console.outputln('KERNEL', 'DEVICE DRIVERS: INIT END.');
{ Bus Drivers } { Bus Drivers }
@@ -242,6 +250,9 @@ begin
pci.init(); pci.init();
console.outputln('KERNEL', 'BUS DRIVERS: INIT END.'); console.outputln('KERNEL', 'BUS DRIVERS: INIT END.');
{ Auto-mount discovered volumes into VFS }
vfs.auto_mount_volumes();
{ Network Stack } { Network Stack }
tracer.push_trace('kmain.NETDRV'); tracer.push_trace('kmain.NETDRV');
net.init; net.init;
+8 -1
View File
@@ -177,15 +177,22 @@ var
i, j : uint32; i, j : uint32;
hp : PHeapPage; hp : PHeapPage;
miss : boolean; miss : boolean;
maxSearch : uint32;
begin begin
//push_trace('lmemorymanager.kalloc'); //push_trace('lmemorymanager.kalloc');
Heap_Entries:= size div 8; Heap_Entries:= size div 8;
If sint32(size-(Heap_Entries*8)) > 0 then Heap_Entries:= Heap_Entries + 1; If sint32(size-(Heap_Entries*8)) > 0 then Heap_Entries:= Heap_Entries + 1;
{ Prevent searching past end of Entries array }
if Heap_Entries > MAX_ENTRIES then begin
kalloc := nil;
exit;
end;
maxSearch := MAX_ENTRIES - Heap_Entries;
hp:= Search_Page; hp:= Search_Page;
kalloc:= nil; kalloc:= nil;
while kalloc = nil do begin while kalloc = nil do begin
for i:=0 to MAX_ENTRIES-1 do begin for i:=0 to maxSearch do begin
miss:= false; miss:= false;
for j:=0 to Heap_Entries-1 do begin for j:=0 to Heap_Entries-1 do begin
if hp^.Entries[i+j].Present then begin if hp^.Entries[i+j].Present then begin
File diff suppressed because it is too large. Load diff
+586 -143
View File
File diff suppressed because it is too large. Load diff
+144
View File
@@ -0,0 +1,144 @@
{
Prog->inio - Inline IO
Usage:
inio <file> < Read file contents to terminal
inio <file> > text Write text to file
@author(Aaron Hance <[email protected]>)
}
unit inio;
interface
uses
console,
lmemorymanager,
strings,
terminal,
tracer,
util,
vfs;
procedure init();
implementation
procedure Run(Params : PParamList);
var
filePath : pchar;
absPath : pchar;
op : pchar;
fError : vfs.TError;
fHandle : vfs.TFileHandle;
buf : pchar;
bytesRead : uint32;
content : pchar;
part : pchar;
tmp : pchar;
i : uint32;
pCount : uint32;
contentLen : uint32;
begin
tracer.push_trace('inio.run');
pCount := paramCount(Params);
if pCount < 2 then begin
console.writestringlnWND('Usage: inio <file> < | inio <file> > text', getTerminalHWND());
exit;
end;
filePath := getParam(0, Params);
op := getParam(1, Params);
if filePath = nil then begin
console.writestringlnWND('Error: no file specified.', getTerminalHWND());
exit;
end;
if op = nil then begin
console.writestringlnWND('Error: no operation specified.', getTerminalHWND());
exit;
end;
absPath := vfs.MakeAbsolutePath(filePath);
{ ---- READ ---- }
if op[0] = '<' then begin
fHandle := vfs.OpenFile(absPath, omReadOnly, wmRewrite, false, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
console.writestringlnWND('Error: cannot open file for reading.', getTerminalHWND());
kfree(void(absPath));
exit;
end;
buf := pchar(kalloc(32768));
memset(uint32(buf), 0, 32768);
bytesRead := vfs.ReadFile(fHandle, 0, puint8(buf), 32767);
vfs.CloseFile(fHandle);
if bytesRead > 0 then begin
buf[bytesRead] := char(0);
console.writestringWND(buf, getTerminalHWND());
console.writestringlnWND(' ', getTerminalHWND());
end else begin
console.writestringlnWND('(0 bytes read)', getTerminalHWND());
end;
kfree(puint32(buf));
end
{ ---- WRITE ---- }
else if op[0] = '>' then begin
if pCount < 3 then begin
console.writestringlnWND('Error: no content to write.', getTerminalHWND());
kfree(void(absPath));
exit;
end;
{ Build content string by joining params 2..N with spaces }
content := stringCopy(getParam(2, Params));
i := 3;
while i < pCount do begin
part := getParam(i, Params);
if part <> nil then begin
{ content + ' ' + part }
tmp := stringConcat(content, ' ');
kfree(void(content));
content := stringConcat(tmp, part);
kfree(void(tmp));
end;
i := i + 1;
end;
contentLen := stringSize(content);
{ Try read-write rewrite first (existing file) }
fHandle := vfs.OpenFile(absPath, omReadWrite, wmRewrite, false, @fError);
if (fHandle = 0) or (fError <> eNone) then begin
{ Try creating new file }
fHandle := vfs.OpenFile(absPath, omWriteOnly, wmNew, false, @fError);
end;
if (fHandle = 0) or (fError <> eNone) then begin
console.writestringlnWND('Error: cannot open file for writing.', getTerminalHWND());
kfree(void(content));
kfree(void(absPath));
exit;
end;
vfs.WriteFile(fHandle, 0, puint8(content), contentLen);
vfs.CloseFile(fHandle);
console.writestringlnWND('Written.', getTerminalHWND());
kfree(void(content));
end else begin
console.writestringlnWND('Error: operation must be < or >.', getTerminalHWND());
end;
kfree(void(absPath));
end;
procedure init();
begin
tracer.push_trace('inio.init');
terminal.registerCommand('INIO', @Run, 'Inline IO: inio <file> < | inio <file> > text');
end;
end.
Loaded 20 of 23 files, more files were not shown because too many files have changed in this diff. Show more