mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-06-02 17:58:00 +00:00
Implemented partition detection
This commit is contained in:
parent
2650202bc5
commit
ca33e7b85b
155
Core/Disk.cpp
Normal file
155
Core/Disk.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include <disk.hpp>
|
||||||
|
|
||||||
|
#include <memory.hpp>
|
||||||
|
#include <printf.h>
|
||||||
|
|
||||||
|
#include "../kernel.h"
|
||||||
|
#include "../DAPI.hpp"
|
||||||
|
#include "../Fex.hpp"
|
||||||
|
|
||||||
|
namespace Disk
|
||||||
|
{
|
||||||
|
void Manager::FetchDisks(unsigned long DriverUID)
|
||||||
|
{
|
||||||
|
KernelCallback *callback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback)));
|
||||||
|
memset(callback, 0, sizeof(KernelCallback));
|
||||||
|
callback->Reason = FetchReason;
|
||||||
|
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||||
|
this->AvailablePorts = callback->DiskCallback.Fetch.Ports;
|
||||||
|
this->BytesPerSector = callback->DiskCallback.Fetch.BytesPerSector;
|
||||||
|
|
||||||
|
if (this->AvailablePorts <= 0)
|
||||||
|
{
|
||||||
|
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector));
|
||||||
|
|
||||||
|
for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++)
|
||||||
|
{
|
||||||
|
Drive *drive = new Drive;
|
||||||
|
sprintf_(drive->Name, "sd%ld-%d", DriverUID, this->AvailablePorts);
|
||||||
|
// TODO: Implement disk type detection. Very useful in the future.
|
||||||
|
drive->MechanicalDisk = true;
|
||||||
|
|
||||||
|
memset(RWBuffer, 0, this->BytesPerSector);
|
||||||
|
memset(callback, 0, sizeof(KernelCallback));
|
||||||
|
callback->Reason = ReceiveReason;
|
||||||
|
callback->DiskCallback.RW = {
|
||||||
|
.Sector = 0,
|
||||||
|
.SectorCount = 2,
|
||||||
|
.Port = ItrPort,
|
||||||
|
.Buffer = RWBuffer,
|
||||||
|
.Write = false,
|
||||||
|
};
|
||||||
|
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||||
|
memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable));
|
||||||
|
|
||||||
|
/*
|
||||||
|
----> Add to devfs the disk
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (drive->Table.GPT.Signature == GPT_MAGIC)
|
||||||
|
{
|
||||||
|
drive->Style = GPT;
|
||||||
|
uint32_t Entries = 512 / drive->Table.GPT.EntrySize;
|
||||||
|
uint32_t Sectors = drive->Table.GPT.PartCount / Entries;
|
||||||
|
for (uint32_t Block = 0; Block < Sectors; Block++)
|
||||||
|
{
|
||||||
|
memset(RWBuffer, 0, this->BytesPerSector);
|
||||||
|
memset(callback, 0, sizeof(KernelCallback));
|
||||||
|
callback->Reason = ReceiveReason;
|
||||||
|
callback->DiskCallback.RW = {
|
||||||
|
.Sector = 2 + Block,
|
||||||
|
.SectorCount = 1,
|
||||||
|
.Port = ItrPort,
|
||||||
|
.Buffer = RWBuffer,
|
||||||
|
.Write = false,
|
||||||
|
};
|
||||||
|
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||||
|
|
||||||
|
for (uint32_t e = 0; e < Entries; e++)
|
||||||
|
{
|
||||||
|
GUIDPartitionTablePartition GPTPartition = reinterpret_cast<GUIDPartitionTablePartition *>(RWBuffer)[e];
|
||||||
|
if (GPTPartition.TypeLow || GPTPartition.TypeHigh)
|
||||||
|
{
|
||||||
|
Partition *partition = new Partition;
|
||||||
|
memcpy(partition->Label, GPTPartition.Label, sizeof(partition->Label));
|
||||||
|
partition->StartLBA = GPTPartition.StartLBA;
|
||||||
|
partition->EndLBA = GPTPartition.EndLBA;
|
||||||
|
partition->Sectors = partition->EndLBA - partition->StartLBA;
|
||||||
|
partition->Port = ItrPort;
|
||||||
|
partition->Flags = Present;
|
||||||
|
partition->Style = GPT;
|
||||||
|
if (GPTPartition.Attributes & 1)
|
||||||
|
partition->Flags |= EFISystemPartition;
|
||||||
|
partition->Index = drive->Partitions.size();
|
||||||
|
// why there is NUL (\0) between every char?????
|
||||||
|
char PartName[72];
|
||||||
|
memcpy(PartName, GPTPartition.Label, 72);
|
||||||
|
for (char i = 0; i < 72; i++)
|
||||||
|
if (PartName[i] == '\0')
|
||||||
|
PartName[i] = ' ';
|
||||||
|
PartName[71] = '\0';
|
||||||
|
trace("GPT partition \"%s\" found with %lld sectors", PartName, partition->Sectors);
|
||||||
|
drive->Partitions.push_back(partition);
|
||||||
|
|
||||||
|
char *PartitionName = new char[64];
|
||||||
|
sprintf_(PartitionName, "sd%ldp%ld", drives.size() - 1, partition->Index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
----> Add to devfs the disk
|
||||||
|
*/
|
||||||
|
|
||||||
|
delete[] PartitionName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trace("%d GPT partitions found.", drive->Partitions.size());
|
||||||
|
}
|
||||||
|
else if (drive->Table.MBR.Signature[0] == MBR_MAGIC0 && drive->Table.MBR.Signature[1] == MBR_MAGIC1)
|
||||||
|
{
|
||||||
|
drive->Style = MBR;
|
||||||
|
for (size_t p = 0; p < 4; p++)
|
||||||
|
if (drive->Table.MBR.Partitions[p].LBAFirst != 0)
|
||||||
|
{
|
||||||
|
Partition *partition = new Partition;
|
||||||
|
partition->StartLBA = drive->Table.MBR.Partitions[p].LBAFirst;
|
||||||
|
partition->EndLBA = drive->Table.MBR.Partitions[p].LBAFirst + drive->Table.MBR.Partitions[p].Sectors;
|
||||||
|
partition->Sectors = drive->Table.MBR.Partitions[p].Sectors;
|
||||||
|
partition->Port = ItrPort;
|
||||||
|
partition->Flags = Present;
|
||||||
|
partition->Style = MBR;
|
||||||
|
partition->Index = drive->Partitions.size();
|
||||||
|
trace("Partition \"%#llx\" found with %lld sectors.", drive->Table.MBR.UniqueID, partition->Sectors);
|
||||||
|
drive->Partitions.push_back(partition);
|
||||||
|
|
||||||
|
char *PartitionName = new char[64];
|
||||||
|
sprintf_(PartitionName, "sd%ldp%ld", drives.size() - 1, partition->Index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
----> Add to devfs the disk
|
||||||
|
*/
|
||||||
|
|
||||||
|
delete[] PartitionName;
|
||||||
|
}
|
||||||
|
trace("%d MBR partitions found.", drive->Partitions.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warn("No partition table found on port %d!", ItrPort);
|
||||||
|
|
||||||
|
drives.push_back(drive);
|
||||||
|
}
|
||||||
|
|
||||||
|
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::Manager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::~Manager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
27
KThread.cpp
27
KThread.cpp
@ -6,13 +6,19 @@
|
|||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <cwalk.h>
|
#include <cwalk.h>
|
||||||
|
|
||||||
|
#include "DAPI.hpp"
|
||||||
|
#include "Fex.hpp"
|
||||||
|
|
||||||
Driver::Driver *DriverManager = nullptr;
|
Driver::Driver *DriverManager = nullptr;
|
||||||
|
Disk::Manager *DiskManager = nullptr;
|
||||||
|
|
||||||
void StartFilesystem()
|
void StartFilesystem()
|
||||||
{
|
{
|
||||||
KPrint("Initializing Filesystem...");
|
KPrint("Initializing Filesystem...");
|
||||||
vfs = new FileSystem::Virtual;
|
vfs = new FileSystem::Virtual;
|
||||||
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
||||||
|
KPrint("Initializing Disk Manager...");
|
||||||
|
DiskManager = new Disk::Manager;
|
||||||
/* ... */
|
/* ... */
|
||||||
TEXIT(0);
|
TEXIT(0);
|
||||||
}
|
}
|
||||||
@ -24,6 +30,19 @@ void LoadDrivers()
|
|||||||
TEXIT(0);
|
TEXIT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FetchDisks()
|
||||||
|
{
|
||||||
|
KPrint("Fetching Disks...");
|
||||||
|
foreach (auto Driver in DriverManager->GetDrivers())
|
||||||
|
{
|
||||||
|
FexExtended *DrvExtHdr = (FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS);
|
||||||
|
|
||||||
|
if (DrvExtHdr->Driver.Type == FexDriverType::FexDriverType_Storage)
|
||||||
|
DiskManager->FetchDisks(Driver->DriverUID);
|
||||||
|
}
|
||||||
|
TEXIT(0);
|
||||||
|
}
|
||||||
|
|
||||||
void KernelMainThread()
|
void KernelMainThread()
|
||||||
{
|
{
|
||||||
Tasking::TCB *CurrentWorker = nullptr;
|
Tasking::TCB *CurrentWorker = nullptr;
|
||||||
@ -31,7 +50,7 @@ void KernelMainThread()
|
|||||||
KPrint("C++ Language Version (__cplusplus) :%ld", __cplusplus);
|
KPrint("C++ Language Version (__cplusplus) :%ld", __cplusplus);
|
||||||
|
|
||||||
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem);
|
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem);
|
||||||
CurrentWorker->Rename("Filesystem");
|
CurrentWorker->Rename("Disk");
|
||||||
CurrentWorker->SetPriority(100);
|
CurrentWorker->SetPriority(100);
|
||||||
TaskManager->WaitForThread(CurrentWorker);
|
TaskManager->WaitForThread(CurrentWorker);
|
||||||
|
|
||||||
@ -39,6 +58,12 @@ void KernelMainThread()
|
|||||||
CurrentWorker->Rename("Drivers");
|
CurrentWorker->Rename("Drivers");
|
||||||
CurrentWorker->SetPriority(100);
|
CurrentWorker->SetPriority(100);
|
||||||
TaskManager->WaitForThread(CurrentWorker);
|
TaskManager->WaitForThread(CurrentWorker);
|
||||||
|
|
||||||
|
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks);
|
||||||
|
CurrentWorker->Rename("Fetch Disks");
|
||||||
|
CurrentWorker->SetPriority(100);
|
||||||
|
TaskManager->WaitForThread(CurrentWorker);
|
||||||
|
|
||||||
KPrint("Waiting for userspace process to start...");
|
KPrint("Waiting for userspace process to start...");
|
||||||
/* Load init file */
|
/* Load init file */
|
||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
|
137
include/disk.hpp
Normal file
137
include/disk.hpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#ifndef __FENNIX_KERNEL_DISK_H__
|
||||||
|
#define __FENNIX_KERNEL_DISK_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <vector.hpp>
|
||||||
|
|
||||||
|
namespace Disk
|
||||||
|
{
|
||||||
|
#define MBR_MAGIC0 0x55
|
||||||
|
#define MBR_MAGIC1 0xAA
|
||||||
|
|
||||||
|
// "EFI PART"
|
||||||
|
#define GPT_MAGIC 0x5452415020494645ULL
|
||||||
|
|
||||||
|
enum PartitionStyle
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
MBR,
|
||||||
|
GPT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PartitionFlags
|
||||||
|
{
|
||||||
|
Present,
|
||||||
|
Bootable,
|
||||||
|
EFISystemPartition
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MasterBootRecordPartition
|
||||||
|
{
|
||||||
|
uint8_t Flags;
|
||||||
|
uint8_t CHSFirst[3];
|
||||||
|
uint8_t Type;
|
||||||
|
uint8_t CHSLast[3];
|
||||||
|
uint32_t LBAFirst;
|
||||||
|
uint32_t Sectors;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct MasterBootRecord
|
||||||
|
{
|
||||||
|
uint8_t Bootstrap[440];
|
||||||
|
uint32_t UniqueID;
|
||||||
|
uint16_t Reserved;
|
||||||
|
MasterBootRecordPartition Partitions[4];
|
||||||
|
uint8_t Signature[2];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct GUIDPartitionTablePartition
|
||||||
|
{
|
||||||
|
uint64_t TypeLow;
|
||||||
|
uint64_t TypeHigh;
|
||||||
|
uint64_t GUIDLow;
|
||||||
|
uint64_t GUIDHigh;
|
||||||
|
uint64_t StartLBA;
|
||||||
|
uint64_t EndLBA;
|
||||||
|
uint64_t Attributes;
|
||||||
|
char Label[72];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct GUIDPartitionTable
|
||||||
|
{
|
||||||
|
uint64_t Signature;
|
||||||
|
uint32_t Revision;
|
||||||
|
uint32_t HdrSize;
|
||||||
|
uint32_t HdrCRC32;
|
||||||
|
uint32_t Reserved;
|
||||||
|
uint64_t LBA;
|
||||||
|
uint64_t ALTLBA;
|
||||||
|
uint64_t FirstBlock;
|
||||||
|
uint64_t LastBlock;
|
||||||
|
uint64_t GUIDLow;
|
||||||
|
uint64_t GUIDHigh;
|
||||||
|
uint64_t PartLBA;
|
||||||
|
uint32_t PartCount;
|
||||||
|
uint32_t EntrySize;
|
||||||
|
uint32_t PartCRC32;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct PartitionTable
|
||||||
|
{
|
||||||
|
MasterBootRecord MBR;
|
||||||
|
GUIDPartitionTable GPT;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Partition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char Label[72] = "Unidentified Partition";
|
||||||
|
uint64_t StartLBA = 0xdeadbeef;
|
||||||
|
uint64_t EndLBA = 0xdeadbeef;
|
||||||
|
uint64_t Sectors = 0xdeadbeef;
|
||||||
|
uint64_t Flags = 0xdeadbeef;
|
||||||
|
unsigned char Port = 0xdeadbeef;
|
||||||
|
PartitionStyle Style = PartitionStyle::Unknown;
|
||||||
|
size_t Index = 0;
|
||||||
|
|
||||||
|
uint64_t Read(uint64_t Offset, uint64_t Count, uint8_t *Buffer) {}
|
||||||
|
uint64_t Write(uint64_t Offset, uint64_t Count, uint8_t *Buffer) {}
|
||||||
|
Partition() {}
|
||||||
|
~Partition() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Drive
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char Name[64] = "Unidentified Drive";
|
||||||
|
uint8_t *Buffer = nullptr;
|
||||||
|
PartitionTable Table;
|
||||||
|
PartitionStyle Style = PartitionStyle::Unknown;
|
||||||
|
Vector<Partition *> Partitions;
|
||||||
|
bool MechanicalDisk = false;
|
||||||
|
uint64_t UniqueIdentifier = 0xdeadbeef;
|
||||||
|
|
||||||
|
uint64_t Read(uint64_t Offset, uint64_t Count, uint8_t *Buffer) {}
|
||||||
|
uint64_t Write(uint64_t Offset, uint64_t Count, uint8_t *Buffer) {}
|
||||||
|
Drive()
|
||||||
|
{ // TODO: Allocate buffer
|
||||||
|
}
|
||||||
|
~Drive() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Manager
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
unsigned char AvailablePorts = 0;
|
||||||
|
int BytesPerSector = 0;
|
||||||
|
|
||||||
|
Vector<Drive *> drives;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void FetchDisks(unsigned long DriverUID);
|
||||||
|
Manager();
|
||||||
|
~Manager();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_DISK_H__
|
2
kernel.h
2
kernel.h
@ -13,6 +13,7 @@
|
|||||||
#include <power.hpp>
|
#include <power.hpp>
|
||||||
#include <task.hpp>
|
#include <task.hpp>
|
||||||
#include <time.hpp>
|
#include <time.hpp>
|
||||||
|
#include <disk.hpp>
|
||||||
#include <pci.hpp>
|
#include <pci.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ extern Tasking::Task *TaskManager;
|
|||||||
extern Time::time *TimeManager;
|
extern Time::time *TimeManager;
|
||||||
extern FileSystem::Virtual *vfs;
|
extern FileSystem::Virtual *vfs;
|
||||||
extern Driver::Driver *DriverManager;
|
extern Driver::Driver *DriverManager;
|
||||||
|
extern Disk::Manager *DiskManager;
|
||||||
|
|
||||||
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
|
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
|
||||||
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
|
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
|
||||||
|
Loading…
x
Reference in New Issue
Block a user