Compare commits
42
Commits
develop
...
64a83a6c83
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64a83a6c83 | ||
|
|
81d1b97cd0 | ||
|
|
84b589c856 | ||
|
|
8b80b6864b | ||
|
|
232f6b5485 | ||
|
|
569b2f0bca | ||
|
|
ed0f8d9c08 | ||
|
|
a2f6d7e76d | ||
|
|
babe4290e4 | ||
|
|
05eab23956 | ||
|
|
f04f8aa411 | ||
|
|
6a3ebf1387 | ||
|
|
b2ecbe58da | ||
|
|
2014ce4f9c | ||
|
|
6cd9ae4f46 | ||
|
|
0855abfd41 | ||
|
|
fd0de9f1d2 | ||
|
|
920aca5bbf | ||
|
|
837d69a44b | ||
|
|
f0d5eb21f1 | ||
|
|
07e9095582 | ||
|
|
72769fbef7 | ||
|
|
95599c0e7c | ||
|
|
fcaafa0d12 | ||
|
|
e490b95f1d | ||
|
|
b601080960 | ||
|
|
27177979a2 | ||
|
|
f88a282893 | ||
|
|
ff4c597ff3 | ||
|
|
24c371cab1 | ||
|
|
7588a4c9cb | ||
|
|
5cb415c76b | ||
|
|
118d8b0c03 | ||
|
|
28caca3bcc | ||
|
|
6476a774dc | ||
|
|
e791edb02a | ||
|
|
da36f6fabb | ||
|
|
97e1a18253 | ||
|
|
88a850e8fc | ||
|
|
10c9194c5f | ||
|
|
94b477d8f7 | ||
|
|
ba38f4fd19 |
No files matched your search
+1
-2
@@ -10,5 +10,4 @@
|
||||
/*.sh~
|
||||
/*.img
|
||||
src/include/asuro.pas
|
||||
.vscode/launch.json
|
||||
.vscode
|
||||
localenv.json
|
||||
Vendored
+3
-10
@@ -3,18 +3,11 @@
|
||||
{
|
||||
"name":"Run",
|
||||
"request": "launch",
|
||||
"type": "coreclr",
|
||||
"type": "PowerShell",
|
||||
"preLaunchTask": "Build",
|
||||
"program": "VBoxSDL",
|
||||
"args": [
|
||||
"--comment",
|
||||
"Asuro",
|
||||
"--startvm",
|
||||
"7d395c96-891c-4139-b77d-9b6b144b0b93"
|
||||
],
|
||||
"script": "${workspaceFolder}/virtualbox-wrapper.ps1",
|
||||
"args": ["-Command", "up"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "internalConsole",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+24
-2
@@ -9,14 +9,18 @@
|
||||
"command": "docker-compose",
|
||||
"args": [
|
||||
"run",
|
||||
"builder"
|
||||
"builder",
|
||||
],
|
||||
"type": "shell",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"Close VirtualBox",
|
||||
"Clean"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Build (Builder)",
|
||||
@@ -26,6 +30,24 @@
|
||||
"builder"
|
||||
],
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"label": "Clean",
|
||||
"command": "docker-compose",
|
||||
"args": [
|
||||
"down",
|
||||
"--remove-orphans"
|
||||
],
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"label": "Close VirtualBox",
|
||||
"command": "./virtualbox-wrapper.ps1",
|
||||
"args": [
|
||||
"-Command",
|
||||
"down"
|
||||
],
|
||||
"type": "shell"
|
||||
}
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -4,4 +4,4 @@ echo "======================="
|
||||
echo " "
|
||||
echo "Compiling FPC Sources..."
|
||||
echo " "
|
||||
fpc -Aelf -gw -n -va -O3 -Op3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -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
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 = 0x0B00B1E5
|
||||
|
||||
|
||||
the Rest of the sector is reserved
|
||||
|
||||
---
|
||||
|
||||
Starting from sector 1 is the file table. Table size is determined by entry size (64) * 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
|
||||
|
||||
---
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
builder:
|
||||
build: .
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Hello from the Asuro ISO!
|
||||
@@ -13,8 +13,8 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
|
||||
I don't think this needs an explaination.
|
||||
* [VSCode (Optional, but highly recommended)](https://code.visualstudio.com/)
|
||||
Visual Studio code is our IDE of choice, and we have a number of recommended plugins.
|
||||
* [C# Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp)
|
||||
This plugin gives you the ability to use the 'coreclr' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro.
|
||||
* [PowerShell Plugin by Microsoft](https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell)
|
||||
This plugin gives you the ability to use the 'PowerShell' task type, allowing the automatic launching of virtualbox with the resulting image generated during compilation of Asuro.
|
||||
* [VirtualBox](https://www.virtualbox.org/)
|
||||
Virtualbox is our Virtualisation environment of choice, don't ask why, it just is.
|
||||
|
||||
@@ -27,7 +27,7 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
|
||||
3. Install Docker for Windows.
|
||||
4. Install Git for Windows.
|
||||
5. Install VSCode & the listed plugins.
|
||||
6. Install VirtualBox.
|
||||
6. Install VirtualBox (v7+).
|
||||
7. Clone this repository.
|
||||
8. Run the following command in the root of the repo to build the docker image:
|
||||
```powershell
|
||||
@@ -50,32 +50,29 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
|
||||
```xml
|
||||
<Machine uuid="{7d395c96-891c-4139-b77d-9b6b144b0b93}" name="Asuro" OSType="Linux" snapshotFolder="Snapshots" lastStateChange="2021-06-20T20:33:07Z">
|
||||
```
|
||||
Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` and replace the uuid found in `.vscode\launch.json` under `args`, so that it looks something like this:
|
||||
Copy the uuid, in our case `7d395c96-891c-4139-b77d-9b6b144b0b93` & create a `localenv.json` file in the project root with the following content:
|
||||
```json
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name":"Run",
|
||||
"request": "launch",
|
||||
"type": "coreclr",
|
||||
"preLaunchTask": "Build",
|
||||
"program": "VBoxSDL",
|
||||
"args": [
|
||||
"--comment",
|
||||
"Asuro",
|
||||
"--startvm",
|
||||
"<YOUR UUID HERE>"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "internalConsole",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
}
|
||||
]
|
||||
"VirtualBox":{
|
||||
"MachineName":"<YOUR_UUID_OR_MACHINE_NAME>"
|
||||
}
|
||||
}
|
||||
```
|
||||
This will allow VSCode to automatically launch VirtualBox once Asuro has been compiled.
|
||||
|
||||
You can also enable the serial adapter "COM1" in mode "Raw File", give it a path, and provide this path in the `localenv.json` as follows:
|
||||
```json
|
||||
{
|
||||
"VirtualBox" : {
|
||||
"MachineName": "<YOUR_UUID_OR_MACHINE_NAME>",
|
||||
"LogLocation": "Fully\\Qualified\\Path\\To\\Your\\Log\\File"
|
||||
}
|
||||
}
|
||||
```
|
||||
This will allow you to see the console output from Asuro in your host terminal.
|
||||
13. Open your project folder in VSCode, use CTRL+SHIFT+B to build & F5 to build + run in VBox.
|
||||
14. Congratulations! You can now play with Asuro!
|
||||
|
||||
### Gotchas
|
||||
### Notes & Gotchas
|
||||
- The above process has been updated to be compatible with VirtualBox 7+, in which VBoxSDL was removed and vboxmanage should be used in its place. A small wrapper powershell script is used to achieve this.
|
||||
- It was noted that Windows builds above `20H2` seem to have issues installing WSL2. We may have to wait for a patch from Microsoft to fix this. Our devs are currently using build `20H2`.
|
||||
+585
File diff suppressed because it is too large.
Load diff
@@ -91,6 +91,7 @@ function getDeviceInfo(class_code : uint8; subclass_code : uint8; prog_if : uint
|
||||
procedure requestConfig(bus : uint8; slot : uint8; func : uint8; row : uint8);
|
||||
procedure writeConfig(bus: uint8; slot : uint8; func : uint8; row : uint8; val : uint32);
|
||||
procedure setBusMaster(bus : uint8; slot : uint8; func : uint8; master : boolean);
|
||||
procedure enableDevice(bus : uint8; slot : uint8; func : uint8);
|
||||
|
||||
implementation
|
||||
|
||||
@@ -442,4 +443,34 @@ begin
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
//Enable device inturrupts and set bus master
|
||||
procedure enableDevice(bus : uint8; slot : uint8; func : uint8);
|
||||
var
|
||||
addr : uint32;
|
||||
cmd : uint32;
|
||||
begin
|
||||
push_trace('PCI.enableDevice');
|
||||
|
||||
addr := ($1 shl 31);
|
||||
addr := addr or (bus shl 16);
|
||||
addr := addr or ((slot) shl 11);
|
||||
addr := addr or ((func) shl 8);
|
||||
addr := addr or ($04 and $FC);
|
||||
|
||||
outl(PCI_CONFIG_ADDRESS_PORT, addr);
|
||||
cmd := inl(PCI_CONFIG_DATA_PORT);
|
||||
cmd := cmd or PCI_COMMAND_MEM_SPACE;
|
||||
cmd := cmd or PCI_COMMAND_BUS_MASTER;
|
||||
cmd := cmd or (3 shl 1);
|
||||
|
||||
//enable interrupts, remove disable interrupt bit maybe
|
||||
cmd := cmd and not PCI_COMMAND_INT_DISABLE;
|
||||
// cmd := cmd and not (1 shl 9);
|
||||
|
||||
outl(PCI_CONFIG_ADDRESS_PORT, addr);
|
||||
outl(PCI_CONFIG_DATA_PORT, cmd);
|
||||
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -21,6 +21,29 @@ unit drivertypes;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
PCI_CONFIG_ADDRESS_PORT = $0CF8;
|
||||
PCI_CONFIG_DATA_PORT = $0CFC;
|
||||
|
||||
PCI_COMMAND_IO_SPACE = $0001;
|
||||
PCI_COMMAND_MEM_SPACE = $0002;
|
||||
PCI_COMMAND_BUS_MASTER = $0004;
|
||||
PCI_COMMAND_SPECIAL_CYC = $0008;
|
||||
PCI_COMMAND_MEM_WRITE = $0010;
|
||||
PCI_COMMAND_VGA_PALETTE = $0020;
|
||||
PCI_COMMAND_PARITY = $0040;
|
||||
PCI_COMMAND_WAIT = $0080;
|
||||
PCI_COMMAND_SERR = $0100;
|
||||
PCI_COMMAND_FAST_BACK = $0200;
|
||||
PCI_COMMAND_INT_DISABLE = $0400;
|
||||
PCI_COMMAND_SERR_ENABLE = $8000;
|
||||
|
||||
PCI_CAP_ID_MSI = $05;
|
||||
|
||||
// Bits in the MSI Control register (16-bit):
|
||||
MSI_CONTROL_ENABLE = 1 shl 0; // Bit 0
|
||||
MSI_CONTROL_64BIT = 1 shl 7; // Bit 7
|
||||
MSI_CONTROL_PVMASK = 1 shl 8; // Bit 8 (optional: per-vector masking)
|
||||
type
|
||||
|
||||
PPCI_Device = ^TPCI_Device;
|
||||
@@ -44,6 +67,7 @@ type
|
||||
address1 : uint32;
|
||||
address2 : uint32;
|
||||
address3 : uint32;
|
||||
|
||||
address4 : uint32;
|
||||
address5 : uint32;
|
||||
CIS_pointer : uint32;
|
||||
|
||||
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,58 @@
|
||||
# AHCI Driver Notes
|
||||
|
||||
## Pre-scheduling / Process Kill Hazards
|
||||
|
||||
### 1. Dangling DMA Buffer (critical)
|
||||
When a process is killed, its `kalloc`'d buffers get freed. But the AHCI hardware
|
||||
is still DMA'ing into that physical memory. The DMA write lands on whatever now
|
||||
occupies that memory, silently corrupting the kernel heap or another process.
|
||||
|
||||
**Fix:** Before freeing a process's memory, either:
|
||||
- Wait for all its pending AHCI slots to drain (`cmd_issue` bits clear), or
|
||||
- Issue a port reset to abort in-flight commands, *then* free memory.
|
||||
|
||||
### 2. Dangling Completion Callback / Userdata Pointer (critical)
|
||||
In `storage_read`/`storage_write`, the completion callback writes to `@done` —
|
||||
a **stack-local variable**. If the scheduler preempts or kills the process while
|
||||
it's in the `hlt` loop, that stack frame is gone. The ISR fires and writes to a
|
||||
dangling stack address, corrupting whatever now uses that stack page.
|
||||
|
||||
**Fix:** The `done` flag and completion context must be heap-allocated (or in a
|
||||
kernel-owned structure that outlives the process). A per-request struct like:
|
||||
```pascal
|
||||
type TPendingIO = record
|
||||
done : uint32;
|
||||
ownerPID : uint32; { skip delivery if process is dead }
|
||||
end;
|
||||
```
|
||||
|
||||
### 3. Command Slot Leak
|
||||
If a process is killed with pending I/O, `pending[slot].inUse` stays `true`
|
||||
forever. Eventually all 32 slots fill up and the device becomes unusable.
|
||||
|
||||
**Fix:** When killing a process, scan all AHCI devices for `pending[]` entries
|
||||
belonging to that process, and either:
|
||||
- Let the hardware finish but null out the completion callback (ISR just frees slot), or
|
||||
- Abort the command (port reset) and clear the slot.
|
||||
|
||||
### 4. Interrupt-Disabled Preemption
|
||||
The `asm sti` before the `hlt` loop is fine, but if the timer fires during setup
|
||||
(between `readCallbackAsync(...)` and `asm sti`), the process could be switched
|
||||
out with interrupts in an unexpected state. `hlt` is also not preemption-safe.
|
||||
|
||||
**Fix:** Move to a proper wait-queue/sleep mechanism instead of `hlt`.
|
||||
|
||||
## Recommended Path Forward
|
||||
Implement a small **I/O request queue** owned by the kernel (not the process stack):
|
||||
1. Allocate a request struct
|
||||
2. Put it on a per-device queue
|
||||
3. ISR completes it
|
||||
4. Process kill walks the queue and cancels entries for that PID
|
||||
|
||||
## Other Bugs Fixed (2026-03-03)
|
||||
- **vtop mask bug:** `$FFFFFF` (24-bit) → `$3FFFFF` (22-bit) for 4MB page offset
|
||||
- **find_cmd_slot:** Now checks `pending[].inUse` in addition to `cmd_issue` bit
|
||||
- **Missing lba5:** Both `send_read_dma_async` and `send_write_dma_async` now write all 48 LBA bits
|
||||
- **IOAPIC routing:** PCI interrupts routed through IOAPIC so AHCI interrupts actually reach the CPU
|
||||
- **LAPIC EOI:** `ISR_N` now sends LAPIC EOI for IOAPIC-delivered interrupts
|
||||
- **PxIS pre-clear removed:** No longer blanket-clears port interrupt status before issuing commands (was eating other slots' completions)
|
||||
@@ -1,85 +0,0 @@
|
||||
// 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.
|
||||
|
||||
{
|
||||
Drivers->Storage->ATA_ISR - Primary ATA IRQ.
|
||||
|
||||
@author(Aaron Hance <[email protected]>)
|
||||
}
|
||||
unit ATA_ISR;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
util,
|
||||
console,
|
||||
isr_types,
|
||||
isrmanager,
|
||||
IDT;
|
||||
|
||||
procedure register();
|
||||
procedure hook(hook_method : uint32);
|
||||
procedure unhook(hook_method : uint32);
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
Hooks : Array[1..MAX_HOOKS] of pp_hook_method;
|
||||
|
||||
procedure Main(); interrupt;
|
||||
var
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
CLI;
|
||||
for i:=0 to MAX_HOOKS-1 do begin
|
||||
if uint32(Hooks[i]) <> 0 then Hooks[i](void($00000000));
|
||||
end;
|
||||
console.writestringln('Disk Operation Complete');
|
||||
end;
|
||||
|
||||
procedure register();
|
||||
begin
|
||||
memset(uint32(@Hooks[0]), 0, sizeof(pp_hook_method)*MAX_HOOKS);
|
||||
//isrmanager.registerISR(76, @Main);
|
||||
//IDT.set_gate(76, uint32(@Main), $08, ISR_RING_0);
|
||||
end;
|
||||
|
||||
procedure hook(hook_method : uint32);
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
for i:=0 to MAX_HOOKS-1 do begin
|
||||
if uint32(Hooks[i]) = hook_method then exit;
|
||||
end;
|
||||
for i:=0 to MAX_HOOKS-1 do begin
|
||||
if uint32(Hooks[i]) = 0 then begin
|
||||
Hooks[i]:= pp_hook_method(hook_method);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure unhook(hook_method : uint32);
|
||||
var
|
||||
i : uint32;
|
||||
begin
|
||||
for i:=0 to MAX_HOOKS-1 do begin
|
||||
If uint32(Hooks[i]) = hook_method then Hooks[i]:= nil;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -23,14 +23,16 @@ interface
|
||||
|
||||
uses
|
||||
console,
|
||||
storagemanagement,
|
||||
util, terminal,
|
||||
lmemorymanager,
|
||||
strings,
|
||||
lists,
|
||||
tracer,
|
||||
lmemorymanager,
|
||||
rtc,
|
||||
serial,
|
||||
rtc;
|
||||
storagemanagement,
|
||||
storagemanager,
|
||||
strings,
|
||||
terminal,
|
||||
tracer,
|
||||
util;
|
||||
|
||||
type
|
||||
|
||||
@@ -99,7 +101,7 @@ begin
|
||||
filesystemRecord^.endOfData := filesystemRecord.sectorsPerTable;
|
||||
//filesystemRecord.volumeLabel := config^
|
||||
|
||||
disk^.writecallback(disk, start, 1, buffer);
|
||||
storagemanager.storage_write(disk, start, 1, buffer);
|
||||
memset(uint32(buffer), 0, disk^.sectorSize);
|
||||
|
||||
fileEntry := PFileEntry(buffer)[0];
|
||||
@@ -112,7 +114,7 @@ begin
|
||||
fileEntry^.attributes := 0;
|
||||
fileEntry^.location := 1;
|
||||
|
||||
disk^.writecallback(disk, start + 1, 1, buffer);
|
||||
storagemanager.storage_write(disk, start + 1, 1, buffer);
|
||||
|
||||
|
||||
end;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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.
|
||||
Loaded 20 of 52 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user