From 8ef99527391d2ed35f17c8afbcc1039145692a58 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 11:10:52 +0200 Subject: feat(ahci-generic): validate sector_sz when dealing with AHCI I/O. why? - This will cause math exceptions being raised by the CPU if it happens to be zero. Signed-off-by: Amlal --- dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 3f2cf9e8..cf1841bd 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -132,11 +132,16 @@ STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept { template STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept { - NE_UNUSED(sector_sz); + if (sector_sz == 0) { + kout << "Invalid sector size.\r"; + err_global_get() = kErrorDisk; + return; + } lba /= sector_sz; if (lba > kSATASectorCount) { + kout << "Out of range LBA.\r"; err_global_get() = kErrorDisk; return; } @@ -165,6 +170,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz // Clear old command table memory volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*) (((UInt64) command_header->Ctbau << 32) | command_header->Ctba); + rt_set_memory((VoidPtr) command_table, 0, sizeof(HbaCmdTbl)); VoidPtr ptr = rtl_dma_alloc(size_buffer, 4096); @@ -270,7 +276,6 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz ahci_io_end: rtl_dma_free(size_buffer); - err_global_get() = kErrorSuccess; } } -- cgit v1.2.3 From 69fffdd906c02b6ea65f5346c31719ea0f8c3bbc Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 15:45:48 +0200 Subject: feat(kernel): Working on the last parts of HeFS V1, which will act as the base layer of the filesystem. Signed-off-by: Amlal --- dev/boot/amd64-desktop.make | 2 +- dev/kernel/FSKit/HeFS.h | 43 ++-- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 348 +++++++++++++++++++---------- 3 files changed, 250 insertions(+), 143 deletions(-) diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 8b2aa760..652ba31e 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) 1G + qemu-img create -f raw $(IMG) 4G .PHONY: efi efi: diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 27fe2838..ce9b9226 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -21,10 +21,11 @@ #define kHeFSMagic " HeFS" #define kHeFSMagicLen (8) +#define kHeFSBlockLen (512U) #define kHeFSFileNameLen (256U) #define kHeFSPartNameLen (128U) -#define kHeFSMinimumDiskSize (mib_cast(16)) +#define kHeFSMinimumDiskSize (gib_cast(1)) #define kHeFSDefaultVoluneName u8"HeFS Volume" @@ -36,6 +37,7 @@ struct HEFS_BOOT_NODE; struct HEFS_INDEX_NODE; struct HEFS_INDEX_NODE_DIRECTORY; struct HEFS_JOURNAL_NODE; +struct HEFS_INODE_SLICE; enum : UInt8 { kHeFSHardDrive = 0xC0, // Hard Drive @@ -123,16 +125,21 @@ struct PACKED HEFS_BOOT_NODE final { Kernel::UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). Kernel::UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). - Kernel::UInt64 fStartIN; /// @brief Reserved for future use. - Kernel::UInt64 fEndIN; /// @brief Reserved for future use. - Kernel::UInt64 fReserved; /// @brief Reserved for future use. - Kernel::UInt64 fReserved1; /// @brief Reserved for future use. + Kernel::UInt64 fStartIN; /// @brief Reserved for future use. + Kernel::UInt64 fEndIN; /// @brief Reserved for future use. + Kernel::UInt64 fStartBlock; /// @brief Reserved for future use. + Kernel::UInt64 fEndBlock; /// @brief Reserved for future use. Kernel::Char fPad[272]; }; inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000; inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1; +struct PACKED HEFS_INODE_SLICE { + Kernel::UInt32 fBase; + Kernel::UInt32 fLength; +}; + /// @brief HeFS index node. /// @details This structure is used to store the file information of a file. /// @note The index node is a special type of INode that contains the file information. @@ -156,10 +163,7 @@ struct PACKED HEFS_INDEX_NODE final { /// @details Using an offset to ask fBase, and fLength to compute each slice's length. Kernel::UInt64 fOffsetSlices; - struct { - Kernel::UInt32 fBase; - Kernel::UInt32 fLength; - } fSlices[kHeFSSliceCount]; /// @brief block slice + HEFS_INODE_SLICE fSlices[kHeFSSliceCount]; /// @brief block slice Kernel::Char fPad[309]; }; @@ -378,23 +382,22 @@ class HeFileSystemParser final { const Utf8Char* dir); _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, - const Utf8Char* name); + const Utf8Char* name, const UInt8 kind); _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, - const Utf8Char* name); - - _Output Bool WriteINode(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz, - const Utf8Char* dir, const Utf8Char* name); + const Utf8Char* name, const UInt8 kind); - _Output Bool ReadINode(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz, - const Utf8Char* dir, const Utf8Char* name); + _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz, + const Utf8Char* dir, const UInt8 kind, const Utf8Char* name, + const BOOL in); private: - _Output Bool INodeCtl_(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, - const Utf8Char* name, const BOOL delete_or_create); + _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create, + const UInt8 kind); - _Output Bool INodeDirectoryCtl_(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const BOOL delete_or_create); + _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf8Char* dir, const BOOL delete_or_create); }; /// @brief Initialize HeFS inside the main disk. diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index b3e1d4d0..97afd614 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -37,7 +37,7 @@ namespace Detail { /***********************************************************************************/ /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. + /// @param mnt The mnt to read from. /// @param dir_name The name of the directory. /// @param file_name The name of the file. /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic @@ -52,7 +52,7 @@ namespace Detail { /***********************************************************************************/ /// @brief Allocate a new index node-> /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. + /// @param mnt The mnt to read/write from. /// @param dir_name The name of the parent directory. /// @return Status, see err_global_get(). /***********************************************************************************/ @@ -63,14 +63,14 @@ namespace Detail { /***********************************************************************************/ /// @brief Balance RB-Tree of the filesystem. /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. + /// @param mnt The mnt to read/write from. /// @return Status, see err_global_get(). /***********************************************************************************/ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt); /// @brief Alllocate IND from boot node. /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. + /// @param mnt The mnt to read from. /// @param dir_name The name of the directory. /// @param dir_name The parent of the directory. /// @param flags Directory flags. @@ -165,7 +165,7 @@ namespace Detail { if (try_new) start += sizeof(HEFS_INDEX_NODE_DIRECTORY); if (start == 0) start = ind_start; - (Void)(kout << "LBA_" << number(start) << kendl); + (Void)(kout << "LBA_" << hex_number(start) << kendl); } /***********************************************************************************/ @@ -254,7 +254,7 @@ namespace Detail { /// @brief Alllocate IND from boot node. /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. + /// @param mnt The mnt to read from. /// @param dir_name The name of the directory. /// @param dir_name The parent of the directory. /// @param flags Directory flags. @@ -449,7 +449,7 @@ namespace Detail { /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. + /// @param mnt The mnt to read from. /// @param dir_name The name of the directory. /// @param file_name The name of the file. /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic @@ -460,16 +460,6 @@ namespace Detail { const Utf8Char* file_name, UInt8 kind, SizeT* cnt) { if (mnt) { - HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt]; - - if (!node_arr) { - return nullptr; - } - - HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE)); - HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - auto start = root->fStartIND; if (start > root->fEndIND) return nullptr; @@ -477,6 +467,15 @@ namespace Detail { auto start_cnt = 0UL; + HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt + 1]; + + if (!node_arr) { + return nullptr; + } + + HEFS_INDEX_NODE_DIRECTORY* dir = + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + while (YES) { mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -484,46 +483,41 @@ namespace Detail { mnt->fInput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorFileNotFound; + if (hefsi_hash_64(dir_name) == dir->fHashPath && dir->fKind == kHeFSFileKindDirectory) { + for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) { + if (dir->fINSlices[inode_index] != 0) { + HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE)); - delete[] node_arr; - return nullptr; - } + mnt->fPacket.fPacketLba = dir->fINSlices[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; - if (dir->fKind == kHeFSFileKindDirectory) { - if (hefsi_hash_64(dir_name) == dir->fHashPath || - KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { - if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != - dir->fChecksum) - ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 checksum failed on HeFS IND!"); - - for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) { - if (dir->fINSlices[inode_index] != 0) { - if (ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)) != node->fChecksum) - ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!"); - - if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) { - node_arr[start_cnt] = *node; - ++start_cnt; - - if (start_cnt > *cnt) { - err_global_get() = kErrorSuccess; - return node_arr; - } + mnt->fInput(mnt->fPacket); + + if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) { + node_arr[start_cnt] = *node; + ++start_cnt; + + if (start_cnt > *cnt) { + err_global_get() = kErrorSuccess; + + delete dir; + + return node_arr; } } } - } else if (dir->fHashPath == 0) { - break; } } hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES); - if (start > root->fEndIND || start == 0) break; + if (start > root->fEndIND) break; } - err_global_get() = kErrorSuccess; + node_arr[start_cnt + 1].fDeleted = 1UL; + err_global_get() = kErrorSuccess; + delete dir; + return node_arr; } @@ -567,15 +561,10 @@ namespace Detail { if (dir->fINSlices[inode_index] == 0 && !delete_or_create) { dir->fINSlices[inode_index] = root->fStartIN; - root->fStartIN += sizeof(HEFS_INDEX_NODE); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = root; - mnt->fOutput(mnt->fPacket); ++dir->fEntryCount; + dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); mnt->fPacket.fPacketLba = start; @@ -586,12 +575,36 @@ namespace Detail { auto lba = dir->fINSlices[inode_index]; + node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)); + + node->fOffsetSlices = root->fStartBlock; + + auto offset = 0; + + SizeT cnt = 0ULL; + + while (cnt < kHeFSSliceCount) { + HEFS_INODE_SLICE& slice = node->fSlices[cnt]; + slice.fBase = offset; + slice.fLength = kHeFSBlockLen; + offset += kHeFSBlockLen; + + ++cnt; + } + mnt->fPacket.fPacketLba = lba; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); mnt->fPacket.fPacketContent = node; mnt->fOutput(mnt->fPacket); + root->fStartIN += sizeof(HEFS_INDEX_NODE); + root->fStartBlock += (kHeFSSliceCount * kHeFSBlockLen); + + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; + mm_delete_heap(dir); return YES; @@ -617,6 +630,7 @@ namespace Detail { } root->fStartIN -= sizeof(HEFS_INDEX_NODE); + root->fStartBlock -= (kHeFSSliceCount * kHeFSBlockLen); mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); @@ -664,7 +678,7 @@ namespace Detail { /// @brief Balance RB-Tree of the filesystem. /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. + /// @param mnt The mnt to read/write from. /// @return Status, see err_global_get(). STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt) { if (mnt) { @@ -739,16 +753,16 @@ namespace Detail { /// @note This is certainly take longer to format a disk with it, but worth-it in the long run. namespace Kernel::HeFS { -/// @brief Make a EPM+HeFS drive out of the disk. -/// @param drive The drive to write on. +/// @brief Make a EPM+HeFS mnt out of the disk. +/// @param mnt The mnt to write on. /// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, +_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input const Int32 flags, _Input const Utf8Char* vol_name) { // Verify Disk. - drive->fVerify(drive->fPacket); + mnt->fVerify(mnt->fPacket); // if disk isn't good, then error out. - if (false == drive->fPacket.fPacketGood) { + if (false == mnt->fPacket.fPacketGood) { err_global_get() = kErrorDiskIsCorrupted; return false; } @@ -761,13 +775,13 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE)); - drive->fPacket.fPacketLba = drive->fLbaStart; - drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - drive->fPacket.fPacketContent = root; + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; - drive->fInput(drive->fPacket); + mnt->fInput(mnt->fPacket); - if (!drive->fPacket.fPacketGood) { + if (!mnt->fPacket.fPacketGood) { err_global_get() = kErrorDiskIsCorrupted; return NO; @@ -792,13 +806,13 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input return NO; } - rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); urt_copy_memory((VoidPtr) vol_name, root->fVolName, urt_string_len(vol_name) + 1); rt_copy_memory((VoidPtr) kHeFSMagic, root->fMagic, kHeFSMagicLen - 1); - if (drive->fLbaStart > drive->fLbaEnd) { + if (mnt->fLbaStart > mnt->fLbaEnd) { err_global_get() = kErrorDiskIsCorrupted; return NO; @@ -807,16 +821,16 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fBadSectors = 0; root->fSectorCount = drv_std_get_sector_count(); - root->fSectorSize = drive->fSectorSz; + root->fSectorSize = mnt->fSectorSz; MUST_PASS(root->fSectorSize); - const SizeT max_lba = drive->fLbaEnd / root->fSectorSize; + const SizeT max_lba = mnt->fLbaEnd / root->fSectorSize; const SizeT dir_max = max_lba / 20; // 20% for directory metadata const SizeT inode_max = max_lba / 20; // 10% for inodes - root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset; + root->fStartIND = mnt->fLbaStart + kHeFSINDStartOffset; root->fEndIND = root->fStartIND + dir_max; root->fStartIN = root->fEndIND + sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -827,20 +841,21 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fINDCount = 0; // let's lie here. - root->fDiskSize = drive->fLbaEnd; + root->fDiskSize = mnt->fLbaEnd; root->fDiskStatus = kHeFSStatusUnlocked; root->fDiskFlags = flags; - if (drive->fKind & kMassStorageDrive) { - } else if (drive->fKind & kHeFSOpticalDrive) { + if (mnt->fKind & kMassStorageDrive) { + root->fDiskKind = kHeFSMassStorageDevice; + } else if (mnt->fKind & kHeFSOpticalDrive) { root->fDiskKind = kHeFSOpticalDrive; } else { root->fDiskKind = kHeFSUnknown; } - root->fReserved = 0; - root->fReserved1 = 0; + root->fStartBlock = root->fEndIN + sizeof(HEFS_INDEX_NODE); + root->fEndBlock = mnt->fLbaEnd; root->fVersion = kHeFSVersion; @@ -848,20 +863,23 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)); - drive->fPacket.fPacketLba = drive->fLbaStart; - drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - drive->fPacket.fPacketContent = root; + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; - drive->fOutput(drive->fPacket); + mnt->fOutput(mnt->fPacket); - (Void)(kout << "Protocol: " << drive->fProtocol() << kendl); + (Void)(kout << "Protocol: " << mnt->fProtocol() << kendl); (Void)(kout8 << u8"Volume Name: " << root->fVolName << kendl8); (Void)(kout << "Start IND: " << hex_number(root->fStartIND) << kendl); + (Void)(kout << "End IND: " << hex_number(root->fEndIND) << kendl); + (Void)(kout << "Start IN: " << hex_number(root->fStartIN) << kendl); + (Void)(kout << "End IN: " << hex_number(root->fEndIN) << kendl); (Void)(kout << "Number of IND: " << hex_number(root->fINDCount) << kendl); (Void)(kout << "Sector Size: " << hex_number(root->fSectorSize) << kendl); - (Void)(kout << "Drive Kind:" << Detail::hefs_drive_kind_to_string(root->fDiskKind) << kendl); + (Void)(kout << "Drive Kind: " << Detail::hefs_drive_kind_to_string(root->fDiskKind) << kendl); - if (!drive->fPacket.fPacketGood) { + if (!mnt->fPacket.fPacketGood) { err_global_get() = kErrorDiskIsCorrupted; return NO; @@ -871,7 +889,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input u8"/network", u8"/devices", u8"/media"}; for (SizeT i = 0; i < kHeFSPreallocateCount; ++i) { - this->CreateINodeDirectory(drive, kHeFSEncodingFlagsUTF8, kFileMap[i]); + this->CreateINodeDirectory(mnt, kHeFSEncodingFlagsUTF8, kFileMap[i]); } err_global_get() = kErrorSuccess; @@ -880,13 +898,14 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input } /// @brief Create a new directory on the disk. -/// @param drive The drive to write on. +/// @param mnt The mnt to write on. /// @param flags The flags to use. /// @param dir The directory to create the file in. /// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive, - _Input const Int32 flags, const Utf8Char* dir, - const BOOL delete_or_create) { +_Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt, + _Input const Int32 flags, + const Utf8Char* dir, + const BOOL delete_or_create) { if (urt_string_len(dir) > kHeFSFileNameLen) { err_global_get() = kErrorDisk; return NO; @@ -894,14 +913,19 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive, HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No); - rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); - drive->fPacket.fPacketLba = drive->fLbaStart; - drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - drive->fPacket.fPacketContent = root; + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; + + mnt->fInput(mnt->fPacket); - drive->fInput(drive->fPacket); + if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) { + err_global_get() = kErrorDisk; + return YES; + } if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) { err_global_get() = kErrorDiskIsCorrupted; @@ -919,9 +943,9 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive, return NO; } - if (Detail::hefsi_update_ind_status(root, drive, dir, flags, delete_or_create)) { + if (Detail::hefsi_update_ind_status(root, mnt, dir, flags, delete_or_create)) { // todo: make it smarter for high-throughput. - Detail::hefsi_balance_ind(root, drive); + Detail::hefsi_balance_ind(root, mnt); mm_delete_heap((VoidPtr) root); return YES; @@ -931,37 +955,114 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive, return NO; } -_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* drive, +_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* mnt, _Input const Int32 flags, const Utf8Char* dir) { - return this->INodeDirectoryCtl_(drive, flags, dir, YES); + return this->INodeDirectoryCtlManip(mnt, flags, dir, YES); } -_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* drive, +_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* mnt, _Input const Int32 flags, const Utf8Char* dir) { - return this->INodeDirectoryCtl_(drive, flags, dir, NO); + return this->INodeDirectoryCtlManip(mnt, flags, dir, NO); +} + +_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* mnt, _Input const Int32 flags, + const Utf8Char* dir, const Utf8Char* name, + const UInt8 kind) { + return this->INodeCtlManip(mnt, flags, dir, name, YES, kind); } -_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name) { - return this->INodeCtl_(drive, flags, dir, name, YES); +_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* mnt, _Input const Int32 flags, + const Utf8Char* dir, const Utf8Char* name, + const UInt8 kind) { + return this->INodeCtlManip(mnt, flags, dir, name, NO, kind); } -_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name) { - return this->INodeCtl_(drive, flags, dir, name, NO); +_Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz, + const Utf8Char* dir, const UInt8 kind, + const Utf8Char* name, const BOOL in) { + if (urt_string_len(dir) > kHeFSFileNameLen) { + err_global_get() = kErrorDisk; + return NO; + } + + if (urt_string_len(name) > kHeFSFileNameLen) { + err_global_get() = kErrorDisk; + return NO; + } + + HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE)); + + if (!root) { + err_global_get() = kErrorInvalidData; + return NO; + } + + rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; + + mnt->fInput(mnt->fPacket); + + if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) { + err_global_get() = kErrorDisk; + return YES; + } + + if (root->fStartBlock > root->fEndBlock) return NO; + + SizeT cnt = block_sz / sizeof(HEFS_INDEX_NODE); + auto nodes = Detail::hefsi_fetch_in(root, mnt, dir, name, kind, &cnt); + + if (!nodes) return NO; + + for (SizeT i = 0UL; i < cnt; ++i) { + auto& start = nodes[i]; + SizeT cnt_slice = 0; + SizeT sz_out = 0; + + while (cnt_slice < kHeFSSliceCount) { + struct HEFS_INODE_SLICE& slice = start.fSlices[cnt_slice]; + + mnt->fPacket.fPacketLba = slice.fBase + start.fOffsetSlices; + mnt->fPacket.fPacketSize = kHeFSBlockLen; + mnt->fPacket.fPacketContent = block; + + in ? mnt->fInput(mnt->fPacket) : mnt->fOutput(mnt->fPacket); + + sz_out += kHeFSBlockLen; + + if (!in) { + delete[] nodes; + return YES; + } else { + if (sz_out >= block_sz) { + delete[] nodes; + return YES; + } + } + + ++cnt_slice; + } + } + + delete[] nodes; + return NO; } /// @brief Create a new file on the disk. -/// @param drive The drive to write on. +/// @param mnt The mnt to write on. /// @param flags The flags to use. /// @param dir The directory to create the file in. /// @param name The name of the file. /// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::INodeCtl_(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name, - const BOOL delete_or_create) { +_Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input const Int32 flags, + const Utf8Char* dir, const Utf8Char* name, + const BOOL delete_or_create, const UInt8 kind) { if (urt_string_len(name) > kHeFSFileNameLen) { err_global_get() = kErrorDisk; return NO; @@ -990,14 +1091,19 @@ _Output Bool HeFileSystemParser::INodeCtl_(_Input DriveTrait* drive, _Input cons return NO; } - rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); - drive->fPacket.fPacketLba = drive->fLbaStart; - drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - drive->fPacket.fPacketContent = root; + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; - drive->fInput(drive->fPacket); + mnt->fInput(mnt->fPacket); + + if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) { + err_global_get() = kErrorDisk; + return YES; + } if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) { kout << "Error: Invalid file name.\r"; @@ -1025,18 +1131,17 @@ _Output Bool HeFileSystemParser::INodeCtl_(_Input DriveTrait* drive, _Input cons node->fDeleted = delete_or_create ? 1UL : 0UL; node->fModified = 0; node->fSize = 0; - node->fKind = kHeFSFileKindRegular; + node->fKind = kind; node->fFlags = flags; - node->fChecksum = 0; node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)); node->fGID = 0; node->fUID = 0; node->fHashPath = Detail::hefsi_hash_64(name); - if (Detail::hefsi_update_in_status(root, drive, dir, node, delete_or_create)) { + if (Detail::hefsi_update_in_status(root, mnt, dir, node, delete_or_create)) { mm_delete_heap((VoidPtr) node); - Detail::hefsi_balance_ind(root, drive); + Detail::hefsi_balance_ind(root, mnt); err_global_get() = kErrorSuccess; return YES; @@ -1065,13 +1170,12 @@ Boolean fs_init_hefs(Void) { parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVoluneName); MUST_PASS(parser.CreateINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly, - u8"/boot", u8".filetest")); - MUST_PASS(parser.DeleteINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly, - u8"/boot", u8".filetest")); - MUST_PASS(parser.CreateINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly, - u8"/network", u8".filetest")); - MUST_PASS(parser.DeleteINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly, - u8"/network", u8".filetest")); + u8"/boot", u8"ジェット警察.txt", kHeFSFileKindRegular)); + + Utf8Char contents_1[kHeFSBlockLen] = u8"ロケットにはジエットエンジン\r"; + + MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot", + kHeFSFileKindRegular, u8"ジェット警察.txt", NO)); return YES; } -- cgit v1.2.3 From 89c7f5088ffed6cf90402b46c5fa60aa9c1c2e28 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 19:38:55 +0200 Subject: dev(fix): Use VEPM in DriveMgr, to avoid unformatted disk error. Signed-off-by: Amlal --- dev/kernel/src/DriveMgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index f26890b5..96ff2766 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -4,7 +4,7 @@ ------------------------------------------- */ -#include +#include #include #include #include -- cgit v1.2.3 From 1fcf371998f4d1cb6e65564aa9df744d4030eda9 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 19:39:58 +0200 Subject: dev(kernel): add __NE_VEPM__ macro to compile under VEPM. Signed-off-by: Amlal --- dev/kernel/amd64-ci.make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/kernel/amd64-ci.make b/dev/kernel/amd64-ci.make index 4fb87ee1..d431342a 100644 --- a/dev/kernel/amd64-ci.make +++ b/dev/kernel/amd64-ci.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NE_VEPM__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm -- cgit v1.2.3 From 4b904e071396aa79f238baf244255ac57f869337 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 19:42:14 +0200 Subject: dev(kernel): add __NE_VEPM__ macro to compile under VEPM. Signed-off-by: Amlal --- dev/kernel/amd64-desktop.make | 2 +- dev/kernel/arm64-desktop.make | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index 7a901229..f13bc63a 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_HEFS__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_HEFS__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm diff --git a/dev/kernel/arm64-desktop.make b/dev/kernel/arm64-desktop.make index 8a1a8c19..31d8f49e 100644 --- a/dev/kernel/arm64-desktop.make +++ b/dev/kernel/arm64-desktop.make @@ -7,7 +7,7 @@ CC = clang++ LD = lld-link CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno-rtti -fno-exceptions -I./ \ -target aarch64-unknown-windows \ - -std=c++20 -O3 -D__NEOSKRNL__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../ + -std=c++20 -O3 -D__NEOSKRNL__ -D__NE_VEPM__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../ ASM = clang++ -- cgit v1.2.3 From bd65fcfb90c5c4d58a875a41057001bccc6c3530 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 19:43:46 +0200 Subject: feat(kernel/HeFS): move sz_out out of the loop, to avoid it being reset. Signed-off-by: Amlal --- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 97afd614..39ed6916 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -1020,10 +1020,11 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc if (!nodes) return NO; + SizeT sz_out = 0; + for (SizeT i = 0UL; i < cnt; ++i) { auto& start = nodes[i]; SizeT cnt_slice = 0; - SizeT sz_out = 0; while (cnt_slice < kHeFSSliceCount) { struct HEFS_INODE_SLICE& slice = start.fSlices[cnt_slice]; -- cgit v1.2.3 From ed6c7d2e771da75c02a7f96644baab407bcf85e5 Mon Sep 17 00:00:00 2001 From: Amlal Date: Tue, 6 May 2025 20:28:11 +0200 Subject: feat(HeFS): Filesystem fixes and optimizations. Signed-off-by: Amlal --- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 39ed6916..53e05c08 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -156,7 +156,7 @@ namespace Detail { continue; } - start += kHeFSINDStartOffset; + start += sizeof(HEFS_INDEX_NODE_DIRECTORY); break; } } @@ -561,8 +561,6 @@ namespace Detail { if (dir->fINSlices[inode_index] == 0 && !delete_or_create) { dir->fINSlices[inode_index] = root->fStartIN; - mnt->fOutput(mnt->fPacket); - ++dir->fEntryCount; dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); @@ -1021,7 +1019,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc if (!nodes) return NO; SizeT sz_out = 0; - + for (SizeT i = 0UL; i < cnt; ++i) { auto& start = nodes[i]; SizeT cnt_slice = 0; -- cgit v1.2.3 From 4a80c0e7eaa36817f52e0f3cd6d8c8e07bf860dc Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 6 May 2025 21:07:48 +0200 Subject: dev(kernel): Fix typo of `kHeFSDefaultVoluneName` to `kHeFSDefaultVolumeName` in HeFS. --- dev/kernel/FSKit/HeFS.h | 2 +- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 2 +- docs/tex/hefs.tex | 2 +- tooling/hefs.h | 2 +- tooling/mkfs.hefs.cc | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index ce9b9226..f7e1d648 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -27,7 +27,7 @@ #define kHeFSMinimumDiskSize (gib_cast(1)) -#define kHeFSDefaultVoluneName u8"HeFS Volume" +#define kHeFSDefaultVolumeName u8"HeFS Volume" #define kHeFSINDStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY) + sizeof(HEFS_BOOT_NODE)) diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 53e05c08..d3331710 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -1166,7 +1166,7 @@ Boolean fs_init_hefs(Void) { HeFileSystemParser parser; - parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVoluneName); + parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName); MUST_PASS(parser.CreateINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly, u8"/boot", u8"ジェット警察.txt", kHeFSFileKindRegular)); diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index afafc472..dd857795 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -25,7 +25,7 @@ The High-throughput Extended File System (HeFS) is a custom filesystem tailored \texttt{kHeFSFileNameLen} & 256 characters \\ \texttt{kHeFSPartNameLen} & 128 characters \\ \texttt{kHeFSMinimumDiskSize} & 16 MiB \\ -\texttt{kHeFSDefaultVoluneName} & "HeFS Volume" \\ +\texttt{kHeFSDefaultVolumeName} & "HeFS Volume" \\ \texttt{kHeFSINDStartOffset} & Offset after boot + dir nodes \\ \texttt{kHeFSSearchAllStr} & "\*" (wildcard string) \\ \hline diff --git a/tooling/hefs.h b/tooling/hefs.h index ded6cbef..f281e7a3 100644 --- a/tooling/hefs.h +++ b/tooling/hefs.h @@ -16,7 +16,7 @@ #define kHeFSFileNameLen (256U) #define kHeFSPartNameLen (128U) -#define kHeFSDefaultVoluneName u8"HeFS Volume" +#define kHeFSDefaultVolumeName u8"HeFS Volume" namespace mkfs::hefs { diff --git a/tooling/mkfs.hefs.cc b/tooling/mkfs.hefs.cc index bc1f3d3c..5a706646 100644 --- a/tooling/mkfs.hefs.cc +++ b/tooling/mkfs.hefs.cc @@ -11,7 +11,7 @@ static size_t kDiskSize = 1024 * 1024 * 1024 * 4UL; static uint16_t kVersion = kHeFSVersion; -static std::u8string kLabel = kHeFSDefaultVoluneName; +static std::u8string kLabel = kHeFSDefaultVolumeName; static size_t kSectorSize = 512; int main(int argc, char** argv) { @@ -43,7 +43,7 @@ int main(int argc, char** argv) { kSectorSize = std::strtol(mkfs::get_option(args, "-s").data(), nullptr, 10); kLabel = mkfs::get_option(args_wide, u8"-L"); - if (kLabel.empty()) kLabel = kHeFSDefaultVoluneName; + if (kLabel.empty()) kLabel = kHeFSDefaultVolumeName; kDiskSize = std::strtol(mkfs::get_option(args, "-S").data(), nullptr, 10) * 1024 * 1024 * 1024; -- cgit v1.2.3 From c9242551bd16ef8458626b1eea765dff336ab6dd Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 08:35:04 +0200 Subject: feat(docs): Add MBCI specification, a mini bus HW interface. where? - Inside /docs/tex why? - Provide an independent standard for future HW interfaces. Signed-off-by: Amlal --- docs/tex/mbci.tex | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 docs/tex/mbci.tex diff --git a/docs/tex/mbci.tex b/docs/tex/mbci.tex new file mode 100644 index 00000000..a23bc87b --- /dev/null +++ b/docs/tex/mbci.tex @@ -0,0 +1,114 @@ + +\documentclass{article} +\usepackage{geometry} +\usepackage{longtable} +\usepackage{listings} +\usepackage{xcolor} +\geometry{margin=1in} +\title{MBCI: Mini Bus Controller Interface Specification} +\author{Amlal El Mahrouss} +\date{2025} + +\begin{document} + +\maketitle + +\section{Overview} +The Mini Bus Controller Interface (MBCI) is a standardized memory-mapped I/O bus specification designed for use in embedded systems and operating system kernels. It provides an extensible framework for managing hardware devices via a shared bus using memory-mapped registers. + +\section{Signal Lines} +The MBCI bus interface includes the following signal lines: + +\begin{itemize} + \item \textbf{VCC} (IN) – Power supply (OUT for MCU) + \item \textbf{CLK} (IN) – Clock line (OUT for MCU) + \item \textbf{ACK} (BI) – Acknowledge line containing packet frame + \item \textbf{D0-, D1-} (IN) – Host interface packet input + \item \textbf{D0+, D1+} (OUT) – Host interface packet output + \item \textbf{GND} (IN) – Ground line (OUT for MCU) +\end{itemize} + +\section{Host Structure} + +\subsection*{IMBCIHost Structure} + +\begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] +struct IMBCIHost { + UInt32 Magic; + UInt32 HostId; + UInt16 VendorId; + UInt16 DeviceId; + UInt8 MemoryType; + UInt16 HostType; + UInt16 HostFlags; + UInt8 Error; + UInt32 MMIOTest; + UInt16 State; + UInt8 Status; + UInt8 InterruptEnable; + UInt64 BaseAddressRegister; + UInt64 BaseAddressRegisterSize; + UInt32 CommandIssue; + UInt8 Esb[64]; // Extended Signature Block + UInt8 Zero[8]; +}; +\end{lstlisting} + +\section{Enumerations} + +\subsection*{Device Speeds} +\begin{itemize} + \item \texttt{kMBCISpeedDeviceInvalid} + \item \texttt{kMBCILowSpeedDevice} + \item \texttt{kMBCIHighSpeedDevice} +\end{itemize} + +\subsection*{Host Flags} +\begin{itemize} + \item \texttt{kMBCIHostFlagsSupportsNothing} + \item \texttt{kMBCIHostFlagsSupportsAPM} + \item \texttt{kMBCIHostFlagsSupportsDaisyChain} + \item \texttt{kMBCIHostFlagsSupportsHWInterrupts} + \item \texttt{kMBCIHostFlagsSupportsDMA} + \item \texttt{kMBCIHostFlagsExtended} +\end{itemize} + +\subsection*{Host Types} +\begin{itemize} + \item \texttt{kMBCIHostKindHardDisk} + \item \texttt{kMBCIHostKindOpticalDisk} + \item \texttt{kMBCIHostKindKeyboardLow} + \item \texttt{kMBCIHostKindMouseLow} + \item \texttt{kMBCIHostKindMouseHigh} + \item \texttt{kMBCIHostKindKeyboardHigh} + \item \texttt{kMBCIHostKindNetworkInterface} + \item \texttt{kMBCIHostKindDaisyChain} + \item \texttt{kMBCIHostKindStartExtended} +\end{itemize} + +\subsection*{Host State} +\begin{itemize} + \item \texttt{kMBCIHostStateInvalid} + \item \texttt{kMBCIHostStateReset} + \item \texttt{kMBCIHostStateSuccess} + \item \texttt{kMBCIHostStateReady} + \item \texttt{kMBCIHostStateDmaStart} + \item \texttt{kMBCIHostStateDmaEnd} + \item \texttt{kMBCIHostStateFail} +\end{itemize} + +\section{Functions} + +\subsection*{Auth Key Reader} +Reads the 24-bit auth key encoded in the last three bytes of the Extended Signature Block: +\begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] +inline MBCIAuthKeyType mbci_read_auth_key(volatile IMBCIHost* host); +\end{lstlisting} + +\subsection*{MMIO Test} +Tests if MMIO is accessible by writing and reading a challenge value. +\begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] +inline BOOL mbci_test_mmio(volatile IMBCIHost* host); +\end{lstlisting} + +\end{document} -- cgit v1.2.3 From 1eaea2474bb377cc0b9eab6b8cdc9336170988c4 Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 10:11:54 +0200 Subject: feat(docs): Update HeFS specification. Signed-off-by: Amlal --- docs/tex/hefs.tex | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index dd857795..c8bb24f8 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -110,7 +110,7 @@ Red-black tree based directory node. \section{Timestamp Layout (ATime)} -\texttt{ATime} is a 64-bit timestamp with the following structure: +\texttt{ATime} is a 64-bit timestamp, and allocation status tracker with the following structure: \begin{itemize} \item Bits 63-32: Year @@ -134,15 +134,14 @@ Provided by \texttt{Kernel::HeFS::HeFileSystemParser}. \item \texttt{Format(drive, flags, name)} - Format drive with HeFS \item \texttt{CreateINodeDirectory(drive, flags, dir)} \item \texttt{RemoveINodeDirectory(drive, flags, dir)} - \item \texttt{CreateINode(drive, flags, dir, name)} - \item \texttt{DeleteINode(drive, flags, dir, name)} - \item \texttt{WriteINode(drive, block, size, dir, name)} - \item \texttt{ReadINode(drive, block, size, dir, name)} + \item \texttt{CreateINode(drive, flags, dir, name, kind)} + \item \texttt{DeleteINode(drive, flags, dir, name, kind)} + \item \texttt{INodeManip(drive, block, size, dir, kind, name, in)} \end{itemize} Internal helpers: \begin{itemize} - \item \texttt{INodeCtl\_}, \texttt{INodeDirectoryCtl\_} + \item \texttt{INodeCtlManip}, \texttt{INodeDirectoryCtlManip} \end{itemize} \section{Conclusion} -- cgit v1.2.3 From f7492b792e5ef083a856787fde2f581f369fa200 Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 10:19:31 +0200 Subject: feat(modules/MBCI): Finalize MBCI base module. Signed-off-by: Amlal --- dev/kernel/src/DriveMgr.cc | 2 +- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 2 +- dev/modules/MBCI/MBCI.h | 27 ++++++++++++--------------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index 96ff2766..449640f9 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -4,8 +4,8 @@ ------------------------------------------- */ -#include #include +#include #include #include #include diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index d3331710..465cfc32 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -1018,7 +1018,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc if (!nodes) return NO; - SizeT sz_out = 0; + SizeT sz_out = 0; for (SizeT i = 0UL; i < cnt; ++i) { auto& start = nodes[i]; diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index 1038f17c..f2bd7f71 100644 --- a/dev/modules/MBCI/MBCI.h +++ b/dev/modules/MBCI/MBCI.h @@ -96,27 +96,24 @@ enum MBCIHostState { /// @brief An AuthKey is a context used to tokenize data for an MBCI packet. typedef UInt32 MBCIAuthKeyType; +/// @internal +inline BOOL busi_test_mmio(_Input volatile struct IMBCIHost* host, const UInt32 test) { + host->MMIOTest = test; + while (host->MMIOTest == test); + + return host->MMIOTest == 0; +} + /// @brief Read Auth key for MBCI host. /// @param host the mbci host to get the key on. /// @return the 24-bit key. inline MBCIAuthKeyType mbci_read_auth_key(_Input volatile struct IMBCIHost* host) { - constexpr auto const kChallengeMBCI = 0xdeadbeef; - - host->MMIOTest = kChallengeMBCI; - - if (host->MMIOTest == kChallengeMBCI) { - return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) | - (host->Esb[kMBCIESBSz - 3] & 0xFF); - } - - return kChallengeMBCI; -} + auto const kChallengeMBCI = 0x1; // MBCI Challenge test -inline BOOL mbci_test_mmio(_Input volatile struct IMBCIHost* host) { - constexpr auto const kChallengeMBCI = 0xdeadbeef; + if (!busi_test_mmio(host, kChallengeMBCI)) return ~0; - host->MMIOTest = kChallengeMBCI; - return host->MMIOTest == kChallengeMBCI; + return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) | + (host->Esb[kMBCIESBSz - 3] & 0xFF); } } // namespace Kernel -- cgit v1.2.3 From a3ee1df87feddec339c710068e0922a40c6fd494 Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 10:25:43 +0200 Subject: feat(modules/MBCI): add tiemout for memory test. Signed-off-by: Amlal --- dev/modules/MBCI/MBCI.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index f2bd7f71..37c18f79 100644 --- a/dev/modules/MBCI/MBCI.h +++ b/dev/modules/MBCI/MBCI.h @@ -99,7 +99,14 @@ typedef UInt32 MBCIAuthKeyType; /// @internal inline BOOL busi_test_mmio(_Input volatile struct IMBCIHost* host, const UInt32 test) { host->MMIOTest = test; - while (host->MMIOTest == test); + UInt16 timeout = 0UL; + + while (host->MMIOTest == test) { + ++timeout; + + if (timeout > 0x1000) + return NO; + } return host->MMIOTest == 0; } -- cgit v1.2.3 From 8acaf9b721973fdd852abc01fc44ba1152b8f72a Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 11:14:25 +0200 Subject: feat(kernel): HeFS fixes, AHCI improvements, and MBCI tweaks. why? - Some parts were causing issues on the filesystem. - The slot probe code was naive. - Made the current MBCI implementation clearer. Signed-off-by: Amlal --- dev/kernel/HALKit/AMD64/HalDebugOutput.cc | 64 +++++++++++++++++++------ dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 18 +++++-- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 15 ++++-- dev/modules/MBCI/MBCI.h | 6 +-- docs/tex/mbci.tex | 2 +- 5 files changed, 79 insertions(+), 26 deletions(-) diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index 34b99ffe..a9759fc0 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -57,6 +57,54 @@ namespace Detail { TerminalDevice::~TerminalDevice() = default; +EXTERN_C void ke_utf_io_write(IDeviceObject* obj, const Utf8Char* bytes) { + NE_UNUSED(bytes); + NE_UNUSED(obj); + +#ifdef __DEBUG__ + Detail::hal_serial_init(); + + if (!bytes || Detail::kState != kStateReady) return; + + if (*bytes == 0) return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = urt_string_len(bytes); + + static BOOL not_important = YES; + + while (index < len) { + if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); + + HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); + + char tmp_str[2]; + tmp_str[0] = bytes[index]; + tmp_str[1] = 0; + + if (bytes[index] == '*') { + if (not_important) + not_important = NO; + else + not_important = YES; + + ++index; + + continue; + } + + ++index; + } + + Detail::kState = kStateReady; +#endif // __DEBUG__ +} + EXTERN_C void ke_io_write(IDeviceObject* obj, const Char* bytes) { NE_UNUSED(bytes); NE_UNUSED(obj); @@ -74,7 +122,7 @@ EXTERN_C void ke_io_write(IDeviceObject* obj, const Char* bytes) { SizeT len = 0; index = 0; - len = rt_string_len(bytes, 256U); + len = rt_string_len(bytes); static SizeT x = kFontSizeX, y = kFontSizeY; @@ -172,20 +220,8 @@ TerminalDevice TerminalDevice::The() noexcept { Utf8TerminalDevice::~Utf8TerminalDevice() = default; -STATIC Void ke_io_write_utf(IDeviceObject*, const Utf8Char* str) { - auto len = urt_string_len(str); - - for (auto size = 0ul; size < len; ++size) { - Char buf[2]; - buf[0] = str[size]; - buf[1] = 0; - - Kernel::ke_io_write(nullptr, buf); - } -} - Utf8TerminalDevice Utf8TerminalDevice::The() noexcept { - Utf8TerminalDevice out(Kernel::ke_io_write_utf, + Utf8TerminalDevice out(Kernel::ke_utf_io_write, [](IDeviceObject*, const Utf8Char*) -> Void {}); return out; } diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index cf1841bd..4b0270ab 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -154,10 +154,18 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz UIntPtr slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - if (slot == ~0UL) { - kout << "No free command slot!\r"; - err_global_get() = kErrorDisk; - return; + UInt16 timeout = 0; + + while (slot == ~0UL) { + kout << "No free command slot found, AHCI disk is busy!\r"; + + if (timeout > 0x1000) { + err_global_get() = kErrorDisk; + return; + } + + slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); + ++timeout; } volatile HbaCmdHeader* command_header = @@ -173,7 +181,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz rt_set_memory((VoidPtr) command_table, 0, sizeof(HbaCmdTbl)); - VoidPtr ptr = rtl_dma_alloc(size_buffer, 4096); + VoidPtr ptr = rtl_dma_alloc(size_buffer, kib_cast(4)); rtl_dma_flush(ptr, size_buffer); diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 465cfc32..1cd7e61a 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -514,10 +514,14 @@ namespace Detail { if (start > root->fEndIND) break; } - node_arr[start_cnt + 1].fDeleted = 1UL; err_global_get() = kErrorSuccess; delete dir; + if (start_cnt == 0) { + delete[] node_arr; + node_arr = nullptr; + } + return node_arr; } @@ -577,7 +581,7 @@ namespace Detail { node->fOffsetSlices = root->fStartBlock; - auto offset = 0; + auto offset = kHeFSBlockLen; SizeT cnt = 0ULL; @@ -1031,6 +1035,10 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc mnt->fPacket.fPacketSize = kHeFSBlockLen; mnt->fPacket.fPacketContent = block; + if (mnt->fPacket.fPacketLba > root->fEndBlock) { + goto inode_manip_fail; + } + in ? mnt->fInput(mnt->fPacket) : mnt->fOutput(mnt->fPacket); sz_out += kHeFSBlockLen; @@ -1049,6 +1057,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc } } +inode_manip_fail: delete[] nodes; return NO; } @@ -1174,7 +1183,7 @@ Boolean fs_init_hefs(Void) { Utf8Char contents_1[kHeFSBlockLen] = u8"ロケットにはジエットエンジン\r"; MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot", - kHeFSFileKindRegular, u8"ジェット警察.txt", NO)); + kHeFSFileKindRegular, u8"ジェット警察.txt", YES)); return YES; } diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index 37c18f79..37f802ec 100644 --- a/dev/modules/MBCI/MBCI.h +++ b/dev/modules/MBCI/MBCI.h @@ -39,7 +39,7 @@ enum { }; /// @brief MBCI Host header. -struct PACKED IMBCIHost final { +volatile struct PACKED IMBCIHost final { UInt32 Magic; UInt32 HostId; UInt16 VendorId; @@ -97,7 +97,7 @@ enum MBCIHostState { typedef UInt32 MBCIAuthKeyType; /// @internal -inline BOOL busi_test_mmio(_Input volatile struct IMBCIHost* host, const UInt32 test) { +inline BOOL busi_test_mmio(_Input struct IMBCIHost* host, _Input const UInt32 test) { host->MMIOTest = test; UInt16 timeout = 0UL; @@ -114,7 +114,7 @@ inline BOOL busi_test_mmio(_Input volatile struct IMBCIHost* host, const UInt32 /// @brief Read Auth key for MBCI host. /// @param host the mbci host to get the key on. /// @return the 24-bit key. -inline MBCIAuthKeyType mbci_read_auth_key(_Input volatile struct IMBCIHost* host) { +inline MBCIAuthKeyType mbci_read_auth_key(_Input struct IMBCIHost* host) { auto const kChallengeMBCI = 0x1; // MBCI Challenge test if (!busi_test_mmio(host, kChallengeMBCI)) return ~0; diff --git a/docs/tex/mbci.tex b/docs/tex/mbci.tex index a23bc87b..99676803 100644 --- a/docs/tex/mbci.tex +++ b/docs/tex/mbci.tex @@ -33,7 +33,7 @@ The MBCI bus interface includes the following signal lines: \subsection*{IMBCIHost Structure} \begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] -struct IMBCIHost { +volatile struct IMBCIHost { UInt32 Magic; UInt32 HostId; UInt16 VendorId; -- cgit v1.2.3 From 1afe090bd504c4ec74b8c14c5aa6a520114b88ab Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 12:20:04 +0200 Subject: feat(kernel): update TeX specs. Signed-off-by: Amlal --- docs/tex/hefs.tex | 30 +++++++++++++++++++++++------- docs/tex/mbci.tex | 17 ++++++++++------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index c8bb24f8..c8b5a79b 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -22,9 +22,11 @@ The High-throughput Extended File System (HeFS) is a custom filesystem tailored \hline \texttt{kHeFSVersion} & 0x0103 \\ \texttt{kHeFSMagic} & " HeFS" (8-byte magic identifier) \\ +\texttt{kHeFSMagicLen} & 8 \\ +\texttt{kHeFSBlockLen} & 512 bytes \\ \texttt{kHeFSFileNameLen} & 256 characters \\ \texttt{kHeFSPartNameLen} & 128 characters \\ -\texttt{kHeFSMinimumDiskSize} & 16 MiB \\ +\texttt{kHeFSMinimumDiskSize} & 1 GiB \\ \texttt{kHeFSDefaultVolumeName} & "HeFS Volume" \\ \texttt{kHeFSINDStartOffset} & Offset after boot + dir nodes \\ \texttt{kHeFSSearchAllStr} & "\*" (wildcard string) \\ @@ -54,7 +56,16 @@ The High-throughput Extended File System (HeFS) is a custom filesystem tailored \subsection{Encoding Flags (\texttt{UInt16})} \begin{itemize} -\item UTF-8, UTF-16, UTF-32, Binary (with endianness variants) +\item UTF-8 +\item UTF-16 +\item UTF-32 +\item UTF-16BE +\item UTF-16LE +\item UTF-32BE +\item UTF-32LE +\item UTF-8BE +\item UTF-8LE +\item Binary \end{itemize} \subsection{File Kinds (\texttt{UInt16})} @@ -71,7 +82,12 @@ The High-throughput Extended File System (HeFS) is a custom filesystem tailored \subsection{File Flags (\texttt{UInt32})} \begin{itemize} -\item ReadOnly, Hidden, System, Archive, Device +\item 0x000: None +\item 0x100: ReadOnly +\item 0x101: Hidden +\item 0x102: System +\item 0x103: Archive +\item 0x104: Device \end{itemize} \section{Structures} @@ -84,7 +100,7 @@ Acts as the superblock. \item Sector and disk geometry: \texttt{fSectorCount}, \texttt{fSectorSize}, \texttt{fBadSectors} \item Drive info: \texttt{fDiskKind}, \texttt{fEncoding}, \texttt{fDiskStatus}, \texttt{fDiskFlags}, \texttt{fVID} \item Tree layout: \texttt{fStartIND}, \texttt{fEndIND}, \texttt{fINDCount} - \item Reserved: \texttt{fStartIN}, \texttt{fEndIN}, \texttt{fReserved}, \texttt{fReserved1} + \item Reserved: \texttt{fStartIN}, \texttt{fEndIN}, \texttt{fStartBlock}, \texttt{fEndBlock} \end{itemize} \subsection{HEFS\_INDEX\_NODE} @@ -92,7 +108,7 @@ Contains file metadata and block layout. \begin{itemize} \item \texttt{fHashPath}, \texttt{fFlags}, \texttt{fKind}, \texttt{fSize}, \texttt{fChecksum} - \item Symbolic link: \texttt{fSymLink} + \item \texttt{fSymLink} - if set, \texttt{fHashPath} represents the symlink target \item Time: \texttt{fCreated}, \texttt{fAccessed}, \texttt{fModified}, \texttt{fDeleted} \item Ownership: \texttt{fUID}, \texttt{fGID}, \texttt{fMode} \item Block data: \texttt{fOffsetSlices}, \texttt{fSlices[kHeFSSliceCount]} as (base, length) pairs @@ -104,13 +120,13 @@ Red-black tree based directory node. \begin{itemize} \item \texttt{fHashPath}, \texttt{fFlags}, \texttt{fKind}, \texttt{fEntryCount}, \texttt{fChecksum} \item Time and ownership same as inode - \item \texttt{fINSlices[kHeFSSliceCount]} for storing child inodes + \item \texttt{fINSlices[kHeFSSliceCount]} for storing child inode links \item Tree links: \texttt{fColor}, \texttt{fNext}, \texttt{fPrev}, \texttt{fChild}, \texttt{fParent} \end{itemize} \section{Timestamp Layout (ATime)} -\texttt{ATime} is a 64-bit timestamp, and allocation status tracker with the following structure: +\texttt{ATime} is a 64-bit timestamp and allocation status tracker with the following structure: \begin{itemize} \item Bits 63-32: Year diff --git a/docs/tex/mbci.tex b/docs/tex/mbci.tex index 99676803..71907376 100644 --- a/docs/tex/mbci.tex +++ b/docs/tex/mbci.tex @@ -14,7 +14,7 @@ \maketitle \section{Overview} -The Mini Bus Controller Interface (MBCI) is a standardized memory-mapped I/O bus specification designed for use in embedded systems and operating system kernels. It provides an extensible framework for managing hardware devices via a shared bus using memory-mapped registers. +The Mini Bus Controller Interface (MBCI) is a standardized memory-mapped I/O bus specification designed for use in embedded systems and operating system kernels. It provides an extensible framework for managing hardware devices via a shared bus using memory-mapped registers. It is designed to remain abstract and platform-agnostic, leaving platform-specific interrupt and address logic to the HAL. \section{Signal Lines} The MBCI bus interface includes the following signal lines: @@ -95,20 +95,23 @@ volatile struct IMBCIHost { \item \texttt{kMBCIHostStateDmaStart} \item \texttt{kMBCIHostStateDmaEnd} \item \texttt{kMBCIHostStateFail} + \item \texttt{kMBCIHostStateCount} \end{itemize} \section{Functions} -\subsection*{Auth Key Reader} -Reads the 24-bit auth key encoded in the last three bytes of the Extended Signature Block: +\subsection*{MMIO Test} +Tests if MMIO is accessible by writing and checking a challenge value. Times out if the bus does not respond. + \begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] -inline MBCIAuthKeyType mbci_read_auth_key(volatile IMBCIHost* host); +inline BOOL busi_test_mmio(struct IMBCIHost* host, const UInt32 test); \end{lstlisting} -\subsection*{MMIO Test} -Tests if MMIO is accessible by writing and reading a challenge value. +\subsection*{Auth Key Reader} +Reads the 24-bit auth key encoded in the last three bytes of the Extended Signature Block after verifying MMIO test success: + \begin{lstlisting}[language=C++,basicstyle=\ttfamily\footnotesize] -inline BOOL mbci_test_mmio(volatile IMBCIHost* host); +inline MBCIAuthKeyType mbci_read_auth_key(struct IMBCIHost* host); \end{lstlisting} \end{document} -- cgit v1.2.3 From a8782019a20f5487494e436f79b876b57f7229e1 Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 8 May 2025 08:48:57 +0200 Subject: feat(tooling): update HeFS headers, and better HeFS tooling. Signed-off-by: Amlal --- dev/kernel/FSKit/HeFS.h | 8 +-- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 20 ++----- dev/modules/MBCI/MBCI.h | 5 +- tooling/hefs.h | 4 +- tooling/mkfs.hefs.cc | 92 ++++++++++++++++++------------ 5 files changed, 68 insertions(+), 61 deletions(-) diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index f7e1d648..f5f42b47 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -125,10 +125,10 @@ struct PACKED HEFS_BOOT_NODE final { Kernel::UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). Kernel::UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). - Kernel::UInt64 fStartIN; /// @brief Reserved for future use. - Kernel::UInt64 fEndIN; /// @brief Reserved for future use. - Kernel::UInt64 fStartBlock; /// @brief Reserved for future use. - Kernel::UInt64 fEndBlock; /// @brief Reserved for future use. + Kernel::UInt64 fStartIN; /// @brief Start INodes range + Kernel::UInt64 fEndIN; /// @brief End INodes range + Kernel::UInt64 fStartBlock; /// @brief Start Blocks range + Kernel::UInt64 fEndBlock; /// @brief End Blocks range Kernel::Char fPad[272]; }; diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 1cd7e61a..a324da2a 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -459,7 +459,7 @@ namespace Detail { const Utf8Char* dir_name, const Utf8Char* file_name, UInt8 kind, SizeT* cnt) { - if (mnt) { + if (mnt && cnt) { auto start = root->fStartIND; if (start > root->fEndIND) return nullptr; @@ -514,7 +514,7 @@ namespace Detail { if (start > root->fEndIND) break; } - err_global_get() = kErrorSuccess; + err_global_get() = kErrorSuccess; delete dir; if (start_cnt == 0) { @@ -535,7 +535,7 @@ namespace Detail { STATIC ATTRIBUTE(unused) _Output BOOL hefsi_update_in_status(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name, HEFS_INDEX_NODE* node, BOOL delete_or_create) { - if (!root) return NO; + if (!root || !mnt) return NO; auto start = root->fStartIND; @@ -555,8 +555,6 @@ namespace Detail { mnt->fInput(mnt->fPacket); - kout8 << dir_name << u8"\r"; - (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl); (Void)(kout << hex_number(dir->fHashPath) << kendl); @@ -621,12 +619,6 @@ namespace Detail { mnt->fInput(mnt->fPacket); - kout8 << u8"HashPath: "; - (Void)(kout << hex_number(tmp_node.fHashPath) << kendl); - - kout8 << u8"HashPath: "; - (Void)(kout << hex_number(hash_file) << kendl); - if (tmp_node.fHashPath != hash_file) { continue; } @@ -690,7 +682,7 @@ namespace Detail { auto start = root->fStartIND; while (YES) { - if (start == 0 || start > root->fEndIND) break; + if (start == 0UL || start > root->fEndIND) break; mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -714,10 +706,10 @@ namespace Detail { mnt->fOutput(mnt->fPacket); } - if (dir->fColor == kHeFSBlack && dir->fChild != 0) { + if (dir->fColor == kHeFSBlack && dir->fChild != 0UL) { dir->fColor = kHeFSRed; hefsi_rotate_tree(start, mnt); - } else if (dir->fColor == kHeFSBlack && dir->fChild == 0) { + } else if (dir->fColor == kHeFSBlack && dir->fChild == 0UL) { dir->fColor = kHeFSBlack; mnt->fPacket.fPacketLba = start; diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index 37f802ec..99ecf802 100644 --- a/dev/modules/MBCI/MBCI.h +++ b/dev/modules/MBCI/MBCI.h @@ -100,12 +100,11 @@ typedef UInt32 MBCIAuthKeyType; inline BOOL busi_test_mmio(_Input struct IMBCIHost* host, _Input const UInt32 test) { host->MMIOTest = test; UInt16 timeout = 0UL; - + while (host->MMIOTest == test) { ++timeout; - if (timeout > 0x1000) - return NO; + if (timeout > 0x1000) return NO; } return host->MMIOTest == 0; diff --git a/tooling/hefs.h b/tooling/hefs.h index f281e7a3..68e0f906 100644 --- a/tooling/hefs.h +++ b/tooling/hefs.h @@ -102,8 +102,8 @@ struct __attribute__((packed)) BootNode { std::uint16_t vid{}; std::uint64_t startIN{}; std::uint64_t endIN{}; - std::uint64_t reserved3{}; - std::uint64_t reserved4{}; + std::uint64_t startBlock{}; + std::uint64_t endBlock{}; char pad[272]{}; }; } // namespace mkfs::hefs diff --git a/tooling/mkfs.hefs.cc b/tooling/mkfs.hefs.cc index 5a706646..2ddc7484 100644 --- a/tooling/mkfs.hefs.cc +++ b/tooling/mkfs.hefs.cc @@ -16,9 +16,10 @@ static size_t kSectorSize = 512; int main(int argc, char** argv) { if (argc < 2) { - mkfs::console_out() << "hefs: Usage: mkfs.hefs -L