diff options
Diffstat (limited to 'dev')
31 files changed, 557 insertions, 396 deletions
diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 181be973..cc80e359 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -40,7 +40,7 @@ /***********************************************************************************/ namespace Boot { -EXTERN void ThrowError(const WideChar* errorCode, const WideChar* reason) noexcept; +void ThrowError(const WideChar* errorCode, const WideChar* reason) noexcept; class BootTextWriter; class BootFileReader; @@ -51,7 +51,8 @@ typedef Char* PEFImagePtr; typedef Char* PEImagePtr; typedef WideChar CharacterTypeUTF16; -typedef Char CharacterTypeUTF8; +typedef Char CharacterTypeASCII; +typedef char8_t CharacterTypeUTF8; using namespace Kernel; @@ -86,7 +87,7 @@ class BootTextWriter final { Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len); -Kernel::SizeT BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, +Kernel::SizeT BSetMem(CharacterTypeASCII* src, const CharacterTypeASCII byte, const Kernel::SizeT len); /// String length functions. @@ -151,7 +152,7 @@ typedef UInt8* BlobType; /// @brief Bootloader Version String. class BVersionString final { public: - static const CharacterTypeUTF8* The() { return BOOTLOADER_VERSION; } + static const CharacterTypeASCII* The() { return BOOTLOADER_VERSION; } }; /***********************************************************************************/ diff --git a/dev/boot/BootKit/HW/SATA.h b/dev/boot/BootKit/HW/SATA.h index 8cf48ec7..eecf426d 100644 --- a/dev/boot/BootKit/HW/SATA.h +++ b/dev/boot/BootKit/HW/SATA.h @@ -10,6 +10,8 @@ #include <CompilerKit/CompilerKit.h> #include <modules/AHCI/AHCI.h> +#define kAHCISectorSz (4096) + class BootDeviceSATA final { public: explicit BootDeviceSATA() noexcept; @@ -32,13 +34,11 @@ class BootDeviceSATA final { constexpr static auto kSectorSize = kAHCISectorSize; - BootDeviceSATA& Read(Boot::CharacterTypeUTF8* Buf, const Kernel::SizeT SecCount); - BootDeviceSATA& Write(Boot::CharacterTypeUTF8* Buf, const Kernel::SizeT SecCount); + BootDeviceSATA& Read(Boot::CharacterTypeASCII* Buf, const Kernel::SizeT SecCount); + BootDeviceSATA& Write(Boot::CharacterTypeASCII* Buf, const Kernel::SizeT SecCount); SATATrait& Leak(); private: SATATrait mTrait; }; - -#define kAHCISectorSz 4096 diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 8b2aa760..c660df87 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) 8G .PHONY: efi efi: diff --git a/dev/boot/src/BootString.cc b/dev/boot/src/BootString.cc index 8762a151..277f3273 100644 --- a/dev/boot/src/BootString.cc +++ b/dev/boot/src/BootString.cc @@ -62,7 +62,7 @@ Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 by return cnt; } -Kernel::SizeT Boot::BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, +Kernel::SizeT Boot::BSetMem(CharacterTypeASCII* src, const CharacterTypeASCII byte, const Kernel::SizeT len) { if (!src) return 0; diff --git a/dev/boot/src/HEL/AMD64/BootATA+Next.cc b/dev/boot/src/HEL/AMD64/BootATA+Next.cc index 723224c1..547d4f99 100644 --- a/dev/boot/src/HEL/AMD64/BootATA+Next.cc +++ b/dev/boot/src/HEL/AMD64/BootATA+Next.cc @@ -103,7 +103,7 @@ ATAInit_Retry: return true; } -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, +Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, SizeT Size) { Lba /= SectorSz; @@ -136,7 +136,7 @@ Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, } } -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, +Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, SizeT Size) { Lba /= SectorSz; @@ -208,7 +208,7 @@ BootDeviceATA::operator bool() { @param Sz Sector size @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { if (!boot_ata_detected()) { Leak().mErr = true; return *this; @@ -229,7 +229,7 @@ BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { @param Sz Sector size @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { if (!boot_ata_detected()) { Leak().mErr = true; return *this; diff --git a/dev/boot/src/HEL/AMD64/BootATA.cc b/dev/boot/src/HEL/AMD64/BootATA.cc index 0fd46832..e1ccbfc3 100644 --- a/dev/boot/src/HEL/AMD64/BootATA.cc +++ b/dev/boot/src/HEL/AMD64/BootATA.cc @@ -101,7 +101,7 @@ ATAInit_Retry: return NO; } -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, +Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, SizeT Size) { Lba /= SectorSz; @@ -130,7 +130,7 @@ Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, } } -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, +Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, SizeT Size) { Lba /= SectorSz; @@ -196,7 +196,7 @@ BootDeviceATA::operator bool() { @param Sz Sector size @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { if (!boot_ata_detected()) { Leak().mErr = true; return *this; @@ -217,7 +217,7 @@ BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { @param Sz Sector size @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { if (!boot_ata_detected()) { Leak().mErr = true; return *this; diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 260d7c00..dbc12265 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -17,11 +17,6 @@ #include <modules/CoreGfx/CoreGfx.h> #include <modules/CoreGfx/TextGfx.h> -// Makes the compiler shut up. -#ifndef kMachineModel -#define kMachineModel "OS" -#endif // !kMachineModel - /** Graphics related. */ STATIC EfiGraphicsOutputProtocol* kGop = nullptr; @@ -136,14 +131,14 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa Int32 trials = 5 * 10000000; writer.Write("BootZ: Welcome to BootZ.\r"); - writer.Write("BootZ: Allocating sufficent memory, trying 4GB...\r"); + writer.Write("BootZ: Allocating sufficient memory, trying 4GB...\r"); while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) { --trials; if (!trials) { - writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r"); + writer.Write("BootZ: Unable to allocate sufficient memory, trying again with 2GB...\r"); trials = 3 * 10000000; diff --git a/dev/boot/src/HEL/AMD64/BootSATA.cc b/dev/boot/src/HEL/AMD64/BootSATA.cc index 2b1bc78e..b0b0b52f 100644 --- a/dev/boot/src/HEL/AMD64/BootSATA.cc +++ b/dev/boot/src/HEL/AMD64/BootSATA.cc @@ -48,7 +48,7 @@ BootDeviceSATA::BootDeviceSATA() noexcept { @param Sz Sector size @param Buf buffer */ -BootDeviceSATA& BootDeviceSATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceSATA& BootDeviceSATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { NE_UNUSED(Buf); NE_UNUSED(SectorSz); @@ -62,7 +62,7 @@ BootDeviceSATA& BootDeviceSATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { @param Sz Sector size @param Buf buffer */ -BootDeviceSATA& BootDeviceSATA::Write(CharacterTypeUTF8* Buf, SizeT SectorSz) { +BootDeviceSATA& BootDeviceSATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { NE_UNUSED(Buf); NE_UNUSED(SectorSz); diff --git a/dev/boot/src/docs/KERN_VER.md b/dev/boot/src/docs/KERN_VER.md index abe3e823..cabdb1d2 100644 --- a/dev/boot/src/docs/KERN_VER.md +++ b/dev/boot/src/docs/KERN_VER.md @@ -1,4 +1,4 @@ -# /props/kern_ver +# The `/props/kern_ver` NVRAM variable The `/props/kern_ver` variable is used to track NeKernel's current version in a BCD format. diff --git a/dev/generic_kits/BenchKit/Chrono.h b/dev/generic_kits/BenchKit/Chrono.h new file mode 100644 index 00000000..98f3d980 --- /dev/null +++ b/dev/generic_kits/BenchKit/Chrono.h @@ -0,0 +1,16 @@ +/* ------------------------------------------- + +Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#ifndef BENCHKIT_CHRONO_H +#define BENCHKIT_CHRONO_H + +#include <NewKit/Defines.h> + +namespace Kernel { +class ChronoInterface; +} // namespace Kernel + +#endif // BENCHKIT_CHRONO_H diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 27fe2838..bf1bf867 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -21,14 +21,16 @@ #define kHeFSMagic " HeFS"
#define kHeFSMagicLen (8)
+#define kHeFSBlockLen (512U)
#define kHeFSFileNameLen (256U)
#define kHeFSPartNameLen (128U)
-#define kHeFSMinimumDiskSize (mib_cast(16))
+#define kHeFSMinimumDiskSize (gib_cast(8))
-#define kHeFSDefaultVoluneName u8"HeFS Volume"
+#define kHeFSDefaultVolumeName u8"HeFS Volume"
-#define kHeFSINDStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY) + sizeof(HEFS_BOOT_NODE))
+#define kHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE))
+#define kHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY))
#define kHeFSSearchAllStr u8"*"
@@ -98,70 +100,78 @@ namespace Kernel { /// @brief Access time type.
/// @details Used to keep track of the INode, INodeDir allocation status.
typedef UInt64 ATime;
-} // namespace Kernel
/// @brief HeFS Boot node.
/// @details Acts like a superblock, it contains the information about the filesystem.
/// @note The boot node is the first block of the filesystem.
struct PACKED HEFS_BOOT_NODE final {
- Kernel::Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem.
- Kernel::Utf8Char fVolName[kHeFSPartNameLen]; /// @brief Volume name.
- Kernel::UInt32 fVersion; /// @brief Version of the filesystem.
- Kernel::UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem.
- Kernel::UInt64 fSectorCount; /// @brief Number of sectors in the filesystem.
- Kernel::UInt64 fSectorSize; /// @brief Size of the sector.
- Kernel::UInt32 fChecksum; /// @brief Checksum of the boot node.
- Kernel::UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
- /// Drive, etc).
- Kernel::UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
- Kernel::UInt64 fStartIND; /// @brief Start of the INode directory tree.
- Kernel::UInt64 fEndIND; /// @brief End of the INode directory tree.
- Kernel::UInt64 fINDCount; /// @brief Number of leafs in the INode tree.
- Kernel::UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the
- /// real size of the disk.)
- Kernel::UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid).
- 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::Char fPad[272];
+ Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem.
+ Utf8Char fVolName[kHeFSPartNameLen]; /// @brief Volume name.
+ UInt32 fVersion; /// @brief Version of the filesystem.
+ UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem.
+ UInt64 fSectorCount; /// @brief Number of sectors in the filesystem.
+ UInt64 fSectorSize; /// @brief Size of the sector.
+ UInt32 fChecksum; /// @brief Checksum of the boot node.
+ UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
+ /// Drive, etc).
+ UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
+ UInt64 fStartIND; /// @brief Start of the INode directory tree.
+ UInt64 fEndIND; /// @brief End of the INode directory tree.
+ UInt64 fINDCount; /// @brief Number of leafs in the INode tree.
+ UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the
+ /// real size of the disk.)
+ UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid).
+ UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc).
+ UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used).
+ UInt64 fStartIN; /// @brief Start INodes range
+ UInt64 fEndIN; /// @brief End INodes range
+ UInt64 fStartBlock; /// @brief Start Blocks range
+ UInt64 fEndBlock; /// @brief End Blocks range
+ UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA.
+ Char fPad[264];
};
-inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000;
-inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1;
+inline constexpr ATime kHeFSTimeInvalid = 0x0000000000000000;
+inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1;
+
+/// @brief Journal Node structure
+/// @param fHashPath target hash path
+/// @param fStatus target status
+/// @param fCopyElem copy of element
+/// @param fCopyKind kind of element
+struct PACKED HEFS_JOURNAL_NODE {
+ UInt64 fHashPath;
+ UInt64 fStatus;
+ UInt64 fCopyElem;
+ UInt8 fCopyKind;
+ UInt8 fPad[487];
+};
/// @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.
/// @note The index node is used to store the file information of a file.
struct PACKED HEFS_INDEX_NODE final {
- Kernel::UInt64 fHashPath; /// @brief File name.
- Kernel::UInt32 fFlags; /// @brief File flags.
- Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
- /// Symbolic Link, Unknown).
- Kernel::UInt32 fSize; /// @brief File size.
- Kernel::UInt32 fChecksum; /// @brief Checksum.
+ UInt64 fHashPath; /// @brief File name.
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
+ /// Symbolic Link, Unknown).
+ UInt32 fSize; /// @brief File size.
+ UInt32 fChecksum; /// @brief Checksum.
- Kernel::Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to
- /// the file and blocklinkstart and end contains it's inodes.)
+ Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to
+ /// the file and blocklinkstart and end contains it's inodes.)
- Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
- Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
- Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+ ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
/// @brief Extents system by using blocks
/// @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
+ UInt32 fOffsetSliceLow;
+ UInt32 fOffsetSliceHigh;
- Kernel::Char fPad[309];
+ Char fPad[437];
};
enum {
@@ -175,69 +185,69 @@ enum { /// @details This structure is used to store the directory information of a file.
/// @note The directory node is a special type of INode that contains the directory entries.
struct PACKED HEFS_INDEX_NODE_DIRECTORY final {
- Kernel::UInt64 fHashPath; /// @brief Directory path as FNV hash.
+ UInt64 fHashPath; /// @brief Directory path as FNV hash.
- Kernel::UInt32 fFlags; /// @brief File flags.
- Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
- /// Symbolic Link, Unknown).
- Kernel::UInt32 fEntryCount; /// @brief Entry Count of this directory inode.
- Kernel::UInt32 fChecksum; /// @brief Checksum of the file, index node checksum.
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fReserved; /// @note Reserved for future use.
+ UInt32 fEntryCount; /// @brief Entry Count of this directory inode.
+ UInt32 fChecksum; /// @brief Checksum of the file, index node checksum.
- Kernel::ATime fCreated, fAccessed, fModified,
- fDeleted; /// @brief File timestamps and allocation status.
- Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
- Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+ ATime fCreated, fAccessed, fModified,
+ fDeleted; /// @brief File timestamps and allocation status.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
/// @note These slices are organized as:
/// [0] = OFFSET
/// [1] = SIZE
/// @note Thus the += 2 when iterating over them.
- Kernel::UInt64 fINSlices[kHeFSSliceCount]; /// @brief Start of the index node.
+ UInt64 fINSlices[kHeFSSliceCount]; /// @brief Start of the index node.
- Kernel::UInt8 fColor; /// @brief Color of the node. (Red or Black).
- Kernel::Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers.
+ UInt8 fColor; /// @brief Color of the node. (Red or Black).
+ Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers.
- Kernel::Char fPad[285];
+ Char fPad[285];
};
+} // namespace Kernel
namespace Kernel::Detail {
-/// @brief HeFS get year from Kernel::ATime.
-/// @param raw_atime the raw Kernel::ATime value.
+/// @brief HeFS get year from ATime.
+/// @param raw_atime the raw ATime value.
/// @return the year value.
-/// @note The year is stored in the upper 32 bits of the Kernel::ATime value.
-inline UInt32 hefs_year_get(Kernel::ATime raw_atime) noexcept {
+/// @note The year is stored in the upper 32 bits of the ATime value.
+inline UInt32 hefs_year_get(ATime raw_atime) noexcept {
return (raw_atime) >> 32;
}
-/// @brief HeFS get month from Kernel::ATime.
-/// @param raw_atime the raw Kernel::ATime value.
+/// @brief HeFS get month from ATime.
+/// @param raw_atime the raw ATime value.
/// @return the month value.
-/// @note The month is stored in the upper 24 bits of the Kernel::ATime value.
-inline UInt32 hefs_month_get(Kernel::ATime raw_atime) noexcept {
+/// @note The month is stored in the upper 24 bits of the ATime value.
+inline UInt32 hefs_month_get(ATime raw_atime) noexcept {
return (raw_atime) >> 24;
}
-/// @brief HeFS get day from Kernel::ATime.
-/// @param raw_atime the raw Kernel::ATime value.
+/// @brief HeFS get day from ATime.
+/// @param raw_atime the raw ATime value.
/// @return the day value.
-/// @note The day is stored in the upper 16 bits of the Kernel::ATime value.
-inline UInt32 hefs_day_get(Kernel::ATime raw_atime) noexcept {
+/// @note The day is stored in the upper 16 bits of the ATime value.
+inline UInt32 hefs_day_get(ATime raw_atime) noexcept {
return (raw_atime) >> 16;
}
-/// @brief HeFS get hour from Kernel::ATime.
-/// @param raw_atime the raw Kernel::ATime value.
+/// @brief HeFS get hour from ATime.
+/// @param raw_atime the raw ATime value.
/// @return the hour value.
-/// @note The hour is stored in the upper 8 bits of the Kernel::ATime value.
-inline UInt32 hefs_hour_get(Kernel::ATime raw_atime) noexcept {
+/// @note The hour is stored in the upper 8 bits of the ATime value.
+inline UInt32 hefs_hour_get(ATime raw_atime) noexcept {
return (raw_atime) >> 8;
}
-/// @brief HeFS get minute from Kernel::ATime.
-/// @param raw_atime the raw Kernel::ATime value.
+/// @brief HeFS get minute from ATime.
+/// @param raw_atime the raw ATime value.
/// @return the minute value.
-/// @note The minute is stored in the lower 8 bits of the Kernel::ATime value.
-inline UInt32 hefs_minute_get(Kernel::ATime raw_atime) noexcept {
+/// @note The minute is stored in the lower 8 bits of the ATime value.
+inline UInt32 hefs_minute_get(ATime raw_atime) noexcept {
return (raw_atime) & 0xFF;
}
@@ -378,23 +388,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 Utf8Char* name, const UInt8 kind,
+ const BOOL input);
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/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index 34b99ffe..bd8fe734 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -57,7 +57,7 @@ namespace Detail { TerminalDevice::~TerminalDevice() = default; -EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) { +EXTERN_C void ke_utf_io_write(IDeviceObject<const Utf8Char*>* obj, const Utf8Char* bytes) { NE_UNUSED(bytes); NE_UNUSED(obj); @@ -74,11 +74,40 @@ EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) { SizeT len = 0; index = 0; - len = rt_string_len(bytes, 256U); + len = urt_string_len(bytes); + + while (index < len) { + if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); + + HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); + + ++index; + } + + Detail::kState = kStateReady; +#endif // __DEBUG__ +} + +EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) { + NE_UNUSED(bytes); + NE_UNUSED(obj); - static SizeT x = kFontSizeX, y = kFontSizeY; +#ifdef __DEBUG__ + Detail::hal_serial_init<Detail::kPort>(); - static BOOL not_important = YES; + if (!bytes || Detail::kState != kStateReady) return; + + if (*bytes == 0) return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes); + + STATIC SizeT x = kFontSizeX, y = kFontSizeY; while (index < len) { if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); @@ -89,18 +118,7 @@ EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) { tmp_str[0] = bytes[index]; tmp_str[1] = 0; - if (bytes[index] == '*') { - if (not_important) - not_important = NO; - else - not_important = YES; - - ++index; - - continue; - } - - fb_render_string(tmp_str, y, x, not_important ? RGB(0xff, 0xff, 0xff) : RGB(0x00, 0x00, 0xff)); + fb_render_string(tmp_str, y, x, RGB(0xff, 0xff, 0xff)); if (bytes[index] == '\r') { y += kFontSizeY; @@ -172,20 +190,8 @@ TerminalDevice TerminalDevice::The() noexcept { Utf8TerminalDevice::~Utf8TerminalDevice() = default; -STATIC Void ke_io_write_utf(IDeviceObject<const Utf8Char*>*, 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*>*, 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 3f2cf9e8..42242dbe 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -71,6 +71,10 @@ STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept; STATIC Void drv_compute_disk_ahci() noexcept; +STATIC SizeT drv_get_size_ahci(); + +STATIC SizeT drv_get_sector_count_ahci(); + /***********************************************************************************/ /// @brief Identify device and read LBA info, Disk OEM vendor. /***********************************************************************************/ @@ -132,15 +136,14 @@ STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept { template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept { - NE_UNUSED(sector_sz); - - lba /= sector_sz; - - if (lba > kSATASectorCount) { + if (sector_sz == 0) { + kout << "Invalid sector size.\r"; err_global_get() = kErrorDisk; return; } + lba /= sector_sz; + if (!buffer || size_buffer == 0) { kout << "Invalid buffer for AHCI I/O.\r"; err_global_get() = kErrorDisk; @@ -149,10 +152,20 @@ 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; + + constexpr static UInt16 kTimeout = 0x8000; + + while (slot == ~0UL) { + if (timeout > kTimeout) { + kout << "No free command slot found, AHCI disk is busy!\r"; + + err_global_get() = kErrorDisk; + return; + } + + slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); + ++timeout; } volatile HbaCmdHeader* command_header = @@ -165,9 +178,12 @@ 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); + + MUST_PASS(command_table); + 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); @@ -177,7 +193,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz rtl_dma_flush(ptr, size_buffer); - // Build the PRDT + // Build the PRD table. SizeT bytes_remaining = size_buffer; SizeT prdt_index = 0; UIntPtr buffer_phys = (UIntPtr) ptr; @@ -198,11 +214,13 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz ++prdt_index; } + // Mark the last PRD entry, for the FIS to process the table. command_table->Prdt[prdt_index - 1].Ie = YES; if (bytes_remaining > 0) { kout << "Warning: AHCI PRDT overflow, cannot map full buffer.\r"; err_global_get() = kErrorDisk; + rtl_dma_free(size_buffer); return; } @@ -241,7 +259,17 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz // Issue command kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); + timeout = 0UL; + while (YES) { + if (timeout > kTimeout) { + kout << "Disk hangup!\r"; + kSATAHba->Ports[kSATAIndex].Ci = 0; + return; + } + + ++timeout; + if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break; } @@ -270,7 +298,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; } } @@ -279,13 +306,13 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz @brief Gets the number of sectors inside the drive. @return Sector size in bytes. */ -SizeT drv_get_sector_count_ahci() { +STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() { return kSATASectorCount; } /// @brief Get the drive size. /// @return Disk size in bytes. -SizeT drv_get_size_ahci() { +STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() { return drv_std_get_sector_count() * kAHCISectorSize; } diff --git a/dev/kernel/KernelKit/KernelProcessScheduler.h b/dev/kernel/KernelKit/KernelProcessScheduler.h deleted file mode 100644 index 24d40a36..00000000 --- a/dev/kernel/KernelKit/KernelProcessScheduler.h +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once
\ No newline at end of file diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h new file mode 100644 index 00000000..ca10003f --- /dev/null +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/// @file KernelTaskScheduler.h +/// @brief Kernel Task Scheduler header file. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + +#include <ArchKit/ArchKit.h> +#include <KernelKit/CoreProcessScheduler.h> +#include <KernelKit/LockDelegate.h>
\ No newline at end of file diff --git a/dev/kernel/KernelKit/ProcessScheduler.h b/dev/kernel/KernelKit/ProcessScheduler.h index 6da176b3..6bdc8b1c 100644 --- a/dev/kernel/KernelKit/ProcessScheduler.h +++ b/dev/kernel/KernelKit/ProcessScheduler.h @@ -6,5 +6,5 @@ #pragma once -#include <KernelKit/KernelProcessScheduler.h> +#include <KernelKit/KernelTaskScheduler.h> #include <KernelKit/UserProcessScheduler.h>
\ No newline at end of file diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 1e8719ca..b64e5ce1 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -8,7 +8,7 @@ #define INC_PROCESS_SCHEDULER_H /// @file UserProcessScheduler.h -/// @brief User USER_PROCESS scheduler code and definitions. +/// @brief User Process Scheduler header file. /// @author Amlal El Mahrouss (amlal@nekernel.org) #include <ArchKit/ArchKit.h> diff --git a/dev/kernel/NewKit/Utils.h b/dev/kernel/NewKit/Utils.h index 0cf0484a..e3420d84 100644 --- a/dev/kernel/NewKit/Utils.h +++ b/dev/kernel/NewKit/Utils.h @@ -26,7 +26,7 @@ Int rt_to_uppercase(Int c); Int rt_to_lower(Int c); voidPtr rt_string_in_string(const Char* in, const Char* needle); char* rt_string_has_char(Char* str, Char chr); - -Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len); -Size urt_string_len(const Utf8Char* str); +Void urt_set_memory(const voidPtr src, UInt32 dst, Size len); +Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len); +Size urt_string_len(const Utf8Char* str); } // namespace Kernel 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 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++ diff --git a/dev/kernel/kernel_rsrc.rsrc b/dev/kernel/kernel_rsrc.rsrc index 69922999..b7a11036 100644 --- a/dev/kernel/kernel_rsrc.rsrc +++ b/dev/kernel/kernel_rsrc.rsrc @@ -8,7 +8,7 @@ BEGIN BEGIN BLOCK "080904E4" BEGIN - VALUE "CompanyName", "Amlal El Mahrouss." + VALUE "CompanyName", "Amlal El Mahrouss" VALUE "FileDescription", "NeKernel" VALUE "FileVersion", KERNEL_VERSION VALUE "InternalName", "neoskrnl" diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index 8bf1432e..bbf7a477 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -12,7 +12,7 @@ namespace Kernel { /// @brief Unlocks the binary mutex. /***********************************************************************************/ Bool BinaryMutex::Unlock() noexcept { - if (fLockingProcess) { + if (fLockingProcess.Status == ProcessStatusKind::kRunning) { fLockingProcess = USER_PROCESS(); fLockingProcess.Status = ProcessStatusKind::kFrozen; diff --git a/dev/kernel/src/DriveMgr+IO.cc b/dev/kernel/src/DriveMgr+IO.cc index 4c9b20e0..9137c91e 100644 --- a/dev/kernel/src/DriveMgr+IO.cc +++ b/dev/kernel/src/DriveMgr+IO.cc @@ -17,10 +17,10 @@ * *************************************************************/ -/// Useful macros. +/// Useful macros regarding the IFS. -#define rtl_nefs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS) -#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS) +#define fsi_ifs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS) +#define fsi_ifs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS) namespace Kernel { /// @brief Read from newfs disk. @@ -35,19 +35,19 @@ Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex switch (DrvIndex) { case MountpointInterface::kDriveIndexA: { - rtl_nefs_read(A, DrvTrait.fPacket, Mnt); + fsi_ifs_read(A, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexB: { - rtl_nefs_read(B, DrvTrait.fPacket, Mnt); + fsi_ifs_read(B, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexC: { - rtl_nefs_read(C, DrvTrait.fPacket, Mnt); + fsi_ifs_read(C, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexD: { - rtl_nefs_read(D, DrvTrait.fPacket, Mnt); + fsi_ifs_read(D, DrvTrait.fPacket, Mnt); break; } } @@ -67,19 +67,19 @@ Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvInde switch (DrvIndex) { case MountpointInterface::kDriveIndexA: { - rtl_nefs_write(A, DrvTrait.fPacket, Mnt); + fsi_ifs_write(A, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexB: { - rtl_nefs_write(B, DrvTrait.fPacket, Mnt); + fsi_ifs_write(B, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexC: { - rtl_nefs_write(C, DrvTrait.fPacket, Mnt); + fsi_ifs_write(C, DrvTrait.fPacket, Mnt); break; } case MountpointInterface::kDriveIndexD: { - rtl_nefs_write(D, DrvTrait.fPacket, Mnt); + fsi_ifs_write(D, DrvTrait.fPacket, Mnt); break; } } diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index f26890b5..449640f9 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -4,8 +4,8 @@ ------------------------------------------- */ -#include <FirmwareKit/EPM.h> #include <FirmwareKit/GPT.h> +#include <FirmwareKit/VEPM.h> #include <KernelKit/DebugOutput.h> #include <KernelKit/DriveMgr.h> #include <NewKit/Utils.h> diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index b3e1d4d0..e91040b2 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -32,12 +32,12 @@ namespace Detail { /***********************************************************************************/ STATIC ATTRIBUTE(unused) _Output Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind, - Lba& start, const BOOL try_new = NO); + Lba& start); /***********************************************************************************/ /// @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 @@ -47,12 +47,12 @@ namespace Detail { DriveTrait* mnt, const Utf8Char* dir_name, const Utf8Char* file_name, - UInt8 kind, SizeT* cnt); + UInt8 kind); /***********************************************************************************/ /// @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. @@ -107,65 +107,63 @@ namespace Detail { /// @param start The starting point of the traversal. /// @note This function is used to traverse the RB-Tree of the filesystem. /// @internal Internal filesystem use only. - STATIC ATTRIBUTE(unused) Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& ind_start, - Lba& start, const BOOL try_new) { + STATIC ATTRIBUTE(unused) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, + const Lba& ind_start, Lba& start) { if (!mnt || !dir) return; - BOOL check_is_good = NO; + BOOL check_is_good = NO; + HEFS_INDEX_NODE_DIRECTORY* dir_tmp = new HEFS_INDEX_NODE_DIRECTORY(); while (YES) { mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; + mnt->fPacket.fPacketContent = dir_tmp; mnt->fInput(mnt->fPacket); if (!mnt->fPacket.fPacketGood) break; - if (dir->fNext != 0) { + if (dir_tmp->fNext != 0) { if (check_is_good) break; - start = dir->fNext; + start = dir_tmp->fNext; check_is_good = YES; continue; - } else if (dir->fPrev != 0) { + } else if (dir_tmp->fPrev != 0) { if (check_is_good) break; - start = dir->fPrev; + start = dir_tmp->fPrev; check_is_good = YES; continue; } else { - if (dir->fParent != 0) { + if (dir_tmp->fParent != 0) { if (check_is_good) break; - start = dir->fParent; + start = dir_tmp->fParent; check_is_good = YES; continue; - } else if (dir->fPrev != 0) { + } else if (dir_tmp->fPrev != 0) { if (check_is_good) break; - start = dir->fPrev; + start = dir_tmp->fPrev; check_is_good = YES; continue; } else { - if (!try_new) break; - if (start == 0) { start = ind_start; continue; } - start += kHeFSINDStartOffset; + start += sizeof(HEFS_INDEX_NODE_DIRECTORY); break; } } } - if (try_new) start += sizeof(HEFS_INDEX_NODE_DIRECTORY); - if (start == 0) start = ind_start; + delete dir_tmp; - (Void)(kout << "LBA_" << number(start) << kendl); + start += sizeof(HEFS_INDEX_NODE_DIRECTORY); + if (start == 0) start = ind_start; } /***********************************************************************************/ @@ -254,7 +252,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. @@ -307,7 +305,7 @@ namespace Detail { dirent->fModified = 0UL; dirent->fEntryCount = 0UL; - dirent->fKind = kHeFSFileKindDirectory; + dirent->fReserved = 0; dirent->fFlags = flags; dirent->fChecksum = 0; @@ -351,7 +349,7 @@ namespace Detail { break; } - hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first, YES); + hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first); } } @@ -422,6 +420,8 @@ namespace Detail { else --root->fINDCount; + root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)); + mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); mnt->fPacket.fPacketContent = root; @@ -433,8 +433,8 @@ namespace Detail { prev_location = start; - hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start, YES); - if (start > root->fEndIND) break; + hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start); + if (start > root->fEndIND || start == 0) break; } err_global_get() = kErrorDisk; @@ -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 @@ -458,24 +458,16 @@ namespace Detail { DriveTrait* mnt, const Utf8Char* dir_name, const Utf8Char* file_name, - UInt8 kind, SizeT* cnt) { + UInt8 kind) { if (mnt) { - HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt]; + if (root->fStartIND > root->fEndIND) return nullptr; + if (root->fStartIN > root->fEndIN) return nullptr; - if (!node_arr) { - return nullptr; - } + auto start = root->fStartIND; + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); - 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; - if (root->fStartIN > root->fEndIN) return nullptr; - - auto start_cnt = 0UL; + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); while (YES) { mnt->fPacket.fPacketLba = start; @@ -484,50 +476,37 @@ namespace Detail { mnt->fInput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorFileNotFound; + (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl); + (Void)(kout << hex_number(dir->fHashPath) << kendl); - delete[] node_arr; - return nullptr; - } + if (hefsi_hash_64(dir_name) == dir->fHashPath) { + for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) { + 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); + + (Void)(kout << hex_number(hefsi_hash_64(file_name)) << kendl); + (Void)(kout << hex_number(node->fHashPath) << kendl); + + if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) { + return node; } - } else if (dir->fHashPath == 0) { - break; } } - hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES); - if (start > root->fEndIND || start == 0) break; + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); } - err_global_get() = kErrorSuccess; - return node_arr; + delete node; + node = nullptr; + + delete dir; + dir = nullptr; } - kout << "Error: Failed to find index node->\r"; + kout << "Error: Failed to find IN.\r"; err_global_get() = kErrorFileNotFound; @@ -537,7 +516,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; @@ -557,8 +536,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); @@ -567,15 +544,8 @@ 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 +556,28 @@ namespace Detail { auto lba = dir->fINSlices[inode_index]; + node->fOffsetSliceLow = (UInt32) (root->fStartBlock); + node->fOffsetSliceHigh = (UInt32) (root->fStartBlock >> 32); + + node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)); + 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 += kHeFSBlockLen; + + root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)); + + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; + + mnt->fOutput(mnt->fPacket); + mm_delete_heap(dir); return YES; @@ -606,17 +592,17 @@ 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; } + node->fOffsetSliceLow = 0; + node->fOffsetSliceHigh = 0; + root->fStartIN -= sizeof(HEFS_INDEX_NODE); + root->fStartBlock -= kHeFSBlockLen; + + root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)); mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); @@ -649,7 +635,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; } @@ -664,7 +650,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) { @@ -674,7 +660,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); @@ -698,10 +684,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; @@ -721,7 +707,7 @@ namespace Detail { mnt->fOutput(mnt->fPacket); } - hefsi_traverse_tree(dir, mnt, root->fStartIND, start, NO); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); } err_global_get() = kErrorSuccess; @@ -739,16 +725,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 +747,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 +778,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,71 +793,76 @@ _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; + /// @note all HeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048. + const SizeT max_lba = drv_std_get_size() / root->fSectorSize; - const SizeT dir_max = max_lba / 20; // 20% for directory metadata - const SizeT inode_max = max_lba / 20; // 10% for inodes + const SizeT dir_max = max_lba / 20; // 20% for directory inodes + const SizeT inode_max = max_lba / 30; // 30% 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); + root->fStartIN = root->fEndIND; root->fEndIN = root->fStartIN + inode_max; - constexpr SizeT kHeFSPreallocateCount = 0x6UL; + root->fStartBlock = root->fEndIN; + root->fEndBlock = drv_std_get_size(); root->fINDCount = 0; - // let's lie here. - root->fDiskSize = drive->fLbaEnd; + root->fDiskSize = drv_std_get_size(); 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->fVersion = kHeFSVersion; root->fVID = kHeFSInvalidVID; 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 << "Start Block: " << hex_number(root->fStartBlock) << kendl); + (Void)(kout << "End Block: " << hex_number(root->fEndBlock) << 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; } + constexpr const SizeT kHeFSPreallocateCount = 0x6UL; + const Utf8Char* kFileMap[kHeFSPreallocateCount] = {u8"/", u8"/boot", u8"/system", 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 +871,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 +886,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 +916,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 +928,99 @@ _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* drive, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name) { - return this->INodeCtl_(drive, flags, dir, name, YES); +_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::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::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::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz, + const Utf8Char* dir, const Utf8Char* name, + const UInt8 kind, const BOOL is_input) { + 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*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No); + + 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) { + (Void)(kout << "Invalid Boot Node, HeFS partition is invalid." << kendl); + mm_delete_heap((VoidPtr) root); + err_global_get() = kErrorDisk; + return NO; + } + + auto start = Detail::hefsi_fetch_in(root, mnt, dir, name, kind); + + if (start) { + (Void)(kout << hex_number(start->fHashPath) << kendl); + (Void)(kout << hex_number(start->fOffsetSliceLow) << kendl); + + if (start->fOffsetSliceLow) { + mnt->fPacket.fPacketLba = start->fOffsetSliceLow | (UInt64) start->fOffsetSliceHigh << 32; + mnt->fPacket.fPacketSize = block_sz; + mnt->fPacket.fPacketContent = block; + + if (is_input) { + mnt->fInput(mnt->fPacket); + } else { + mnt->fOutput(mnt->fPacket); + } + } + } + + mm_delete_heap((VoidPtr) root); + delete start; + return YES; } /// @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 +1049,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 +1089,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; @@ -1062,16 +1125,38 @@ 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".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"bootinfo.cfg", kHeFSFileKindRegular)); + + Utf8Char contents_1[kHeFSBlockLen] = {0}; + + urt_set_memory(contents_1, 0, kHeFSBlockLen); + + MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot", u8"bootinfo.cfg", + kHeFSFileKindRegular, YES)); + + if (*contents_1 != u'\0') { + (Void)(kout << "/boot/bootinfo.cfg:" << kendl); + (Void)(kout8 << contents_1 << kendl8); + } else { + auto src = + u8"[boot]\r" + u8"path=bootz.efi\r" + u8"name=BootZ\r" + u8"[kernel]\r" + u8"path=krnl.efi\r" + u8"name=NeKernel\r" + u8"[chk]\r" + u8"path=chk.efi\r" + u8"name=SysChk\r"; + + urt_copy_memory((VoidPtr) src, contents_1, urt_string_len(src)); + + MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot", + u8"bootinfo.cfg", kHeFSFileKindRegular, NO)); + } return YES; } diff --git a/dev/kernel/src/KernelProcessScheduler.cc b/dev/kernel/src/KernelTaskScheduler.cc index d0abfce0..1997c175 100644 --- a/dev/kernel/src/KernelProcessScheduler.cc +++ b/dev/kernel/src/KernelTaskScheduler.cc @@ -2,16 +2,16 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - FILE: KernelProcessScheduler.cc - PURPOSE: Privileged/Ring-0 process scheduler. + FILE: KernelTaskScheduler.cc + PURPOSE: Kernel Task scheduler. ------------------------------------------- */ -#include <KernelKit/ProcessScheduler.h> +#include <KernelKit/KernelTaskScheduler.h> /***********************************************************************************/ -/// @file KernelProcessScheduler.cc -/// @brief Privileged/Ring-0 process scheduler. +/// @file KernelTaskScheduler.cc +/// @brief Kernel Task scheduler. /// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index 001f970a..9b7bea43 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -219,7 +219,7 @@ _Output Int32 mm_delete_heap(VoidPtr heap_ptr) { heap_info_ptr->fMagic = 0; heap_info_ptr->fPad = 0; - (Void)(kout << "Address has been successfully freed: " << hex_number((UIntPtr) heap_info_ptr) + (Void)(kout << "Freed heap address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl); PTEWrapper page_wrapper( diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index dbe3882f..2082642c 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -3,7 +3,7 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.cc - PURPOSE: Low level/Ring-3 process scheduler. + PURPOSE: Low-Privilege/Ring-3 process scheduler. ------------------------------------------- */ @@ -14,12 +14,13 @@ /***********************************************************************************/ #include <ArchKit/ArchKit.h> +#include <NewKit/KString.h> + #include <KernelKit/HardwareThreadScheduler.h> #include <KernelKit/IPEFDylibObject.h> #include <KernelKit/KPC.h> #include <KernelKit/MemoryMgr.h> #include <KernelKit/ProcessScheduler.h> -#include <NewKit/KString.h> ///! BUGS: 0 diff --git a/dev/kernel/src/UtfUtils.cc b/dev/kernel/src/UtfUtils.cc index 079efb7b..11d7471a 100644 --- a/dev/kernel/src/UtfUtils.cc +++ b/dev/kernel/src/UtfUtils.cc @@ -10,11 +10,21 @@ namespace Kernel { Size urt_string_len(const Utf8Char* str) { SizeT len{0}; - while (str[len] != u'\0') ++len; + while (str[len] != u8'\0') ++len; return len; } +Void urt_set_memory(const voidPtr src, UInt32 dst, Size len) { + Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src); + Size index = 0; + + while (index < len) { + srcChr[index] = dst; + ++index; + } +} + Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len) { Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src); Utf8Char* dstChar = reinterpret_cast<Utf8Char*>(dst); diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index 1038f17c..99ecf802 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; @@ -96,27 +96,30 @@ enum MBCIHostState { /// @brief An AuthKey is a context used to tokenize data for an MBCI packet. typedef UInt32 MBCIAuthKeyType; -/// @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; +/// @internal +inline BOOL busi_test_mmio(_Input struct IMBCIHost* host, _Input const UInt32 test) { + host->MMIOTest = test; + UInt16 timeout = 0UL; - host->MMIOTest = kChallengeMBCI; + while (host->MMIOTest == test) { + ++timeout; - if (host->MMIOTest == kChallengeMBCI) { - return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) | - (host->Esb[kMBCIESBSz - 3] & 0xFF); + if (timeout > 0x1000) return NO; } - return kChallengeMBCI; + return host->MMIOTest == 0; } -inline BOOL mbci_test_mmio(_Input volatile struct IMBCIHost* host) { - constexpr auto const kChallengeMBCI = 0xdeadbeef; +/// @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 struct IMBCIHost* host) { + auto const kChallengeMBCI = 0x1; // MBCI Challenge test + + 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 |
