diff options
| author | Amlal <amlal@nekernel.org> | 2025-04-28 21:24:37 +0200 |
|---|---|---|
| committer | Amlal <amlal@nekernel.org> | 2025-04-28 21:24:37 +0200 |
| commit | a435ad97c1dac5282e148e6dac2d82aabcb553e5 (patch) | |
| tree | 8e5ba5d7ba21d4d78f7793a8de375c880b1fd62c | |
| parent | fc91bc6dacb8e53e081695054a31fe3e34bef5a0 (diff) | |
kernel: getting that filesystem to work as intended.
Signed-off-by: Amlal <amlal@nekernel.org>
| -rw-r--r-- | dev/boot/amd64-desktop.make | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 4 | ||||
| -rw-r--r-- | dev/kernel/src/FS/HeFS.cc | 208 | ||||
| -rw-r--r-- | dev/modules/AHCI/AHCI.h | 8 |
4 files changed, 123 insertions, 99 deletions
diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 652ba31e..9558446e 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -131,7 +131,7 @@ run-efi-amd64-ata: run-efi-amd64-ata-dma # img_2 is the rescue disk. img is the bootable disk, as provided by the NeKernel specs. .PHONY: epm-img epm-img: - qemu-img create -f raw $(IMG) 4G + qemu-img create -f raw $(IMG) 32M .PHONY: efi efi: diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 3994a1a9..4391bd40 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -196,8 +196,8 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz } command_header->Prdtl = prdt_index; - command_header->Struc.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); - command_header->Struc.Write = Write; + command_header->HbaFlags.Struct.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); + command_header->HbaFlags.Struct.Write = Write; volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*) (&command_table->Cfis[0]); diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 94f7dac1..f0bb5d78 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -219,21 +219,8 @@ namespace Detail { SizeT sz = 0UL; auto start = root->fStartIND; - auto end = root->fEndIND; - - auto hop_watch = 0UL; while (YES) { - if (start > end) { - kout << "Error: Invalid start/end values.\r"; - break; - } - - if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; @@ -327,11 +314,54 @@ namespace Detail { dirent->fEntryCount = 0; - dirent->fChild = tmpdir->fChild; - dirent->fParent = tmpdir->fParent; - dirent->fNext = tmpdir->fNext; - dirent->fPrev = tmpdir->fPrev; - dirent->fColor = tmpdir->fColor; + dirent->fNext = tmpdir->fNext; + dirent->fPrev = tmpdir->fPrev; + + if (dirent->fPrev == 0) { + dirent->fPrev = root->fStartIND; + } + + if (dirent->fNext == 0) { + if (start == root->fEndIND) { + dirent->fNext = start + sizeof(HEFS_INDEX_NODE_DIRECTORY); + } + } + + if (tmpdir->fParent == 0) { + tmpdir->fParent = root->fStartIND; + } + + if (tmpdir->fChild == 0) { + auto child = root->fEndIND; + + while (YES) { + mnt->fPacket.fPacketLba = child; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = tmpdir; + + mnt->fInput(mnt->fPacket); + + if ((!tmpdir->fCreated && tmpdir->fDeleted) || *tmpdir->fName == u8'\0') { + break; + } + + child -= sizeof(HEFS_INDEX_NODE_DIRECTORY); + if (child > root->fEndIND) break; + } + + dirent->fColor = kHeFSRed; + dirent->fChild = child; + + if (child > root->fEndIND) dirent->fChild = root->fEndIND; + } else { + dirent->fColor = tmpdir->fColor; + dirent->fChild = tmpdir->fChild; + } + + for (SizeT index = 0UL; index < (kHeFSBlockCount * 2); index += 2) { + dirent->fIndexNode[index] = root->fStartIN; + dirent->fIndexNode[index + 1] = 0UL; + } mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -351,6 +381,7 @@ namespace Detail { } hefsi_traverse_tree(tmpdir, root, start); + if (start > root->fEndIND) break; } err_global_get() = kErrorDisk; @@ -368,22 +399,9 @@ namespace Detail { if (root && mnt) { HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); - auto start = mnt->fLbaStart + kHeFSINDStartLBA; - auto end = mnt->fLbaEnd; - - auto hop_watch = 0UL; + auto start = root->fStartIND; while (YES) { - if (start > end) { - kout << "Error: Invalid start/end values.\r"; - break; - } - - if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; @@ -392,7 +410,6 @@ namespace Detail { if (!mnt->fPacket.fPacketGood) { delete dir; - dir = nullptr; err_global_get() = kErrorFileNotFound; @@ -441,23 +458,10 @@ namespace Detail { } auto start = root->fStartIND; - auto end = root->fEndIND; auto start_cnt = 0UL; - auto hop_watch = 0UL; - while (YES) { - if (start > end) { - kout << "Error: Invalid start/end values.\r"; - break; - } - - if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; @@ -479,7 +483,7 @@ namespace Detail { if (dir->fKind == kHeFSFileKindDirectory) { if (KStringBuilder::Equals(dir_name, dir->fName) || KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { + for (SizeT inode_index = 0UL; inode_index < (kHeFSBlockCount * 2); inode_index += 2) { if (dir->fIndexNode[inode_index] != 0) { mnt->fPacket.fPacketLba = dir->fIndexNode[inode_index]; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); @@ -551,16 +555,7 @@ namespace Detail { auto start = root->fStartIND; - auto hop_watch = 0UL; - while (YES) { - if (start > root->fEndIND) break; - - if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; @@ -568,7 +563,7 @@ namespace Detail { mnt->fInput(mnt->fPacket); if (KStringBuilder::Equals(dir->fName, parent_dir_name)) { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { + for (SizeT inode_index = 0UL; inode_index < (kHeFSBlockCount * 2); inode_index += 2) { if (dir->fIndexNode[inode_index] != 0) { HEFS_INDEX_NODE prev_node; @@ -580,26 +575,23 @@ namespace Detail { mnt->fInput(mnt->fPacket); - if (prev_node.fDeleted > 0 && !prev_node.fCreated) { - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; + mnt->fPacket.fPacketLba = lba; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - if (mnt->fPacket.fPacketGood) { - delete dir; - dir = nullptr; + if (mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - return YES; - } + return YES; } } } } hefsi_traverse_tree(dir, root, start); - if (start > root->fEndIND) break; } @@ -624,22 +616,13 @@ namespace Detail { auto start = root->fStartIND; - SizeT hop_watch = 0UL; - while (YES) { - if (start > root->fEndIND) break; - mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; mnt->fInput(mnt->fPacket); - if (hop_watch++ > (root->fSectorCount)) { // <-- NEW (stall protection) - kout << "Warning: Traversal stalled during balancing.\r"; - break; // Exit cleanly instead of hanging forever - } - if (!mnt->fPacket.fPacketGood) { delete dir; dir = nullptr; @@ -717,7 +700,6 @@ namespace Detail { } hefsi_traverse_tree(dir, root, start); - if (start > root->fEndIND) break; continue; @@ -726,7 +708,6 @@ namespace Detail { hefsi_rotate_left(dir, start, mnt); hefsi_traverse_tree(dir, root, start); - if (start > root->fEndIND) break; continue; @@ -753,7 +734,6 @@ namespace Detail { } hefsi_traverse_tree(dir, root, start); - if (start > root->fEndIND) break; } @@ -840,12 +820,6 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input urt_copy_memory((VoidPtr) part_name, root->fVolName, urt_string_len(part_name)); rt_copy_memory((VoidPtr) kHeFSMagic, root->fMagic, kHeFSMagicLen - 1); - root->fBadSectors = 0; - - root->fSectorCount = drv_std_get_sector_count(); - - root->fSectorSize = drive->fSectorSz; - SizeT start = drive->fLbaStart + kHeFSINDStartLBA; if (start > drive->fLbaEnd) { @@ -857,8 +831,21 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input return NO; } + root->fBadSectors = 0; + + root->fSectorCount = drv_std_get_sector_count(); + root->fSectorSize = drive->fSectorSz; + + SizeT disk_sectors = drv_std_get_size() / drive->fSectorSz; // Get total sectors + + SizeT dir_sectors = disk_sectors / 20; // 5% for directory metadata + SizeT inode_sectors = disk_sectors / 10; // 10% for inodes + root->fStartIND = start; - root->fEndIND = drive->fLbaEnd; + root->fEndIND = root->fStartIND + dir_sectors - sizeof(HEFS_INDEX_NODE_DIRECTORY); + + root->fStartIN = root->fEndIND + 1; + root->fEndIN = root->fStartIN + inode_sectors - sizeof(HEFS_INDEX_NODE); root->fINDCount = 0; @@ -898,6 +885,45 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input return NO; } + start = root->fStartIND; + + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + rt_set_memory(dir, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + urt_copy_memory((VoidPtr) u8".CoreFS", dir->fName, urt_string_len(u8".CoreFS")); + + dir->fFlags = flags; + dir->fKind = kHeFSFileKindDirectory; + + dir->fCreated = 0; + dir->fDeleted = kHeFSTimeMax; /// TODO: Add current time. + + dir->fEntryCount = 0; + + dir->fIndexNodeChecksum = 0; + + dir->fUID = 0; + dir->fGID = 0; + dir->fMode = 0; + + dir->fColor = kHeFSBlack; + dir->fChild = root->fStartIND; + dir->fParent = root->fStartIND; + dir->fNext = root->fStartIND; + dir->fPrev = root->fStartIND; + + dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + drive->fPacket.fPacketLba = start; + drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + drive->fPacket.fPacketContent = dir; + + start += sizeof(HEFS_INDEX_NODE_DIRECTORY); + + drive->fOutput(drive->fPacket); + + delete dir; + constexpr SizeT kHeFSPreallocateCount = 0x7UL; const Utf8Char* kFileMap[kHeFSPreallocateCount] = { @@ -908,8 +934,6 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input this->CreateDirectory(drive, kHeFSEncodingUTF8, kFileMap[i]); } - Detail::hefsi_balance_filesystem(root, drive); - delete root; root = nullptr; @@ -938,8 +962,6 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu if (!root) { kout << "Error: Failed to allocate memory for boot node.\r"; - if (root) delete root; - return NO; } @@ -960,7 +982,7 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu err_global_get() = kErrorDiskIsCorrupted; - kout << "Invalid BootNode!\r"; + kout << "Invalid Boot Node, this can't continue!\r"; return NO; } @@ -1087,6 +1109,8 @@ Boolean fs_init_hefs(Void) noexcept { parser.Format(&kMountPoint, kHeFSEncodingUTF8, kHeFSDefaultVoluneName); + parser.CreateFile(&kMountPoint, kHeFSEncodingUTF8, u8"/", u8"bootnet.efi"); + return YES; } } // namespace Kernel::HeFS diff --git a/dev/modules/AHCI/AHCI.h b/dev/modules/AHCI/AHCI.h index 7303e8c5..c6d9ac07 100644 --- a/dev/modules/AHCI/AHCI.h +++ b/dev/modules/AHCI/AHCI.h @@ -262,8 +262,8 @@ typedef HbaMem* HbaMemRef; typedef struct HbaCmdHeader final { // DW0 - union { - struct { + union HbaFlags { + struct HbaFlags_ { Kernel::UInt8 Cfl : 5; // Command FIS length in DWORDS, 2 ~ 16 Kernel::UInt8 Atapi : 1; // ATAPI Kernel::UInt8 Write : 1; // Write, 1: H2D, 0: D2H @@ -274,10 +274,10 @@ typedef struct HbaCmdHeader final { Kernel::UInt8 Clear : 1; // Clear busy upon R_OK Kernel::UInt8 Reserved0 : 1; // Reserved Kernel::UInt8 Pmp : 4; // Port multiplier port - } Struc; + } Struct; Kernel::UInt16 Flags; - }; + } HbaFlags; Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred |
