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 "Compiling FPC Sources..."
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;
interface
uses
util,
PCI,
drivertypes,
drivermanagement,
lmemorymanager,
console,
vmemorymanager,
drivermanagement,
drivertypes,
idetypes,
lists;
lists,
lmemorymanager,
PCI,
util,
vmemorymanager;
const
AHCI_CONTROLLER_MODE = $80000000;
+1 -1
View File
@@ -140,7 +140,7 @@ begin
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].sector_count, getTerminalHWND());
+7 -6
View File
@@ -23,14 +23,15 @@ interface
uses
console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists,
tracer,
lmemorymanager,
rtc,
serial,
rtc;
storagemanagement,
strings,
terminal,
tracer,
util;
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
* Unit: Drivers/storage/partitontable
* Unit: Drivers/storage/partitiontable
* Description: partionTable
*
************************************************
@@ -8,32 +8,33 @@
* Contributors:
************************************************ }
unit partitontable;
unit partitiontable;
interface
uses
console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists,
lmemorymanager,
rtc,
storagemanagement,
strings,
terminal,
tracer,
rtc;
util;
type
TPartitonTable = record
TpartitionTable = record
end;
PPartitonTable = ^TPartitonTable;
PpartitionTable = ^TpartitionTable;
var
location = $1BE;
procedure create_new(device : PStorage_Device);
function get_table() : PPartitonTable;
function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume);
implementation
@@ -45,7 +46,7 @@ begin
end;
function get_table() : PPartitonTable;
function get_table() : PpartitionTable;
procedure add_volume(volume : TStorage_Volume);
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
{ Controller types }
TControllerType = (
ControllerATA,
ControllerATAPI,
@@ -38,6 +39,7 @@ type
ControllerSCSI
);
{ Filesystem type identifiers }
TFileSystemType = (
FileSystemFAT32,
FileSystemExFAT,
@@ -47,12 +49,31 @@ type
FileSystemOther
);
{ Directory entry types }
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
{ Forward declarations }
PStorage_device = ^TStorage_Device;
PStorage_Volume = ^TStorage_Volume;
PFilesystem = ^TFilesystem;
PDirectory_Entry = ^TDirectory_Entry;
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;
{ 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;
PByteArray8 = ^byteArray8;
@@ -70,17 +91,39 @@ type
start : uint32; //start of device in sectors
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 }
TStorage_Volume = record
id : uint32;
device : PStorage_device;
name : pchar;
fileSystem : TFileSystemType;
size : uint32; //size of volume in sectors
start : uint32; //start of volume in sectors
sectorStart : uint32;
sectorSize : uint32;
sectorCount : uint32;
freeSectors : uint32;
filesystem : PFilesystem;
isBootDrive : boolean;
end;
PStorage_Volume = ^TStorage_Volume;
{ Generic directory entry }
TDirectory_Entry = record
fileName : pchar;
extension : pchar;
entryType : TDirectory_Entry_Type;
end;
TDrive_Error = record
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
uses
util,
lists,
lmemorymanager,
lists;
util;
function stringToUpper(str : pchar) : pchar;
function stringToLower(str : pchar) : pchar;
@@ -116,6 +116,11 @@ var
size : uint32;
begin
if str = nil then begin
result := stringNew(0);
stringCopy := result;
exit;
end;
size:= stringSize(str);
result:= stringNew(size);
memcpy(uint32(str), uint32(result), size);
@@ -137,6 +142,10 @@ var
i : uint32;
begin
if str = nil then begin
stringSize := 0;
exit;
end;
i:=0;
while byte(str[i]) <> 0 do begin
inc(i);
@@ -300,8 +309,30 @@ begin
end;
function intToString(i : uint32) : pchar;
var
buf : array[0..11] of char;
p : uint32;
tmp : uint32;
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;
function boolToString(b : boolean; ext : boolean) : pchar;
@@ -311,11 +342,15 @@ var
begin
if ext then begin
t:= stringCopy('true');
f:= stringCopy('false');
t:= stringNew(4);
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
t:= stringCopy('1');
f:= stringCopy('0');
t:= stringNew(1);
t[0]:= '1';
f:= stringNew(1);
f[0]:= '0';
end;
if b then begin
kfree(void(f));
+19 -8
View File
@@ -42,11 +42,13 @@ uses
IDE,
// storagemanagement,
// drivemanager,
storagemanager,
volumemanager,
filesystemmanager,
lists,
net,
// fat32,
// flatfs,
fat32,
flatfs,
isrmanager,
faults,
fonts,
@@ -59,7 +61,10 @@ uses
terminal,
hashmap, vfs,
AHCI,
AHCITest;
AHCITest,
diskcmd,
partcmd,
volcmd;
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
@@ -210,9 +215,9 @@ begin
tracer.push_trace('kmain.DRVMGMT');
drivermanagement.init();
tracer.push_trace('kmain.STRMGMT');
// storagemanagement.init();
// drivemanager.init();
// volumemanager.init();
storagemanager.init();
volumemanager.init();
filesystemmanager.init();
{ Hook Timer for Ticks }
tracer.push_trace('kmain.TMR');
@@ -220,8 +225,8 @@ begin
TMR_0_ISR.hook(uint32(@bios_data_area.tick_update));
{ Filsystems }
// fat32.init();
// flatfs.init();
fat32.init();
flatfs.init();
{ Device Drivers }
tracer.push_trace('kmain.DEVDRV');
@@ -233,6 +238,9 @@ begin
// IDE.init();
AHCI.init();
AHCITest.init();
diskcmd.init();
partcmd.init();
volcmd.init();
console.outputln('KERNEL', 'DEVICE DRIVERS: INIT END.');
{ Bus Drivers }
@@ -242,6 +250,9 @@ begin
pci.init();
console.outputln('KERNEL', 'BUS DRIVERS: INIT END.');
{ Auto-mount discovered volumes into VFS }
vfs.auto_mount_volumes();
{ Network Stack }
tracer.push_trace('kmain.NETDRV');
net.init;
+8 -1
View File
@@ -177,15 +177,22 @@ var
i, j : uint32;
hp : PHeapPage;
miss : boolean;
maxSearch : uint32;
begin
//push_trace('lmemorymanager.kalloc');
Heap_Entries:= size div 8;
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;
kalloc:= nil;
while kalloc = nil do begin
for i:=0 to MAX_ENTRIES-1 do begin
for i:=0 to maxSearch do begin
miss:= false;
for j:=0 to Heap_Entries-1 do 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