Refactor filesystem & stl code

This commit is contained in:
EnderIce2
2024-05-18 07:42:01 +03:00
parent 77a291d08b
commit 6801475243
186 changed files with 15784 additions and 9746 deletions

View File

@ -16,14 +16,16 @@
*/
#include <driver.hpp>
#include <interface/driver.h>
#include <interface/fs.h>
#include <type_traits>
#include "../../kernel.h"
#include "../../driver.h"
// #define DEBUG_API
#ifdef DEBUG_API
#define dbg_api(Format, ...) function(Format, ##__VA_ARGS__)
#define dbg_api(Format, ...) func(Format, ##__VA_ARGS__)
#else
#define dbg_api(Format, ...)
#endif
@ -53,19 +55,19 @@ namespace Driver
{
case _drf_Entry:
drv->Entry = (int (*)())Function;
debug("Entry %#lx for %s", (uintptr_t)Function, drv->Path);
debug("Entry %#lx for %s", (uintptr_t)Function, drv->Path.c_str());
break;
case _drf_Final:
drv->Final = (int (*)())Function;
debug("Finalize %#lx for %s", (uintptr_t)Function, drv->Path);
debug("Finalize %#lx for %s", (uintptr_t)Function, drv->Path.c_str());
break;
case _drf_Panic:
drv->Panic = (int (*)())Function;
debug("Panic %#lx for %s", (uintptr_t)Function, drv->Path);
debug("Panic %#lx for %s", (uintptr_t)Function, drv->Path.c_str());
break;
case _drf_Probe:
drv->Probe = (int (*)())Function;
debug("Probe %#lx for %s", (uintptr_t)Function, drv->Path);
debug("Probe %#lx for %s", (uintptr_t)Function, drv->Path.c_str());
break;
default:
assert(!"Invalid driver function type");
@ -134,7 +136,7 @@ namespace Driver
{
if (ih.first == IRQ)
{
debug("Removing IRQ %d: %#lx for %s", IRQ, (uintptr_t)ih.second, drv->Path);
debug("Removing IRQ %d: %#lx for %s", IRQ, (uintptr_t)ih.second, drv->Path.c_str());
Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))ih.second, IRQ);
drv->InterruptHandlers->erase(IRQ);
break;
@ -177,7 +179,7 @@ namespace Driver
foreach (auto &i in * drv->InterruptHandlers)
{
Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))Handler, i.first);
debug("Removed IRQ %d: %#lx for %s", i.first, (uintptr_t)Handler, drv->Path);
debug("Removed IRQ %d: %#lx for %s", i.first, (uintptr_t)Handler, drv->Path.c_str());
}
drv->InterruptHandlers->clear();
return 0;
@ -185,217 +187,6 @@ namespace Driver
/* --------- */
dev_t RegisterInputDevice(dev_t MajorID, DeviceDriverType Type)
{
dbg_api("%d, %d", MajorID, Type);
switch (Type)
{
case ddt_Keyboard:
return DriverManager->InputKeyboardDev->Register(MajorID);
case ddt_Mouse:
return DriverManager->InputMouseDev->Register(MajorID);
/* ... */
default:
assert(!"Invalid input device type");
}
}
int UnregisterInputDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type)
{
dbg_api("%d, %d, %d", MajorID, MinorID, Type);
switch (Type)
{
case ddt_Keyboard:
return DriverManager->InputKeyboardDev->Unregister(MajorID, MinorID);
case ddt_Mouse:
return DriverManager->InputMouseDev->Unregister(MajorID, MinorID);
/* ... */
default:
assert(!"Invalid input device type");
}
}
int ReportKeyboardEvent(dev_t MajorID, dev_t MinorID, uint8_t ScanCode)
{
dbg_api("%d, %d, %d", MajorID, MinorID, ScanCode);
return DriverManager->InputKeyboardDev->ReportKeyEvent(MajorID, MinorID, ScanCode);
}
int ReportRelativeMouseEvent(dev_t MajorID, dev_t MinorID, __MouseButtons Button, int X, int Y, int8_t Z)
{
dbg_api("%d, %d, %d, %d, %d, %d", MajorID, MinorID, Button, X, Y, Z);
return DriverManager->InputMouseDev->ReportMouseEvent(MajorID, MinorID,
Button.LeftButton, Button.RightButton, Button.MiddleButton,
Button.Button4, Button.Button5, Button.Button6, Button.Button7, Button.Button8,
X, Y, Z, true);
}
int ReportAbsoluteMouseEvent(dev_t MajorID, dev_t MinorID, __MouseButtons Button, uintptr_t X, uintptr_t Y, int8_t Z)
{
dbg_api("%d, %d, %d, %d, %d, %d", MajorID, MinorID, Button, X, Y, Z);
return DriverManager->InputMouseDev->ReportMouseEvent(MajorID, MinorID,
Button.LeftButton, Button.RightButton, Button.MiddleButton,
Button.Button4, Button.Button5, Button.Button6, Button.Button7, Button.Button8,
X, Y, Z, false);
}
/* --------- */
dev_t RegisterBlockDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl)
{
dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl);
switch (Type)
{
case ddt_SATA:
{
dev_t ret = DriverManager->BlockSATADev->Register(MajorID);
DriverManager->BlockSATADev->NewBlock(MajorID, ret,
(SlaveDeviceFile::drvOpen_t)Open,
(SlaveDeviceFile::drvClose_t)Close,
(SlaveDeviceFile::drvRead_t)Read,
(SlaveDeviceFile::drvWrite_t)Write,
(SlaveDeviceFile::drvIoctl_t)Ioctl);
return ret;
}
case ddt_ATA:
{
dev_t ret = DriverManager->BlockHDDev->Register(MajorID);
DriverManager->BlockHDDev->NewBlock(MajorID, ret,
(SlaveDeviceFile::drvOpen_t)Open,
(SlaveDeviceFile::drvClose_t)Close,
(SlaveDeviceFile::drvRead_t)Read,
(SlaveDeviceFile::drvWrite_t)Write,
(SlaveDeviceFile::drvIoctl_t)Ioctl);
return ret;
}
case ddt_NVMe:
{
dev_t ret = DriverManager->BlockNVMeDev->Register(MajorID);
DriverManager->BlockNVMeDev->NewBlock(MajorID, ret,
(SlaveDeviceFile::drvOpen_t)Open,
(SlaveDeviceFile::drvClose_t)Close,
(SlaveDeviceFile::drvRead_t)Read,
(SlaveDeviceFile::drvWrite_t)Write,
(SlaveDeviceFile::drvIoctl_t)Ioctl);
return ret;
}
/* ... */
default:
assert(!"Invalid storage device type");
}
}
int UnregisterBlockDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type)
{
dbg_api("%d, %d, %d", MajorID, MinorID, Type);
switch (Type)
{
case ddt_SATA:
return DriverManager->BlockSATADev->Unregister(MajorID, MinorID);
case ddt_ATA:
return DriverManager->BlockHDDev->Unregister(MajorID, MinorID);
case ddt_NVMe:
return DriverManager->BlockNVMeDev->Unregister(MajorID, MinorID);
/* ... */
default:
assert(!"Invalid storage device type");
}
}
/* --------- */
dev_t RegisterAudioDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl)
{
dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl);
switch (Type)
{
case ddt_Audio:
{
dev_t ret = DriverManager->AudioDev->Register(MajorID);
DriverManager->AudioDev->NewAudio(MajorID, ret,
(SlaveDeviceFile::drvOpen_t)Open,
(SlaveDeviceFile::drvClose_t)Close,
(SlaveDeviceFile::drvRead_t)Read,
(SlaveDeviceFile::drvWrite_t)Write,
(SlaveDeviceFile::drvIoctl_t)Ioctl);
return ret;
}
/* ... */
default:
assert(!"Invalid audio device type");
}
}
int UnregisterAudioDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type)
{
dbg_api("%d, %d, %d", MajorID, MinorID, Type);
switch (Type)
{
case ddt_Audio:
return DriverManager->AudioDev->Unregister(MajorID, MinorID);
/* ... */
default:
assert(!"Invalid audio device type");
}
}
/* --------- */
dev_t RegisterNetDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl)
{
dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl);
switch (Type)
{
case ddt_Network:
{
dev_t ret = DriverManager->NetDev->Register(MajorID);
DriverManager->NetDev->NewNet(MajorID, ret,
(SlaveDeviceFile::drvOpen_t)Open,
(SlaveDeviceFile::drvClose_t)Close,
(SlaveDeviceFile::drvRead_t)Read,
(SlaveDeviceFile::drvWrite_t)Write,
(SlaveDeviceFile::drvIoctl_t)Ioctl);
return ret;
}
/* ... */
default:
assert(!"Invalid audio device type");
}
}
int UnregisterNetDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type)
{
dbg_api("%d, %d, %d", MajorID, MinorID, Type);
switch (Type)
{
case ddt_Network:
return DriverManager->NetDev->Unregister(MajorID, MinorID);
/* ... */
default:
assert(!"Invalid audio device type");
}
}
int ReportNetworkPacket(dev_t MajorID, dev_t MinorID, void *Buffer, size_t Size)
{
dbg_api("%d, %d, %#lx, %d", MajorID, MinorID, Buffer, Size);
return DriverManager->NetDev->ReportNetworkPacket(MajorID, MinorID, Buffer, Size);
}
/* --------- */
void d_KPrint(dev_t MajorID, const char *Format, va_list args)
{
dbg_api("%d %s, %#lx", MajorID, Format, args);
@ -891,22 +682,6 @@ namespace Driver
api->UnregisterInterruptHandler = UnregisterInterruptHandler;
api->UnregisterAllInterruptHandlers = UnregisterAllInterruptHandlers;
api->RegisterInputDevice = RegisterInputDevice;
api->UnregisterInputDevice = UnregisterInputDevice;
api->ReportKeyboardEvent = ReportKeyboardEvent;
api->ReportRelativeMouseEvent = ReportRelativeMouseEvent;
api->ReportAbsoluteMouseEvent = ReportAbsoluteMouseEvent;
api->RegisterBlockDevice = RegisterBlockDevice;
api->UnregisterBlockDevice = UnregisterBlockDevice;
api->RegisterAudioDevice = RegisterAudioDevice;
api->UnregisterAudioDevice = UnregisterAudioDevice;
api->RegisterNetDevice = RegisterNetDevice;
api->UnregisterNetDevice = UnregisterNetDevice;
api->ReportNetworkPacket = ReportNetworkPacket;
api->KPrint = d_KPrint;
api->KernelLog = KernelLog;
@ -944,3 +719,28 @@ namespace Driver
api->strstr = api__strstr;
}
}
dev_t __api_RegisterFileSystem(FileSystemInfo *Info, struct Inode *Root)
{
return fs->RegisterFileSystem(Info, Root);
}
int __api_UnregisterFileSystem(dev_t Device)
{
return fs->UnregisterFileSystem(Device);
}
struct APISymbols
{
const char *Name;
void *Function;
};
static struct APISymbols APISymbols[] = {
{"RegisterFileSystem", (void *)__api_RegisterFileSystem},
{"UnregisterFileSystem", (void *)__api_UnregisterFileSystem},
};
/* Checking functions signatures */
static_assert(std::is_same_v<decltype(__api_RegisterFileSystem), decltype(RegisterFileSystem)>);
static_assert(std::is_same_v<decltype(__api_UnregisterFileSystem), decltype(UnregisterFileSystem)>);

View File

@ -1,327 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.hpp>
#include <memory.hpp>
#include <ints.hpp>
#include <task.hpp>
#include <printf.h>
#include <exec.hpp>
#include <cwalk.h>
#include <md5.h>
#include "../../../kernel.h"
#include "../../../driver.h"
using namespace vfs;
namespace Driver
{
int MasterDeviceFile::open(int Flags, mode_t Mode)
{
switch (this->DeviceType)
{
default:
if (this->SlavesMap.empty())
return -ENOSYS;
Slaves slave = this->SlavesMap.begin()->second;
return slave->begin()->second->open(Flags, Mode);
}
}
int MasterDeviceFile::close()
{
switch (this->DeviceType)
{
default:
if (this->SlavesMap.empty())
return -ENOSYS;
Slaves slave = this->SlavesMap.begin()->second;
return slave->begin()->second->close();
}
}
size_t MasterDeviceFile::read(uint8_t *Buffer,
size_t Size,
off_t Offset)
{
switch (this->DeviceType)
{
case ddt_Keyboard:
{
while (KeyQueue.empty())
TaskManager->Yield();
/* Request scancode */
if (Size == 2 && Buffer[1] == 0x00)
{
while (RawKeyQueue.empty())
TaskManager->Yield();
Buffer[0] = RawKeyQueue.front();
RawKeyQueue.pop_front();
return 1;
}
Buffer[0] = KeyQueue.front();
KeyQueue.pop_front();
return 1;
}
default:
if (this->SlavesMap.empty())
return 0;
Slaves slave = this->SlavesMap.begin()->second;
return slave->begin()->second->read(Buffer, Size, Offset);
}
}
size_t MasterDeviceFile::write(uint8_t *Buffer,
size_t Size,
off_t Offset)
{
switch (this->DeviceType)
{
default:
if (this->SlavesMap.empty())
return 0;
Slaves slave = this->SlavesMap.begin()->second;
return slave->begin()->second->write(Buffer, Size, Offset);
}
}
int MasterDeviceFile::ioctl(unsigned long Request,
void *Argp)
{
switch (this->DeviceType)
{
default:
if (this->SlavesMap.empty())
return -ENOSYS;
Slaves slave = this->SlavesMap.begin()->second;
return slave->begin()->second->ioctl(Request, Argp);
}
}
void MasterDeviceFile::ClearBuffers()
{
this->RawKeyQueue.clear();
this->KeyQueue.clear();
/* ... */
foreach (auto &sm in this->SlavesMap)
{
Slaves slave = sm.second;
foreach (auto &sdf in *slave)
sdf.second->ClearBuffers();
}
}
int MasterDeviceFile::ReportKeyEvent(maj_t ID, min_t MinorID, uint8_t ScanCode)
{
debug("New key event: %02x", ScanCode);
if (this->SlavesMap.find(ID) == this->SlavesMap.end())
return -EINVAL;
std::unordered_map<min_t, SlaveDeviceFile *> *slave = this->SlavesMap[ID];
if ((*slave).find(MinorID) == (*slave).end())
return -EINVAL;
/* We are master, keep a copy of the scancode and
converted key */
if (RawKeyQueue.size() > 16)
RawKeyQueue.pop_front();
RawKeyQueue.push_back(ScanCode);
if (KeyQueue.size() > 16)
KeyQueue.pop_front();
switch (ScanCode & ~KEY_PRESSED)
{
case KEY_LEFT_SHIFT:
case KEY_RIGHT_SHIFT:
{
if (ScanCode & KEY_PRESSED)
UpperCase = true;
else
UpperCase = false;
break;
}
case KEY_CAPS_LOCK:
{
if (ScanCode & KEY_PRESSED)
CapsLock = !CapsLock;
break;
}
default:
break;
}
if (ScanCode & KEY_PRESSED)
KeyQueue.push_back(GetScanCode(ScanCode, UpperCase || CapsLock));
SlaveDeviceFile *sdf = (*slave)[MinorID];
return sdf->ReportKeyEvent(ScanCode);
}
int MasterDeviceFile::ReportMouseEvent(maj_t ID, min_t MinorID,
bool LeftButton, bool RightButton, bool MiddleButton,
bool Button4, bool Button5, bool Button6, bool Button7, bool Button8,
uintptr_t X, uintptr_t Y, int8_t Z, bool Relative)
{
return -ENOSYS;
}
int MasterDeviceFile::ReportNetworkPacket(maj_t ID, min_t MinorID, void *Buffer, size_t Size)
{
/* TODO: Buffer must be allocated by the kernel */
return -ENOSYS;
}
int MasterDeviceFile::NewBlock(maj_t ID, min_t MinorID, drvOpen_t Open, drvClose_t Close,
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
{
assert(this->SlavesMap.find(ID) != this->SlavesMap.end());
Slaves slave = this->SlavesMap[ID];
assert((*slave).find(MinorID) != (*slave).end());
SlaveDeviceFile *sdf = (*slave)[MinorID];
sdf->Open = Open;
sdf->Close = Close;
sdf->Read = Read;
sdf->Write = Write;
sdf->Ioctl = Ioctl;
return 0;
}
int MasterDeviceFile::NewAudio(maj_t ID, min_t MinorID, drvOpen_t Open, drvClose_t Close,
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
{
assert(this->SlavesMap.find(ID) != this->SlavesMap.end());
Slaves slave = this->SlavesMap[ID];
assert((*slave).find(MinorID) != (*slave).end());
SlaveDeviceFile *sdf = (*slave)[MinorID];
sdf->Open = Open;
sdf->Close = Close;
sdf->Read = Read;
sdf->Write = Write;
sdf->Ioctl = Ioctl;
return 0;
}
int MasterDeviceFile::NewNet(maj_t ID, min_t MinorID, drvOpen_t Open, drvClose_t Close,
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
{
assert(this->SlavesMap.find(ID) != this->SlavesMap.end());
Slaves slave = this->SlavesMap[ID];
assert((*slave).find(MinorID) != (*slave).end());
SlaveDeviceFile *sdf = (*slave)[MinorID];
sdf->Open = Open;
sdf->Close = Close;
sdf->Read = Read;
sdf->Write = Write;
sdf->Ioctl = Ioctl;
return 0;
}
dev_t MasterDeviceFile::Register(maj_t ID)
{
debug("Registering slave device %d", ID);
Slaves slave;
if (this->SlavesMap.find(ID) != this->SlavesMap.end())
slave = this->SlavesMap[ID];
else
slave = new std::unordered_map<min_t, SlaveDeviceFile *>();
char name[24];
sprintf(name, "%s%ld", this->SlaveName, this->SlaveIDCounter);
SlaveDeviceFile *sdf = new SlaveDeviceFile(name,
this->SlaveParent,
this->DeviceType,
this->Type);
sdf->DeviceMajor = ID;
sdf->DeviceMinor = this->SlaveIDCounter;
(*slave)[this->SlaveIDCounter] = sdf;
this->SlavesMap[ID] = slave;
return this->SlaveIDCounter++;
}
int MasterDeviceFile::Unregister(maj_t ID, min_t MinorID)
{
debug("Unregistering slave device %d:%d", ID, MinorID);
if (this->SlavesMap.find(ID) == this->SlavesMap.end())
return -EINVAL;
std::unordered_map<min_t, SlaveDeviceFile *> *slave = this->SlavesMap[ID];
if ((*slave).find(MinorID) == (*slave).end())
return -EINVAL;
SlaveDeviceFile *sdf = (*slave)[MinorID];
delete sdf;
slave->erase(MinorID);
if (slave->empty())
{
delete slave;
this->SlavesMap.erase(ID);
}
return 0;
}
MasterDeviceFile::MasterDeviceFile(const char *MasterName,
const char *_SlaveName,
Node *Parent,
int Type)
: Node(Parent, MasterName, NodeType::FILE)
{
strncpy(this->SlaveName, _SlaveName, sizeof(this->Name));
this->DeviceType = Type;
this->SlaveParent = Parent;
switch (Type)
{
case ddt_Keyboard:
case ddt_Mouse:
case ddt_Joystick:
case ddt_Gamepad:
case ddt_Touchpad:
case ddt_Touchscreen:
this->Type = NodeType::CHARDEVICE;
break;
case ddt_SATA:
case ddt_ATA:
case ddt_NVMe:
this->Type = NodeType::BLOCKDEVICE;
break;
default:
break;
}
}
MasterDeviceFile::~MasterDeviceFile()
{
foreach (auto &sm in this->SlavesMap)
{
Slaves slave = sm.second;
foreach (auto &sdf in *slave)
delete sdf.second;
delete slave;
}
this->SlavesMap.clear();
}
}

View File

@ -1,131 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <driver.hpp>
#include <memory.hpp>
#include <ints.hpp>
#include <task.hpp>
#include <printf.h>
#include <exec.hpp>
#include <cwalk.h>
#include <md5.h>
#include "../../../kernel.h"
#include "../../../driver.h"
using namespace vfs;
namespace Driver
{
int SlaveDeviceFile::open(int Flags, mode_t Mode)
{
switch (this->DeviceType)
{
default:
if (this->Open)
return this->Open(this->DeviceMajor, this->DeviceMinor,
Flags, Mode);
return -ENOSYS;
}
}
int SlaveDeviceFile::close()
{
switch (this->DeviceType)
{
default:
if (this->Close)
return this->Close(this->DeviceMajor, this->DeviceMinor);
return -ENOSYS;
}
}
size_t SlaveDeviceFile::read(uint8_t *Buffer,
size_t Size,
off_t Offset)
{
switch (this->DeviceType)
{
case ddt_Keyboard:
{
while (KeyQueue.empty())
TaskManager->Yield();
Buffer[0] = KeyQueue.front();
KeyQueue.pop_front();
return 1;
}
default:
if (this->Read)
return this->Read(this->DeviceMajor, this->DeviceMinor,
Buffer, Size, Offset);
return 0;
}
}
size_t SlaveDeviceFile::write(uint8_t *Buffer,
size_t Size,
off_t Offset)
{
switch (this->DeviceType)
{
default:
if (this->Write)
return this->Write(this->DeviceMajor, this->DeviceMinor,
Buffer, Size, Offset);
return 0;
}
}
int SlaveDeviceFile::ioctl(unsigned long Request,
void *Argp)
{
switch (this->DeviceType)
{
default:
if (this->Ioctl)
return this->Ioctl(this->DeviceMajor, this->DeviceMinor,
Request, Argp);
return -ENOSYS;
}
}
void SlaveDeviceFile::ClearBuffers()
{
KeyQueue.clear();
/* ... */
}
int SlaveDeviceFile::ReportKeyEvent(uint8_t ScanCode)
{
if (KeyQueue.size() > 16)
KeyQueue.pop_front();
KeyQueue.push_back(ScanCode);
return 0;
}
SlaveDeviceFile::SlaveDeviceFile(const char *Name, vfs::Node *Parent, int Type, vfs::NodeType NType)
: Node(Parent, Name, NType)
{
this->DeviceType = Type;
}
SlaveDeviceFile::~SlaveDeviceFile()
{
}
}

View File

@ -17,6 +17,7 @@
#include <driver.hpp>
#include <interface/driver.h>
#include <memory.hpp>
#include <ints.hpp>
#include <task.hpp>
@ -26,12 +27,64 @@
#include <md5.h>
#include "../../kernel.h"
#include "../../driver.h"
using namespace vfs;
namespace Driver
{
void Manager::PreloadDrivers()
{
debug("Initializing driver manager");
const char *DriverDirectory = Config.DriverDirectory;
FileNode *drvDirNode = fs->GetByPath(DriverDirectory, nullptr);
if (!drvDirNode)
{
error("Failed to open driver directory %s", DriverDirectory);
KPrint("Failed to open driver directory %s", DriverDirectory);
return;
}
foreach (const auto &drvNode in drvDirNode->Children)
{
debug("Checking driver %s", drvNode->Path.c_str());
if (!drvNode->IsRegularFile())
continue;
if (Execute::GetBinaryType(drvNode->Path) != Execute::BinTypeELF)
{
error("Driver %s is not an ELF binary", drvNode->Path.c_str());
continue;
}
Memory::VirtualMemoryArea *dVma = new Memory::VirtualMemoryArea(thisProcess->PageTable);
uintptr_t EntryPoint, BaseAddress;
int err = this->LoadDriverFile(EntryPoint, BaseAddress, dVma, drvNode);
debug("err = %d (%s)", err, strerror(err));
if (err != 0)
{
error("Failed to load driver %s: %s",
drvNode->Path.c_str(), strerror(err));
delete dVma;
continue;
}
Drivers[DriverIDCounter++] = {
.BaseAddress = BaseAddress,
.EntryPoint = EntryPoint,
.vma = dVma,
.Path = drvNode->Path,
.InterruptHandlers = new std::unordered_map<uint8_t, void *>};
dev_t countr = DriverIDCounter - 1;
const char *drvName;
size_t drvNameLen;
cwk_path_get_basename(drvNode->Path.c_str(), &drvName, &drvNameLen);
strncpy(Drivers[countr].Name, drvName, sizeof(Drivers[countr].Name));
}
}
void Manager::LoadAllDrivers()
{
if (Drivers.empty())
@ -56,7 +109,7 @@ namespace Driver
dApi->Base = Drv->BaseAddress;
PopulateDriverAPI(dApi);
debug("Calling driver %s at %#lx", Drv->Path, Drv->EntryPoint);
debug("Calling driver %s at %#lx", Drv->Path.c_str(), Drv->EntryPoint);
int (*DrvInit)(__driverAPI *) = (int (*)(__driverAPI *))Drv->EntryPoint;
Drv->ErrorCode = DrvInit(dApi);
if (Drv->ErrorCode < 0)
@ -64,7 +117,7 @@ namespace Driver
KPrint("FATAL: _start() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
error("Failed to load driver %s: %s",
Drv->Path, strerror(Drv->ErrorCode));
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv->vma->FreeAllPages();
continue;
@ -73,48 +126,36 @@ namespace Driver
KPrint("Loading driver %s", Drv->Name);
debug("Calling Probe()=%#lx on driver %s",
Drv->Probe, Drv->Path);
Drv->Probe, Drv->Path.c_str());
Drv->ErrorCode = Drv->Probe();
if (Drv->ErrorCode < 0)
{
KPrint("Probe() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
error("Failed to probe driver %s: %s",
Drv->Path, strerror(Drv->ErrorCode));
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv->vma->FreeAllPages();
continue;
}
debug("Calling driver Entry()=%#lx function on driver %s",
Drv->Entry, Drv->Path);
Drv->Entry, Drv->Path.c_str());
Drv->ErrorCode = Drv->Entry();
if (Drv->ErrorCode < 0)
{
KPrint("Entry() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
error("Failed to initialize driver %s: %s",
Drv->Path, strerror(Drv->ErrorCode));
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv->vma->FreeAllPages();
continue;
}
debug("Loaded driver %s", Drv->Path);
debug("Loaded driver %s", Drv->Path.c_str());
Drv->Initialized = true;
}
InputMouseDev->ClearBuffers();
InputKeyboardDev->ClearBuffers();
BlockSATADev->ClearBuffers();
BlockHDDev->ClearBuffers();
BlockNVMeDev->ClearBuffers();
AudioDev->ClearBuffers();
NetDev->ClearBuffers();
/* ... */
}
void Manager::UnloadAllDrivers()
@ -151,6 +192,9 @@ namespace Driver
void Manager::Panic()
{
Memory::Virtual vmm;
if (Drivers.size() == 0)
return;
foreach (auto Driver in Drivers)
{
if (!Driver.second.Initialized)
@ -168,21 +212,18 @@ namespace Driver
}
}
int Manager::LoadDriverFile(uintptr_t &EntryPoint,
uintptr_t &BaseAddress,
Memory::VirtualMemoryArea *dVma,
RefNode *rDrv)
int Manager::LoadDriverFile(uintptr_t &EntryPoint, uintptr_t &BaseAddress,
Memory::VirtualMemoryArea *dVma, FileNode *rDrv)
{
Elf64_Ehdr ELFHeader;
rDrv->seek(0, SEEK_SET);
rDrv->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
rDrv->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
if (ELFHeader.e_type != ET_DYN)
{
error("Driver %s is not a shared object", rDrv->node->FullPath);
error("Driver %s is not a shared object", rDrv->Path.c_str());
return -ENOEXEC;
}
trace("Loading driver %s in memory", rDrv->node->Name);
trace("Loading driver %s in memory", rDrv->Name.c_str());
BaseAddress = 0;
{
@ -192,8 +233,7 @@ namespace Driver
size_t SegmentsSize = 0;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
{
rDrv->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
rDrv->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
if (ProgramHeader.p_type == PT_LOAD ||
ProgramHeader.p_type == PT_DYNAMIC)
@ -217,8 +257,7 @@ namespace Driver
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
{
rDrv->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
rDrv->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
switch (ProgramHeader.p_type)
{
@ -237,8 +276,7 @@ namespace Driver
if (ProgramHeader.p_filesz > 0)
{
rDrv->seek(ProgramHeader.p_offset, SEEK_SET);
rDrv->read((uint8_t *)SegmentDestination, ProgramHeader.p_filesz);
rDrv->Read(SegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
@ -264,8 +302,7 @@ namespace Driver
if (ProgramHeader.p_filesz > 0)
{
rDrv->seek(ProgramHeader.p_offset, SEEK_SET);
rDrv->read((uint8_t *)DynamicSegmentDestination, ProgramHeader.p_filesz);
rDrv->Read(DynamicSegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
@ -288,8 +325,7 @@ namespace Driver
Elf64_Phdr ProgramHeader;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
{
rDrv->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
rDrv->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
if (ProgramHeader.p_type == PT_DYNAMIC)
{
@ -381,14 +417,11 @@ namespace Driver
break;
}
vfs::RefNode *fd = fs->Open(rDrv->node->FullPath);
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(fd, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(fd, DT_STRTAB);
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_STRTAB);
Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
char *DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
UNUSED(DynStr);
delete fd;
Elf64_Rela *Rela = (Elf64_Rela *)(BaseAddress + Dynamic->d_un.d_ptr);
for (size_t i = 0; i < (PltRelSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
@ -431,14 +464,12 @@ namespace Driver
{
fixme("DT_SYMTAB");
break;
vfs::RefNode *fd = fs->Open(rDrv->node->FullPath);
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(fd, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(fd, DT_STRTAB);
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_STRTAB);
Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
char *DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
UNUSED(DynStr);
delete fd;
size_t symtabEntrySize = 0;
Elf64_Dyn *entrySizeDyn = Dynamic;
@ -476,8 +507,8 @@ namespace Driver
* this will create more issues :/ */
// if (strcmp(SymbolName, "DriverProbe") == 0)
// {
// Drivers[MajorIDCounter].Probe = (int (*)())(BaseAddress + s->st_value);
// debug("Found probe function at %#lx", Drivers[MajorIDCounter].Probe);
// Drivers[DriverIDCounter].Probe = (int (*)())(BaseAddress + s->st_value);
// debug("Found probe function at %#lx", Drivers[DriverIDCounter].Probe);
// }
}
break;
@ -498,7 +529,7 @@ namespace Driver
EntryPoint += BaseAddress;
debug("Driver %s has entry point %#lx and base %#lx",
rDrv->node->FullPath, EntryPoint, BaseAddress);
rDrv->Path.c_str(), EntryPoint, BaseAddress);
/* FIXME: Do not add to the KernelSymbolTable! */
// Memory::SmartHeap sh(rDrv->Size);
@ -510,79 +541,11 @@ namespace Driver
Manager::Manager()
{
debug("Initializing driver manager");
const char *DriverDirectory = Config.DriverDirectory;
RefNode *drvDirNode = fs->Open(DriverDirectory);
if (!drvDirNode)
{
error("Failed to open driver directory %s", DriverDirectory);
KPrint("Failed to open driver directory %s", DriverDirectory);
return;
}
foreach (auto drvNode in drvDirNode->node->Children)
{
if (drvNode->Type != vfs::FILE)
continue;
if (Execute::GetBinaryType(drvNode->FullPath) != Execute::BinTypeELF)
{
error("Driver %s is not an ELF binary", drvNode->FullPath);
continue;
}
RefNode *rDrv = drvNode->CreateReference();
Memory::VirtualMemoryArea *dVma =
new Memory::VirtualMemoryArea(thisProcess->PageTable);
uintptr_t EntryPoint, BaseAddress;
int err = this->LoadDriverFile(EntryPoint, BaseAddress, dVma, rDrv);
debug("err = %d (%s)", err, strerror(err));
if (err != 0)
{
error("Failed to load driver %s: %s",
drvNode->FullPath, strerror(err));
delete rDrv;
delete dVma;
continue;
}
delete rDrv;
Drivers[MajorIDCounter++] = {
.BaseAddress = BaseAddress,
.EntryPoint = EntryPoint,
.vma = dVma,
.Path = drvNode->FullPath,
.InterruptHandlers = new std::unordered_map<uint8_t, void *>};
dev_t countr = MajorIDCounter - 1;
const char *drvName;
size_t drvNameLen;
cwk_path_get_basename(drvNode->FullPath, &drvName, &drvNameLen);
strncpy(Drivers[countr].Name, drvName, sizeof(Drivers[countr].Name));
}
delete drvDirNode;
InputMouseDev = new MasterDeviceFile("mice", "mouse", DevFS, ddt_Mouse);
InputKeyboardDev = new MasterDeviceFile("key", "kbd", DevFS, ddt_Keyboard);
BlockSATADev = new MasterDeviceFile("sd", "sd", DevFS, ddt_SATA);
BlockHDDev = new MasterDeviceFile("hd", "hd", DevFS, ddt_ATA);
BlockNVMeDev = new MasterDeviceFile("nvme", "nvme", DevFS, ddt_NVMe);
AudioDev = new MasterDeviceFile("audio", "snd", DevFS, ddt_Audio);
NetDev = new MasterDeviceFile("network", "net", DevFS, ddt_Network);
}
Manager::~Manager()
{
debug("Unloading drivers");
UnloadAllDrivers();
delete InputMouseDev;
delete InputKeyboardDev;
}
}

View File

@ -15,10 +15,9 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <interface/driver.h>
#include <driver.hpp>
#include "../../driver.h"
static char ScanCodeConversionTableLower[] = {
[KEY_1] = '1',
[KEY_2] = '2',