Update kernel

This commit is contained in:
EnderIce2
2024-01-19 06:47:42 +02:00
parent fd15592608
commit 96daa43d38
282 changed files with 25486 additions and 15700 deletions

View File

@ -25,23 +25,8 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/close.html */
int sys_close(SysFrm *,

View File

@ -26,36 +26,22 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using vfs::RefNode;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html */
int sys_execve(SysFrm *Frame, const char *path,
char *const argv[], char *const envp[])
{
PCB *pcb = thisProcess;
Memory::Virtual vmm(pcb->PageTable);
Virtual vmm = Virtual(pcb->PageTable);
if (path == nullptr ||
!vmm.Check((void *)path, Memory::US) ||
!vmm.Check((void *)argv, Memory::US) ||
!vmm.Check((void *)envp, Memory::US))
!vmm.Check((void *)path, US) ||
!vmm.Check((void *)argv, US) ||
!vmm.Check((void *)envp, US))
return -ENOENT;
const char *safe_path;
@ -65,7 +51,7 @@ int sys_execve(SysFrm *Frame, const char *path,
safe_argv = (char **)pcb->vma->RequestPages(TO_PAGES(MAX_ARG));
safe_envp = (char **)pcb->vma->RequestPages(TO_PAGES(MAX_ARG));
{
Memory::SwapPT swap(pcb->PageTable);
SwapPT swap(pcb->PageTable);
size_t len = strlen(path);
memset((void *)safe_path, 0, PAGE_SIZE);
memcpy((void *)safe_path, path, len);
@ -114,7 +100,7 @@ int sys_execve(SysFrm *Frame, const char *path,
#endif
RefNode *File = fs->Open(safe_path,
pcb->CurrentWorkingDirectory);
pcb->CurrentWorkingDirectory);
if (!File)
{
@ -193,7 +179,8 @@ int sys_execve(SysFrm *Frame, const char *path,
int ret = Execute::Spawn((char *)safe_path,
(const char **)safe_argv,
(const char **)safe_envp,
pcb->Parent, pcb->Info.Compatibility);
pcb->Parent, true,
pcb->Info.Compatibility);
if (ret < 0)
{
@ -205,8 +192,8 @@ int sys_execve(SysFrm *Frame, const char *path,
delete File;
Tasking::Task *ctx = pcb->GetContext();
ctx->Sleep(1000);
pcb->State = Tasking::Zombie;
pcb->ExitCode = 0;
pcb->SetState(Tasking::Zombie);
pcb->SetExitCode(0); /* FIXME: get process exit code */
while (true)
ctx->Yield();
__builtin_unreachable();

View File

@ -25,23 +25,9 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
using Tasking::TaskState::Zombie;
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/exit.html */
__noreturn void sys_exit(SysFrm *, int status)
@ -53,9 +39,8 @@ __noreturn void sys_exit(SysFrm *, int status)
t->ID, status,
status < 0 ? -status : status);
t->ExitCode = status;
t->KeepTime = TimeManager->CalculateTarget(10, Time::Seconds);
t->State = Terminated;
t->SetState(Zombie);
t->SetExitCode(status);
while (true)
t->GetContext()->Yield();
__builtin_unreachable();

View File

@ -25,23 +25,26 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
void sys_fork_return()
{
#if defined(a64)
typedef long arch_t;
asmv("movq $0, %rax\n"); /* Return 0 */
asmv("movq %r8, %rsp\n"); /* Restore stack pointer */
asmv("movq %r8, %rbp\n"); /* Restore base pointer */
asmv("swapgs\n"); /* Swap GS back to the user GS */
asmv("sti\n"); /* Enable interrupts */
asmv("sysretq\n"); /* Return to rcx address in user mode */
#elif defined(a32)
typedef int arch_t;
#warning "sys_fork not implemented for i386"
#endif
__builtin_unreachable();
}
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/fork.html */
int sys_fork(SysFrm *Frame)
@ -54,15 +57,11 @@ int sys_fork(SysFrm *Frame)
PCB *Parent = thisThread->Parent;
TCB *Thread = thisThread;
void *ProcSymTable = nullptr;
if (Parent->ELFSymbolTable)
ProcSymTable = Parent->ELFSymbolTable->GetImage();
PCB *NewProcess =
TaskManager->CreateProcess(Parent,
Parent->Name,
Parent->Security.ExecutionMode,
ProcSymTable);
nullptr, true);
if (!NewProcess)
{
@ -70,7 +69,18 @@ int sys_fork(SysFrm *Frame)
return -EAGAIN;
}
NewProcess->IPC->Fork(Parent->IPC);
if (Parent->ELFSymbolTable &&
Parent->ELFSymbolTable->SymTableExists)
{
NewProcess->ELFSymbolTable = new SymbolResolver::Symbols(0);
foreach (auto sym in Parent->ELFSymbolTable->GetSymTable())
{
NewProcess->ELFSymbolTable->AddSymbol(sym.Address,
sym.FunctionName);
}
}
NewProcess->PageTable = Parent->PageTable->Fork();
TCB *NewThread =
TaskManager->CreateThread(NewProcess,
@ -92,50 +102,30 @@ int sys_fork(SysFrm *Frame)
TaskManager->UpdateFrame();
/* This if statement will overwrite
most of the registers except rcx
and r8-r15 */
if (thisThread->ID == NewThread->ID)
{
/* We can't just return 0; because the
gsTCB->SyscallStack is no
longer valid */
#if defined(a64)
asmv("movq $0, %rax\n"); /* Return 0 */
asmv("movq %r8, %rsp\n"); /* Restore stack pointer */
asmv("movq %r8, %rbp\n"); /* Restore base pointer */
asmv("swapgs\n"); /* Swap GS back to the user GS */
asmv("sti\n"); /* Enable interrupts */
asmv("sysretq\n"); /* Return to rcx address in user mode */
#elif defined(a32)
#warning "sys_fork not implemented for i386"
#endif
__builtin_unreachable();
}
memcpy(&NewThread->FPU, &Thread->FPU, sizeof(CPU::x64::FXState));
NewThread->FPU = Thread->FPU;
NewThread->Stack->Fork(Thread->Stack);
NewThread->Info.Architecture = Thread->Info.Architecture;
NewThread->Info.Compatibility = Thread->Info.Compatibility;
NewThread->Security.IsCritical = Thread->Security.IsCritical;
NewThread->Registers = Thread->Registers;
#if defined(a64)
NewThread->Registers.rip = (uintptr_t)sys_fork_return;
/* For sysretq */
NewThread->Registers.rcx = Frame->ReturnAddress;
NewThread->Registers.r8 = Frame->StackPointer;
#endif
if (Thread->Security.IsCritical)
NewThread->SetCritical(true);
#ifdef a86
NewThread->GSBase = NewThread->ShadowGSBase;
NewThread->ShadowGSBase = Thread->ShadowGSBase;
NewThread->FSBase = Thread->FSBase;
#endif
debug("ret addr: %#lx, stack: %#lx ip: %#lx", Frame->ReturnAddress,
Frame->StackPointer, (uintptr_t)sys_fork_return);
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)",
Thread->Name, Thread->ID,
NewThread->Name, NewThread->ID);
NewThread->State = Ready;
NewThread->SetState(Ready);
return (int)NewProcess->ID;
}

View File

@ -25,23 +25,8 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/lseek.html */
off_t sys_lseek(SysFrm *, int fildes,

View File

@ -24,24 +24,10 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/mmap.html */
void *sys_mmap(SysFrm *,
void *addr, size_t len,
@ -103,8 +89,8 @@ void *sys_mmap(SysFrm *,
(!m_Shared && !m_Private))
return (void *)-EINVAL;
Tasking::PCB *pcb = thisProcess;
Memory::VirtualMemoryArea *vma = pcb->vma;
PCB *pcb = thisProcess;
VirtualMemoryArea *vma = pcb->vma;
intptr_t ret = (intptr_t)vma->CreateCoWRegion(addr, len,
p_Read, p_Write, p_Exec,
m_Fixed, m_Shared);

View File

@ -25,24 +25,10 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/mprotect.html */
int sys_mprotect(SysFrm *,
void *addr, size_t len, int prot)
@ -58,16 +44,16 @@ int sys_mprotect(SysFrm *,
bool p_Write = prot & sc_PROT_WRITE;
// bool p_Exec = prot & sc_PROT_EXEC;
Tasking::PCB *pcb = thisProcess;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
PCB *pcb = thisProcess;
Virtual vmm = Virtual(pcb->PageTable);
for (uintptr_t i = uintptr_t(addr);
i < uintptr_t(addr) + len;
i += PAGE_SIZE)
{
if (likely(!vmm.Check((void *)i, Memory::G)))
if (likely(!vmm.Check((void *)i, G)))
{
Memory::PageTableEntry *pte = vmm.GetPTE(addr);
PageTableEntry *pte = vmm.GetPTE(addr);
if (!pte->Present ||
(!pte->UserSupervisor && p_Read) ||
(!pte->ReadWrite && p_Write))

View File

@ -25,24 +25,10 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/munmap.html */
int sys_munmap(SysFrm *,
void *addr, size_t len)
@ -53,16 +39,16 @@ int sys_munmap(SysFrm *,
if (len == 0)
return -EINVAL;
Tasking::PCB *pcb = thisProcess;
Memory::VirtualMemoryArea *vma = pcb->vma;
Memory::Virtual vmm = Memory::Virtual(pcb->PageTable);
PCB *pcb = thisProcess;
VirtualMemoryArea *vma = pcb->vma;
Virtual vmm = Virtual(pcb->PageTable);
for (uintptr_t i = uintptr_t(addr);
i < uintptr_t(addr) + len;
i += PAGE_SIZE)
{
if (likely(!vmm.Check((void *)i, Memory::G)))
vmm.Remap((void *)i, (void *)i, Memory::P | Memory::RW);
if (likely(!vmm.Check((void *)i, G)))
vmm.Remap((void *)i, (void *)i, P | RW);
else
warn("%p is a global page", (void *)i);
}

View File

@ -25,37 +25,23 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/open.html */
int sys_open(SysFrm *,
const char *path,
int oflag, mode_t mode)
{
const char *safe_path = nullptr;
Tasking::PCB *pcb = thisProcess;
Memory::SmartHeap sh(512, pcb->vma);
PCB *pcb = thisProcess;
SmartHeap sh(512, pcb->vma);
safe_path = (const char *)sh.Get();
{
Memory::SwapPT swap(pcb->PageTable);
SwapPT swap(pcb->PageTable);
size_t len = strlen(path);
memcpy((void *)safe_path, path, len);
memcpy((void *)safe_path, path, MAX(len, size_t(511)));
}
function("%s, %d, %d", safe_path, oflag, mode);

View File

@ -25,31 +25,17 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/read.html */
ssize_t sys_read(SysFrm *, int fildes,
void *buf, size_t nbyte)
{
void *safe_buf = nullptr;
Tasking::PCB *pcb = thisProcess;
Memory::SmartHeap sh(nbyte, pcb->vma);
PCB *pcb = thisProcess;
SmartHeap sh(nbyte, pcb->vma);
safe_buf = sh.Get();
function("%d, %p, %d", fildes, buf, nbyte);
@ -61,7 +47,7 @@ ssize_t sys_read(SysFrm *, int fildes,
return ret;
{
Memory::SwapPT swap(pcb->PageTable);
SwapPT swap(pcb->PageTable);
memcpy(buf, safe_buf, nbyte);
}
return ret;

View File

@ -0,0 +1,81 @@
/*
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 <syscalls.hpp>
#include <memory.hpp>
#include <utsname.h>
#include <lock.hpp>
#include <exec.hpp>
#include <errno.h>
#include <debug.h>
#include "../../syscalls.h"
#include "../../kernel.h"
using Tasking::PCB;
using namespace Memory;
/* https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html */
ssize_t sys_readlink(SysFrm *, const char *path, char *buf,
size_t bufsize)
{
if (!path || !buf)
return -EINVAL;
if (bufsize > PAGE_SIZE)
{
warn("bufsize is too large: %ld", bufsize);
return -EINVAL;
}
PCB *pcb = thisProcess;
Memory::Virtual vmm(pcb->PageTable);
if (!vmm.Check((void *)buf, Memory::US))
{
warn("Invalid address %#lx", buf);
return -EFAULT;
}
const char *pPath = pcb->PageTable->Get(path);
char *pBuf = pcb->PageTable->Get(buf);
function("%s %#lx %ld", pPath, buf, bufsize);
vfs::FileDescriptorTable *fdt = pcb->FileDescriptors;
int fd = fdt->_open(pPath, O_RDONLY, 0);
if (fd < 0)
return -ENOENT;
vfs::FileDescriptorTable::Fildes fildes = fdt->GetDescriptor(fd);
vfs::Node *node = fildes.Handle->node;
fdt->_close(fd);
if (node->Type != vfs::NodeType::SYMLINK)
return -EINVAL;
if (!node->Symlink)
{
warn("Symlink null for \"%s\"?", pPath);
return -EINVAL;
}
size_t len = strlen(node->Symlink);
if (len > bufsize)
len = bufsize;
strncpy(pBuf, node->Symlink, len);
return len;
}

69
syscalls/native/uname.cpp Normal file
View File

@ -0,0 +1,69 @@
/*
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 <syscalls.hpp>
#include <memory.hpp>
#include <utsname.h>
#include <lock.hpp>
#include <exec.hpp>
#include <errno.h>
#include <debug.h>
#include "../../syscalls.h"
#include "../../kernel.h"
using Tasking::PCB;
using namespace Memory;
/* https://pubs.opengroup.org/onlinepubs/9699919799/functions/uname.html */
int sys_uname(SysFrm *, struct utsname *buf)
{
assert(sizeof(struct utsname) < PAGE_SIZE);
Tasking::PCB *pcb = thisProcess;
Memory::Virtual vmm(pcb->PageTable);
if (!vmm.Check(buf, Memory::US))
{
warn("Invalid address %#lx", buf);
return -EFAULT;
}
auto pBuf = pcb->PageTable->Get(buf);
struct utsname uname =
{
/* TODO: This shouldn't be hardcoded */
.sysname = KERNEL_NAME,
.nodename = "fennix",
.release = KERNEL_VERSION,
.version = KERNEL_VERSION,
#if defined(a64)
.machine = "x86_64",
#elif defined(a32)
.machine = "i386",
#elif defined(aa64)
.machine = "arm64",
#elif defined(aa32)
.machine = "arm",
#endif
};
memcpy(pBuf, &uname, sizeof(struct utsname));
return 0;
}

View File

@ -25,34 +25,20 @@
#include "../../syscalls.h"
#include "../../kernel.h"
#include "../../ipc.h"
using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID;
using Tasking::PCB;
using Tasking::TCB;
using Tasking::TaskState::Ready;
using Tasking::TaskState::Terminated;
using namespace Memory;
#define SysFrm SyscallsFrame
#if defined(a64)
typedef long arch_t;
#elif defined(a32)
typedef int arch_t;
#endif
/* https://pubs.opengroup.org/onlinepubs/009604499/functions/write.html */
ssize_t sys_write(SysFrm *, int fildes,
const void *buf, size_t nbyte)
{
const void *safe_buf = nullptr;
Tasking::PCB *pcb = thisProcess;
Memory::SmartHeap sh(nbyte, pcb->vma);
PCB *pcb = thisProcess;
SmartHeap sh(nbyte, pcb->vma);
safe_buf = sh.Get();
{
Memory::SwapPT swap(pcb->PageTable);
SwapPT swap(pcb->PageTable);
memcpy((void *)safe_buf, buf, nbyte);
}