Update kernel

This commit is contained in:
Alex
2023-08-06 04:53:14 +03:00
parent 3b65386399
commit 2c51e4432f
181 changed files with 21873 additions and 21475 deletions

View File

@ -23,11 +23,12 @@
class Bitmap
{
public:
size_t Size;
uint8_t *Buffer;
bool operator[](uint64_t index);
bool Set(uint64_t index, bool value);
bool Get(uint64_t index);
size_t Size;
uint8_t *Buffer;
bool Set(uint64_t index, bool value);
bool Get(uint64_t index);
bool operator[](uint64_t index);
};
#endif // !__FENNIX_KERNEL_BITMAP_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -230,7 +230,9 @@ enum SegmentTypes
PT_SUNWSTACK = 0x6ffffffa,
PT_HISUNW = 0x6fffffff,
PT_LOPROC = 0x70000000,
PT_HIPROC = 0x7fffffff
PT_HIPROC = 0x7fffffff,
PT_GNU_EH_FRAME = 0x6474e550,
PT_GNU_STACK = 0x6474e551,
};
enum DynamicArrayTags
@ -718,6 +720,13 @@ struct Elf64_Dyn
} d_un;
};
typedef struct
{
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
typedef struct
{
Elf64_Addr r_offset;
@ -725,4 +734,34 @@ typedef struct
Elf64_Sxword r_addend;
} Elf64_Rela;
#if defined(a64) || defined(aa64)
typedef Elf64_Addr Elf_Addr;
typedef Elf64_Half Elf_Half;
typedef Elf64_Off Elf_Off;
typedef Elf64_Sword Elf_Sword;
typedef Elf64_Word Elf_Word;
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Rel Elf_Rel;
typedef Elf64_Sym Elf_Sym;
typedef Elf64_Dyn Elf_Dyn;
typedef Elf64_Rela Elf_Rela;
#elif defined(a32)
typedef Elf32_Addr Elf_Addr;
typedef Elf32_Half Elf_Half;
typedef Elf32_Off Elf_Off;
typedef Elf32_Sword Elf_Sword;
typedef Elf32_Word Elf_Word;
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Rel Elf_Rel;
typedef Elf32_Sym Elf_Sym;
typedef Elf32_Dyn Elf_Dyn;
typedef Elf32_Rela Elf_Rela;
#endif
#endif // !__FENNIX_KERNEL_ELF_H__

View File

@ -23,12 +23,13 @@
#include <filesystem.hpp>
#include <task.hpp>
#include <std.hpp>
#include <errno.h>
#include <vector>
#include <elf.h>
namespace Execute
{
enum BinaryType
enum BinaryType : int
{
BinTypeInvalid,
BinTypeFex,
@ -39,28 +40,6 @@ namespace Execute
BinTypeUnknown
};
enum ExStatus
{
Unknown,
OK,
Unsupported,
GenericError,
LoadingProcedureFailed,
InvalidFile,
InvalidFileFormat,
InvalidFileHeader,
InvalidFileData,
InvalidFileEntryPoint,
InvalidFilePath
};
struct SpawnData
{
ExStatus Status;
Tasking::PCB *Process;
Tasking::TCB *Thread;
};
struct SharedLibrary
{
char Identifier[64];
@ -72,25 +51,6 @@ namespace Execute
size_t Length;
};
struct ELFBaseLoad
{
bool Success;
bool Interpreter;
SpawnData sd;
Tasking::IP InstructionPointer;
std::vector<const char *> NeededLibraries;
void *MemoryImage;
void *VirtualMemoryImage;
/* This should be deleted after copying the allocated pages to the thread
Intended to be used only inside BaseLoad.cpp */
Memory::MemMgr *TmpMem;
/* Same as above, for BaseLoad.cpp only */
std::vector<AuxiliaryVector> auxv;
};
struct MmImage
{
void *Physical;
@ -100,46 +60,46 @@ namespace Execute
class ELFObject
{
private:
ELFBaseLoad BaseLoadInfo{};
bool IsElfValid;
const char **ELFargv;
const char **ELFenvp;
std::vector<AuxiliaryVector> Elfauxv;
Tasking::IP ip;
ELFBaseLoad LoadExec_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
void LoadExec_x86_32(int fd,
Tasking::PCB *TargetProcess);
ELFBaseLoad LoadExec_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
void LoadExec_x86_64(int fd,
Tasking::PCB *TargetProcess);
ELFBaseLoad LoadDyn_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
void LoadDyn_x86_32(int fd,
Tasking::PCB *TargetProcess);
ELFBaseLoad LoadDyn_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
void LoadDyn_x86_64(int fd,
Tasking::PCB *TargetProcess);
bool LoadInterpreter(int fd,
Tasking::PCB *TargetProcess);
public:
ELFBaseLoad GetBaseLoadInfo() { return BaseLoadInfo; }
bool IsValid() { return BaseLoadInfo.Success; }
decltype(IsElfValid) &IsValid = IsElfValid;
decltype(ip) &InstructionPointer = ip;
decltype(ELFargv) &argv = ELFargv;
decltype(ELFenvp) &envp = ELFenvp;
decltype(Elfauxv) &auxv = Elfauxv;
ELFObject(char *AbsolutePath,
Tasking::PCB *TargetProcess,
bool IsLibrary = false);
const char **argv,
const char **envp);
~ELFObject();
};
/* Full binary size. */
BinaryType GetBinaryType(void *Image);
BinaryType GetBinaryType(const char *Path);
BinaryType GetBinaryType(char *Path);
SpawnData Spawn(char *Path, const char **argv, const char **envp);
ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp,
Tasking::TaskCompatibility Compatibility = Tasking::TaskCompatibility::Native);
void ELFInterpreterIPCThread(Tasking::PCB *TargetProcess,
std::string *TargetPath,
void *MemoryImage,
std::vector<const char *> *NeededLibraries);
int Spawn(char *Path, const char **argv, const char **envp,
Tasking::PCB *Parent = nullptr,
Tasking::TaskCompatibility Compatibility = Tasking::TaskCompatibility::Native);
bool ELFIs64(void *Header);
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header);
@ -147,44 +107,17 @@ namespace Execute
char *GetELFStringTable(Elf64_Ehdr *Header);
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset);
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name);
Elf64_Sym ELFLookupSymbol(VirtualFileSystem::File &ElfFile, const char *Name);
Elf64_Sym ELFLookupSymbol(int fd, const char *Name);
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector<Elf32_Phdr> ELFGetSymbolType_x86_32(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(int fd, SegmentTypes Tag);
std::vector<Elf32_Phdr> ELFGetSymbolType_x86_32(int fd, SegmentTypes Tag);
std::vector<Elf64_Shdr> ELFGetSections_x86_64(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector<Elf32_Shdr> ELFGetSections_x86_32(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector<Elf64_Shdr> ELFGetSections_x86_64(int fd, const char *SectionName);
std::vector<Elf32_Shdr> ELFGetSections_x86_32(int fd, const char *SectionName);
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(VirtualFileSystem::File &ElfFile, DynamicArrayTags Tag);
std::vector<Elf32_Dyn> ELFGetDynamicTag_x86_32(VirtualFileSystem::File &ElfFile, DynamicArrayTags Tag);
void CopyLOADSegments(VirtualFileSystem::File &ElfFile, uintptr_t HdrsBase, uintptr_t PhysicalBase);
void GetBaseAndSize(VirtualFileSystem::File &ElfFile, uintptr_t &Base, size_t &Size);
/**
* @brief Create a ELF Memory Image
*
* @param mem The memory manager to use
* @param vmm Memory::Virtual object to use
* @param ElfFile The ELF File
* @param Length Length of @p ElfFile
* @return The Memory Image (Physical and Virtual)
*/
MmImage ELFCreateMemoryImage(Memory::MemMgr *mem,
Memory::Virtual &vmm,
VirtualFileSystem::File &ElfFile,
size_t Length);
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem,
Memory::Virtual &vmm,
const char *Interpreter);
void LibraryManagerService();
bool AddLibrary(char *Identifier,
VirtualFileSystem::File &ExFile,
const Memory::Virtual &vmm = Memory::Virtual());
SharedLibrary GetLibrary(char *Identifier);
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(int fd, DynamicArrayTags Tag);
std::vector<Elf32_Dyn> ELFGetDynamicTag_x86_32(int fd, DynamicArrayTags Tag);
}
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__

View File

@ -19,203 +19,389 @@
#define __FENNIX_KERNEL_FILESYSTEM_H__
#include <types.h>
#include <smart_ptr.hpp>
#include <vector>
namespace VirtualFileSystem
{
#include <smart_ptr.hpp>
#include <lock.hpp>
#include <errno.h>
#include <vector>
#include <atomic>
#include <string>
#define FILENAME_LENGTH 256
#define PATH_MAX 256
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
struct Node;
#define S_IXOTH 0001
#define S_IWOTH 0002
#define S_IROTH 0004
#define S_IRWXO 0007
#define S_IXGRP 0010
#define S_IWGRP 0020
#define S_IRGRP 0040
#define S_IRWXG 0070
#define S_IXUSR 0100
#define S_IWUSR 0200
#define S_IRUSR 0400
#define S_IRWXU 0700
typedef size_t (*OperationMount)(const char *, unsigned long, const void *);
typedef size_t (*OperationUmount)(int);
typedef size_t (*OperationRead)(Node *node, size_t Size, uint8_t *Buffer);
typedef size_t (*OperationWrite)(Node *node, size_t Size, uint8_t *Buffer);
typedef void (*OperationOpen)(Node *node, uint8_t Mode, uint8_t Flags);
typedef void (*OperationClose)(Node *node);
typedef size_t (*OperationSync)(void);
typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength);
typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength);
typedef size_t (*OperationSeek)(Node *node, size_t Offset, uint8_t Whence);
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100
#define O_EXCL 0200
#define O_TRUNC 01000
#define O_APPEND 02000
#define O_CLOEXEC 02000000
#define MountFSFunction(name) size_t name(const char *unknown0, unsigned long unknown1, const uint8_t *unknown2)
#define UMountFSFunction(name) size_t name(int unknown0)
#define S_IFIFO 0010000
#define S_IFCHR 0020000
#define S_IFDIR 0040000
#define S_IFBLK 0060000
#define S_IFREG 0100000
#define S_IFLNK 0120000
#define S_IFSOCK 0140000
#define ReadFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Size, uint8_t *Buffer)
#define WriteFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Size, uint8_t *Buffer)
#define OpenFSFunction(name) void name(VirtualFileSystem::Node *node, uint8_t Mode, uint8_t Flags)
#define CloseFSFunction(name) void name(VirtualFileSystem::Node *node)
#define SyncFSFunction(name) size_t name(void)
#define CreateFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
#define MkdirFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
#define SeekFSFunction(name) off_t name(VirtualFileSystem::Node *node, off_t Offset, uint8_t Whence)
#define S_IFMT 0170000
enum FileStatus
{
OK,
NotFound,
NotEmpty,
NotSupported,
AccessDenied,
Timeout,
SectorNotFound,
PartiallyCompleted,
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK)
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO)
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK)
InvalidName,
InvalidParameter,
InvalidHandle,
InvalidPath,
InvalidDevice,
InvalidOperator,
InvalidNode,
struct stat
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
FileExists,
FileIsADirectory,
FileIsInvalid,
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
blksize_t st_blksize;
blkcnt_t st_blocks;
mode_t st_attr;
};
DirectoryNotEmpty,
NotADirectory,
struct stat64
{
dev_t st_dev;
ino64_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off64_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
blksize_t st_blksize;
blkcnt64_t st_blocks;
mode_t st_attr;
};
UnknownFileStatusError
};
static inline int ConvertFileFlags(const char *Mode)
{
int Flags = 0;
enum NodeFlags
{
NODE_FLAG_ERROR = 0x0,
FILE = 0x01,
DIRECTORY = 0x02,
CHARDEVICE = 0x03,
BLOCKDEVICE = 0x04,
PIPE = 0x05,
SYMLINK = 0x06,
MOUNTPOINT = 0x08
};
if (strchr(Mode, '+'))
Flags |= O_RDWR;
else if (*Mode == 'r')
Flags |= O_RDONLY;
else
Flags |= O_WRONLY;
struct FileSystemOperations
{
char Name[FILENAME_LENGTH];
OperationMount Mount = nullptr;
OperationUmount Umount = nullptr;
OperationRead Read = nullptr;
OperationWrite Write = nullptr;
OperationOpen Open = nullptr;
OperationClose Close = nullptr;
OperationCreate Create = nullptr;
OperationMkdir MakeDirectory = nullptr;
OperationSeek Seek = nullptr;
};
if (strchr(Mode, 'x'))
Flags |= O_EXCL;
struct Node
{
char Name[FILENAME_LENGTH];
uint64_t IndexNode = 0;
uint64_t Mask = 0;
uint64_t Mode = 0;
NodeFlags Flags = NodeFlags::NODE_FLAG_ERROR;
uint64_t UserIdentifier = 0, GroupIdentifier = 0;
uintptr_t Address = 0;
size_t Length = 0;
off_t Offset = 0;
Node *Parent = nullptr;
FileSystemOperations *Operator = nullptr;
/* For root node:
0 - root "/"
1 - etc
...
*/
std::vector<Node *> Children;
};
if (strchr(Mode, 'e'))
Flags |= O_CLOEXEC;
struct File
{
char Name[FILENAME_LENGTH];
FileStatus Status;
bool IsOK()
{
return Status == FileStatus::OK;
}
if (*Mode != 'r')
Flags |= O_CREAT;
size_t GetLength()
{
return node->Length;
}
if (*Mode == 'w')
Flags |= O_TRUNC;
std::vector<Node *> GetChildren()
{
return node->Children;
}
if (*Mode == 'a')
Flags |= O_APPEND;
NodeFlags GetFlags()
{
return node->Flags;
}
/** @brief Special cases only. */
Node *GetNode()
{
return node;
}
private:
Node *node;
off_t ContextOffset;
friend class Virtual;
};
/* Manage / etc.. */
class Virtual
{
private:
Node *FileSystemRoot = nullptr;
public:
std::shared_ptr<char> GetPathFromNode(Node *node);
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
/**
* @brief Convert a Node to a File
*
* @param node Node to convert
* @return Converted node
*/
File ConvertNodeToFILE(Node *node);
bool PathIsRelative(const char *Path);
Node *GetParent(const char *Path, Node *Parent);
Node *GetRootNode() { return FileSystemRoot; }
Node *AddNewChild(const char *Name, Node *Parent);
Node *GetChild(const char *Name, Node *Parent);
FileStatus RemoveChild(const char *Name, Node *Parent);
std::shared_ptr<char> NormalizePath(const char *Path, Node *Parent = nullptr);
bool PathExists(const char *Path, Node *Parent = nullptr);
Node *CreateRoot(const char *RootName, FileSystemOperations *Operator);
Node *Create(const char *Path, NodeFlags Flag, Node *Parent = nullptr);
FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
File Mount(const char *Path, FileSystemOperations *Operator);
FileStatus Unmount(File &File);
size_t Read(File &File, uint8_t *Buffer, size_t Size);
size_t Write(File &File, uint8_t *Buffer, size_t Size);
off_t Seek(File &File, off_t Offset, uint8_t Whence);
File Open(const char *Path, Node *Parent = nullptr);
FileStatus Close(File &File);
Virtual();
~Virtual();
};
return Flags;
}
namespace VirtualFileSystem
{
struct Node;
typedef std::size_t (*OperationRead)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset);
typedef std::size_t (*OperationWrite)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset);
typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset);
typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset);
typedef std::size_t (*OperationSeek)(Node *node, std::size_t Offset, int Whence, off_t &RefOffset);
#define ReadFSFunction(name) \
std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset)
#define WriteFSFunction(name) \
std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset)
#define CreateFSFunction(name) \
void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset)
#define MkdirFSFunction(name) \
void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset)
#define SeekFSFunction(name) \
off_t name(VirtualFileSystem::Node *node, off_t Offset, uint8_t Whence, off_t &RefOffset)
enum NodeFlags
{
NODE_FLAG_ERROR = 0x0,
FILE = S_IFREG,
DIRECTORY = S_IFDIR,
CHARDEVICE = S_IFCHR,
BLOCKDEVICE = S_IFBLK,
PIPE = S_IFIFO,
SYMLINK = S_IFLNK,
MOUNTPOINT = S_IFDIR
};
struct FileSystemOperations
{
/**
* Name of the filesystem operations
*
* @note Mandatory
*/
char Name[FILENAME_LENGTH];
/**
* Pointer to the read function
*
* @note Mandatory
*/
OperationRead Read = nullptr;
/**
* Pointer to the write function
*
* @note Mandatory
*/
OperationWrite Write = nullptr;
/**
* Pointer to the create function
*
* @note Optional
*/
OperationCreate Create = nullptr;
/**
* Pointer to the mkdir function
*
* @note Optional
*/
OperationMkdir MakeDirectory = nullptr;
/**
* Pointer to the seek function
*
* @note Optional
*/
OperationSeek Seek = nullptr;
};
#define RefNode VirtualFileSystem::ReferenceNode
class ReferenceNode
{
private:
std::atomic_int64_t Offset = 0;
off_t FileSize = 0;
NewLock(RefNodeLock);
Node *node;
RefNode *SymlinkTo;
public:
decltype(FileSize) &Length = FileSize;
Node *GetNode() const { return node; }
std::string AbsolutePath;
size_t Read(uint8_t *Buffer, size_t Size);
size_t Write(uint8_t *Buffer, size_t Size);
off_t Seek(off_t Offset, int Whence);
ReferenceNode(Node *node);
~ReferenceNode();
friend class Virtual;
friend class FileDescriptorTable;
};
class Node
{
private:
NewLock(NodeLock);
public:
class Virtual *FileSystem = nullptr;
ino_t IndexNode = 0;
const char *Name;
const char *Symlink;
Node *SymlinkTarget = nullptr;
mode_t Mode = 0;
NodeFlags Flags = NodeFlags::NODE_FLAG_ERROR;
uid_t UserIdentifier = 0;
gid_t GroupIdentifier = 0;
uintptr_t Address = 0;
off_t Length = 0;
Node *Parent = nullptr;
FileSystemOperations *Operator = nullptr;
/* For root node:
0 - root "/"
1 - etc
...
*/
std::vector<Node *> Children;
/**
* References to this node (open files, etc..)
*/
std::vector<ReferenceNode *> References;
/**
* Create a new reference to this node
* @return Pointer to the new reference
*/
ReferenceNode *CreateReference();
/**
* Remove a reference to this node
* @param Reference Pointer to the reference to remove
*/
void RemoveReference(ReferenceNode *Reference);
Node() {}
~Node() {}
};
class Virtual
{
private:
Node *FileSystemRoot = nullptr;
NewLock(VirtualLock);
/**
* @note This function is NOT thread safe
*/
Node *AddNewChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
Node *GetChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
int RemoveChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
Node *GetParent(const char *Path, Node *Parent);
/**
* @note This function is NOT thread safe
*/
Node *GetNodeFromPath_Unsafe(const char *Path, Node *Parent = nullptr);
public:
std::string GetPathFromNode(Node *node);
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
bool PathIsRelative(const char *Path);
Node *GetRootNode() { return FileSystemRoot; }
std::string NormalizePath(const char *Path, Node *Parent = nullptr);
bool PathExists(const char *Path, Node *Parent = nullptr);
Node *CreateRoot(const char *RootName, FileSystemOperations *Operator);
Node *Create(const char *Path, NodeFlags Flag, Node *Parent = nullptr);
int Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
int Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
Node *Mount(const char *Path, FileSystemOperations *Operator);
int Unmount(Node *File);
/**
* Open a file
* @param Path The path to the file, relative or absolute. The buffer shouldn't be modified while the function is running.
* @param Parent Pointer to the parent node, if nullptr, the root node will be used.
* @return A pointer to the VirtualFileSystem::ReferenceNode, or nullptr if the file doesn't exist.
*/
RefNode *Open(const char *Path, Node *Parent = nullptr);
Virtual();
~Virtual();
};
class FileDescriptorTable
{
public:
struct FileDescriptor
{
RefNode *Handle{};
mode_t Mode = 0;
int Flags = 0;
int Descriptor = -1;
};
private:
std::vector<FileDescriptor> FileDescriptors;
VirtualFileSystem::Node *fdDir = nullptr;
FileDescriptor GetFileDescriptor(int FileDescriptor);
int ProbeMode(mode_t Mode, int Flags);
int AddFileDescriptor(const char *AbsolutePath, mode_t Mode, int Flags);
int RemoveFileDescriptor(int FileDescriptor);
int GetFreeFileDescriptor();
public:
std::string GetAbsolutePath(int FileDescriptor);
std::vector<FileDescriptor> &GetFileDescriptors() { return FileDescriptors; }
int _open(const char *pathname, int flags, mode_t mode);
int _creat(const char *pathname, mode_t mode);
ssize_t _read(int fd, void *buf, size_t count);
ssize_t _write(int fd, const void *buf, size_t count);
int _close(int fd);
off_t _lseek(int fd, off_t offset, int whence);
int _stat(const char *pathname, struct stat *statbuf);
int _fstat(int fd, struct stat *statbuf);
int _lstat(const char *pathname, struct stat *statbuf);
FileDescriptorTable(void *Owner);
~FileDescriptorTable();
};
}
int fopen(const char *pathname, const char *mode);
int creat(const char *pathname, mode_t mode);
ssize_t fread(int fd, void *buf, size_t count);
ssize_t fwrite(int fd, const void *buf, size_t count);
int fclose(int fd);
off_t lseek(int fd, off_t offset, int whence);
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
#endif // !__FENNIX_KERNEL_FILESYSTEM_H__

View File

@ -1,414 +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/>.
*/
#ifndef __FENNIX_KERNEL_GUI_H__
#define __FENNIX_KERNEL_GUI_H__
#include <types.h>
#include <display.hpp>
#include <memory.hpp>
#include <debug.h>
#include <vector>
namespace GraphicalUserInterface
{
typedef uintptr_t Handle;
struct MouseData
{
size_t X;
size_t Y;
size_t Z;
bool Left;
bool Right;
bool Middle;
};
struct ScreenBitmap
{
size_t Width;
size_t Height;
size_t Size;
size_t Pitch;
uint64_t BitsPerPixel;
uint8_t *Data;
};
struct Rect
{
int64_t Left;
int64_t Top;
size_t Width;
size_t Height;
bool Contains(int64_t X, int64_t Y)
{
return (X >= Left &&
X <= Left + (int64_t)Width &&
Y >= Top &&
Y <= Top + (int64_t)Height);
}
bool Contains(Rect rect)
{
return (rect.Left >= Left &&
rect.Left + rect.Width <= Left + Width &&
rect.Top >= Top &&
rect.Top + rect.Height <= Top + Height);
}
};
enum CursorType
{
Visible = 0,
Hidden,
Arrow,
Hand,
Wait,
IBeam,
ResizeHorizontal,
ResizeVertical,
ResizeDiagonalLeft,
ResizeDiagonalRight,
ResizeAll,
Cross,
Help,
No,
AppStarting,
};
struct Event
{
struct
{
size_t Width;
size_t Height;
} Resize;
struct
{
size_t X;
size_t Y;
bool Left;
bool Right;
bool Middle;
} MouseDown;
struct
{
size_t X;
size_t Y;
bool Left;
bool Right;
bool Middle;
} MouseUp;
struct
{
size_t X;
size_t Y;
bool Left;
bool Right;
bool Middle;
} MouseMove;
};
/*
virtual void OnMouseMove(Event *e) {}
virtual void OnMouseClick(Event *e) {}
virtual void OnMouseDoubleClick(Event *e) {}
virtual void OnMouseDown(Event *e) {}
virtual void OnMouseUp(Event *e) {}
virtual void OnMouseWheel(Event *e) {}
virtual void OnMouseEnter(Event *e) {}
virtual void OnMouseLeave(Event *e) {}
virtual void OnMouseHover(Event *e) {}
virtual void OnMouseDrag(Event *e) {}
virtual void OnMouseDragStart(Event *e) {}
virtual void OnMouseDragEnd(Event *e) {}
virtual void OnMouseDragEnter(Event *e) {}
virtual void OnMouseDragLeave(Event *e) {}
virtual void OnMouseDragHover(Event *e) {}
virtual void OnMouseDragDrop(Event *e) {}
virtual void OnMouseDragDropEnter(Event *e) {}
virtual void OnMouseDragDropLeave(Event *e) {}
virtual void OnMouseDragDropHover(Event *e) {}
virtual void OnMouseDragDropEnd(Event *e) {}
virtual void OnMouseDragDropStart(Event *e) {}
virtual void OnMouseDragDropCancel(Event *e) {}
virtual void OnMouseDragDropComplete(Event *e) {}
virtual void OnMouseDragDropAbort(Event *e) {}
virtual void OnKeyDown(Event *e) {}
virtual void OnKeyUp(Event *e) {}
virtual void OnKeyPress(Event *e) {}
virtual void OnFocusEnter(Event *e) {}
virtual void OnFocusLeave(Event *e) {}
virtual void OnFocusHover(Event *e) {}
virtual void OnResize(Event *e) {}
virtual void OnMinimize(Event *e) {}
virtual void OnMaximize(Event *e) {}
virtual void OnMove(Event *e) {}
virtual void OnShow(Event *e) {}
virtual void OnHide(Event *e) {}
virtual void OnClose(Event *e) {}
virtual void OnDestroy(Event *e) {}
virtual void OnPaint(Event *e) {}
virtual void OnPaintBackground(Event *e) {}
virtual void OnPaintForeground(Event *e) {}
virtual void OnPaintOverlay(Event *e) {}
virtual void OnPaintAll(Event *e) {}
virtual void OnPaintChildren(Event *e) {}
virtual void OnPaintChildrenBackground(Event *e) {}
virtual void OnPaintChildrenForeground(Event *e) {}
virtual void OnPaintChildrenBorder(Event *e) {}
virtual void OnPaintChildrenShadow(Event *e) {}
virtual void OnPaintChildrenOverlay(Event *e) {}
virtual void OnPaintChildrenAll(Event *e) {}
*/
void SetPixel(ScreenBitmap *Bitmap, size_t X, size_t Y, uint32_t Color);
void DrawOverBitmap(ScreenBitmap *DestinationBitmap,
ScreenBitmap *SourceBitmap,
int64_t Top,
int64_t Left,
bool IgnoreZero = true);
void PutRect(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
void PutBorder(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
uint32_t BlendColors(uint32_t c1, uint32_t c2, float t);
void PutBorderWithShadow(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
void DrawShadow(ScreenBitmap *Bitmap, Rect rect);
void PaintChar(Video::Font *font, ScreenBitmap *Bitmap, char c, uint32_t Color, int64_t *CharCursorX, int64_t *CharCursorY);
void DrawString(ScreenBitmap *Bitmap, Rect rect, const char *Text, uint32_t Color);
class WidgetCollection
{
private:
Memory::MemMgr *mem;
ScreenBitmap *Buffer;
Video::Font *CurrentFont;
void *ParentWindow;
bool NeedRedraw;
struct HandleMeta
{
char Type[4];
};
struct LabelObject
{
HandleMeta Handle;
Rect rect;
char Text[512];
uint32_t Color;
int64_t CharCursorX, CharCursorY;
};
struct PanelObject
{
HandleMeta Handle;
Rect rect;
uint32_t Color;
uint32_t BorderColor;
uint32_t ShadowColor;
bool Shadow;
};
struct ButtonObject
{
HandleMeta Handle;
Rect rect;
char Text[512];
uint32_t Color;
uint32_t HoverColor;
uint32_t PressedColor;
uint32_t BorderColor;
uint32_t ShadowColor;
int64_t CharCursorX, CharCursorY;
bool Shadow;
bool Hover;
bool Pressed;
uintptr_t OnClick;
};
std::vector<LabelObject *> Labels;
std::vector<PanelObject *> Panels;
std::vector<ButtonObject *> Buttons;
public:
void ReplaceFont(Video::Font *NewFont)
{
delete this->CurrentFont;
this->CurrentFont = NewFont;
}
Handle CreatePanel(Rect rect, uint32_t Color);
Handle CreateButton(Rect rect, const char *Text, uintptr_t OnClick = (uintptr_t) nullptr);
Handle CreateLabel(Rect rect, const char *Text);
Handle CreateTextBox(Rect rect, const char *Text);
Handle CreateCheckBox(Rect rect, const char *Text);
Handle CreateRadioButton(Rect rect, const char *Text);
Handle CreateComboBox(Rect rect, const char *Text);
Handle CreateListBox(Rect rect, const char *Text);
Handle CreateProgressBar(Rect rect, const char *Text);
Handle CreateContextMenu(Rect rect, const char *Text);
void SetText(Handle handle, const char *Text);
WidgetCollection(void /* Window */ *ParentWindow);
~WidgetCollection();
void OnMouseMove(Event *e);
void OnMouseClick(Event *e);
void OnMouseDoubleClick(Event *e);
void OnMouseDown(Event *e);
void OnMouseUp(Event *e);
void OnMouseWheel(Event *e);
void OnMouseEnter(Event *e);
void OnMouseLeave(Event *e);
void OnMouseHover(Event *e);
void OnMouseDrag(Event *e);
void OnMouseDragStart(Event *e);
void OnMouseDragEnd(Event *e);
void OnKeyDown(Event *e);
void OnKeyUp(Event *e);
void OnKeyPress(Event *e);
void OnShow(Event *e);
void OnHide(Event *e);
void OnDestroy(Event *e);
void OnPaint(Event *e);
void OnPaintBackground(Event *e);
void OnPaintForeground(Event *e);
};
class Window
{
private:
Memory::MemMgr *mem;
ScreenBitmap *Buffer;
Rect Position;
Rect LastPosition;
char Title[256];
std::vector<WidgetCollection *> Widgets;
void *ParentGUI;
bool Maximized;
bool Minimized;
public:
bool IsMaximized() { return Maximized; }
bool IsMinimized() { return Minimized; }
ScreenBitmap *GetBuffer() { return Buffer; }
Rect GetPosition() { return Position; }
Rect *GetPositionPtr() { return &Position; }
const char *GetTitle() { return (const char *)Title; }
void SetTitle(const char *Title) { strcpy(this->Title, Title); }
void AddWidget(WidgetCollection *widget);
Window(void *ParentGUI, Rect rect, const char *Title);
~Window();
void OnMouseMove(Event *e);
void OnMouseClick(Event *e);
void OnMouseDoubleClick(Event *e);
void OnMouseDown(Event *e);
void OnMouseUp(Event *e);
void OnMouseWheel(Event *e);
void OnMouseEnter(Event *e);
void OnMouseLeave(Event *e);
void OnMouseHover(Event *e);
void OnMouseDrag(Event *e);
void OnMouseDragStart(Event *e);
void OnMouseDragEnd(Event *e);
void OnKeyDown(Event *e);
void OnKeyUp(Event *e);
void OnKeyPress(Event *e);
void OnFocusEnter(Event *e);
void OnFocusLeave(Event *e);
void OnFocusHover(Event *e);
void OnResize(Event *e);
void OnMinimize(Event *e);
void OnMaximize(Event *e);
void OnMove(Event *e);
void OnShow(Event *e);
void OnHide(Event *e);
void OnClose(Event *e);
void OnDestroy(Event *e);
void OnPaint(Event *e);
void OnPaintBackground(Event *e);
void OnPaintForeground(Event *e);
void OnPaintOverlay(Event *e);
void OnPaintAll(Event *e);
void OnPaintChildren(Event *e);
void OnPaintChildrenBackground(Event *e);
void OnPaintChildrenForeground(Event *e);
void OnPaintChildrenBorder(Event *e);
void OnPaintChildrenShadow(Event *e);
void OnPaintChildrenOverlay(Event *e);
void OnPaintChildrenAll(Event *e);
};
class GUI
{
private:
MouseData MouseArray[256];
Memory::MemMgr *mem;
Video::Font *CurrentFont;
Rect Desktop;
ScreenBitmap *BackBuffer;
ScreenBitmap *DesktopBuffer;
ScreenBitmap *OverlayBuffer;
ScreenBitmap *CursorBuffer;
std::vector<WidgetCollection *> Widgets;
std::vector<Window *> Windows;
CursorType Cursor = CursorType::Arrow;
CursorType LastCursor = CursorType::Arrow;
bool CursorVisible = true;
bool IsRunning = false;
bool DesktopBufferRepaint = true;
bool OverlayBufferRepaint = true;
bool OverlayFullRepaint = true;
bool CursorBufferRepaint = true;
void FetchInputs();
void PaintDesktop();
void PaintWidgets();
void PaintWindows();
void PaintCursor();
public:
void SetCursorType(CursorType Type = CursorType::Visible) { this->Cursor = Type; }
void Loop();
void AddWindow(Window *window);
void AddWidget(WidgetCollection *widget);
GUI();
~GUI();
};
}
#endif // !__FENNIX_KERNEL_GUI_H__

View File

@ -26,204 +26,204 @@
extern "C"
{
#endif
static inline uint8_t inportb(uint16_t Port)
{
uint8_t Result;
asm("in %%dx, %%al"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint8_t inportb(uint16_t Port)
{
uint8_t Result;
asm("in %%dx, %%al"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint16_t inportw(uint16_t Port)
{
uint16_t Result;
asm("in %%dx, %%ax"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint16_t inportw(uint16_t Port)
{
uint16_t Result;
asm("in %%dx, %%ax"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint32_t inportl(uint16_t Port)
{
uint32_t Result;
asmv("inl %1, %0"
: "=a"(Result)
: "dN"(Port));
return Result;
}
static inline uint32_t inportl(uint16_t Port)
{
uint32_t Result;
asmv("inl %1, %0"
: "=a"(Result)
: "dN"(Port));
return Result;
}
static inline void outportb(uint16_t Port, uint8_t Data)
{
asmv("out %%al, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportb(uint16_t Port, uint8_t Data)
{
asmv("out %%al, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportw(uint16_t Port, uint16_t Data)
{
asmv("out %%ax, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportw(uint16_t Port, uint16_t Data)
{
asmv("out %%ax, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportl(uint16_t Port, uint32_t Data)
{
asmv("outl %1, %0"
:
: "dN"(Port), "a"(Data));
}
static inline void outportl(uint16_t Port, uint32_t Data)
{
asmv("outl %1, %0"
:
: "dN"(Port), "a"(Data));
}
static inline uint8_t mmioin8(uint64_t Address)
{
asmv("" ::
: "memory");
uint8_t Result = *(volatile uint8_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint8_t mmioin8(uint64_t Address)
{
asmv("" ::
: "memory");
uint8_t Result = *(volatile uint8_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint16_t mmioin16(uint64_t Address)
{
asmv("" ::
: "memory");
uint16_t Result = *(volatile uint16_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint16_t mmioin16(uint64_t Address)
{
asmv("" ::
: "memory");
uint16_t Result = *(volatile uint16_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint32_t mmioin32(uint64_t Address)
{
asmv("" ::
: "memory");
uint32_t Result = *(volatile uint32_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint32_t mmioin32(uint64_t Address)
{
asmv("" ::
: "memory");
uint32_t Result = *(volatile uint32_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint64_t mmioin64(uint64_t Address)
{
asmv("" ::
: "memory");
uint64_t Result = *(volatile uint64_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint64_t mmioin64(uint64_t Address)
{
asmv("" ::
: "memory");
uint64_t Result = *(volatile uint64_t *)(uintptr_t)Address;
asmv("" ::
: "memory");
return Result;
}
static inline void mmioout8(uint64_t Address, uint8_t Data)
{
asmv("" ::
: "memory");
*(volatile uint8_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout8(uint64_t Address, uint8_t Data)
{
asmv("" ::
: "memory");
*(volatile uint8_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout16(uint64_t Address, uint16_t Data)
{
asmv("" ::
: "memory");
*(volatile uint16_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout16(uint64_t Address, uint16_t Data)
{
asmv("" ::
: "memory");
*(volatile uint16_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout32(uint64_t Address, uint32_t Data)
{
asmv("" ::
: "memory");
*(volatile uint32_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout32(uint64_t Address, uint32_t Data)
{
asmv("" ::
: "memory");
*(volatile uint32_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout64(uint64_t Address, uint64_t Data)
{
asmv("" ::
: "memory");
*(volatile uint64_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout64(uint64_t Address, uint64_t Data)
{
asmv("" ::
: "memory");
*(volatile uint64_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmoutb(void *Address, uint8_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint8_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutb(void *Address, uint8_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint8_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutw(void *Address, uint16_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint16_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutw(void *Address, uint16_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint16_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutl(void *Address, uint32_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint32_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutl(void *Address, uint32_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint32_t *)(Address)))
: "r"(Value)
: "memory");
}
#if defined(a64)
static inline void mmoutq(void *Address, uint64_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint64_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutq(void *Address, uint64_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint64_t *)(Address)))
: "r"(Value)
: "memory");
}
#endif
static inline uint8_t mminb(void *Address)
{
uint8_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint8_t *)(Address)))
: "memory");
return Result;
}
static inline uint8_t mminb(void *Address)
{
uint8_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint8_t *)(Address)))
: "memory");
return Result;
}
static inline uint16_t mminw(void *Address)
{
uint16_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint16_t *)(Address)))
: "memory");
return Result;
}
static inline uint16_t mminw(void *Address)
{
uint16_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint16_t *)(Address)))
: "memory");
return Result;
}
static inline uint32_t mminl(void *Address)
{
uint32_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint32_t *)(Address)))
: "memory");
return Result;
}
static inline uint32_t mminl(void *Address)
{
uint32_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint32_t *)(Address)))
: "memory");
return Result;
}
#if defined(a64)
static inline uint64_t mminq(void *Address)
{
uint64_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint64_t *)(Address)))
: "memory");
return Result;
}
static inline uint64_t mminq(void *Address)
{
uint64_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint64_t *)(Address)))
: "memory");
return Result;
}
#endif
#ifdef __cplusplus
}

View File

@ -21,12 +21,19 @@
#include <types.h>
#include <memory.hpp>
enum KCSchedType
{
Mono = 0,
Multi = 1,
};
struct KernelConfig
{
Memory::MemoryAllocatorType AllocatorType;
bool SchedulerType;
char DriverDirectory[256];
char InitPath[256];
bool UseLinuxSyscalls;
bool InterruptsOnCrash;
int Cores;
int IOAPICInterruptCore;

View File

@ -20,6 +20,6 @@
#include <types.h>
void StartKernelShell();
void KShellThread();
#endif // !__FENNIX_KERNEL_KERNEL_SHELL_H__

View File

@ -39,121 +39,158 @@ size_t GetLocksCount();
class LockClass
{
public:
struct SpinLockData
{
std::atomic_uint64_t LockData = 0x0;
std::atomic<const char *> CurrentHolder = "(nul)";
std::atomic<const char *> AttemptingToGet = "(nul)";
std::atomic_uintptr_t StackPointerHolder = 0;
std::atomic_uintptr_t StackPointerAttempt = 0;
std::atomic_size_t Count = 0;
std::atomic_long Core = 0;
};
struct SpinLockData
{
std::atomic_uint64_t LockData = 0x0;
std::atomic<const char *> CurrentHolder = "(nul)";
std::atomic<const char *> AttemptingToGet = "(nul)";
std::atomic_uintptr_t StackPointerHolder = 0;
std::atomic_uintptr_t StackPointerAttempt = 0;
std::atomic_size_t Count = 0;
std::atomic_long Core = 0;
};
private:
SpinLockData LockData;
std::atomic_bool IsLocked = false;
std::atomic_ulong DeadLocks = 0;
SpinLockData LockData;
std::atomic_bool IsLocked = false;
std::atomic_ulong DeadLocks = 0;
void DeadLock(SpinLockData Lock);
void TimeoutDeadLock(SpinLockData Lock, uint64_t Timeout);
void DeadLock(SpinLockData &Lock);
void TimeoutDeadLock(SpinLockData &Lock, uint64_t Timeout);
void Yield();
public:
SpinLockData *GetLockData() { return &LockData; }
int Lock(const char *FunctionName);
int Unlock();
SpinLockData *GetLockData() { return &LockData; }
int Lock(const char *FunctionName);
int Unlock();
int TimeoutLock(const char *FunctionName, uint64_t Timeout);
int TimeoutLock(const char *FunctionName, uint64_t Timeout);
};
/** @brief Please use this macro to create a new smart lock. */
class SmartLockClass
{
private:
LockClass *LockPointer = nullptr;
LockClass *LockPointer = nullptr;
public:
SmartLockClass(LockClass &Lock, const char *FunctionName)
{
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockClass() { this->LockPointer->Unlock(); }
SmartLockClass(LockClass &Lock, const char *FunctionName)
{
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockClass() { this->LockPointer->Unlock(); }
};
class SmartTimeoutLockClass
{
private:
LockClass *LockPointer = nullptr;
LockClass *LockPointer = nullptr;
public:
SmartTimeoutLockClass(LockClass &Lock, const char *FunctionName, uint64_t Timeout)
{
this->LockPointer = &Lock;
this->LockPointer->TimeoutLock(FunctionName, Timeout);
}
~SmartTimeoutLockClass() { this->LockPointer->Unlock(); }
SmartTimeoutLockClass(LockClass &Lock,
const char *FunctionName,
uint64_t Timeout)
{
this->LockPointer = &Lock;
this->LockPointer->TimeoutLock(FunctionName, Timeout);
}
~SmartTimeoutLockClass()
{
this->LockPointer->Unlock();
}
};
/** @brief Please use this macro to create a new smart critical section lock. */
class SmartLockCriticalSectionClass
{
private:
LockClass *LockPointer = nullptr;
bool InterruptsEnabled = false;
LockClass *LockPointer = nullptr;
bool InterruptsEnabled = false;
public:
SmartLockCriticalSectionClass(LockClass &Lock, const char *FunctionName)
{
if (CPU::Interrupts(CPU::Check))
InterruptsEnabled = true;
CPU::Interrupts(CPU::Disable);
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockCriticalSectionClass()
{
this->LockPointer->Unlock();
if (InterruptsEnabled)
CPU::Interrupts(CPU::Enable);
}
SmartLockCriticalSectionClass(LockClass &Lock,
const char *FunctionName)
{
if (CPU::Interrupts(CPU::Check))
InterruptsEnabled = true;
CPU::Interrupts(CPU::Disable);
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockCriticalSectionClass()
{
this->LockPointer->Unlock();
if (InterruptsEnabled)
CPU::Interrupts(CPU::Enable);
}
};
/** @brief Please use this macro to create a new critical section. */
class SmartCriticalSectionClass
{
private:
bool InterruptsEnabled = false;
bool InterruptsEnabled = false;
public:
bool IsInterruptsEnabled() { return InterruptsEnabled; }
bool IsInterruptsEnabled()
{
return InterruptsEnabled;
}
SmartCriticalSectionClass()
{
if (CPU::Interrupts(CPU::Check))
InterruptsEnabled = true;
CPU::Interrupts(CPU::Disable);
}
~SmartCriticalSectionClass()
{
if (InterruptsEnabled)
CPU::Interrupts(CPU::Enable);
}
SmartCriticalSectionClass()
{
if (CPU::Interrupts(CPU::Check))
InterruptsEnabled = true;
CPU::Interrupts(CPU::Disable);
}
~SmartCriticalSectionClass()
{
if (InterruptsEnabled)
CPU::Interrupts(CPU::Enable);
}
};
/** @brief Create a new lock (can be used with SmartCriticalSection). */
/**
* Create a new lock
*
* @note Can be used with SmartCriticalSection
*/
#define NewLock(Name) LockClass Name
/** @brief Simple lock that is automatically released when the scope ends. */
#define SmartLock(LockClassName) SmartLockClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__)
/**
* Simple lock that is automatically released
* when the scope ends.
*/
#define SmartLock(LockClassName) \
SmartLockClass \
CONCAT(lock##_, __COUNTER__)(LockClassName, \
__FUNCTION__)
/** @brief Simple lock with timeout that is automatically released when the scope ends. */
#define SmartTimeoutLock(LockClassName, Timeout) SmartTimeoutLockClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__, Timeout)
/**
* Simple lock with timeout that is automatically
* released when the scope ends.
*/
#define SmartTimeoutLock(LockClassName, Timeout) \
SmartTimeoutLockClass \
CONCAT(lock##_, __COUNTER__)(LockClassName, \
__FUNCTION__, \
Timeout)
/** @brief Simple critical section that is automatically released when the scope ends and interrupts are restored if they were enabled. */
#define SmartCriticalSection(LockClassName) SmartLockCriticalSectionClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__)
/**
* Simple critical section that is
* automatically released when the scope ends
* and interrupts are restored if they
* were enabled.
*/
#define SmartCriticalSection(LockClassName) \
SmartLockCriticalSectionClass \
CONCAT(lock##_, \
__COUNTER__)(LockClassName, \
__FUNCTION__)
/** @brief Automatically disable interrupts and restore them when the scope ends. */
/**
* Automatically disable interrupts and
* restore them when the scope ends.
*/
#define CriticalSection SmartCriticalSectionClass
#endif // __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,6 @@ namespace Power
void InitDSDT();
Power();
~Power();
};
}

View File

@ -127,6 +127,10 @@ RECENT REVISION HISTORY:
#ifndef STBI_INCLUDE_STB_IMAGE_H
#define STBI_INCLUDE_STB_IMAGE_H
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
// DOCUMENTATION
//
// Limitations:
@ -9142,6 +9146,8 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
return stbi__is_16_main(&s);
}
#pragma GCC diagnostic pop
#endif // STB_IMAGE_IMPLEMENTATION
/*

View File

@ -17,29 +17,31 @@
#pragma once
#include <types.h>
#include <vector>
namespace SymbolResolver
{
class Symbols
{
private:
struct SymbolTable
{
uintptr_t Address;
char *FunctionName;
};
class Symbols
{
private:
struct SymbolTable
{
uintptr_t Address = 0;
char *FunctionName = (char *)"<unknown>";
};
SymbolTable SymTable[0x10000];
int64_t TotalEntries = 0;
void *Image;
std::vector<SymbolTable> SymTable;
void *Image;
bool SymbolTableExists = false;
public:
int64_t GetTotalEntries() { return this->TotalEntries; }
void *GetImage() { return this->Image; }
const char *GetSymbolFromAddress(uintptr_t Address);
void AddSymbol(uintptr_t Address, const char *Name);
void AddBySymbolInfo(uint64_t Num, uint64_t EntSize, uint64_t Shndx, uintptr_t Sections);
Symbols(uintptr_t ImageAddress);
~Symbols();
};
public:
decltype(SymbolTableExists) &SymTableExists = this->SymbolTableExists;
void *GetImage() { return this->Image; }
const char *GetSymbolFromAddress(uintptr_t Address);
void AddSymbol(uintptr_t Address, const char *Name);
void AddSymbolInfoFromGRUB(uint64_t Num, uint64_t EntSize, uint64_t Shndx, uintptr_t Sections);
void AppendSymbols(uintptr_t ImageAddress, uintptr_t BaseAddress = 0);
Symbols(uintptr_t ImageAddress);
~Symbols();
};
}

View File

@ -32,14 +32,15 @@
namespace Tasking
{
/** @brief Instruction Pointer */
using VirtualFileSystem::FileDescriptorTable;
using VirtualFileSystem::Node;
/** Instruction Pointer */
typedef __UINTPTR_TYPE__ IP;
/** @brief Process ID */
/** Process ID */
typedef int PID;
/** @brief Thread ID */
/** Thread ID */
typedef int TID;
/* @brief Token */
typedef __UINTPTR_TYPE__ Token;
enum TaskArchitecture
{
@ -47,7 +48,10 @@ namespace Tasking
x32,
x64,
ARM32,
ARM64
ARM64,
_ArchitectureMin = UnknownArchitecture,
_ArchitectureMax = ARM64
};
enum TaskCompatibility
@ -55,26 +59,35 @@ namespace Tasking
UnknownPlatform,
Native,
Linux,
Windows
Windows,
_CompatibilityMin = UnknownPlatform,
_CompatibilityMax = Windows
};
enum TaskTrustLevel
enum TaskExecutionMode
{
UnknownElevation,
UnknownExecutionMode,
Kernel,
System,
User
User,
_ExecuteModeMin = UnknownExecutionMode,
_ExecuteModeMax = User
};
enum TaskStatus
enum TaskStatus : int
{
UnknownStatus,
Ready,
Running,
Sleeping,
Waiting,
Stopped,
Terminated
Blocked,
Zombie,
Terminated,
_StatusMin = UnknownStatus,
_StatusMax = Terminated
};
enum TaskPriority
@ -84,60 +97,81 @@ namespace Tasking
Low = 2,
Normal = 5,
High = 8,
Critical = 10
Critical = 10,
_PriorityMin = UnknownPriority,
_PriorityMax = Critical
};
enum KillErrorCodes : int
{
KILL_SCHEDULER_DESTRUCTION = -0xFFFF,
KILL_CXXABI_EXCEPTION = -0xECE97,
KILL_BY_OTHER_PROCESS = -0x7A55,
KILL_SYSCALL = -0xCA11,
KILL_CRASH = -0xDEAD,
KILL_OOM = -0x1008,
KILL_ERROR = -0x1,
KILL_SUCCESS = 0,
};
struct TaskSecurity
{
TaskTrustLevel TrustLevel;
Token UniqueToken;
bool IsCritical;
bool IsDebugEnabled;
bool IsKernelDebugEnabled;
};
struct TaskInfo
{
size_t OldUserTime = 0;
size_t OldKernelTime = 0;
uint64_t OldUserTime = 0;
uint64_t OldKernelTime = 0;
size_t SleepUntil = 0;
size_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0;
uint64_t Year, Month, Day, Hour, Minute, Second;
bool Affinity[256]; // MAX_CPU
TaskPriority Priority;
TaskArchitecture Architecture;
TaskCompatibility Compatibility;
uint64_t SleepUntil = 0;
uint64_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0;
uint64_t Year = 0, Month = 0, Day = 0, Hour = 0, Minute = 0, Second = 0;
bool Affinity[256] = {true}; // MAX_CPU
TaskPriority Priority = TaskPriority::Normal;
TaskArchitecture Architecture = TaskArchitecture::UnknownArchitecture;
TaskCompatibility Compatibility = TaskCompatibility::UnknownPlatform;
};
struct TCB
/**
* TCB struct for gs register
*/
struct gsTCB
{
/** @brief Used by syscall handler */
uintptr_t SyscallStack; /* gs+0x0 */
/**
* Used by syscall handler
*
* gs+0x0
*/
uintptr_t SyscallStack = __UINTPTR_MAX__;
/** @brief Used by syscall handler */
uintptr_t TempStack; /* gs+0x8 */
/**
* Used by syscall handler
*
* gs+0x8
*/
uintptr_t TempStack = __UINTPTR_MAX__;
TID ID;
char Name[256];
struct PCB *Parent;
IP EntryPoint;
int ExitCode;
/**
* The current thread class
*/
class TCB *t;
};
class TCB
{
private:
class Task *ctx = nullptr;
public:
TID ID = -1;
const char * Name = nullptr;
class PCB *Parent = nullptr;
IP EntryPoint = 0;
std::atomic_int ExitCode;
std::atomic<TaskStatus> Status = TaskStatus::UnknownStatus;
Memory::StackGuard *Stack;
Memory::MemMgr *Memory;
TaskStatus Status;
int ErrorNumber;
#if defined(a64)
CPU::x64::TrapFrame Registers;
CPU::x64::TrapFrame Registers{};
uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(a32)
CPU::x32::TrapFrame Registers; // TODO
@ -146,52 +180,25 @@ namespace Tasking
uintptr_t Registers; // TODO
#endif
uintptr_t IPHistory[128];
TaskSecurity Security;
TaskInfo Info;
struct
{
TaskExecutionMode ExecutionMode = UnknownExecutionMode;
bool IsCritical = false;
bool IsDebugEnabled = false;
bool IsKernelDebugEnabled = false;
} Security{};
TaskInfo Info{};
CPU::x64::FXState *FPU;
void Rename(const char *name)
{
CriticalSection cs;
if (strlen(name) > 256 || strlen(name) == 0)
{
debug("Invalid thread name");
return;
}
void Rename(const char *name);
void SetPriority(TaskPriority priority);
int GetExitCode() { return ExitCode.load(); }
void SetCritical(bool Critical);
void SetDebugMode(bool Enable);
void SetKernelDebugMode(bool Enable);
trace("Renaming thread %s to %s", Name, name);
strncpy(Name, name, 256);
}
void SetPriority(TaskPriority priority)
{
CriticalSection cs;
trace("Setting priority of thread %s to %d", Name, priority);
Info.Priority = priority;
}
int GetExitCode() { return ExitCode; }
void SetCritical(bool Critical)
{
CriticalSection cs;
trace("Setting criticality of thread %s to %s", Name, Critical ? "true" : "false");
Security.IsCritical = Critical;
}
void SetDebugMode(bool Enable)
{
CriticalSection cs;
trace("Setting debug mode of thread %s to %s", Name, Enable ? "true" : "false");
Security.IsDebugEnabled = Enable;
}
void SetKernelDebugMode(bool Enable)
{
CriticalSection cs;
trace("Setting kernel debug mode of thread %s to %s", Name, Enable ? "true" : "false");
Security.IsKernelDebugEnabled = Enable;
}
void Block() { Status.store(TaskStatus::Blocked); }
void Unblock() { Status.store(TaskStatus::Ready); }
void SYSV_ABI_Call(uintptr_t Arg1 = 0,
uintptr_t Arg2 = 0,
@ -199,92 +206,79 @@ namespace Tasking
uintptr_t Arg4 = 0,
uintptr_t Arg5 = 0,
uintptr_t Arg6 = 0,
void *Function = nullptr)
{
CriticalSection cs;
#if defined(a64)
this->Registers.rdi = Arg1;
this->Registers.rsi = Arg2;
this->Registers.rdx = Arg3;
this->Registers.rcx = Arg4;
this->Registers.r8 = Arg5;
this->Registers.r9 = Arg6;
if (Function != nullptr)
this->Registers.rip = (uint64_t)Function;
#else
#warning "SYSV ABI not implemented for this architecture"
#endif
}
void *Function = nullptr);
TCB(class Task *ctx,
PCB *Parent,
IP EntryPoint,
const char **argv = nullptr,
const char **envp = nullptr,
const std::vector<AuxiliaryVector> &auxv = std::vector<AuxiliaryVector>(),
TaskArchitecture Architecture = TaskArchitecture::x64,
TaskCompatibility Compatibility = TaskCompatibility::Native,
bool ThreadNotReady = false);
~TCB();
};
struct PCB
class PCB
{
PID ID;
char Name[256];
PCB *Parent;
int ExitCode;
TaskStatus Status;
TaskSecurity Security;
TaskInfo Info;
private:
class Task *ctx = nullptr;
bool OwnPageTable = false;
public:
PID ID = -1;
const char * Name = nullptr;
PCB *Parent = nullptr;
std::atomic_int ExitCode;
std::atomic<TaskStatus> Status = Zombie;
struct
{
TaskExecutionMode ExecutionMode = UnknownExecutionMode;
bool IsCritical = false;
bool IsDebugEnabled = false;
bool IsKernelDebugEnabled = false;
struct
{
uint16_t UserID = UINT16_MAX;
uint16_t GroupID = UINT16_MAX;
} Real, Effective;
} Security{};
TaskInfo Info{};
std::vector<TCB *> Threads;
std::vector<PCB *> Children;
InterProcessCommunication::IPC *IPC;
Memory::PageTable *PageTable;
SymbolResolver::Symbols *ELFSymbolTable;
VirtualFileSystem::Node *CurrentWorkingDirectory;
VirtualFileSystem::Node *ProcessDirectory;
VirtualFileSystem::Node *memDirectory;
void SetWorkingDirectory(VirtualFileSystem::Node *node)
{
CriticalSection cs;
trace("Setting working directory of process %s to %#lx (%s)", Name, node, node->Name);
CurrentWorkingDirectory = node;
}
};
/** @brief Token Trust Level */
enum TTL
{
UnknownTrustLevel = 0b0001,
Untrusted = 0b0010,
Trusted = 0b0100,
TrustedByKernel = 0b1000,
FullTrust = Trusted | TrustedByKernel,
AllFlags = 0b1111
};
class Security
{
private:
struct TokenData
{
Token token;
int TrustLevel;
uint64_t OwnerID;
bool Process;
};
std::vector<TokenData> Tokens;
Node *CurrentWorkingDirectory;
Node *ProcessDirectory;
Node *memDirectory;
Memory::MemMgr *Memory;
FileDescriptorTable *FileDescriptors;
public:
Token CreateToken();
bool TrustToken(Token token, TTL TrustLevel);
bool AddTrustLevel(Token token, TTL TrustLevel);
bool RemoveTrustLevel(Token token, TTL TrustLevel);
bool UntrustToken(Token token);
bool DestroyToken(Token token);
bool IsTokenTrusted(Token token, TTL TrustLevel);
bool IsTokenTrusted(Token token, int TrustLevel);
int GetTokenTrustLevel(Token token);
Security();
~Security();
void Rename(const char *name);
void SetWorkingDirectory(Node *node);
PCB(class Task *ctx,
PCB *Parent,
const char *Name,
TaskExecutionMode ExecutionMode,
void *Image = nullptr,
bool DoNotCreatePageTable = false,
uint16_t UserID = -1,
uint16_t GroupID = -1);
~PCB();
};
class Task : public Interrupts::Handler
{
private:
Security SecurityManager;
NewLock(SchedulerLock);
NewLock(TaskingLock);
PID NextPID = 0;
TID NextTID = 0;
@ -295,30 +289,76 @@ namespace Tasking
std::atomic_size_t SchedulerTicks = 0;
std::atomic_size_t LastTaskTicks = 0;
std::atomic_int LastCore = 0;
bool StopScheduler = false;
std::atomic_bool StopScheduler = false;
std::atomic_bool SchedulerUpdateTrapFrame = false;
bool InvalidPCB(PCB *pcb);
bool InvalidTCB(TCB *tcb);
/**
* @note This function is NOT thread safe
*/
void RemoveThread(TCB *tcb);
/**
* @note This function is NOT thread safe
*/
void RemoveProcess(PCB *pcb);
void UpdateUsage(TaskInfo *Info, TaskSecurity *Security, int Core);
void UpdateUsage(TaskInfo *Info,
TaskExecutionMode Mode,
int Core);
/**
* @note This function is NOT thread safe
*/
bool FindNewProcess(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool GetNextAvailableThread(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool GetNextAvailableProcess(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool SchedulerSearchProcessThread(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
void UpdateProcessStatus();
/**
* @note This function is NOT thread safe
*/
void WakeUpThreads();
#if defined(a64)
/**
* @note This function is NOT thread safe
*/
void Schedule(CPU::x64::TrapFrame *Frame);
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
#elif defined(a32)
/**
* @note This function is NOT thread safe
*/
void Schedule(void *Frame);
void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
#elif defined(aa64)
/**
* @note This function is NOT thread safe
*/
void Schedule(CPU::aarch64::TrapFrame *Frame);
void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame);
#endif
@ -328,42 +368,62 @@ namespace Tasking
size_t GetLastTaskTicks() { return LastTaskTicks.load(); }
int GetLastCore() { return LastCore.load(); }
std::vector<PCB *> GetProcessList() { return ProcessList; }
Security *GetSecurityManager() { return &SecurityManager; }
void CleanupProcessesThread();
void Panic() { StopScheduler = true; }
bool IsPanic() { return StopScheduler; }
__always_inline inline void Schedule()
/**
* Yield the current thread and switch
* to another thread if available
*/
__always_inline inline void Yield()
{
/* This will trigger the IRQ16
instantly so we won't execute
the next instruction */
#if defined(a86)
asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
asmv("int $0x30");
#elif defined(aa64)
asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
asmv("svc #0x30");
#endif
}
/**
* Update the current thread's trap frame
* without switching to another thread
*/
__always_inline inline void UpdateFrame()
{
SchedulerUpdateTrapFrame = true;
Yield();
}
void SignalShutdown();
void RevertProcessCreation(PCB *Process);
void RevertThreadCreation(TCB *Thread);
void KillThread(TCB *tcb, enum KillErrorCodes Code)
{
tcb->Status = TaskStatus::Terminated;
tcb->ExitCode = (int)Code;
debug("Killing thread %s(%d) with exit code %d",
tcb->Name, tcb->ID, Code);
}
void KillProcess(PCB *pcb, enum KillErrorCodes Code)
{
pcb->Status = TaskStatus::Terminated;
pcb->ExitCode = (int)Code;
debug("Killing process %s(%d) with exit code %d",
pcb->Name, pcb->ID, Code);
}
/**
* @brief Get the Current Process object
* Get the Current Process object
* @return PCB*
*/
PCB *GetCurrentProcess();
/**
* @brief Get the Current Thread object
* Get the Current Thread object
* @return TCB*
*/
TCB *GetCurrentThread();
@ -372,17 +432,17 @@ namespace Tasking
TCB *GetThreadByID(TID ID);
/** @brief Wait for process to terminate */
/** Wait for process to terminate */
void WaitForProcess(PCB *pcb);
/** @brief Wait for thread to terminate */
/** Wait for thread to terminate */
void WaitForThread(TCB *tcb);
void WaitForProcessStatus(PCB *pcb, TaskStatus Status);
void WaitForThreadStatus(TCB *tcb, TaskStatus Status);
/**
* @brief Sleep for a given amount of milliseconds
* Sleep for a given amount of milliseconds
*
* @param Milliseconds Amount of milliseconds to sleep
*/
@ -390,9 +450,11 @@ namespace Tasking
PCB *CreateProcess(PCB *Parent,
const char *Name,
TaskTrustLevel TrustLevel,
TaskExecutionMode TrustLevel,
void *Image = nullptr,
bool DoNotCreatePageTable = false);
bool DoNotCreatePageTable = false,
uint16_t UserID = UINT16_MAX,
uint16_t GroupID = UINT16_MAX);
TCB *CreateThread(PCB *Parent,
IP EntryPoint,
@ -405,11 +467,17 @@ namespace Tasking
Task(const IP EntryPoint);
~Task();
friend PCB;
friend TCB;
};
}
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
#define thisProcess TaskManager->GetCurrentProcess()
#define thisThread TaskManager->GetCurrentThread()
#define PEXIT(Code) thisProcess->ExitCode = Code
#define TEXIT(Code) thisThread->ExitCode = Code
extern "C" void TaskingScheduler_OneShot(int TimeSlice);

View File

@ -65,9 +65,9 @@ namespace Time
uint32_t clk = 0;
HPET *hpet = nullptr;
size_t ClassCreationTime = 0;
uint64_t ClassCreationTime = 0;
inline size_t ConvertUnit(Units Unit)
inline uint64_t ConvertUnit(Units Unit)
{
switch (Unit)
{
@ -101,9 +101,9 @@ namespace Time
public:
bool Sleep(size_t Duration, Units Unit);
size_t GetCounter();
size_t CalculateTarget(size_t Target, Units Unit);
size_t GetNanosecondsSinceClassCreation();
uint64_t GetCounter();
uint64_t CalculateTarget(uint64_t Target, Units Unit);
uint64_t GetNanosecondsSinceClassCreation();
HighPrecisionEventTimer(void *hpet);
~HighPrecisionEventTimer();
@ -112,10 +112,10 @@ namespace Time
class TimeStampCounter
{
private:
size_t clk = 0;
size_t ClassCreationTime = 0;
uint64_t clk = 0;
uint64_t ClassCreationTime = 0;
inline size_t ConvertUnit(Units Unit)
inline uint64_t ConvertUnit(Units Unit)
{
switch (Unit)
{
@ -149,9 +149,9 @@ namespace Time
public:
bool Sleep(size_t Duration, Units Unit);
size_t GetCounter();
size_t CalculateTarget(size_t Target, Units Unit);
size_t GetNanosecondsSinceClassCreation();
uint64_t GetCounter();
uint64_t CalculateTarget(uint64_t Target, Units Unit);
uint64_t GetNanosecondsSinceClassCreation();
TimeStampCounter();
~TimeStampCounter();
@ -190,9 +190,9 @@ namespace Time
}
bool Sleep(size_t Duration, Units Unit);
size_t GetCounter();
size_t CalculateTarget(size_t Target, Units Unit);
size_t GetNanosecondsSinceClassCreation();
uint64_t GetCounter();
uint64_t CalculateTarget(uint64_t Target, Units Unit);
uint64_t GetNanosecondsSinceClassCreation();
void FindTimers(void *acpi);
time();
~time();

View File

@ -51,6 +51,10 @@
#define foreach for
#define in :
#define forItr(itr, container) \
for (auto itr = container.begin(); \
itr != container.end(); ++itr)
#define r_cst(t, v) reinterpret_cast<t>(v)
#define c_cst(t, v) const_cast<t>(v)
#define s_cst(t, v) static_cast<t>(v)
@ -194,8 +198,35 @@ typedef __SIG_ATOMIC_TYPE__ sig_atomic_t;
// TODO: ssize_t
typedef intptr_t ssize_t;
typedef long off_t;
#if defined(a64) || defined(aa64)
typedef int64_t off_t;
typedef long long off64_t;
typedef __INT32_TYPE__ mode_t;
typedef int64_t dev_t;
typedef int64_t ino64_t;
typedef int64_t ino_t;
typedef unsigned int nlink_t;
typedef int blksize_t;
typedef int64_t blkcnt_t;
typedef int64_t blkcnt64_t;
typedef int64_t time_t;
typedef unsigned uid_t;
typedef unsigned gid_t;
#elif defined(a32)
typedef int32_t off_t;
typedef long long off64_t;
typedef __INT32_TYPE__ mode_t;
typedef int32_t dev_t;
typedef int32_t ino64_t;
typedef int32_t ino_t;
typedef unsigned int nlink_t;
typedef int blksize_t;
typedef int32_t blkcnt_t;
typedef int32_t blkcnt64_t;
typedef int32_t time_t;
typedef unsigned uid_t;
typedef unsigned gid_t;
#endif
#define INT8_MAX __INT8_MAX__
#define INT8_MIN (-INT8_MAX - 1)

View File

@ -15,27 +15,22 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_RECOVERY_H__
#define __FENNIX_KERNEL_RECOVERY_H__
#ifndef __FENNIX_KERNEL_VIRTUALIZATION_H__
#define __FENNIX_KERNEL_VIRTUALIZATION_H__
#include <types.h>
#include <memory.hpp>
#include <task.hpp>
namespace Recovery
{
class KernelRecovery
{
private:
Memory::MemMgr *mem;
Tasking::TCB *guiThread;
Tasking::TCB *recoveryThread;
/**
* Detects if the system is running in
* a virtualized environment.
*
* @return true if the system is running
* in a virtualized environment, false otherwise.
*
* @note This function will check every
* time it is called, so it is recommended
* to call it once and store the result.
*/
bool IsVirtualizedEnvironment();
public:
void RecoveryThread();
KernelRecovery();
~KernelRecovery();
};
}
#endif // !__FENNIX_KERNEL_RECOVERY_H__
#endif // !__FENNIX_KERNEL_VIRTUALIZATION_H__