x86_64 do not merge #76
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -28,8 +28,7 @@ uses
|
||||
core.ds.lists,
|
||||
memory.heap,
|
||||
driver.bus.pci,
|
||||
core.util, arch.x86.util,
|
||||
arch.x86.memory.virtual;
|
||||
core.util;
|
||||
|
||||
const
|
||||
AHCI_CONTROLLER_MODE = $80000000;
|
||||
@@ -278,6 +277,7 @@ type
|
||||
device_type : TDeviceType;
|
||||
ata_info : TIdentResponse;
|
||||
supportsNCQ : boolean;
|
||||
supports64BitDMA: boolean;
|
||||
queueDepth : uint32; { safe active depth for this device }
|
||||
slotCount : uint32; { controller slot count from CAP.NCS + 1 }
|
||||
command_list : PHBA_CMD_HEADER;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -62,7 +62,7 @@ implementation
|
||||
|
||||
uses
|
||||
driver.storage.vfs, driver.storage.types, memory.heap, core.strings,
|
||||
core.strings.helpers, debug.tracer, io.syslog, core.util, arch.x86.util;
|
||||
core.strings.helpers, debug.tracer, io.syslog, core.util, arch.platform.cpu;
|
||||
|
||||
type
|
||||
THandlerEntry = record
|
||||
@@ -124,7 +124,7 @@ begin
|
||||
Handlers[i].Used := true;
|
||||
Handlers[i].Kind := hkMagic;
|
||||
Handlers[i].MagicLen := magicLen;
|
||||
memcpy(uint32(magic), uint32(@Handlers[i].Magic[0]), magicLen);
|
||||
memcpy(PtrUInt(magic), PtrUInt(@Handlers[i].Magic[0]), magicLen);
|
||||
copyName(@Handlers[i].Name[0], name, 16);
|
||||
Handlers[i].Handler := handler;
|
||||
inc(HandlerCount);
|
||||
@@ -149,7 +149,7 @@ begin
|
||||
if not Handlers[i].Used then begin
|
||||
Handlers[i].Used := true;
|
||||
Handlers[i].Kind := hkExtension;
|
||||
memcpy(uint32(extList), uint32(@Handlers[i].ExtList[0]), len);
|
||||
memcpy(PtrUInt(extList), PtrUInt(@Handlers[i].ExtList[0]), len);
|
||||
Handlers[i].ExtList[len] := #0;
|
||||
copyName(@Handlers[i].Name[0], name, 16);
|
||||
Handlers[i].Handler := handler;
|
||||
@@ -224,7 +224,7 @@ begin
|
||||
fh := driver.storage.vfs.OpenFile(absPath, omRead, @err);
|
||||
if fh = 0 then exit;
|
||||
|
||||
memset(uint32(@headerBuf[0]), 0, MAX_MAGIC_LEN);
|
||||
memset(PtrUInt(@headerBuf[0]), 0, MAX_MAGIC_LEN);
|
||||
bytesRead := driver.storage.vfs.ReadFile(fh, 0, @headerBuf[0], MAX_MAGIC_LEN);
|
||||
driver.storage.vfs.CloseFile(fh);
|
||||
|
||||
|
||||
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,140 @@
|
||||
// Copyright 2026 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.
|
||||
|
||||
{ Path syntax shared by VFS and boot consumers; no volume or driver access.
|
||||
Returned strings are caller-owned. Normalization is lexical, not symlink
|
||||
resolution, and never climbs above the root. }
|
||||
unit driver.storage.path;
|
||||
|
||||
interface
|
||||
|
||||
function absolute(path, baseDir: pchar): pchar;
|
||||
function normalize(path: pchar): pchar;
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses core.strings, core.util, memory.heap, arch.platform.diagnostics;
|
||||
|
||||
function absolute(path, baseDir: pchar): pchar;
|
||||
var
|
||||
pathLen, baseLen, separator: uint32;
|
||||
result: pchar;
|
||||
begin
|
||||
absolute := nil;
|
||||
if path = nil then begin
|
||||
absolute := stringCopy('/');
|
||||
exit;
|
||||
end;
|
||||
if path[0] = '/' then begin
|
||||
absolute := stringCopy(path);
|
||||
exit;
|
||||
end;
|
||||
if (baseDir = nil) or (baseDir[0] = #0) then baseDir := '/';
|
||||
pathLen := StringSize(path);
|
||||
baseLen := StringSize(baseDir);
|
||||
separator := 0;
|
||||
if baseDir[baseLen - 1] <> '/' then separator := 1;
|
||||
if pathLen >= High(uint32) - separator then exit;
|
||||
if baseLen >= High(uint32) - pathLen - separator then exit;
|
||||
|
||||
result := stringNew(baseLen + separator + pathLen);
|
||||
if result = nil then exit;
|
||||
memcpy(PtrUInt(baseDir), PtrUInt(result), baseLen);
|
||||
if separator <> 0 then result[baseLen] := '/';
|
||||
memcpy(PtrUInt(path), PtrUInt(result) + baseLen + separator, pathLen);
|
||||
absolute := result;
|
||||
end;
|
||||
|
||||
function normalize(path: pchar): pchar;
|
||||
var
|
||||
length, readPos, start, count, used: uint32;
|
||||
result: pchar;
|
||||
begin
|
||||
normalize := nil;
|
||||
if path = nil then path := '';
|
||||
length := StringSize(path);
|
||||
if length >= High(uint32) - 1 then exit;
|
||||
result := stringNew(length + 1);
|
||||
if result = nil then exit;
|
||||
result[0] := '/';
|
||||
used := 1;
|
||||
readPos := 0;
|
||||
|
||||
while readPos < length do begin
|
||||
if path[readPos] = '/' then begin
|
||||
inc(readPos);
|
||||
continue;
|
||||
end;
|
||||
start := readPos;
|
||||
while (readPos < length) and (path[readPos] <> '/') do inc(readPos);
|
||||
count := readPos - start;
|
||||
if (count = 1) and (path[start] = '.') then continue;
|
||||
if (count = 2) and (path[start] = '.') and (path[start + 1] = '.') then begin
|
||||
while (used > 1) and (result[used - 1] <> '/') do dec(used);
|
||||
if used > 1 then dec(used);
|
||||
end else begin
|
||||
if used > 1 then begin
|
||||
result[used] := '/';
|
||||
inc(used);
|
||||
end;
|
||||
memcpy(PtrUInt(path) + start, PtrUInt(result) + used, count);
|
||||
inc(used, count);
|
||||
end;
|
||||
end;
|
||||
result[used] := #0;
|
||||
normalize := result;
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
passed, failed: uint32;
|
||||
beforeFree: SizeUInt;
|
||||
|
||||
procedure Check(actual, expected: pchar);
|
||||
begin
|
||||
if StringEquals(actual, expected) then
|
||||
inc(passed)
|
||||
else begin
|
||||
inc(failed);
|
||||
log('PATH', 'FAIL: path result');
|
||||
end;
|
||||
kfree(void(actual));
|
||||
end;
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
beforeFree := lmm_total_free;
|
||||
Check(absolute('file', '/disk'), '/disk/file');
|
||||
Check(absolute('file', '/disk/'), '/disk/file');
|
||||
Check(absolute('/file', '/disk'), '/file');
|
||||
Check(absolute('file', ''), '/file');
|
||||
Check(absolute('file', nil), '/file');
|
||||
Check(absolute(nil, '/disk'), '/');
|
||||
Check(absolute('', '/disk'), '/disk/');
|
||||
Check(normalize('/a//b/./c/../..'), '/a');
|
||||
Check(normalize('../../a/..'), '/');
|
||||
Check(normalize('/a/../b/../c'), '/c');
|
||||
Check(normalize('a/b/'), '/a/b');
|
||||
Check(normalize('/.../.hidden'), '/.../.hidden');
|
||||
Check(normalize(''), '/');
|
||||
Check(normalize(nil), '/');
|
||||
if lmm_total_free = beforeFree then
|
||||
inc(passed)
|
||||
else begin
|
||||
inc(failed);
|
||||
log('PATH', 'FAIL: path allocation accounting');
|
||||
end;
|
||||
testSummary('PATH', 'PATH_TESTS_PASSED', 'PATH_TESTS_FAILED', passed, failed);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -275,7 +275,7 @@ type
|
||||
TStorage_Device = record
|
||||
id : uint8;
|
||||
controller : TControllerType;
|
||||
controllerId0 : uint32;
|
||||
controllerId0 : PtrUInt;
|
||||
writable : boolean;
|
||||
removed : boolean; { true if device was hot-unplugged }
|
||||
volumes : PDList;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -32,7 +32,7 @@ uses
|
||||
core.strings,
|
||||
io.stdio,
|
||||
debug.tracer,
|
||||
core.util, arch.x86.util;
|
||||
core.util, arch.platform.cpu;
|
||||
|
||||
type
|
||||
|
||||
@@ -91,7 +91,7 @@ var
|
||||
begin
|
||||
|
||||
buffer := puint32(kalloc(disk^.sectorSize))
|
||||
memset(uint32(buffer), 0, disk^.sectorSize);
|
||||
memset(PtrUInt(buffer), 0, disk^.sectorSize);
|
||||
PFilesystemRecord := PFilesystemRecord(buffer);
|
||||
|
||||
filesystemRecord^.magicNumber := $A2F2;
|
||||
@@ -102,7 +102,7 @@ begin
|
||||
//filesystemRecord.volumeLabel := config^
|
||||
|
||||
driver.storage.mgr.storage_write(disk, start, 1, buffer);
|
||||
memset(uint32(buffer), 0, disk^.sectorSize);
|
||||
memset(PtrUInt(buffer), 0, disk^.sectorSize);
|
||||
|
||||
fileEntry := PFileEntry(buffer)[0];
|
||||
fileEntry^.filename := thisArray;
|
||||
|
||||
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
File diff suppressed because it is too large.
Load diff
@@ -14,7 +14,7 @@ uses driver.storage.fs.ext2.types, driver.storage.fs.ext2.core,
|
||||
function ValidateLabel(text : pchar; var normalized : TVolumeLabel) : TError;
|
||||
var i : uint32;
|
||||
begin
|
||||
memset(uint32(@normalized),0,sizeof(normalized));
|
||||
memset(PtrUInt(@normalized),0,sizeof(normalized));
|
||||
ValidateLabel:=eInvalidArgument; if text=nil then exit;
|
||||
i:=0;
|
||||
while (i<16) and (text[i]<>char(0)) do begin
|
||||
@@ -29,7 +29,7 @@ function Geometry(volume : PStorage_Volume; sectors, start : uint32; config : PF
|
||||
var g, count, minimum, perBlock, tables, reserve : uint32; labelText : TVolumeLabel;
|
||||
begin
|
||||
Geometry:=eInvalidArgument;
|
||||
memset(uint32(@v),0,sizeof(v));
|
||||
memset(PtrUInt(@v),0,sizeof(v));
|
||||
if volume=nil then exit;
|
||||
if volume^.device=nil then exit;
|
||||
if not volume^.device^.writable then begin Geometry:=eReadOnly; exit; end;
|
||||
@@ -98,7 +98,7 @@ begin
|
||||
if err<>eNone then begin kfree(void(v)); FormatVolume:=err; exit; end;
|
||||
op:=PExt2Op(kalloc(sizeof(TExt2Op)));
|
||||
if op=nil then begin kfree(void(v)); exit; end;
|
||||
memset(uint32(op),0,sizeof(TExt2Op)); op^.V:=v;
|
||||
memset(PtrUInt(op),0,sizeof(TExt2Op)); op^.V:=v;
|
||||
v^.Super:=puint8(kalloc(1024)); v^.Groups:=puint8(kalloc(v^.GDTBlocks*v^.BlockSize));
|
||||
op^.Scratch:=puint8(kalloc(v^.BlockSize));
|
||||
if (v^.Super=nil) or (v^.Groups=nil) or (op^.Scratch=nil) then begin
|
||||
@@ -106,7 +106,7 @@ begin
|
||||
if op^.Scratch<>nil then kfree(void(op^.Scratch));
|
||||
kfree(void(op)); kfree(void(v)); exit;
|
||||
end;
|
||||
memset(uint32(v^.Super),0,1024); memset(uint32(v^.Groups),0,v^.GDTBlocks*v^.BlockSize);
|
||||
memset(PtrUInt(v^.Super),0,1024); memset(PtrUInt(v^.Groups),0,v^.GDTBlocks*v^.BlockSize);
|
||||
Put32(v^.Super,0,v^.InodeCount); Put32(v^.Super,4,v^.BlockCount);
|
||||
Put32(v^.Super,16,v^.InodeCount-10); Put32(v^.Super,20,v^.FirstBlock);
|
||||
i:=0; if v^.BlockSize=2048 then i:=1 else if v^.BlockSize=4096 then i:=2;
|
||||
@@ -120,13 +120,13 @@ begin
|
||||
v^.Super[110]:=(v^.Super[110] and $0F) or $40;
|
||||
v^.Super[112]:=(v^.Super[112] and $3F) or $80;
|
||||
if config<>nil then if (config^.Flags and FS_FORMAT_PARAM_LABEL)<>0 then
|
||||
memcpy(uint32(@config^.LabelText[0]),uint32(v^.Super)+120,11);
|
||||
memcpy(PtrUInt(@config^.LabelText[0]),PtrUInt(v^.Super)+120,11);
|
||||
tables:=v^.InodesPerGroup div (v^.BlockSize div 128); freeBlocks:=0; rootBlock:=0;
|
||||
for g:=0 to v^.GroupCount-1 do begin
|
||||
first:=v^.FirstBlock+g*v^.BlocksPerGroup; count:=v^.BlockCount-first;
|
||||
if count>v^.BlocksPerGroup then count:=v^.BlocksPerGroup;
|
||||
reserve:=0; if HasSuper(g,1) then reserve:=1+v^.GDTBlocks;
|
||||
d:=PExt2Group(uint32(v^.Groups)+g*32);
|
||||
d:=PExt2Group(PtrUInt(v^.Groups)+g*32);
|
||||
d^.BlockBitmap:=first+reserve; d^.InodeBitmap:=first+reserve+1; d^.InodeTable:=first+reserve+2;
|
||||
used:=reserve+2+tables;
|
||||
d^.FreeInodes:=v^.InodesPerGroup;
|
||||
@@ -135,42 +135,42 @@ begin
|
||||
end;
|
||||
Put32(v^.Super,12,freeBlocks);
|
||||
{ Invalidate the primary signature before writing metadata. Publish it last. }
|
||||
memset(uint32(op^.Scratch),0,v^.BlockSize);
|
||||
memset(PtrUInt(op^.Scratch),0,v^.BlockSize);
|
||||
op^.Error:=storage_write(volume^.device,start+2,2,puint32(op^.Scratch));
|
||||
g:=0;
|
||||
while (g<v^.GroupCount) and (op^.Error=eNone) do begin
|
||||
first:=v^.FirstBlock+g*v^.BlocksPerGroup; count:=v^.BlockCount-first;
|
||||
if count>v^.BlocksPerGroup then count:=v^.BlocksPerGroup;
|
||||
d:=PExt2Group(uint32(v^.Groups)+g*32); used:=count-d^.FreeBlocks;
|
||||
memset(uint32(op^.Scratch),$FF,v^.BlockSize);
|
||||
d:=PExt2Group(PtrUInt(v^.Groups)+g*32); used:=count-d^.FreeBlocks;
|
||||
memset(PtrUInt(op^.Scratch),$FF,v^.BlockSize);
|
||||
for bit:=used to count-1 do op^.Scratch[bit div 8]:=op^.Scratch[bit div 8] and not (1 shl (bit mod 8));
|
||||
WriteBlock(op,d^.BlockBitmap,op^.Scratch);
|
||||
memset(uint32(op^.Scratch),$FF,v^.BlockSize);
|
||||
memset(PtrUInt(op^.Scratch),$FF,v^.BlockSize);
|
||||
used:=0; if g=0 then used:=10;
|
||||
for bit:=used to v^.InodesPerGroup-1 do op^.Scratch[bit div 8]:=op^.Scratch[bit div 8] and not (1 shl (bit mod 8));
|
||||
WriteBlock(op,d^.InodeBitmap,op^.Scratch);
|
||||
memset(uint32(op^.Scratch),0,v^.BlockSize);
|
||||
memset(PtrUInt(op^.Scratch),0,v^.BlockSize);
|
||||
for i:=0 to tables-1 do begin
|
||||
if not WriteBlock(op,d^.InodeTable+i,op^.Scratch) then break;
|
||||
end;
|
||||
if HasSuper(g,1) then begin
|
||||
for i:=0 to v^.GDTBlocks-1 do
|
||||
if not WriteBlock(op,first+1+i,pointer(uint32(v^.Groups)+i*v^.BlockSize)) then break;
|
||||
if not WriteBlock(op,first+1+i,pointer(PtrUInt(v^.Groups)+i*v^.BlockSize)) then break;
|
||||
if g<>0 then begin
|
||||
memset(uint32(op^.Scratch),0,v^.BlockSize);
|
||||
memcpy(uint32(v^.Super),uint32(op^.Scratch),1024); Put16(op^.Scratch,90,g);
|
||||
memset(PtrUInt(op^.Scratch),0,v^.BlockSize);
|
||||
memcpy(PtrUInt(v^.Super),PtrUInt(op^.Scratch),1024); Put16(op^.Scratch,90,g);
|
||||
WriteBlock(op,first,op^.Scratch);
|
||||
end;
|
||||
end;
|
||||
Inc(g);
|
||||
end;
|
||||
if op^.Error=eNone then begin
|
||||
memset(uint32(op^.Scratch),0,v^.BlockSize);
|
||||
inode:=PExt2Inode(uint32(op^.Scratch)+128);
|
||||
memset(PtrUInt(op^.Scratch),0,v^.BlockSize);
|
||||
inode:=PExt2Inode(PtrUInt(op^.Scratch)+128);
|
||||
inode^.Mode:=EXT2_DIR or $1ED; inode^.Size:=v^.BlockSize; inode^.Links:=2;
|
||||
inode^.Sectors:=v^.SectorsPerBlock; inode^.Blocks[0]:=rootBlock;
|
||||
WriteBlock(op,PExt2Group(v^.Groups)^.InodeTable,op^.Scratch);
|
||||
memset(uint32(op^.Scratch),0,v^.BlockSize);
|
||||
memset(PtrUInt(op^.Scratch),0,v^.BlockSize);
|
||||
Put32(op^.Scratch,0,2); Put16(op^.Scratch,4,12); op^.Scratch[6]:=1; op^.Scratch[7]:=2; op^.Scratch[8]:=ord('.');
|
||||
Put32(op^.Scratch,12,2); Put16(op^.Scratch,16,v^.BlockSize-12); op^.Scratch[18]:=2; op^.Scratch[19]:=2;
|
||||
op^.Scratch[20]:=ord('.'); op^.Scratch[21]:=ord('.');
|
||||
@@ -188,14 +188,14 @@ begin
|
||||
SetLabel:=ValidateLabel(text,labelText); if SetLabel<>eNone then exit;
|
||||
op:=BeginOp(volume); if op=nil then begin SetLabel:=eOutOfMemory; exit; end;
|
||||
if BeginMutation(op) then begin
|
||||
memcpy(uint32(@labelText),uint32(op^.V^.Super)+120,16);
|
||||
memcpy(PtrUInt(@labelText),PtrUInt(op^.V^.Super)+120,16);
|
||||
for g:=1 to op^.V^.GroupCount-1 do if HasSuper(g,Get32(op^.V^.Super,100)) then begin
|
||||
first:=op^.V^.FirstBlock+g*op^.V^.BlocksPerGroup;
|
||||
if not ReadBlock(op,first,op^.Scratch) then break;
|
||||
memcpy(uint32(@labelText),uint32(op^.Scratch)+120,16);
|
||||
memcpy(PtrUInt(@labelText),PtrUInt(op^.Scratch)+120,16);
|
||||
if not WriteBlock(op,first,op^.Scratch) then break;
|
||||
end;
|
||||
if FinishMutation(op) then memcpy(uint32(@labelText),uint32(@volume^.labelText),sizeof(labelText));
|
||||
if FinishMutation(op) then memcpy(PtrUInt(@labelText),PtrUInt(@volume^.labelText),sizeof(labelText));
|
||||
end;
|
||||
SetLabel:=op^.Error; EndOp(op);
|
||||
end;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
unit driver.storage.fs.ext2;
|
||||
|
||||
interface
|
||||
uses driver.storage.types;
|
||||
uses arch.platform.cpu, driver.storage.types;
|
||||
procedure StartWorker;
|
||||
procedure init;
|
||||
procedure ReleaseVolume(volume : PStorage_Volume);
|
||||
|
||||
implementation
|
||||
uses boot.mgr, driver.storage.fs.mgr, driver.storage.vol.mgr,
|
||||
uses driver.storage.fs.mgr, driver.storage.vol.mgr,
|
||||
driver.storage.fs.ext2.types, driver.storage.fs.ext2.core,
|
||||
driver.storage.fs.ext2.format, memory.heap, core.util, core.strings,
|
||||
proc.mgr, proc.types;
|
||||
@@ -62,15 +63,17 @@ begin
|
||||
end;
|
||||
|
||||
procedure WorkLoop(pctx : PProcessContext);
|
||||
var work : PWork; done : uint32; error : TError; callback : TIOCallback; data : pointer;
|
||||
var
|
||||
savedIRQ: PtrUInt;
|
||||
work : PWork; done : uint32; error : TError; callback : TIOCallback; data : pointer;
|
||||
begin
|
||||
while true do begin
|
||||
asm pushf; cli end;
|
||||
savedIRQ := arch.platform.cpu.lock;
|
||||
work:=head;
|
||||
if work<>nil then begin
|
||||
head:=work^.Next; if head=nil then tail:=nil; Dec(queued);
|
||||
end else pctx^.State:=psAwaiting;
|
||||
asm popf end;
|
||||
arch.platform.cpu.unlock(savedIRQ);
|
||||
if work=nil then begin
|
||||
{ Queue publication wakes the worker under the same CLI section.
|
||||
No per-I/O process, IRQ continuation, or volatile spin is needed. }
|
||||
@@ -92,7 +95,9 @@ begin worker:=proc.mgr.create('ext2.io',@WorkLoop,nil,1); end;
|
||||
procedure QueueTransfer(volume : PStorage_Volume; directory, name : pchar; offset : uint32;
|
||||
buffer : puint32; count : uint32; ctx : pointer; completed : puint32;
|
||||
callback : TIOCallback; data : pointer; writing : boolean);
|
||||
var work : PWork; error : TError;
|
||||
var
|
||||
savedIRQ: PtrUInt;
|
||||
work : PWork; error : TError;
|
||||
begin
|
||||
if completed<>nil then completed^:=0;
|
||||
error:=eNone;
|
||||
@@ -101,7 +106,7 @@ begin
|
||||
if error<>eNone then begin if callback<>nil then callback(error,data); exit; end;
|
||||
work:=PWork(kalloc(sizeof(TWork)));
|
||||
if work=nil then begin if callback<>nil then callback(eOutOfMemory,data); exit; end;
|
||||
memset(uint32(work),0,sizeof(TWork));
|
||||
memset(PtrUInt(work),0,sizeof(TWork));
|
||||
if ctx=nil then begin
|
||||
if (directory=nil) or (name=nil) then error:=eInvalidArgument else begin
|
||||
work^.Directory:=stringCopy(directory); work^.Name:=stringCopy(name);
|
||||
@@ -112,13 +117,13 @@ begin
|
||||
work^.Volume:=volume; work^.FileCtx:=PExt2File(ctx); work^.Offset:=offset;
|
||||
work^.Buffer:=buffer; work^.Count:=count; work^.Completed:=completed;
|
||||
work^.Writing:=writing; work^.Callback:=callback; work^.CallbackData:=data;
|
||||
asm pushf; cli end;
|
||||
savedIRQ := arch.platform.cpu.lock;
|
||||
if queued>=64 then error:=eQueueFull else begin
|
||||
if tail=nil then head:=work else tail^.Next:=work;
|
||||
tail:=work; Inc(queued);
|
||||
if worker^.State=psAwaiting then worker^.State:=psReady;
|
||||
end;
|
||||
asm popf end;
|
||||
arch.platform.cpu.unlock(savedIRQ);
|
||||
if error<>eNone then begin FreeWork(work); if callback<>nil then callback(error,data); end;
|
||||
end;
|
||||
|
||||
@@ -177,7 +182,7 @@ var volume : PStorage_Volume;
|
||||
begin
|
||||
if device=nil then exit;
|
||||
volume:=PStorage_Volume(kalloc(sizeof(TStorage_Volume))); if volume=nil then exit;
|
||||
memset(uint32(volume),0,sizeof(TStorage_Volume));
|
||||
memset(PtrUInt(volume),0,sizeof(TStorage_Volume));
|
||||
volume^.device:=device; volume^.sectorCount:=device^.maxSectorCount; volume^.sectorSize:=device^.sectorSize;
|
||||
if Identify(volume) then begin
|
||||
volume^.filesystem:=@filesystem;
|
||||
@@ -187,7 +192,7 @@ end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
memset(uint32(@filesystem),0,sizeof(filesystem));
|
||||
memset(PtrUInt(@filesystem),0,sizeof(filesystem));
|
||||
filesystem.sName:='EXT2'; filesystem.system_id:=$83;
|
||||
filesystem.identifyCallback:=@Identify; filesystem.detectCallback:=@Detect;
|
||||
filesystem.validateFormat:=@ValidateFormat; filesystem.createCallback:=@FormatVolume;
|
||||
@@ -203,7 +208,4 @@ begin
|
||||
driver.storage.fs.mgr.register_filesystem(@filesystem);
|
||||
end;
|
||||
|
||||
initialization
|
||||
boot.mgr.registerBoot('driver.storage.fs.ext2',@init,'Ext2 Filesystem','driver.storage.fs.mgr');
|
||||
boot.mgr.registerBoot('driver.storage.ext2.worker',@StartWorker,'Ext2 I/O Worker','proc.mgr');
|
||||
end.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -14,7 +14,7 @@ function normalize_label(text : pchar; var normalized : TVolumeLabel) : TError;
|
||||
var i, n, first : uint32; c : char;
|
||||
begin
|
||||
normalize_label := eInvalidArgument;
|
||||
memset(uint32(@normalized[0]), 0, sizeof(normalized));
|
||||
memset(PtrUInt(@normalized[0]), 0, sizeof(normalized));
|
||||
if text = nil then exit;
|
||||
n := 0;
|
||||
while (n < 12) and (text[n] <> #0) do Inc(n);
|
||||
@@ -37,7 +37,7 @@ end;
|
||||
procedure unpack_label(src : pchar; var dest : TVolumeLabel);
|
||||
var n, i : uint32;
|
||||
begin
|
||||
memset(uint32(@dest[0]), 0, sizeof(dest));
|
||||
memset(PtrUInt(@dest[0]), 0, sizeof(dest));
|
||||
n := 11; while (n > 0) and ((src[n-1] = ' ') or (src[n-1] = #0)) do Dec(n);
|
||||
for i := 0 to 10 do if i < n then dest[i] := src[i];
|
||||
end;
|
||||
@@ -62,7 +62,7 @@ begin
|
||||
br := PBootRecord(buffer); lim := FAT32ClusterLimit(br);
|
||||
if (lim <= 2) or (br^.manySectors = 0) or (br^.manySectors > volume^.sectorCount) or
|
||||
(br^.rootCluster < 2) or (br^.rootCluster >= lim) or
|
||||
(puint16(uint32(buffer)+510)^ <> $AA55) then load_boot := eCorruptFilesystem;
|
||||
(puint16(PtrUInt(buffer)+510)^ <> $AA55) then load_boot := eCorruptFilesystem;
|
||||
end;
|
||||
|
||||
{ Bounded walk of the root FAT chain. A label is authoritative when present.
|
||||
@@ -113,12 +113,12 @@ var mem, boot, scratch : puint32; sector, offset, i : uint32; found, noName : bo
|
||||
begin
|
||||
mem := puint32(kalloc(1024));
|
||||
if mem = nil then begin read_label := eOutOfMemory; exit; end;
|
||||
boot := mem; scratch := puint32(uint32(mem)+512);
|
||||
boot := mem; scratch := puint32(PtrUInt(mem)+512);
|
||||
read_label := load_boot(volume,boot);
|
||||
if read_label = eNone then begin
|
||||
read_label := locate_label(volume,PBootRecord(boot),scratch,sector,offset,found);
|
||||
if read_label = eNone then begin
|
||||
if found then unpack_label(pchar(uint32(scratch)+offset),value)
|
||||
if found then unpack_label(pchar(PtrUInt(scratch)+offset),value)
|
||||
else begin
|
||||
unpack_label(pchar(@PBootRecord(boot)^.volumeLabel[0]),value);
|
||||
noName := true;
|
||||
@@ -142,8 +142,8 @@ begin
|
||||
if not volume^.device^.writable then begin write_label := eReadOnly; exit; end;
|
||||
mem := puint32(kalloc(5*512));
|
||||
if mem = nil then begin write_label := eOutOfMemory; exit; end;
|
||||
boot := mem; scratch := puint32(uint32(mem)+512); rootOld := puint32(uint32(mem)+1024);
|
||||
backupOld := puint32(uint32(mem)+1536); bootOld := puint32(uint32(mem)+2048);
|
||||
boot := mem; scratch := puint32(PtrUInt(mem)+512); rootOld := puint32(PtrUInt(mem)+1024);
|
||||
backupOld := puint32(PtrUInt(mem)+1536); bootOld := puint32(PtrUInt(mem)+2048);
|
||||
bootWritten := false; backupWritten := false; rootWritten := false; backup := 0;
|
||||
repeat
|
||||
write_label := load_boot(volume,boot); if write_label <> eNone then break;
|
||||
@@ -153,17 +153,17 @@ begin
|
||||
if (sector = 0) and (value[0] <> #0) then begin write_label := eDiskFull; break; end;
|
||||
if sector <> 0 then begin
|
||||
write_label := storage_read(volume^.device,sector,1,scratch); if write_label <> eNone then break;
|
||||
memcpy(uint32(scratch),uint32(rootOld),512);
|
||||
entry := PDirectory(uint32(scratch)+offset);
|
||||
memcpy(PtrUInt(scratch),PtrUInt(rootOld),512);
|
||||
entry := PDirectory(PtrUInt(scratch)+offset);
|
||||
if value[0] = #0 then begin
|
||||
if found then entry^.fileName[0] := char($E5);
|
||||
end else begin
|
||||
if entry^.fileName[0] = #0 then begin
|
||||
{ Retain an end marker after a newly inserted label. }
|
||||
if offset = 480 then begin write_label := eDiskFull; break; end;
|
||||
puint8(uint32(entry)+32)^ := 0;
|
||||
puint8(PtrUInt(entry)+32)^ := 0;
|
||||
end;
|
||||
memset(uint32(entry),0,32); pack_label(@value[0],@entry^.fileName[0]); entry^.attributes := $08;
|
||||
memset(PtrUInt(entry),0,32); pack_label(@value[0],@entry^.fileName[0]); entry^.attributes := $08;
|
||||
end;
|
||||
end;
|
||||
if (br^.backupCluster <> 0) and (br^.backupCluster <> $FFFF) then begin
|
||||
@@ -171,7 +171,7 @@ begin
|
||||
backup := volume^.sectorStart+br^.backupCluster;
|
||||
write_label := storage_read(volume^.device,backup,1,backupOld); if write_label <> eNone then break;
|
||||
end;
|
||||
memcpy(uint32(boot),uint32(bootOld),512);
|
||||
memcpy(PtrUInt(boot),PtrUInt(bootOld),512);
|
||||
if value[0] = #0 then pack_label('NO NAME',pchar(@br^.volumeLabel[0]))
|
||||
else pack_label(@value[0],pchar(@br^.volumeLabel[0]));
|
||||
bootWritten := true;
|
||||
@@ -180,7 +180,7 @@ begin
|
||||
bootWritten := true;
|
||||
if backup <> 0 then begin
|
||||
{ Preserve backup-specific bytes; only update its label. }
|
||||
memcpy(uint32(backupOld),uint32(boot),512);
|
||||
memcpy(PtrUInt(backupOld),PtrUInt(boot),512);
|
||||
if value[0] = #0 then pack_label('NO NAME',pchar(@br^.volumeLabel[0]))
|
||||
else pack_label(@value[0],pchar(@br^.volumeLabel[0]));
|
||||
backupWritten := true;
|
||||
|
||||
@@ -3,7 +3,6 @@ unit driver.storage.fs.fat32;
|
||||
interface
|
||||
|
||||
uses
|
||||
boot.mgr,
|
||||
driver.storage.fs.mgr,
|
||||
driver.storage.types;
|
||||
|
||||
@@ -31,7 +30,7 @@ end;
|
||||
procedure init;
|
||||
begin
|
||||
io.syslog.logln('FAT32', 'init: registering FAT32 filesystem');
|
||||
memset(uint32(@filesystem), 0, sizeof(TFilesystem));
|
||||
memset(PtrUInt(@filesystem), 0, sizeof(TFilesystem));
|
||||
filesystem.sName := 'FAT32';
|
||||
filesystem.system_id := $0B;
|
||||
filesystem.readDirCallback := @FAT32ReadDirectory;
|
||||
@@ -61,7 +60,4 @@ begin
|
||||
driver.storage.fs.mgr.register_filesystem(@filesystem);
|
||||
end;
|
||||
|
||||
initialization
|
||||
boot.mgr.registerBoot('driver.storage.fs.fat32', @init, 'FAT32 Filesystem', 'driver.storage.fs.mgr');
|
||||
|
||||
end.
|
||||
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