summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-04-29 16:59:14 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-04-29 16:59:14 +0200
commita21859d722597e4eb1216a4a48d08d8f2659b514 (patch)
tree84b30c251e1b444873f4723ecab047689526e9f0
parent461fe537aa1f9533bfa5c2504cb84843b9eac501 (diff)
MHR-18: Fixes and improvements regarding NewFS.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
-rw-r--r--Private/KernelKit/PEF.hpp3
-rw-r--r--Private/NewBoot/BootKit/BootKit.hxx8
-rw-r--r--Private/NewBoot/Source/makefile2
-rw-r--r--Private/Source/AppMain.cxx55
-rw-r--r--Private/Source/FS/NewFS.cxx293
5 files changed, 141 insertions, 220 deletions
diff --git a/Private/KernelKit/PEF.hpp b/Private/KernelKit/PEF.hpp
index 9fabb189..fe7430ab 100644
--- a/Private/KernelKit/PEF.hpp
+++ b/Private/KernelKit/PEF.hpp
@@ -103,4 +103,7 @@ enum {
#define kPefStart "__ImageStart"
+#define kPefForkKind "PEF!"
+#define kPefForkKindFAT "FEP!"
+
#endif /* ifndef __PEF__ */
diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx
index 47a8c9a2..ca6f56ac 100644
--- a/Private/NewBoot/BootKit/BootKit.hxx
+++ b/Private/NewBoot/BootKit/BootKit.hxx
@@ -246,7 +246,7 @@ private:
/// @param fileBlobs the blobs.
/// @param blobCount the number of blobs to write.
/// @param partBlock the NewFS partition block.
- Boolean FormatCatalog(BFileDescriptor* fileBlobs, SizeT blobCount,
+ Boolean WriteRootCatalog(BFileDescriptor* fileBlobs, SizeT blobCount,
NewPartitionBlock& partBlock) {
if (partBlock.SectorSize != BootDev::kSectorSize) return false;
@@ -381,13 +381,15 @@ inline Boolean BDiskFormatFactory<BootDev>::Format(const char* partName,
partBlock->CatalogCount = blobCount;
partBlock->Kind = kNewFSHardDrive;
partBlock->SectorSize = sectorSz;
- partBlock->FreeCatalog = fDiskDev.GetSectorsCount();
+ partBlock->FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NewCatalog);
partBlock->SectorCount = fDiskDev.GetSectorsCount();
partBlock->FreeSectors = fDiskDev.GetSectorsCount();
partBlock->StartCatalog = kNewFSCatalogStartAddress;
partBlock->DiskSize = fDiskDev.GetDiskSize();
+ partBlock->Flags |= kNewFSPartitionTypeBoot;
- if (this->FormatCatalog(fileBlobs, blobCount, *partBlock)) {
+ /// if we can write a root catalog, then write the partition block.
+ if (this->WriteRootCatalog(fileBlobs, blobCount, *partBlock)) {
fDiskDev.Leak().mBase = kNewFSAddressAsLba;
fDiskDev.Leak().mSize = sectorSz;
diff --git a/Private/NewBoot/Source/makefile b/Private/NewBoot/Source/makefile
index 9f70d903..9018623f 100644
--- a/Private/NewBoot/Source/makefile
+++ b/Private/NewBoot/Source/makefile
@@ -75,7 +75,7 @@ run-efi-amd64:
.PHONY: epm-img
epm-img:
- qemu-img create -f raw $(IMG) 512M
+ qemu-img create -f raw $(IMG) 1G
qemu-img create -f raw $(IMG_2) 512M
.PHONY: download-edk
diff --git a/Private/Source/AppMain.cxx b/Private/Source/AppMain.cxx
index 404889d7..6a23e20d 100644
--- a/Private/Source/AppMain.cxx
+++ b/Private/Source/AppMain.cxx
@@ -10,10 +10,12 @@
#include <KernelKit/FileManager.hpp>
#include <KernelKit/Framebuffer.hpp>
#include <KernelKit/KernelHeap.hpp>
+#include <KernelKit/PEF.hpp>
#include <KernelKit/PEFCodeManager.hxx>
#include <KernelKit/ProcessScheduler.hpp>
#include <KernelKit/UserHeap.hpp>
#include <NewKit/Json.hpp>
+#include <NewKit/Utils.hpp>
/// @file Main microkernel entrypoint.
@@ -24,25 +26,52 @@ EXTERN_C NewOS::Void AppMain(NewOS::Void) {
NewOS::FilesystemManagerInterface::Mount(newFS);
if (newFS->GetImpl()) {
- NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/");
+ NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/");
- if (mountCatalog) {
- delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0, kNewFSCatalogKindDir);
- NewCatalog* newKernelCatalog = newFS->GetImpl()->CreateCatalog("/Boot/System/NewKernel");
+ if (mountCatalog) {
+ delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0,
+ kNewFSCatalogKindDir);
+ NewCatalog* newKernelCatalog =
+ newFS->GetImpl()->CreateCatalog("/Boot/System/ExampleTextFile");
- if (newKernelCatalog)
- NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name << NewOS::endl;
+ if (newKernelCatalog)
+ NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name
+ << NewOS::endl;
- NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name << NewOS::endl;
+ NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name
+ << NewOS::endl;
- delete newKernelCatalog;
- delete mountCatalog;
- } else {
- delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir);
- }
+ constexpr auto cDataSz = 512;
+ NewOS::Char theData[cDataSz] = {
+ "THIS FORK\rCONTAINS DATA\rAS\rYOU\rCAN\rSEE...THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS "
+ "DATA\rAS\rYOU\rCAN\rSEE.."};
+
+ NewFork theFork{0};
+ NewOS::rt_copy_memory((NewOS::VoidPtr) "EditableText",
+ (NewOS::VoidPtr)theFork.Name,
+ NewOS::rt_string_len("EditableText"));
+
+ theFork.Kind = NewOS::kNewFSDataForkKind;
+ theFork.DataSize = cDataSz;
+
+ newFS->GetImpl()->CreateFork(newKernelCatalog, theFork);
+ newFS->GetImpl()->WriteCatalog(newKernelCatalog, theData, cDataSz);
+
+ delete newKernelCatalog;
+ delete mountCatalog;
+ } else {
+ delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir);
+ }
}
- while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0);
+ while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0)
+ ;
delete newFS;
}
diff --git a/Private/Source/FS/NewFS.cxx b/Private/Source/FS/NewFS.cxx
index a91d440e..57f61cd2 100644
--- a/Private/Source/FS/NewFS.cxx
+++ b/Private/Source/FS/NewFS.cxx
@@ -16,12 +16,6 @@
using namespace NewOS;
-/// forward decl.
-
-STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog,
- Boolean isDataFork);
-STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv);
-
STATIC MountpointInterface sMountpointInterface;
/// @brief Creates a new fork inside the New filesystem partition.
@@ -31,68 +25,39 @@ STATIC MountpointInterface sMountpointInterface;
_Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog,
_Input NewFork& theFork) {
if (catalog && theFork.Name[0] != 0 && theFork.DataSize > 0) {
- Lba whereFork = 0;
-
- theFork.DataOffset =
- ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog,
- theFork.Kind == kNewFSDataForkKind);
- theFork.Flags |= kNewFSFlagCreated;
- Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork
- : catalog->ResourceFork;
-
- if (lba <= kNewFSAddressAsLba) {
- lba = whereFork;
- } else {
- if (lba <= kNewFSAddressAsLba) {
- theFork.PreviousSibling = lba;
- }
- }
+ theFork.Flags = kNewFSFlagCreated;
+ Lba lba = (theFork.Kind == kNewFSDataForkKind) ? catalog->DataFork
+ : catalog->ResourceFork;
- if (theFork.Kind == kNewFSDataForkKind) {
- if (catalog->DataFork == 0) {
- catalog->DataFork = whereFork;
- } else {
- theFork.PreviousSibling = catalog->DataFork;
- }
- } else {
- if (catalog->ResourceFork == 0) {
- catalog->ResourceFork = whereFork;
- } else {
- theFork.PreviousSibling = catalog->ResourceFork;
- }
- }
+ if (lba <= kNewFSCatalogStartAddress) return nullptr;
+
+ theFork.DataOffset = lba + sizeof(NewFork);
if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr;
auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex);
- drv->fPacket.fLba = whereFork;
- drv->fPacket.fPacketSize = theFork.DataSize;
- drv->fPacket.fPacketContent = (VoidPtr)&theFork;
+ Char cpyFork[sizeof(NewFork)] = {0};
- rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, 16);
+ drv->fPacket.fLba = lba + sizeof(NewCatalog);
+ drv->fPacket.fPacketSize = sizeof(NewFork);
+ drv->fPacket.fPacketContent = (VoidPtr)cpyFork;
- if (auto res =
- fs_newfs_write(&sMountpointInterface, *drv, this->fDriveIndex);
- res) {
- switch (res) {
- case 1:
- DbgLastError() = kErrorDiskReadOnly;
- break;
- case 2:
- DbgLastError() = kErrorDiskIsFull;
- break;
- DbgLastError() = kErrorNoSuchDisk;
- break;
+ drv->fInput(&drv->fPacket);
- default:
- break;
- }
- return nullptr;
- }
+ NewFork* cpyForkStruct = (NewFork*)cpyFork;
- /// Also update catalog.
- this->WriteCatalog(catalog, nullptr, 0);
+ if (cpyForkStruct->Flags == kNewFSFlagCreated) return nullptr;
+
+ /// special treatment.
+ rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime,
+ rt_string_len("fs/newfs-packet"));
+
+ drv->fPacket.fLba = lba;
+ drv->fPacket.fPacketSize = sizeof(NewFork);
+ drv->fPacket.fPacketContent = (VoidPtr)&theFork;
+
+ drv->fOutput(&drv->fPacket);
return &theFork;
}
@@ -171,7 +136,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator())
return nullptr;
- /// as well as this, we don't want that.
+ /// as well as this, we don't want that.
if (kind != kNewFSCatalogKindDir &&
name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator())
return nullptr;
@@ -193,8 +158,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
return nullptr;
}
- for (SizeT indexFill = 0; indexFill < rt_string_len(name);
- ++indexFill) {
+ for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) {
copyName[indexFill] = name[indexFill];
}
@@ -207,14 +171,14 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
copyName[--indexReverseCopy] = 0;
while (copyName[indexReverseCopy] != '/') {
- copyName[indexReverseCopy] = 0;
- --indexReverseCopy;
+ copyName[indexReverseCopy] = 0;
+ --indexReverseCopy;
}
NewCatalog* catalog = this->FindCatalog(copyName, outLba);
if (!catalog) {
- return nullptr;
+ return nullptr;
}
if (catalog->Kind == kNewFSCatalogKindFile) {
@@ -222,13 +186,10 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
return nullptr;
}
- constexpr SizeT cDefaultForkSize = 8096;
+ constexpr SizeT cDefaultForkSize = 8192;
NewCatalog* catalogChild = new NewCatalog();
- catalogChild->DataFork = 0UL;
- catalogChild->ResourceFork = 0UL;
-
catalogChild->ResourceForkOverallSize = cDefaultForkSize;
catalogChild->DataForkSize = cDefaultForkSize;
@@ -259,21 +220,24 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
NewCatalog* nextSibling = (NewCatalog*)sectorBuf;
if (startFree <= kNewFSAddressAsLba) {
- delete catalogChild;
- delete catalog;
+ delete catalogChild;
+ delete catalog;
- return nullptr;
+ return nullptr;
}
/// allocation or reallocation or catalog...
- if (StringBuilder::Equals(nextSibling->Name, name) ||
- (nextSibling->Name[0] == 0 &&
+ if ((nextSibling->Name[0] == 0 &&
nextSibling->Flags != kNewFSFlagCreated)) {
+ catalogChild->DataFork = startFree + sizeof(NewCatalog);
+ catalogChild->ResourceFork =
+ startFree + sizeof(NewCatalog) + catalogChild->DataForkSize;
+
if ((nextSibling->Flags != kNewFSFlagCreated)) {
nextSibling->Flags = kNewFSFlagCreated;
drive->fPacket.fPacketContent = catalogChild;
- drive->fPacket.fPacketSize = kNewFSMinimumSectorSz;
+ drive->fPacket.fPacketSize = sizeof(NewCatalog);
drive->fPacket.fLba = startFree;
if (catalogChild->Kind == kNewFSCatalogKindFile) {
@@ -290,7 +254,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name,
drive->fOutput(&drive->fPacket);
- kcout << "New OS: Create new catalog with success!\r\n";
+ kcout << "New OS: Create new catalog successfully!\r\n";
Char sectBuf[sizeof(NewCatalog)] = {0};
@@ -379,11 +343,13 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) {
partBlock->Version = kNewFSVersionInteger;
+ const auto cUntitledHD = "New OS HD\0";
+
rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident,
kNewFSIdentLen);
- rt_copy_memory((VoidPtr) "Untitled HD\0",
- (VoidPtr)partBlock->PartitionName,
- rt_string_len("Untitled HD\0"));
+
+ rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)partBlock->PartitionName,
+ rt_string_len(cUntitledHD));
SizeT catalogCount = 0;
SizeT sectorCount = drv_std_get_sector_count();
@@ -391,8 +357,8 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) {
partBlock->Kind = kNewFSPartitionTypeStandard;
partBlock->StartCatalog = kNewFSCatalogStartAddress;
- ;
- partBlock->CatalogCount = catalogCount;
+ partBlock->Flags |= kNewFSPartitionTypeStandard;
+ partBlock->CatalogCount = sectorCount / sizeof(NewCatalog);
partBlock->SectorCount = sectorCount;
partBlock->DiskSize = diskSize;
partBlock->FreeCatalog = partBlock->StartCatalog;
@@ -406,7 +372,7 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) {
return true;
}
- kcout << "New OS: Partition already exists.\r\n";
+ kcout << "New OS: PartitionBlock already exists.\r\n";
/// return success as well, do not ignore that partition.
return true;
@@ -418,9 +384,51 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) {
/// @brief Writes the data fork into a specific catalog.
/// @param catalog the catalog itself
/// @param data the data.
-/// @return
+/// @return if the catalog w rote the contents successfully.
bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data,
SizeT sizeOfData) {
+ if (sizeOfData > catalog->DataForkSize) return false;
+ if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return false;
+
+ NewFork* forkData = new NewFork();
+
+ auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex);
+
+ auto startFork = catalog->DataFork;
+
+ /// sanity check of the fork position as the condition to run the loop.
+ if (startFork >= kNewFSCatalogStartAddress) {
+ drive->fPacket.fPacketContent = forkData;
+ drive->fPacket.fPacketSize = sizeof(NewFork);
+ drive->fPacket.fLba = startFork;
+
+ drive->fInput(&drive->fPacket);
+
+ /// check if fork even exists.
+ if (forkData->Flags != kNewFSFlagCreated) {
+ DbgLastError() = kErrorDiskIsCorrupted;
+
+ delete forkData;
+ return false;
+ }
+
+ /// sanity check the fork.
+ if (forkData->DataOffset <= kNewFSCatalogStartAddress) {
+ DbgLastError() = kErrorDiskIsCorrupted;
+
+ delete forkData;
+ return false;
+ }
+
+ drive->fPacket.fPacketContent = data;
+ drive->fPacket.fPacketSize = sizeOfData;
+ drive->fPacket.fLba = forkData->DataOffset;
+
+ drive->fOutput(&drive->fPacket);
+
+ return true;
+ }
+
return false;
}
@@ -568,127 +576,6 @@ SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) {
return 0;
}
-/// @brief Find a free fork inside the filesystem.
-/// @param sz the size of the fork to set.
-/// @return the valid lba.
-STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog,
- Boolean isDataFork) {
- if (sMountpointInterface.GetAddressOf(drv)) {
- auto drive = *sMountpointInterface.GetAddressOf(drv);
-
- /// prepare packet.
- bool done = false;
- bool error = false;
-
- Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork;
-
- while (!done) {
- UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0};
-
- drive.fPacket.fPacketContent = sectorBuf;
- drive.fPacket.fPacketSize = kNewFSMinimumSectorSz;
- drive.fPacket.fLba = lba;
-
- drive.fInput(&drive.fPacket);
-
- if (!drive.fPacket.fPacketGood) {
- ///! not a lot of choices, disk has become unreliable.
- if (ke_calculate_crc32((Char*)sectorBuf, kNewFSMinimumSectorSz) !=
- drive.fPacket.fPacketCRC32) {
- DbgLastError() = kErrorDiskIsCorrupted;
- }
-
- error = true;
- break;
- }
-
- NewFork* fork = (NewFork*)sectorBuf;
-
- if (fork->DataSize == 0 && fork->Name[0] == 0 &&
- (fork->Flags == kNewFSFlagDeleted ||
- fork->Flags == kNewFSFlagUnallocated)) {
- fork->DataSize = sz;
- fork->Flags = kNewFSFlagCreated;
-
- drive.fOutput(&drive.fPacket);
-
- /// here it's either a read-only filesystem or something bad happened.'
- if (!drive.fPacket.fPacketGood) {
- DbgLastError() = kErrorDiskReadOnly;
-
- return 0;
- }
-
- return lba;
- }
-
- lba += sizeof(NewFork);
- }
-
- if (error) {
- DbgLastError() = kErrorDisk;
- return 0;
- }
- }
-
- return 0;
-}
-
-/// @brief find a free catalog.
-/// @param kind the catalog kind.
-/// @return the valid lba.
-STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) {
- if (sMountpointInterface.GetAddressOf(drv)) {
- auto drive = *sMountpointInterface.GetAddressOf(drv);
- UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0};
-
- /// prepare packet.
-
- drive.fPacket.fPacketContent = sectorBuf;
- drive.fPacket.fPacketSize = kNewFSMinimumSectorSz;
- drive.fPacket.fLba = kNewFSAddressAsLba;
-
- drive.fInput(&drive.fPacket);
-
- NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBuf;
-
- /// check for a valid partition.
- if (partBlock->PartitionName[0] != 0 &&
- rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen) == 0) {
- auto startLba = partBlock->FreeCatalog;
-
- if (startLba == 0) {
- DbgLastError() = kErrorDiskIsFull;
- return 1;
- } else {
- while (startLba != 0) {
- drive.fPacket.fPacketContent = sectorBuf;
- drive.fPacket.fPacketSize = kNewFSMinimumSectorSz;
- drive.fPacket.fLba = startLba;
-
- drive.fInput(&drive.fPacket);
-
- NewCatalog* catalog = (NewCatalog*)sectorBuf;
-
- if (catalog->Flags == kNewFSFlagUnallocated ||
- catalog->Flags == kNewFSFlagDeleted) {
- catalog->Flags = kNewFSFlagCreated;
- catalog->Kind |= kind;
-
- return startLba;
- }
-
- startLba = catalog->NextSibling;
- }
-
- return 0;
- }
- }
- }
-
- return 0;
-}
-
namespace NewOS::Detail {
Boolean fs_init_newfs(Void) noexcept {
sMountpointInterface.A() = construct_main_drive();