From e791edb02a8ef6b58265bc363483b568fb898527 Mon Sep 17 00:00:00 2001 From: aaronhance Date: Sat, 29 Jan 2022 20:05:11 +0000 Subject: [PATCH] Progress --- .vscode/launch.json | 2 +- doc/flatfs.md | 33 ++++++ src/driver/storage/MBR.pas | 5 +- src/driver/storage/fat32.pas | 5 +- src/driver/storage/flatfs.pas | 109 ++++++++++++++++++++ src/driver/storage/storagemanagement.pas | 120 ++++++++++++---------- src/driver/storage/volumemanager.pas | 123 ++++++++++++++++++++++- 7 files changed, 334 insertions(+), 63 deletions(-) create mode 100644 doc/flatfs.md create mode 100644 src/driver/storage/flatfs.pas diff --git a/.vscode/launch.json b/.vscode/launch.json index c945c666..7ffce0c3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "--comment", "Asuro", "--startvm", - "7d395c96-891c-4139-b77d-9b6b144b0b93" + "0c971fec-6de7-42c0-a377-de11bb1cafa2" ], "cwd": "${workspaceFolder}", "console": "internalConsole", diff --git a/doc/flatfs.md b/doc/flatfs.md new file mode 100644 index 00000000..e99ed358 --- /dev/null +++ b/doc/flatfs.md @@ -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 + +--- \ No newline at end of file diff --git a/src/driver/storage/MBR.pas b/src/driver/storage/MBR.pas index 37e5d544..1f1c5b12 100644 --- a/src/driver/storage/MBR.pas +++ b/src/driver/storage/MBR.pas @@ -28,10 +28,7 @@ type 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; + partition : array[0..3] of TPartition_table; boot_sector : uint16; end; diff --git a/src/driver/storage/fat32.pas b/src/driver/storage/fat32.pas index e37ba6eb..22adb367 100644 --- a/src/driver/storage/fat32.pas +++ b/src/driver/storage/fat32.pas @@ -905,7 +905,7 @@ begin if (puint32(buffer)[127] = $55AA) and (PBootRecord(buffer)^.bsignature = $29) then begin //TODO partition table console.writestringln('FAT32: volume found!'); 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^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first volume^.filesystem := @filesystem; @@ -919,13 +919,14 @@ procedure init(); begin push_trace('fat32.init()'); filesystem.sName:= 'FAT32'; - filesystem.system_id:= $00; + filesystem.system_id:= $01; 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; diff --git a/src/driver/storage/flatfs.pas b/src/driver/storage/flatfs.pas new file mode 100644 index 00000000..c7175125 --- /dev/null +++ b/src/driver/storage/flatfs.pas @@ -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. diff --git a/src/driver/storage/storagemanagement.pas b/src/driver/storage/storagemanagement.pas index 84371725..364ecf17 100644 --- a/src/driver/storage/storagemanagement.pas +++ b/src/driver/storage/storagemanagement.pas @@ -31,7 +31,9 @@ uses strings, lists, tracer, - rtc; + rtc, + MBR, + volumemanager; type @@ -54,26 +56,26 @@ type PPHIOHook_ = procedure; - TFilesystem = record - sName : pchar; - writeCallback : PPWriteHook; - readCallback : PPReadHook; - createCallback : PPCreateHook; - detectCallback : PPDetectHook; - createDirCallback : PPCreateDirHook; - readDirCallback : PPReadDirHook; - end; - PFileSystem = ^TFilesystem; + // TFilesystem = record + // sName : pchar; + // writeCallback : PPWriteHook; + // readCallback : PPReadHook; + // createCallback : PPCreateHook; + // detectCallback : PPDetectHook; + // createDirCallback : PPCreateDirHook; + // readDirCallback : PPReadDirHook; + // end; + // PFileSystem = ^TFilesystem; - TStorage_Volume = record - device : PStorage_device; - sectorStart : uint32; - sectorSize : uint32; - freeSectors : uint32; - filesystem : PFilesystem; - { True if this drive contains the loaded OS } - isBootDrive : boolean; - end; + // TStorage_Volume = record + // device : PStorage_device; + // sectorStart : uint32; + // sectorSize : uint32; + // freeSectors : uint32; + // filesystem : PFilesystem; + // { True if this drive contains the loaded OS } + // isBootDrive : boolean; + // end; { Generic storage device } TStorage_Device = record @@ -89,6 +91,7 @@ type hpc : uint16; spt : uint16; end; + APStorage_Device = array[0..255] of PStorage_device; { Generic directory entry } @@ -112,7 +115,7 @@ function get_device_list() : PLinkedListBase; 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 readFile(fileName : pchar; extension : pchar; buffer : puint32; byteCount : puint32) : puint32; @@ -171,16 +174,57 @@ var filesystemString : pchar; filesystem : PFileSystem; spc : puint32; + + sectorCount : uint32; + volumeId : uint8; + + mb : PMaster_Boot_Record; + i : uint32 = 0; + begin + //format + spc:= puint32(kalloc(4)); - spc^:= 4; + spc^:= 1; driveIndex:= stringToInt( getParam(1, params) ); 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 - 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); writeintWnd(driveIndex, getTerminalHWND); @@ -217,10 +261,6 @@ begin format_command(params); end; - //lsfs command for listing filesystems - if stringEquals(subcmd, 'lsfs') then begin - end; - pop_trace(); end; @@ -231,11 +271,8 @@ begin setworkingdirectory('.'); storageDevices:= ll_new(sizeof(TStorage_Device)); - fileSystems:= ll_New(sizeof(TFilesystem)); terminal.registerCommand('DISK', @disk_command, 'Disk utility'); - - end; { 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)); //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(); end; @@ -266,23 +301,4 @@ begin get_device_list:= storageDevices; 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. \ No newline at end of file diff --git a/src/driver/storage/volumemanager.pas b/src/driver/storage/volumemanager.pas index 49a06d51..9e32ce26 100644 --- a/src/driver/storage/volumemanager.pas +++ b/src/driver/storage/volumemanager.pas @@ -48,6 +48,7 @@ type 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 + PPFormatVolumeHook = procedure(disk : PStorage_device; sectorCount : uint32; start : uint32; config : puint32); PPHIOHook_ = procedure; @@ -60,6 +61,7 @@ type detectCallback : PPDetectHook; createDirCallback : PPCreateDirHook; readDirCallback : PPReadDirHook; + formatVolumeCallback : PPFormatVolumeHook; end; TStorage_Volume = record @@ -96,6 +98,58 @@ var 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(); var i : uint32; @@ -116,9 +170,15 @@ begin console.writestringWnd(' ', getTerminalHWND()); console.writeintWnd(i, getTerminalHWND()); console.writestringWnd(' - Capacity: ', getTerminalHWND()); - console.writeintWnd(uint32(volume^.sectorSize * volume^.sectorCount DIV 1024 DIV 1024), getTerminalHWND()); - console.writestringWnd('MB System: ', getTerminalHWND()); - console.writestringlnWnd(volume^.filesystem^.sName, getTerminalHWND()); + console.writeintWnd(uint32((volume^.sectorSize * volume^.sectorCount) DIV 1024 DIV 1024), getTerminalHWND()); + console.writestringWnd('MB, Filesystem: ', getTerminalHWND()); + + if volume^.filesystem <> nil then begin + console.writestringlnWnd(volume^.filesystem^.sName, getTerminalHWND()); + end else begin + console.writestringlnWnd('None', getTerminalHWND()); + end; + end; end; @@ -143,6 +203,16 @@ begin list_volume_command(); exit; 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; { Initialise volume manager } @@ -189,8 +259,9 @@ begin storageVolume.device := drive; storageVolume.sectorStart := bootrecord^.partition_0.LBA_start; storageVolume.sectorCount := bootrecord^.partition_0.sector_count; + storageVolume.sectorSize := drive^.sectorSize; storageVolume.freeSectors := 0; //TODO impliment - push_trace('VolumeManager.init2'); + storageVolume.filesystem := nil; if LL_Size(filesystems) < 1 then begin console.writestringln('Failed to initalise storage system, no filesystems found, stopping!'); @@ -218,4 +289,48 @@ begin 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. \ No newline at end of file