mirror of https://gitlab.com/nakst/essence
simplify file system device allocation
This commit is contained in:
parent
44f620c3e3
commit
23bc33d5b9
|
@ -1105,6 +1105,19 @@ enum EsClipboard {
|
|||
ES_CLIPBOARD_PRIMARY
|
||||
}
|
||||
|
||||
enum EsDeviceType {
|
||||
ES_DEVICE_OTHER
|
||||
ES_DEVICE_CONTROLLER
|
||||
ES_DEVICE_FILE_SYSTEM
|
||||
ES_DEVICE_GRAPHICS_TARGET
|
||||
ES_DEVICE_BLOCK
|
||||
ES_DEVICE_AUDIO
|
||||
ES_DEVICE_HID
|
||||
ES_DEVICE_NETWORK_CARD
|
||||
ES_DEVICE_USB
|
||||
ES_DEVICE_PCI_FUNCTION
|
||||
}
|
||||
|
||||
function_pointer int EsUICallbackFunction(struct EsElement *element, struct EsMessage *message);
|
||||
|
||||
struct EsBuffer {
|
||||
|
|
|
@ -663,7 +663,7 @@ void ACPIInitialise2() {
|
|||
|
||||
if (AE_OK == AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0)
|
||||
&& AE_OK == AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON, ACPIPowerButtonPressed, nullptr)) {
|
||||
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice));
|
||||
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice), ES_DEVICE_OTHER);
|
||||
}
|
||||
|
||||
void *result;
|
||||
|
@ -695,7 +695,7 @@ void KPS2SafeToInitialise() {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parentDevice) {
|
||||
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice));
|
||||
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER);
|
||||
|
||||
#ifndef SERIAL_STARTUP
|
||||
KThreadCreate("InitACPI", [] (uintptr_t) { ACPIInitialise2(); });
|
||||
|
|
|
@ -827,7 +827,7 @@ void AHCIController::Initialise() {
|
|||
for (uintptr_t i = 0; i < MAX_PORTS; i++) {
|
||||
if (!ports[i].connected) continue;
|
||||
|
||||
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive));
|
||||
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive), ES_DEVICE_BLOCK);
|
||||
|
||||
if (!device) {
|
||||
KernelLog(LOG_ERROR, "AHCI", "allocation failure", "Could not create device for port %d.\n", i);
|
||||
|
@ -863,7 +863,7 @@ void AHCIController::Initialise() {
|
|||
static void DeviceAttach(KDevice *_parent) {
|
||||
KPCIDevice *parent = (KPCIDevice *) _parent;
|
||||
|
||||
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController));
|
||||
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController), ES_DEVICE_CONTROLLER);
|
||||
if (!device) return;
|
||||
device->pci = parent;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void BGADebugClearScreen() {
|
|||
void BGADeviceAttached(KDevice *_parent) {
|
||||
KPCIDevice *parent = (KPCIDevice *) _parent;
|
||||
|
||||
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay));
|
||||
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay), ES_DEVICE_GRAPHICS_TARGET);
|
||||
if (!device) return;
|
||||
|
||||
parent->EnableFeatures(K_PCI_FEATURE_IO_PORT_ACCESS | K_PCI_FEATURE_MEMORY_SPACE_ACCESS | K_PCI_FEATURE_BAR_0);
|
||||
|
|
|
@ -17,9 +17,8 @@
|
|||
#define ESFS_CHECK_FATAL(x, y) if (!(x)) { KernelLog(LOG_ERROR, "EsFS", "damaged file system", "Mount - " y "\n"); return false; }
|
||||
#define ESFS_CHECK_READ_ONLY(x, y) if (!(x)) { KernelLog(LOG_ERROR, "EsFS", "mount read only", "Mount - " y " Mounting as read only.\n"); volume->readOnly = true; }
|
||||
|
||||
struct Volume : KDevice {
|
||||
struct Volume : KFileSystem {
|
||||
Superblock superblock;
|
||||
KFileSystem *fileSystem;
|
||||
struct FSNode *root;
|
||||
bool readOnly;
|
||||
KWriterLock blockBitmapLock;
|
||||
|
@ -39,7 +38,7 @@ struct FSNode {
|
|||
static bool AccessBlock(Volume *volume, uint64_t index, uint64_t count, void *buffer, uint64_t flags, int driveAccess) {
|
||||
// TODO Return EsError.
|
||||
Superblock *superblock = &volume->superblock;
|
||||
bool result = volume->fileSystem->Access(index * superblock->blockSize, count * superblock->blockSize, driveAccess, buffer, flags, nullptr);
|
||||
bool result = volume->Access(index * superblock->blockSize, count * superblock->blockSize, driveAccess, buffer, flags, nullptr);
|
||||
ESFS_CHECK(result, "AccessBlock - Could not access blocks.");
|
||||
return result;
|
||||
}
|
||||
|
@ -585,7 +584,7 @@ static bool AllocateExtent(Volume *volume, uint64_t nearby, uint64_t increaseBlo
|
|||
|
||||
*extentStart += (target - volume->groupDescriptorTable) * superblock->blocksPerGroup;
|
||||
superblock->blocksUsed += *extentCount;
|
||||
volume->fileSystem->spaceUsed += *extentCount * superblock->blockSize;
|
||||
volume->spaceUsed += *extentCount * superblock->blockSize;
|
||||
|
||||
if (zero) {
|
||||
// TODO This is really slow - introduce K_ACCESS_ZERO?
|
||||
|
@ -659,7 +658,7 @@ static bool FreeExtent(Volume *volume, uint64_t extentStart, uint64_t extentCoun
|
|||
target->checksum = 0;
|
||||
target->checksum = CalculateCRC32(target, sizeof(GroupDescriptor));
|
||||
superblock->blocksUsed -= extentCount;
|
||||
volume->fileSystem->spaceUsed -= extentCount * superblock->blockSize;
|
||||
volume->spaceUsed -= extentCount * superblock->blockSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1829,12 +1828,12 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
|
||||
Superblock *superblock = &volume->superblock;
|
||||
|
||||
if (!volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_READ, (uint8_t *) superblock, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_READ, (uint8_t *) superblock, ES_FLAGS_DEFAULT)) {
|
||||
KernelLog(LOG_ERROR, "EsFS", "drive access failure", "Mount - Could not read superblock.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (volume->fileSystem->block->readOnly) {
|
||||
if (volume->block->readOnly) {
|
||||
volume->readOnly = true;
|
||||
}
|
||||
|
||||
|
@ -1847,8 +1846,8 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
|
||||
ESFS_CHECK_FATAL(0 == EsMemoryCompare(volume->superblock.signature, ESFS_SIGNATURE_STRING, 16), "Invalid superblock signature.");
|
||||
ESFS_CHECK_FATAL(volume->superblock.requiredReadVersion <= ESFS_DRIVER_VERSION, "Incompatible file system version.");
|
||||
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->fileSystem->block->sectorSize) == 0, "Invalid block size.");
|
||||
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->fileSystem->block->sectorSize <= volume->fileSystem->block->sectorCount, "More blocks than drive.");
|
||||
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->block->sectorSize) == 0, "Invalid block size.");
|
||||
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->block->sectorSize <= volume->block->sectorCount, "More blocks than drive.");
|
||||
ESFS_CHECK_FATAL(superblock->blocksUsed <= superblock->blockCount, "More blocks used than exist.");
|
||||
ESFS_CHECK_FATAL(superblock->blocksPerGroup <= 65536 && superblock->blocksPerGroup < superblock->blockCount && superblock->blocksPerGroup >= 1024, "Invalid block group size.");
|
||||
ESFS_CHECK_FATAL((superblock->groupCount - 1) * superblock->blocksPerGroup <= superblock->blockCount, "Invalid number of block groups.");
|
||||
|
@ -1870,7 +1869,7 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
superblock->mounted = true;
|
||||
superblock->checksum = 0;
|
||||
superblock->checksum = CalculateCRC32(superblock, sizeof(Superblock));
|
||||
ESFS_CHECK_READ_ONLY(volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE,
|
||||
ESFS_CHECK_READ_ONLY(volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE,
|
||||
K_ACCESS_WRITE, (uint8_t *) superblock, ES_FLAGS_DEFAULT), "Could not mark volume as mounted.");
|
||||
}
|
||||
|
||||
|
@ -1936,7 +1935,7 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
|
|||
}
|
||||
|
||||
static void Unmount(KFileSystem *fileSystem) {
|
||||
Volume *volume = (Volume *) fileSystem->driverData;
|
||||
Volume *volume = (Volume *) fileSystem;
|
||||
Superblock *superblock = &volume->superblock;
|
||||
|
||||
if (!volume->readOnly) {
|
||||
|
@ -1946,7 +1945,7 @@ static void Unmount(KFileSystem *fileSystem) {
|
|||
superblock->mounted = false;
|
||||
superblock->checksum = 0;
|
||||
superblock->checksum = CalculateCRC32(superblock, sizeof(Superblock));
|
||||
volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_WRITE,
|
||||
volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_WRITE,
|
||||
(uint8_t *) superblock, ES_FLAGS_DEFAULT);
|
||||
}
|
||||
|
||||
|
@ -1954,16 +1953,13 @@ static void Unmount(KFileSystem *fileSystem) {
|
|||
}
|
||||
|
||||
static void Register(KDevice *_parent) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) _parent;
|
||||
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", fileSystem, sizeof(Volume));
|
||||
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", _parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
|
||||
|
||||
if (!volume) {
|
||||
KernelLog(LOG_ERROR, "EsFS", "allocation failure", "Register - Could not allocate Volume structure.\n");
|
||||
if (!volume || !FSFileSystemInitialise(volume)) {
|
||||
KernelLog(LOG_ERROR, "EsFS", "allocation failure", "Register - Could not allocate file system.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem = fileSystem;
|
||||
|
||||
EsFileOffsetDifference rootDirectoryChildren;
|
||||
|
||||
if (!Mount(volume, &rootDirectoryChildren)) {
|
||||
|
@ -1972,36 +1968,35 @@ static void Register(KDevice *_parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
fileSystem->spaceUsed = volume->superblock.blocksUsed * volume->superblock.blockSize;
|
||||
fileSystem->spaceTotal = volume->superblock.blockCount * volume->superblock.blockSize;
|
||||
volume->spaceUsed = volume->superblock.blocksUsed * volume->superblock.blockSize;
|
||||
volume->spaceTotal = volume->superblock.blockCount * volume->superblock.blockSize;
|
||||
|
||||
fileSystem->read = Read;
|
||||
fileSystem->scan = Scan;
|
||||
fileSystem->load = Load;
|
||||
fileSystem->enumerate = Enumerate;
|
||||
fileSystem->unmount = Unmount;
|
||||
fileSystem->close = Close;
|
||||
volume->read = Read;
|
||||
volume->scan = Scan;
|
||||
volume->load = Load;
|
||||
volume->enumerate = Enumerate;
|
||||
volume->unmount = Unmount;
|
||||
volume->close = Close;
|
||||
|
||||
if (!volume->readOnly) {
|
||||
fileSystem->write = Write;
|
||||
fileSystem->sync = Sync;
|
||||
fileSystem->resize = Resize;
|
||||
fileSystem->create = Create;
|
||||
fileSystem->remove = Remove;
|
||||
fileSystem->move = Move;
|
||||
volume->write = Write;
|
||||
volume->sync = Sync;
|
||||
volume->resize = Resize;
|
||||
volume->create = Create;
|
||||
volume->remove = Remove;
|
||||
volume->move = Move;
|
||||
}
|
||||
|
||||
volume->superblock.volumeName[ESFS_MAXIMUM_VOLUME_NAME_LENGTH - 1] = 0;
|
||||
fileSystem->nameBytes = EsCStringLength(volume->superblock.volumeName);
|
||||
EsMemoryCopy(fileSystem->name, volume->superblock.volumeName, fileSystem->nameBytes);
|
||||
volume->nameBytes = EsCStringLength(volume->superblock.volumeName);
|
||||
EsMemoryCopy(volume->name, volume->superblock.volumeName, volume->nameBytes);
|
||||
|
||||
fileSystem->driverData = volume;
|
||||
fileSystem->rootDirectory->driverNode = volume->root;
|
||||
fileSystem->rootDirectoryInitialChildren = rootDirectoryChildren;
|
||||
fileSystem->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
|
||||
fileSystem->nodeDataBytes = sizeof(FSNode);
|
||||
volume->rootDirectory->driverNode = volume->root;
|
||||
volume->rootDirectoryInitialChildren = rootDirectoryChildren;
|
||||
volume->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
|
||||
volume->nodeDataBytes = sizeof(FSNode);
|
||||
|
||||
FSRegisterBootFileSystem(fileSystem, volume->superblock.osInstallation);
|
||||
FSRegisterBootFileSystem(volume, volume->superblock.osInstallation);
|
||||
}
|
||||
|
||||
KDriver driverEssenceFS = {
|
||||
|
|
111
drivers/ext2.cpp
111
drivers/ext2.cpp
|
@ -129,8 +129,7 @@ struct FSNode {
|
|||
Inode inode;
|
||||
};
|
||||
|
||||
struct Volume : KDevice {
|
||||
KFileSystem *fileSystem;
|
||||
struct Volume : KFileSystem {
|
||||
SuperBlock superBlock;
|
||||
BlockGroupDescriptor *blockGroupDescriptorTable;
|
||||
size_t blockBytes;
|
||||
|
@ -141,16 +140,16 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
// Load the superblock.
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->fileSystem->block->sectorSize, false, K_FIXED);
|
||||
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->block->sectorSize, false, K_FIXED);
|
||||
|
||||
if (!sectorBuffer) {
|
||||
MOUNT_FAILURE("Could not allocate buffer.\n");
|
||||
}
|
||||
|
||||
EsDefer(EsHeapFree(sectorBuffer, volume->fileSystem->block->sectorSize, K_FIXED));
|
||||
EsDefer(EsHeapFree(sectorBuffer, volume->block->sectorSize, K_FIXED));
|
||||
|
||||
{
|
||||
if (!volume->fileSystem->Access(1024, volume->fileSystem->block->sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(1024, volume->block->sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read boot sector.\n");
|
||||
}
|
||||
|
||||
|
@ -170,7 +169,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
volume->blockBytes = 1024 << volume->superBlock.blockSizeExponent;
|
||||
|
||||
if (volume->blockBytes < volume->fileSystem->block->sectorSize) {
|
||||
if (volume->blockBytes < volume->block->sectorSize) {
|
||||
MOUNT_FAILURE("Block size smaller than drive sector size.\n");
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ static bool Mount(Volume *volume) {
|
|||
MOUNT_FAILURE("Could not allocate the block group descriptor table.\n");
|
||||
}
|
||||
|
||||
if (!volume->fileSystem->Access(firstBlockContainingBlockGroupDescriptorTable * volume->blockBytes,
|
||||
if (!volume->Access(firstBlockContainingBlockGroupDescriptorTable * volume->blockBytes,
|
||||
blockGroupDescriptorTableLengthInBlocks * volume->blockBytes,
|
||||
K_ACCESS_READ, volume->blockGroupDescriptorTable, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read the block group descriptor table from the drive.\n");
|
||||
|
@ -202,29 +201,29 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->fileSystem->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->fileSystem->block->sectorSize;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
|
||||
|
||||
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
|
||||
|
||||
if (!volume->fileSystem->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->fileSystem->block->sectorSize,
|
||||
volume->fileSystem->block->sectorSize,
|
||||
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->block->sectorSize,
|
||||
volume->block->sectorSize,
|
||||
K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read the inode table.\n");
|
||||
}
|
||||
|
||||
volume->fileSystem->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
|
||||
volume->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
|
||||
|
||||
if (!volume->fileSystem->rootDirectory->driverNode) {
|
||||
if (!volume->rootDirectory->driverNode) {
|
||||
MOUNT_FAILURE("Could not allocate root node.\n");
|
||||
}
|
||||
|
||||
FSNode *root = (FSNode *) volume->fileSystem->rootDirectory->driverNode;
|
||||
FSNode *root = (FSNode *) volume->rootDirectory->driverNode;
|
||||
root->volume = volume;
|
||||
EsMemoryCopy(&root->inode, sectorBuffer + offsetInSector, sizeof(Inode));
|
||||
|
||||
volume->fileSystem->rootDirectoryInitialChildren = root->inode.fileSizeLow / sizeof(DirectoryEntry); // TODO This is a terrible upper-bound!
|
||||
volume->rootDirectoryInitialChildren = root->inode.fileSizeLow / sizeof(DirectoryEntry); // TODO This is a terrible upper-bound!
|
||||
|
||||
if ((root->inode.type & 0xF000) != INODE_TYPE_DIRECTORY) {
|
||||
MOUNT_FAILURE("Root directory is not a directory.\n");
|
||||
|
@ -235,7 +234,7 @@ static bool Mount(Volume *volume) {
|
|||
}
|
||||
|
||||
static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, uint8_t *blockBuffer) {
|
||||
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->fileSystem->block->sectorSize > volume->fileSystem->block->sectorCount) { \
|
||||
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->block->sectorSize > volume->block->sectorCount) { \
|
||||
KernelLog(LOG_ERROR, "Ext2", "invalid block index", "GetDataBlock - Block out of bounds.\n"); return 0; }
|
||||
#define GET_DATA_BLOCK_ACCESS_FAILURE() do { KernelLog(LOG_ERROR, "Ext2", "block access failure", "GetDataBlock - Could not read block.\n"); return 0; } while (0)
|
||||
|
||||
|
@ -254,7 +253,7 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
|
|||
if (blockIndex < blockPointersPerBlock) {
|
||||
offset = node->indirectBlockPointers[0] * volume->blockBytes;
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[blockIndex];
|
||||
CHECK_BLOCK_INDEX();
|
||||
return offset;
|
||||
|
@ -265,10 +264,10 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
|
|||
if (blockIndex < blockPointersPerBlock * blockPointersPerBlock) {
|
||||
offset = node->indirectBlockPointers[1] * volume->blockBytes;
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[blockIndex / blockPointersPerBlock];
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[blockIndex % blockPointersPerBlock];
|
||||
CHECK_BLOCK_INDEX();
|
||||
return offset;
|
||||
|
@ -279,13 +278,13 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
|
|||
if (blockIndex < blockPointersPerBlock * blockPointersPerBlock * blockPointersPerBlock) {
|
||||
offset = node->indirectBlockPointers[2] * volume->blockBytes;
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[blockIndex / blockPointersPerBlock / blockPointersPerBlock];
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[(blockIndex / blockPointersPerBlock) % blockPointersPerBlock];
|
||||
CHECK_BLOCK_INDEX();
|
||||
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
|
||||
offset = blockPointers[blockIndex % blockPointersPerBlock];
|
||||
CHECK_BLOCK_INDEX();
|
||||
return offset;
|
||||
|
@ -318,7 +317,7 @@ static EsError Enumerate(KNode *node) {
|
|||
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
||||
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
ENUMERATE_FAILURE("Could not read block.\n");
|
||||
}
|
||||
|
||||
|
@ -388,7 +387,7 @@ static EsError Scan(const char *name, size_t nameBytes, KNode *_directory) {
|
|||
return ES_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
SCAN_FAILURE("Could not read block.\n");
|
||||
}
|
||||
|
||||
|
@ -449,14 +448,14 @@ static EsError Load(KNode *_directory, KNode *node, KNodeMetadata *metadata, con
|
|||
|
||||
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->fileSystem->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->fileSystem->block->sectorSize;
|
||||
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
|
||||
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
|
||||
|
||||
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
|
||||
|
||||
if (!volume->fileSystem->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->fileSystem->block->sectorSize,
|
||||
volume->fileSystem->block->sectorSize,
|
||||
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
|
||||
+ sectorInInodeTable * volume->block->sectorSize,
|
||||
volume->block->sectorSize,
|
||||
K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
@ -505,7 +504,7 @@ struct ReadDispatchGroup : KWorkGroup {
|
|||
void QueueExtent() {
|
||||
if (!extentCount) return;
|
||||
|
||||
volume->fileSystem->Access(extentIndex * volume->blockBytes,
|
||||
volume->Access(extentIndex * volume->blockBytes,
|
||||
volume->blockBytes * extentCount, K_ACCESS_READ, extentBuffer, ES_FLAGS_DEFAULT, this);
|
||||
}
|
||||
|
||||
|
@ -568,7 +567,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
|
|||
dispatchGroup.QueueBlock(volume, block, outputBuffer + outputPosition);
|
||||
outputPosition += volume->blockBytes;
|
||||
} else {
|
||||
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
|
||||
READ_FAILURE("Could not read blocks from drive.\n");
|
||||
}
|
||||
|
||||
|
@ -594,55 +593,53 @@ static void Close(KNode *node) {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume));
|
||||
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
|
||||
|
||||
if (!volume) {
|
||||
KernelLog(LOG_ERROR, "Ext2", "allocate error", "Could not allocate Volume structure.\n");
|
||||
if (!volume || !FSFileSystemInitialise(volume)) {
|
||||
KernelLog(LOG_ERROR, "Ext2", "allocate error", "Could not initialise volume.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem = (KFileSystem *) parent;
|
||||
|
||||
if (volume->fileSystem->block->sectorSize & 0x1FF) {
|
||||
if (volume->block->sectorSize & 0x1FF) {
|
||||
KernelLog(LOG_ERROR, "Ext2", "incorrect sector size", "Expected sector size to be a multiple of 512, but drive's sectors are %D.\n",
|
||||
volume->fileSystem->block->sectorSize);
|
||||
volume->block->sectorSize);
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Mount(volume)) {
|
||||
KernelLog(LOG_ERROR, "Ext2", "mount failure", "Could not mount Ext2 volume.\n");
|
||||
EsHeapFree(volume->fileSystem->rootDirectory->driverNode, 0, K_FIXED);
|
||||
EsHeapFree(volume->rootDirectory->driverNode, 0, K_FIXED);
|
||||
EsHeapFree(volume->blockGroupDescriptorTable, 0, K_FIXED);
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem->read = Read;
|
||||
volume->fileSystem->scan = Scan;
|
||||
volume->fileSystem->load = Load;
|
||||
volume->fileSystem->enumerate = Enumerate;
|
||||
volume->fileSystem->close = Close;
|
||||
volume->read = Read;
|
||||
volume->scan = Scan;
|
||||
volume->load = Load;
|
||||
volume->enumerate = Enumerate;
|
||||
volume->close = Close;
|
||||
|
||||
volume->fileSystem->spaceTotal = volume->superBlock.blockCount * volume->blockBytes;
|
||||
volume->fileSystem->spaceUsed = (volume->superBlock.blockCount - volume->superBlock.unallocatedBlockCount) * volume->blockBytes;
|
||||
volume->spaceTotal = volume->superBlock.blockCount * volume->blockBytes;
|
||||
volume->spaceUsed = (volume->superBlock.blockCount - volume->superBlock.unallocatedBlockCount) * volume->blockBytes;
|
||||
|
||||
volume->fileSystem->nameBytes = sizeof(volume->superBlock.volumeName);
|
||||
if (volume->fileSystem->nameBytes > sizeof(volume->fileSystem->name)) volume->fileSystem->nameBytes = sizeof(volume->fileSystem->name);
|
||||
EsMemoryCopy(volume->fileSystem->name, volume->superBlock.volumeName, volume->fileSystem->nameBytes);
|
||||
volume->nameBytes = sizeof(volume->superBlock.volumeName);
|
||||
if (volume->nameBytes > sizeof(volume->name)) volume->nameBytes = sizeof(volume->name);
|
||||
EsMemoryCopy(volume->name, volume->superBlock.volumeName, volume->nameBytes);
|
||||
|
||||
for (uintptr_t i = 0; i < volume->fileSystem->nameBytes; i++) {
|
||||
if (!volume->fileSystem->name[i]) {
|
||||
volume->fileSystem->nameBytes = i;
|
||||
for (uintptr_t i = 0; i < volume->nameBytes; i++) {
|
||||
if (!volume->name[i]) {
|
||||
volume->nameBytes = i;
|
||||
}
|
||||
}
|
||||
|
||||
volume->fileSystem->directoryEntryDataBytes = sizeof(uint32_t);
|
||||
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
|
||||
volume->directoryEntryDataBytes = sizeof(uint32_t);
|
||||
volume->nodeDataBytes = sizeof(FSNode);
|
||||
|
||||
KernelLog(LOG_INFO, "Ext2", "register file system", "Registering file system with name '%s'.\n",
|
||||
volume->fileSystem->nameBytes, volume->fileSystem->name);
|
||||
FSRegisterFileSystem(volume->fileSystem);
|
||||
volume->nameBytes, volume->name);
|
||||
FSRegisterFileSystem(volume);
|
||||
}
|
||||
|
||||
KDriver driverExt2 = {
|
||||
|
|
|
@ -64,9 +64,7 @@ struct DirectoryEntry {
|
|||
uint32_t fileSizeBytes;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct Volume : KDevice {
|
||||
KFileSystem *fileSystem;
|
||||
|
||||
struct Volume : KFileSystem {
|
||||
union {
|
||||
char _unused0[SECTOR_SIZE];
|
||||
SuperBlock16 sb16;
|
||||
|
@ -84,7 +82,7 @@ struct Volume : KDevice {
|
|||
#define TYPE_FAT32 (32)
|
||||
int type;
|
||||
|
||||
DirectoryEntry *rootDirectory;
|
||||
DirectoryEntry *rootDirectoryEntries;
|
||||
};
|
||||
|
||||
struct DirectoryEntryReference {
|
||||
|
@ -154,7 +152,7 @@ static EsError Load(KNode *_directory, KNode *_node, KNodeMetadata *, const void
|
|||
DirectoryEntry entry;
|
||||
|
||||
if (!directory->rootDirectory) {
|
||||
if (!volume->fileSystem->Access((reference.cluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
if (!volume->Access((reference.cluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
|
||||
return ES_ERROR_UNKNOWN;
|
||||
}
|
||||
|
@ -199,7 +197,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
|
|||
uint32_t bytesFromThisCluster = superBlock->sectorsPerCluster * SECTOR_SIZE - offset;
|
||||
if (bytesFromThisCluster > count) bytesFromThisCluster = count;
|
||||
|
||||
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ,
|
||||
(uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
|
||||
READ_FAILURE("Could not read cluster.\n");
|
||||
|
@ -244,7 +242,7 @@ static EsError Scan(const char *_name, size_t nameLength, KNode *node) {
|
|||
|
||||
while (currentCluster < volume->terminateCluster) {
|
||||
if (!directory->rootDirectory) {
|
||||
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
|
||||
SCAN_FAILURE("Could not read cluster.\n");
|
||||
}
|
||||
|
@ -311,7 +309,7 @@ static EsError Enumerate(KNode *node) {
|
|||
|
||||
while (currentCluster < volume->terminateCluster) {
|
||||
if (!directory->rootDirectory) {
|
||||
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
|
||||
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
|
||||
ENUMERATE_FAILURE("Could not read cluster.\n");
|
||||
}
|
||||
|
@ -373,7 +371,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
{
|
||||
SuperBlockCommon *superBlock = &volume->superBlock;
|
||||
if (!volume->fileSystem->Access(0, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) superBlock, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read superBlock.\n");
|
||||
if (!volume->Access(0, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) superBlock, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read superBlock.\n");
|
||||
|
||||
uint32_t sectorCount = superBlock->totalSectors ?: superBlock->largeSectorCount;
|
||||
uint32_t clusterCount = sectorCount / superBlock->sectorsPerCluster;
|
||||
|
@ -402,16 +400,16 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
volume->fat = (uint8_t *) EsHeapAllocate(sectorsPerFAT * SECTOR_SIZE, true, K_FIXED);
|
||||
if (!volume->fat) MOUNT_FAILURE("Could not allocate FAT.\n");
|
||||
if (!volume->fileSystem->Access(superBlock->reservedSectors * SECTOR_SIZE,
|
||||
if (!volume->Access(superBlock->reservedSectors * SECTOR_SIZE,
|
||||
sectorsPerFAT * SECTOR_SIZE, K_ACCESS_READ, volume->fat, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read FAT.\n");
|
||||
|
||||
volume->fileSystem->spaceUsed = CountUsedClusters(volume) * superBlock->sectorsPerCluster * superBlock->bytesPerSector;
|
||||
volume->fileSystem->spaceTotal = volume->fileSystem->block->sectorSize * volume->fileSystem->block->sectorCount;
|
||||
volume->spaceUsed = CountUsedClusters(volume) * superBlock->sectorsPerCluster * superBlock->bytesPerSector;
|
||||
volume->spaceTotal = volume->block->sectorSize * volume->block->sectorCount;
|
||||
|
||||
volume->fileSystem->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
|
||||
if (!volume->fileSystem->rootDirectory->driverNode) MOUNT_FAILURE("Could not allocate root node.\n");
|
||||
volume->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
|
||||
if (!volume->rootDirectory->driverNode) MOUNT_FAILURE("Could not allocate root node.\n");
|
||||
|
||||
FSNode *root = (FSNode *) volume->fileSystem->rootDirectory->driverNode;
|
||||
FSNode *root = (FSNode *) volume->rootDirectory->driverNode;
|
||||
root->volume = volume;
|
||||
|
||||
if (volume->type == TYPE_FAT32) {
|
||||
|
@ -422,13 +420,13 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
while (currentCluster < volume->terminateCluster) {
|
||||
currentCluster = NextCluster(volume, currentCluster);
|
||||
volume->fileSystem->rootDirectoryInitialChildren += SECTOR_SIZE * superBlock->sectorsPerCluster / sizeof(DirectoryEntry);
|
||||
volume->rootDirectoryInitialChildren += SECTOR_SIZE * superBlock->sectorsPerCluster / sizeof(DirectoryEntry);
|
||||
}
|
||||
} else {
|
||||
root->rootDirectory = (DirectoryEntry *) EsHeapAllocate(rootDirectorySectors * SECTOR_SIZE, true, K_FIXED);
|
||||
volume->rootDirectory = root->rootDirectory;
|
||||
volume->rootDirectoryEntries = root->rootDirectory;
|
||||
|
||||
if (!volume->fileSystem->Access(rootDirectoryOffset * SECTOR_SIZE, rootDirectorySectors * SECTOR_SIZE,
|
||||
if (!volume->Access(rootDirectoryOffset * SECTOR_SIZE, rootDirectorySectors * SECTOR_SIZE,
|
||||
K_ACCESS_READ, (uint8_t *) root->rootDirectory, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not read root directory.\n");
|
||||
}
|
||||
|
@ -436,7 +434,7 @@ static bool Mount(Volume *volume) {
|
|||
for (uintptr_t i = 0; i < superBlock->rootDirectoryEntries; i++) {
|
||||
if (root->rootDirectory[i].name[0] == 0xE5 || root->rootDirectory[i].attributes == 0x0F || (root->rootDirectory[i].attributes & 0x08)) continue;
|
||||
else if (root->rootDirectory[i].name[0] == 0x00) break;
|
||||
else volume->fileSystem->rootDirectoryInitialChildren++;
|
||||
else volume->rootDirectoryInitialChildren++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,57 +454,49 @@ static void Close(KNode *node) {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume));
|
||||
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
|
||||
|
||||
if (!volume) {
|
||||
KernelLog(LOG_ERROR, "FAT", "allocate error", "EntryFAT - Could not allocate Volume structure.\n");
|
||||
if (!volume || !FSFileSystemInitialise(volume)) {
|
||||
KernelLog(LOG_ERROR, "FAT", "allocate error", "DeviceAttach - Could not initialise volume.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem = (KFileSystem *) parent;
|
||||
|
||||
if (!volume->fileSystem) {
|
||||
KernelLog(LOG_ERROR, "FAT", "device error", "EntryFAT - Could not create file system device.\n");
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
if (volume->fileSystem->block->sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "FAT", "mount failure", "EntryFAT - Unsupported sector size.\n");
|
||||
if (volume->block->sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "FAT", "mount failure", "DeviceAttach - Unsupported sector size.\n");
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Mount(volume)) {
|
||||
KernelLog(LOG_ERROR, "FAT", "mount failure", "EntryFAT - Could not mount FAT volume.\n");
|
||||
KernelLog(LOG_ERROR, "FAT", "mount failure", "DeviceAttach - Could not mount FAT volume.\n");
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem->read = Read;
|
||||
volume->fileSystem->load = Load;
|
||||
volume->fileSystem->scan = Scan;
|
||||
volume->fileSystem->enumerate = Enumerate;
|
||||
volume->fileSystem->close = Close;
|
||||
volume->read = Read;
|
||||
volume->load = Load;
|
||||
volume->scan = Scan;
|
||||
volume->enumerate = Enumerate;
|
||||
volume->close = Close;
|
||||
|
||||
if (volume->type == TYPE_FAT32) {
|
||||
volume->fileSystem->nameBytes = sizeof(volume->sb32.label);
|
||||
EsMemoryCopy(volume->fileSystem->name, volume->sb32.label, volume->fileSystem->nameBytes);
|
||||
volume->nameBytes = sizeof(volume->sb32.label);
|
||||
EsMemoryCopy(volume->name, volume->sb32.label, volume->nameBytes);
|
||||
} else {
|
||||
if (volume->rootDirectory[0].attributes & 8) {
|
||||
volume->fileSystem->nameBytes = sizeof(volume->rootDirectory[0].name);
|
||||
EsMemoryCopy(volume->fileSystem->name, volume->rootDirectory[0].name, volume->fileSystem->nameBytes);
|
||||
if (volume->rootDirectoryEntries[0].attributes & 8) {
|
||||
volume->nameBytes = sizeof(volume->rootDirectoryEntries[0].name);
|
||||
EsMemoryCopy(volume->name, volume->rootDirectoryEntries[0].name, volume->nameBytes);
|
||||
} else {
|
||||
volume->fileSystem->nameBytes = sizeof(volume->sb16.label);
|
||||
EsMemoryCopy(volume->fileSystem->name, volume->sb16.label, volume->fileSystem->nameBytes);
|
||||
volume->nameBytes = sizeof(volume->sb16.label);
|
||||
EsMemoryCopy(volume->name, volume->sb16.label, volume->nameBytes);
|
||||
}
|
||||
}
|
||||
|
||||
volume->fileSystem->rootDirectory->driverNode = volume->root;
|
||||
volume->fileSystem->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
|
||||
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
|
||||
volume->rootDirectory->driverNode = volume->root;
|
||||
volume->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
|
||||
volume->nodeDataBytes = sizeof(FSNode);
|
||||
|
||||
FSRegisterFileSystem(volume->fileSystem);
|
||||
FSRegisterFileSystem(volume);
|
||||
}
|
||||
|
||||
KDriver driverFAT = {
|
||||
|
|
|
@ -286,7 +286,7 @@ static void HDAControllerExploreFunctionGroup(HDAController *controller, uint32_
|
|||
|
||||
uint32_t widgetType = ES_EXTRACT_BITS(widgetCapabilities, 23, 20);
|
||||
|
||||
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget));
|
||||
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget), ES_DEVICE_AUDIO);
|
||||
widget->codec = codec;
|
||||
widget->node = j;
|
||||
widget->functionGroup = functionGroupNode;
|
||||
|
@ -382,7 +382,7 @@ static void HDAControllerDestroy(KDevice *_controller) {
|
|||
}
|
||||
|
||||
static void HDAControllerAttach(KDevice *_parent) {
|
||||
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController));
|
||||
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController), ES_DEVICE_CONTROLLER);
|
||||
|
||||
if (!controller) {
|
||||
return;
|
||||
|
|
|
@ -469,7 +469,7 @@ void Controller::Initialise() {
|
|||
static void DeviceAttach(KDevice *_parent) {
|
||||
KPCIDevice *parent = (KPCIDevice *) _parent;
|
||||
|
||||
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller));
|
||||
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller), ES_DEVICE_NETWORK_CARD);
|
||||
if (!device) return;
|
||||
|
||||
device->shutdown = [] (KDevice *device) {
|
||||
|
|
|
@ -551,7 +551,7 @@ void ATAController::Initialise() {
|
|||
for (uintptr_t i = 0; i < ATA_DRIVES; i++) {
|
||||
if (sectorCount[i]) {
|
||||
// Register the drive.
|
||||
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive));
|
||||
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive), ES_DEVICE_BLOCK);
|
||||
|
||||
if (!device) {
|
||||
KernelLog(LOG_ERROR, "IDE", "allocation failure", "Could not create device for drive %d.\n", i);
|
||||
|
@ -585,7 +585,7 @@ static void DeviceAttach(KDevice *_parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController));
|
||||
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController), ES_DEVICE_CONTROLLER);
|
||||
if (!device) return;
|
||||
ataController = device;
|
||||
device->pci = parent;
|
||||
|
|
|
@ -100,8 +100,7 @@ struct FSNode {
|
|||
DirectoryRecord record;
|
||||
};
|
||||
|
||||
struct Volume : KDevice {
|
||||
KFileSystem *fileSystem;
|
||||
struct Volume : KFileSystem {
|
||||
PrimaryDescriptor primaryDescriptor;
|
||||
};
|
||||
|
||||
|
@ -113,7 +112,7 @@ static bool Mount(Volume *volume) {
|
|||
uintptr_t descriptorIndex = 0;
|
||||
|
||||
while (true) {
|
||||
if (!volume->fileSystem->Access(32768 + SECTOR_SIZE * descriptorIndex, SECTOR_SIZE, K_ACCESS_READ, &volume->primaryDescriptor, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(32768 + SECTOR_SIZE * descriptorIndex, SECTOR_SIZE, K_ACCESS_READ, &volume->primaryDescriptor, ES_FLAGS_DEFAULT)) {
|
||||
MOUNT_FAILURE("Could not access descriptor list.\n");
|
||||
}
|
||||
|
||||
|
@ -135,7 +134,7 @@ static bool Mount(Volume *volume) {
|
|||
}
|
||||
|
||||
if (volume->primaryDescriptor.version != 1 || volume->primaryDescriptor.fileStructureVersion != 1) {
|
||||
MOUNT_FAILURE("Unsupported fileSystem version.\n");
|
||||
MOUNT_FAILURE("Unsupported file system version.\n");
|
||||
}
|
||||
|
||||
if (volume->primaryDescriptor.logicalBlockSize.x != SECTOR_SIZE) {
|
||||
|
@ -149,8 +148,8 @@ static bool Mount(Volume *volume) {
|
|||
MOUNT_FAILURE("Could not allocate root node.\n");
|
||||
}
|
||||
|
||||
volume->fileSystem->rootDirectory->driverNode = root;
|
||||
volume->fileSystem->rootDirectoryInitialChildren = volume->primaryDescriptor.rootDirectory.extentSize.x / sizeof(DirectoryRecord);
|
||||
volume->rootDirectory->driverNode = root;
|
||||
volume->rootDirectoryInitialChildren = volume->primaryDescriptor.rootDirectory.extentSize.x / sizeof(DirectoryRecord);
|
||||
|
||||
root->volume = volume;
|
||||
root->record = volume->primaryDescriptor.rootDirectory;
|
||||
|
@ -170,11 +169,11 @@ static bool Mount(Volume *volume) {
|
|||
}
|
||||
|
||||
DirectoryRecord record = {};
|
||||
ScanInternal(EsLiteral("ESSENCE.DAT;1"), volume->fileSystem->rootDirectory, &record);
|
||||
ScanInternal(EsLiteral("ESSENCE.DAT;1"), volume->rootDirectory, &record);
|
||||
record.extentSize.x = (record.extentSize.x + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||
|
||||
if (!record.length || record.extentStart.x >= volume->fileSystem->block->sectorCount
|
||||
|| record.extentSize.x >= volume->fileSystem->block->sectorCount - record.extentStart.x) {
|
||||
if (!record.length || record.extentStart.x >= volume->block->sectorCount
|
||||
|| record.extentSize.x >= volume->block->sectorCount - record.extentStart.x) {
|
||||
goto notBoot;
|
||||
}
|
||||
|
||||
|
@ -189,7 +188,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
EsDefer(EsHeapFree(firstSector, SECTOR_SIZE, K_FIXED));
|
||||
|
||||
if (!volume->fileSystem->Access(record.extentStart.x * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, firstSector, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(record.extentStart.x * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, firstSector, ES_FLAGS_DEFAULT)) {
|
||||
goto notBoot;
|
||||
}
|
||||
|
||||
|
@ -206,7 +205,7 @@ static bool Mount(Volume *volume) {
|
|||
|
||||
KernelLog(LOG_INFO, "ISO9660", "found boot disc", "Found boot disc. Image at %d/%d.\n",
|
||||
record.extentStart.x, record.extentSize.x);
|
||||
FSPartitionDeviceCreate(volume->fileSystem->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, "CD-ROM boot partition");
|
||||
FSPartitionDeviceCreate(volume->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, "CD-ROM boot partition");
|
||||
}
|
||||
|
||||
notBoot:;
|
||||
|
@ -236,7 +235,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
|
|||
|
||||
while (count) {
|
||||
if (offset || count < SECTOR_SIZE) {
|
||||
if (!volume->fileSystem->Access(lba * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(lba * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
READ_FAILURE("Could not read file sector.\n");
|
||||
}
|
||||
|
||||
|
@ -247,7 +246,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
|
|||
} else {
|
||||
uint64_t sectorsToRead = count / SECTOR_SIZE;
|
||||
|
||||
if (!volume->fileSystem->Access(lba * SECTOR_SIZE, sectorsToRead * SECTOR_SIZE, K_ACCESS_READ, outputBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(lba * SECTOR_SIZE, sectorsToRead * SECTOR_SIZE, K_ACCESS_READ, outputBuffer, ES_FLAGS_DEFAULT)) {
|
||||
READ_FAILURE("Could not read file sectors.\n");
|
||||
}
|
||||
|
||||
|
@ -278,7 +277,7 @@ static EsError Enumerate(KNode *node) {
|
|||
uint32_t remainingBytes = directory->record.extentSize.x;
|
||||
|
||||
while (remainingBytes) {
|
||||
bool accessResult = volume->fileSystem->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
|
||||
bool accessResult = volume->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
|
||||
|
||||
if (!accessResult) {
|
||||
ENUMERATE_FAILURE("Could not read sector.\n");
|
||||
|
@ -380,7 +379,7 @@ static EsError ScanInternal(const char *name, size_t nameBytes, KNode *_director
|
|||
uint32_t remainingBytes = directory->record.extentSize.x;
|
||||
|
||||
while (remainingBytes) {
|
||||
bool accessResult = volume->fileSystem->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
|
||||
bool accessResult = volume->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
|
||||
|
||||
if (!accessResult) {
|
||||
SCAN_FAILURE("Could not read sector.\n");
|
||||
|
@ -465,7 +464,7 @@ static EsError Load(KNode *_directory, KNode *_node, KNodeMetadata *, const void
|
|||
|
||||
EsDefer(EsHeapFree(sectorBuffer, SECTOR_SIZE, K_FIXED));
|
||||
|
||||
if (!volume->fileSystem->Access(reference.sector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
if (!volume->Access(reference.sector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT)) {
|
||||
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
||||
|
@ -489,55 +488,53 @@ static void Close(KNode *node) {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume));
|
||||
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
|
||||
|
||||
if (!volume) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "allocate error", "EntryISO9660 - Could not allocate Volume structure.\n");
|
||||
if (!volume || !FSFileSystemInitialise(volume)) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "allocate error", "DeviceAttach - Could not initialise volume.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem = (KFileSystem *) parent;
|
||||
|
||||
if (volume->fileSystem->block->sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "incorrect sector size", "EntryISO9660 - Expected 2KB sectors, but drive's sectors are %D.\n",
|
||||
volume->fileSystem->block->sectorSize);
|
||||
if (volume->block->sectorSize != SECTOR_SIZE) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "incorrect sector size", "DeviceAttach - Expected 2KB sectors, but drive's sectors are %D.\n",
|
||||
volume->block->sectorSize);
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Mount(volume)) {
|
||||
KernelLog(LOG_ERROR, "ISO9660", "mount failure", "EntryISO9660 - Could not mount ISO9660 volume.\n");
|
||||
KernelLog(LOG_ERROR, "ISO9660", "mount failure", "DeviceAttach - Could not mount ISO9660 volume.\n");
|
||||
KDeviceDestroy(volume);
|
||||
return;
|
||||
}
|
||||
|
||||
volume->fileSystem->read = Read;
|
||||
volume->fileSystem->scan = Scan;
|
||||
volume->fileSystem->load = Load;
|
||||
volume->fileSystem->enumerate = Enumerate;
|
||||
volume->fileSystem->close = Close;
|
||||
volume->read = Read;
|
||||
volume->scan = Scan;
|
||||
volume->load = Load;
|
||||
volume->enumerate = Enumerate;
|
||||
volume->close = Close;
|
||||
|
||||
volume->fileSystem->spaceUsed = volume->primaryDescriptor.volumeSize.x * volume->primaryDescriptor.logicalBlockSize.x;
|
||||
volume->fileSystem->spaceTotal = volume->fileSystem->spaceUsed;
|
||||
volume->spaceUsed = volume->primaryDescriptor.volumeSize.x * volume->primaryDescriptor.logicalBlockSize.x;
|
||||
volume->spaceTotal = volume->spaceUsed;
|
||||
|
||||
volume->fileSystem->nameBytes = sizeof(volume->primaryDescriptor.volumeIdentifier);
|
||||
if (volume->fileSystem->nameBytes > sizeof(volume->fileSystem->name)) volume->fileSystem->nameBytes = sizeof(volume->fileSystem->name);
|
||||
EsMemoryCopy(volume->fileSystem->name, volume->primaryDescriptor.volumeIdentifier, volume->fileSystem->nameBytes);
|
||||
volume->nameBytes = sizeof(volume->primaryDescriptor.volumeIdentifier);
|
||||
if (volume->nameBytes > sizeof(volume->name)) volume->nameBytes = sizeof(volume->name);
|
||||
EsMemoryCopy(volume->name, volume->primaryDescriptor.volumeIdentifier, volume->nameBytes);
|
||||
|
||||
for (intptr_t i = volume->fileSystem->nameBytes - 1; i >= 0; i--) {
|
||||
if (volume->fileSystem->name[i] == ' ') {
|
||||
volume->fileSystem->nameBytes--;
|
||||
for (intptr_t i = volume->nameBytes - 1; i >= 0; i--) {
|
||||
if (volume->name[i] == ' ') {
|
||||
volume->nameBytes--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
volume->fileSystem->directoryEntryDataBytes = sizeof(DirectoryRecordReference);
|
||||
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
|
||||
volume->directoryEntryDataBytes = sizeof(DirectoryRecordReference);
|
||||
volume->nodeDataBytes = sizeof(FSNode);
|
||||
|
||||
KernelLog(LOG_INFO, "ISO9660", "register file system", "EntryISO9660 - Registering file system with name '%s'.\n",
|
||||
volume->fileSystem->nameBytes, volume->fileSystem->name);
|
||||
FSRegisterFileSystem(volume->fileSystem);
|
||||
KernelLog(LOG_INFO, "ISO9660", "register file system", "DeviceAttach - Registering file system with name '%s'.\n",
|
||||
volume->nameBytes, volume->name);
|
||||
FSRegisterFileSystem(volume);
|
||||
}
|
||||
|
||||
KDriver driverISO9660 = {
|
||||
|
|
|
@ -1212,7 +1212,7 @@ static void Close(KNode *node) {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
Volume *volume = (Volume *) KDeviceCreate("NTFS", parent, sizeof(Volume));
|
||||
Volume *volume = (Volume *) KDeviceCreate("NTFS", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
|
||||
|
||||
if (!volume) {
|
||||
KernelLog(LOG_ERROR, "NTFS", "allocate error", "EntryNTFS - Could not allocate Volume structure.\n");
|
||||
|
|
|
@ -792,7 +792,7 @@ void NVMeController::Initialise() {
|
|||
KernelLog(LOG_INFO, "NVMe", "namespace identified", "Identifier namespace %d with sectors of size %D, and a capacity of %D.%z\n",
|
||||
nsid, sectorBytes, capacity, readOnly ? " The namespace is read-only." : "");
|
||||
|
||||
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive));
|
||||
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive), ES_DEVICE_BLOCK);
|
||||
|
||||
if (!device) {
|
||||
KernelLog(LOG_ERROR, "NVMe", "allocation failure", "Could not create device for namespace %d.\n", nsid);
|
||||
|
@ -849,7 +849,7 @@ void NVMeController::Shutdown() {
|
|||
static void DeviceAttach(KDevice *_parent) {
|
||||
KPCIDevice *parent = (KPCIDevice *) _parent;
|
||||
|
||||
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController));
|
||||
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController), ES_DEVICE_CONTROLLER);
|
||||
if (!device) return;
|
||||
device->pci = parent;
|
||||
|
||||
|
|
|
@ -433,7 +433,7 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
|
|||
uint32_t deviceClass = ReadConfig(bus, device, function, 0x08);
|
||||
uint32_t interruptInformation = ReadConfig(bus, device, function, 0x3C);
|
||||
|
||||
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice));
|
||||
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice), ES_DEVICE_PCI_FUNCTION);
|
||||
if (!pciDevice) return;
|
||||
|
||||
pciDevice->classCode = (deviceClass >> 24) & 0xFF;
|
||||
|
@ -537,7 +537,7 @@ static void DeviceAttach(KDevice *parent) {
|
|||
return;
|
||||
}
|
||||
|
||||
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController));
|
||||
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController), ES_DEVICE_CONTROLLER);
|
||||
|
||||
if (pci) {
|
||||
pci->Enumerate();
|
||||
|
|
|
@ -550,9 +550,9 @@ void PS2::Initialise(KDevice *parentDevice) {
|
|||
registeredIRQs = true;
|
||||
}
|
||||
|
||||
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice));
|
||||
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice));
|
||||
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice));
|
||||
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice), ES_DEVICE_CONTROLLER);
|
||||
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice), ES_DEVICE_HID);
|
||||
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice), ES_DEVICE_HID);
|
||||
|
||||
KernelLog(LOG_INFO, "PS/2", "controller initialised", "Setup PS/2 controller%z.\n", channels == 2 ? ", with a mouse" : "");
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ void InitialiseVBE(KDevice *parent) {
|
|||
}
|
||||
}
|
||||
|
||||
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget));
|
||||
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
|
||||
|
||||
linearBuffer = (uint8_t *) MMMapPhysical(MMGetKernelSpace(), vbeMode->bufferPhysical,
|
||||
vbeMode->bytesPerScanlineLinear * vbeMode->heightPixels, MM_REGION_WRITE_COMBINING);
|
||||
|
@ -267,7 +267,7 @@ void InitialiseVGA(KDevice *parent) {
|
|||
ProcessorIn8(VGA_INSTAT_READ);
|
||||
ProcessorOut8(VGA_AC_INDEX, 0x20);
|
||||
|
||||
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget));
|
||||
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
|
||||
target->screenWidth = VGA_SCREEN_WIDTH;
|
||||
target->screenHeight = VGA_SCREEN_HEIGHT;
|
||||
target->updateScreen = VGAUpdateScreen;
|
||||
|
|
|
@ -185,7 +185,7 @@ void Device::Initialise() {
|
|||
|
||||
// Register the drive.
|
||||
|
||||
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive));
|
||||
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive), ES_DEVICE_BLOCK);
|
||||
|
||||
if (!drive) {
|
||||
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not create drive for LUN %d.\n", i);
|
||||
|
@ -206,7 +206,7 @@ void Device::Initialise() {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device));
|
||||
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device), ES_DEVICE_OTHER);
|
||||
|
||||
if (!device) {
|
||||
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not allocate device structure.\n");
|
||||
|
|
|
@ -719,7 +719,7 @@ static void DeviceDestroy(KDevice *_device) {
|
|||
}
|
||||
|
||||
static void DeviceAttach(KDevice *parent) {
|
||||
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice));
|
||||
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice), ES_DEVICE_HID);
|
||||
|
||||
if (!device) {
|
||||
KernelLog(LOG_ERROR, "USBHID", "allocation failure", "Could not allocate HIDDevice structure.\n");
|
||||
|
|
|
@ -849,7 +849,7 @@ void XHCIController::OnPortEnable(uintptr_t port) {
|
|||
|
||||
// Register the device with USB subsystem.
|
||||
|
||||
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice));
|
||||
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice), ES_DEVICE_USB);
|
||||
ports[port].device = device;
|
||||
device->port = port;
|
||||
device->controlTransfer = ControlTransferWrapper;
|
||||
|
@ -1255,7 +1255,7 @@ void XHCIController::Initialise() {
|
|||
static void DeviceAttach(KDevice *_parent) {
|
||||
KPCIDevice *parent = (KPCIDevice *) _parent;
|
||||
|
||||
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController));
|
||||
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController), ES_DEVICE_CONTROLLER);
|
||||
if (!device) return;
|
||||
device->pci = parent;
|
||||
|
||||
|
|
|
@ -54,26 +54,6 @@ struct CCSpaceCallbacks {
|
|||
EsError (*writeFrom)(CCSpace *fileCache, const void *buffer, EsFileOffset offset, EsFileOffset count);
|
||||
};
|
||||
|
||||
// Describes the physical and virtual memory covering a file.
|
||||
|
||||
struct CCSpace {
|
||||
// A sorted list of the cached sections in the file.
|
||||
// Maps offset -> physical address.
|
||||
KMutex cachedSectionsMutex;
|
||||
Array<CCCachedSection, K_CORE> cachedSections;
|
||||
|
||||
// A sorted list of the active sections.
|
||||
// Maps offset -> virtual address.
|
||||
KMutex activeSectionsMutex;
|
||||
Array<CCActiveSectionReference, K_CORE> activeSections;
|
||||
|
||||
// Used by CCSpaceFlush.
|
||||
KEvent writeComplete;
|
||||
|
||||
// Callbacks.
|
||||
const CCSpaceCallbacks *callbacks;
|
||||
};
|
||||
|
||||
void CCInitialise();
|
||||
|
||||
void CCDereferenceActiveSection(CCActiveSection *section, uintptr_t startingPage = 0);
|
||||
|
|
|
@ -17,7 +17,7 @@ Array<KInstalledDriver, K_FIXED> installedDrivers;
|
|||
|
||||
void *ResolveKernelSymbol(const char *name, size_t nameBytes);
|
||||
|
||||
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes) {
|
||||
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes, EsDeviceType type) {
|
||||
if (bytes < sizeof(KDevice)) {
|
||||
KernelPanic("KDeviceCreate - Device structure size is too small (less than KDevice).\n");
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes) {
|
|||
device->parent = parent;
|
||||
device->cDebugName = cDebugName;
|
||||
device->handles = 2; // One handle for the creator, and another closed when the device is removed (by the parent).
|
||||
device->type = type;
|
||||
|
||||
if (parent) {
|
||||
KMutexAcquire(&deviceTreeMutex);
|
||||
|
@ -254,7 +255,7 @@ bool KDeviceAttachByName(KDevice *parentDevice, const char *cName) {
|
|||
void DeviceRootAttach(KDevice *parentDevice) {
|
||||
// Load all the root drivers and create their devices.
|
||||
|
||||
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice)), "Root");
|
||||
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER), "Root");
|
||||
|
||||
// Check we have found the drive from which we booted.
|
||||
// TODO Decide the timeout.
|
||||
|
|
|
@ -1014,7 +1014,7 @@ void FSUnmountFileSystem(uintptr_t argument) {
|
|||
}
|
||||
|
||||
KernelLog(LOG_INFO, "FS", "unmount complete", "Unmounted file system %x.\n", fileSystem);
|
||||
KDeviceCloseHandle(fileSystem->children[0]);
|
||||
KDeviceCloseHandle(fileSystem);
|
||||
__sync_fetch_and_sub(&fs.fileSystemsUnmounting, 1);
|
||||
KEventSet(&fs.fileSystemUnmounted, false, true);
|
||||
}
|
||||
|
@ -1594,13 +1594,13 @@ bool FSBlockDeviceAccess(KBlockDeviceAccessRequest request) {
|
|||
}
|
||||
}
|
||||
|
||||
EsError FSReadIntoBlockCache(CCSpace *fileCache, void *buffer, EsFileOffset offset, EsFileOffset count) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) fileCache - 1;
|
||||
EsError FSReadIntoBlockCache(CCSpace *cache, void *buffer, EsFileOffset offset, EsFileOffset count) {
|
||||
KFileSystem *fileSystem = EsContainerOf(KFileSystem, cacheSpace, cache);
|
||||
return fileSystem->Access(offset, count, K_ACCESS_READ, buffer, ES_FLAGS_DEFAULT, nullptr) ? ES_SUCCESS : ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
||||
EsError FSWriteFromBlockCache(CCSpace *fileCache, const void *buffer, EsFileOffset offset, EsFileOffset count) {
|
||||
KFileSystem *fileSystem = (KFileSystem *) fileCache - 1;
|
||||
EsError FSWriteFromBlockCache(CCSpace *cache, const void *buffer, EsFileOffset offset, EsFileOffset count) {
|
||||
KFileSystem *fileSystem = EsContainerOf(KFileSystem, cacheSpace, cache);
|
||||
return fileSystem->Access(offset, count, K_ACCESS_WRITE, (void *) buffer, ES_FLAGS_DEFAULT, nullptr) ? ES_SUCCESS : ES_ERROR_DRIVE_CONTROLLER_REPORTED;
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1631,7 @@ bool KFileSystem::Access(EsFileOffset offset, size_t count, int operation, void
|
|||
// We use the CC_ACCESS_PRECISE flag for file systems that have a block size less than the page size.
|
||||
// Otherwise, we might end up trashing file blocks (which aren't kept in the block device cache).
|
||||
|
||||
EsError result = CCSpaceAccess((CCSpace *) (this + 1), buffer, offset, count,
|
||||
EsError result = CCSpaceAccess(&cacheSpace, buffer, offset, count,
|
||||
operation == K_ACCESS_READ ? CC_ACCESS_READ : (CC_ACCESS_WRITE | CC_ACCESS_WRITE_BACK | CC_ACCESS_PRECISE));
|
||||
|
||||
if (dispatchGroup) {
|
||||
|
@ -1669,7 +1669,7 @@ void FSPartitionDeviceAccess(KBlockDeviceAccessRequest request) {
|
|||
}
|
||||
|
||||
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *cName) {
|
||||
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice));
|
||||
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice), ES_DEVICE_BLOCK);
|
||||
if (!child) return;
|
||||
|
||||
child->parent = parent;
|
||||
|
@ -1692,7 +1692,7 @@ void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOf
|
|||
//////////////////////////////////////////
|
||||
|
||||
bool FSSignatureCheck(KInstalledDriver *driver, KDevice *device) {
|
||||
uint8_t *block = ((KFileSystem *) device)->block->information;
|
||||
uint8_t *block = ((KBlockDevice *) device)->information;
|
||||
|
||||
EsINIState s = {};
|
||||
s.buffer = driver->config;
|
||||
|
@ -1762,6 +1762,28 @@ bool FSCheckMBR(KBlockDevice *device) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FSFileSystemInitialise(KFileSystem *fileSystem) {
|
||||
FSDirectoryEntry *rootEntry = (FSDirectoryEntry *) EsHeapAllocate(sizeof(FSDirectoryEntry), true, K_FIXED);
|
||||
if (!rootEntry) goto error;
|
||||
|
||||
rootEntry->type = ES_NODE_DIRECTORY;
|
||||
if (ES_SUCCESS != FSDirectoryEntryAllocateNode(rootEntry, nullptr, true, false)) goto error;
|
||||
|
||||
fileSystem->rootDirectory = rootEntry->node;
|
||||
fileSystem->rootDirectory->fileSystem = fileSystem;
|
||||
fileSystem->block = (KBlockDevice *) fileSystem->parent;
|
||||
if (!CCSpaceInitialise(&fileSystem->cacheSpace)) goto error;
|
||||
|
||||
fileSystem->cacheSpace.callbacks = &fsBlockCacheCallbacks;
|
||||
return true;
|
||||
|
||||
error:;
|
||||
if (rootEntry && rootEntry->node) FSNodeFree(rootEntry->node);
|
||||
if (rootEntry) EsHeapFree(rootEntry, sizeof(FSDirectoryEntry), K_FIXED);
|
||||
KDeviceDestroy(fileSystem);
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSDetectFileSystem(KBlockDevice *device) {
|
||||
KernelLog(LOG_INFO, "FS", "detect file system", "Detecting file system on block device '%z'.\n", device->cModel);
|
||||
|
||||
|
@ -1793,35 +1815,7 @@ void FSDetectFileSystem(KBlockDevice *device) {
|
|||
if (!device->noMBR && FSCheckMBR(device)) {
|
||||
// Found an MBR.
|
||||
} else {
|
||||
FSDirectoryEntry *rootEntry = nullptr;
|
||||
KFileSystem *fileSystem = nullptr;
|
||||
CCSpace *cache = nullptr;
|
||||
|
||||
rootEntry = (FSDirectoryEntry *) EsHeapAllocate(sizeof(FSDirectoryEntry), true, K_FIXED);
|
||||
if (!rootEntry) goto error;
|
||||
|
||||
rootEntry->type = ES_NODE_DIRECTORY;
|
||||
if (ES_SUCCESS != FSDirectoryEntryAllocateNode(rootEntry, nullptr, true, false)) goto error;
|
||||
|
||||
fileSystem = (KFileSystem *) KDeviceCreate("file system", device, sizeof(KFileSystem) + sizeof(CCSpace));
|
||||
if (!fileSystem) goto error;
|
||||
|
||||
fileSystem->rootDirectory = rootEntry->node;
|
||||
fileSystem->rootDirectory->fileSystem = fileSystem;
|
||||
fileSystem->block = device;
|
||||
cache = (CCSpace *) (fileSystem + 1);
|
||||
if (!CCSpaceInitialise(cache)) goto error;
|
||||
|
||||
cache->callbacks = &fsBlockCacheCallbacks;
|
||||
KDeviceAttach(fileSystem, "Files", FSSignatureCheck);
|
||||
KDeviceCloseHandle(fileSystem);
|
||||
goto success;
|
||||
|
||||
error:;
|
||||
if (fileSystem) KDeviceDestroy(fileSystem);
|
||||
if (rootEntry && rootEntry->node) FSNodeFree(rootEntry->node);
|
||||
if (rootEntry) EsHeapFree(rootEntry, sizeof(FSDirectoryEntry), K_FIXED);
|
||||
success:;
|
||||
KDeviceAttach(device, "Files", FSSignatureCheck);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1862,10 +1856,6 @@ void FSFileSystemDeviceRemoved(KDevice *device) {
|
|||
}
|
||||
|
||||
void FSRegisterFileSystem(KFileSystem *fileSystem) {
|
||||
if (fileSystem->children.Length() != 1) {
|
||||
KernelPanic("FSRegisterFileSystem - File system %x does not have a child device.\n", fileSystem);
|
||||
}
|
||||
|
||||
static volatile uint64_t id = 1;
|
||||
fileSystem->id = __sync_fetch_and_add(&id, 1);
|
||||
|
||||
|
|
|
@ -548,7 +548,7 @@ struct KDevice {
|
|||
|
||||
#define K_DEVICE_REMOVED (1 << 0)
|
||||
uint8_t flags;
|
||||
|
||||
uint16_t type;
|
||||
uint32_t handles;
|
||||
|
||||
// These callbacks are called with the deviceTreeMutex locked.
|
||||
|
@ -582,7 +582,7 @@ void KDeviceAttachAll(KDevice *parentDevice, const char *cParentDriver);
|
|||
// Similar to KDeviceAttach, except it calls `attach` only for the driver matching the provided name. Returns true if the driver was found.
|
||||
bool KDeviceAttachByName(KDevice *parentDevice, const char *cName);
|
||||
|
||||
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */);
|
||||
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */, EsDeviceType type);
|
||||
void KDeviceOpenHandle(KDevice *device);
|
||||
void KDeviceDestroy(KDevice *device); // Call if initialisation of the device failed. Otherwise use KDeviceCloseHandle.
|
||||
void KDeviceCloseHandle(KDevice *device); // The device creator is responsible for one handle after the creating it. The device is destroyed once all handles are closed.
|
||||
|
@ -798,6 +798,24 @@ void KRegisterUSBDevice(KUSBDevice *device); // Takes ownership of the device's
|
|||
// File systems.
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct CCSpace {
|
||||
// A sorted list of the cached sections in the file.
|
||||
// Maps offset -> physical address.
|
||||
KMutex cachedSectionsMutex;
|
||||
Array<struct CCCachedSection, K_CORE> cachedSections;
|
||||
|
||||
// A sorted list of the active sections.
|
||||
// Maps offset -> virtual address.
|
||||
KMutex activeSectionsMutex;
|
||||
Array<struct CCActiveSectionReference, K_CORE> activeSections;
|
||||
|
||||
// Used by CCSpaceFlush.
|
||||
KEvent writeComplete;
|
||||
|
||||
// Callbacks.
|
||||
const struct CCSpaceCallbacks *callbacks;
|
||||
};
|
||||
|
||||
struct KNodeMetadata {
|
||||
// Metadata stored in the node's directory entry.
|
||||
EsNodeType type;
|
||||
|
@ -836,8 +854,6 @@ struct KFileSystem : KDevice {
|
|||
|
||||
// Fill these fields in before registering the file system:
|
||||
|
||||
void *driverData;
|
||||
|
||||
char name[64];
|
||||
size_t nameBytes;
|
||||
|
||||
|
@ -870,6 +886,7 @@ struct KFileSystem : KDevice {
|
|||
bool isBootFileSystem, unmounting;
|
||||
volatile uint64_t totalHandleCount;
|
||||
uint64_t id;
|
||||
CCSpace cacheSpace;
|
||||
|
||||
MMObjectCache cachedDirectoryEntries, // Directory entries without a loaded node.
|
||||
cachedNodes; // Nodes with no handles or directory entries.
|
||||
|
@ -888,6 +905,8 @@ void FSNodeScanAndLoadComplete(KNode *node, bool success);
|
|||
// but lets you pass an arbitrary KNode instead of a [directory, file name] pair.
|
||||
void FSNodeUpdateDriverData(KNode *node, const void *newDriverData);
|
||||
|
||||
bool FSFileSystemInitialise(KFileSystem *fileSystem); // Do not attempt to load the file system if this returns false; the file system will be destroyed.
|
||||
|
||||
// All these functions take ownership of the device's main handle.
|
||||
void FSRegisterBlockDevice(KBlockDevice *blockDevice);
|
||||
void FSRegisterFileSystem(KFileSystem *fileSystem);
|
||||
|
|
|
@ -261,7 +261,7 @@ Option options[] = {
|
|||
{ "Driver.EssenceFS", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.Ext2", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.FAT", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.HDAudio", OPTION_TYPE_BOOL, { .b = false } },
|
||||
{ "Driver.HDAudio", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.I8254x", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.IDE", OPTION_TYPE_BOOL, { .b = true } },
|
||||
{ "Driver.ISO9660", OPTION_TYPE_BOOL, { .b = true } },
|
||||
|
|
34
util/luigi.h
34
util/luigi.h
|
@ -165,6 +165,7 @@ typedef enum UIMessage {
|
|||
UI_MSG_WINDOW_CLOSE, // return 1 to prevent default (process exit for UIWindow; close for UIMDIChild)
|
||||
UI_MSG_TAB_SELECTED, // sent to the tab that was selected (not the tab pane itself)
|
||||
UI_MSG_WINDOW_DROP_FILES, // di = count, dp = char ** of paths
|
||||
UI_MSG_WINDOW_ACTIVATE,
|
||||
|
||||
UI_MSG_USER,
|
||||
} UIMessage;
|
||||
|
@ -4538,6 +4539,7 @@ bool _UIProcessEvent(XEvent *event) {
|
|||
UIWindow *window = _UIFindWindow(event->xfocus.window);
|
||||
if (!window) return false;
|
||||
window->ctrl = window->shift = window->alt = false;
|
||||
UIElementMessage(&window->e, UI_MSG_WINDOW_ACTIVATE, 0, 0);
|
||||
} else if (event->type == ClientMessage && event->xclient.message_type == ui.dndEnterID) {
|
||||
UIWindow *window = _UIFindWindow(event->xclient.window);
|
||||
if (!window) return false;
|
||||
|
@ -4607,11 +4609,19 @@ bool _UIProcessEvent(XEvent *event) {
|
|||
while (!(i && data[i - 1] == '\r' && data[i] == '\n' && i < (int) count)) i++;
|
||||
copy[i - 1] = 0;
|
||||
|
||||
for (int j = 0; s[j]; j++) {
|
||||
if (s[j] == '%' && s[j + 1] && s[j + 2]) {
|
||||
char n[3];
|
||||
n[0] = s[j + 1], n[1] = s[j + 2], n[2] = 0;
|
||||
s[j] = strtol(n, NULL, 16);
|
||||
if (!s[j]) break;
|
||||
memmove(s + j + 1, s + j + 3, strlen(s) - j - 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':' && s[5] == '/' && s[6] == '/') {
|
||||
files[fileCount++] = s + 7;
|
||||
}
|
||||
|
||||
// TODO Replace % codes in the URL.
|
||||
}
|
||||
|
||||
UIElementMessage(&window->e, UI_MSG_WINDOW_DROP_FILES, fileCount, files);
|
||||
|
@ -4847,9 +4857,27 @@ LRESULT CALLBACK _UIWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR
|
|||
|
||||
if (message == WM_SETFOCUS) {
|
||||
_UIInspectorSetFocusedWindow(window);
|
||||
UIElementMessage(&window->e, UI_MSG_WINDOW_ACTIVATE, 0, 0);
|
||||
}
|
||||
} else if (message == WM_MOUSEACTIVATE && (window->e.flags & UI_WINDOW_MENU)) {
|
||||
return MA_NOACTIVATE;
|
||||
} else if (message == WM_DROPFILES) {
|
||||
HDROP drop = (HDROP) wParam;
|
||||
int count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
|
||||
char **files = (char **) UI_MALLOC(sizeof(char *) * count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int length = DragQueryFile(drop, i, NULL, 0);
|
||||
files[i] = (char *) UI_MALLOC(length + 1);
|
||||
files[i][length] = 0;
|
||||
DragQueryFile(drop, i, files[i], length + 1);
|
||||
}
|
||||
|
||||
UIElementMessage(&window->e, UI_MSG_WINDOW_DROP_FILES, count, files);
|
||||
for (int i = 0; i < count; i++) UI_FREE(files[i]);
|
||||
UI_FREE(files);
|
||||
DragFinish(drop);
|
||||
_UIUpdate();
|
||||
} else if (message == WM_APP + 1) {
|
||||
UIElementMessage(&window->e, (UIMessage) wParam, 0, (void *) lParam);
|
||||
_UIUpdate();
|
||||
|
@ -4945,7 +4973,7 @@ UIWindow *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, in
|
|||
window->hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_NOACTIVATE, "shadow", 0, WS_POPUP,
|
||||
0, 0, 0, 0, owner->hwnd, NULL, NULL, NULL);
|
||||
} else {
|
||||
window->hwnd = CreateWindow("normal", cTitle, WS_OVERLAPPEDWINDOW,
|
||||
window->hwnd = CreateWindowEx(WS_EX_ACCEPTFILES, "normal", cTitle, WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, width ? width : CW_USEDEFAULT, height ? height : CW_USEDEFAULT,
|
||||
owner ? owner->hwnd : NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue