mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-27 15:04:33 +00:00
Boot screen & change shutting down/rebooting procedure
This commit is contained in:
parent
cef9d89965
commit
028115a1b0
@ -61,15 +61,10 @@ namespace ACPI
|
|||||||
}
|
}
|
||||||
else if (Event & ACPI_POWER_BUTTON)
|
else if (Event & ACPI_POWER_BUTTON)
|
||||||
{
|
{
|
||||||
BeforeShutdown();
|
if (TaskManager)
|
||||||
this->Shutdown();
|
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)KST_Shutdown);
|
||||||
Time::Clock tm = Time::ReadClock();
|
else
|
||||||
while (tm.Second == Time::ReadClock().Second)
|
KernelShutdownThread(false);
|
||||||
;
|
|
||||||
outw(0xB004, 0x2000);
|
|
||||||
outw(0x604, 0x2000);
|
|
||||||
outw(0x4004, 0x3400);
|
|
||||||
CPU::Stop();
|
|
||||||
}
|
}
|
||||||
else if (Event & ACPI_SLEEP_BUTTON)
|
else if (Event & ACPI_SLEEP_BUTTON)
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,6 @@ namespace Power
|
|||||||
{
|
{
|
||||||
void Power::Reboot()
|
void Power::Reboot()
|
||||||
{
|
{
|
||||||
BeforeShutdown();
|
|
||||||
|
|
||||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||||
((ACPI::DSDT *)this->dsdt)->Reboot();
|
((ACPI::DSDT *)this->dsdt)->Reboot();
|
||||||
@ -44,8 +42,6 @@ namespace Power
|
|||||||
|
|
||||||
void Power::Shutdown()
|
void Power::Shutdown()
|
||||||
{
|
{
|
||||||
BeforeShutdown();
|
|
||||||
|
|
||||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||||
((ACPI::DSDT *)this->dsdt)->Shutdown();
|
((ACPI::DSDT *)this->dsdt)->Shutdown();
|
||||||
|
@ -636,6 +636,7 @@ namespace GraphicalUserInterface
|
|||||||
|
|
||||||
GUI::~GUI()
|
GUI::~GUI()
|
||||||
{
|
{
|
||||||
|
debug("Destructor called");
|
||||||
delete this->mem, this->mem = nullptr;
|
delete this->mem, this->mem = nullptr;
|
||||||
delete this->BackBuffer, this->BackBuffer = nullptr;
|
delete this->BackBuffer, this->BackBuffer = nullptr;
|
||||||
delete this->DesktopBuffer, this->DesktopBuffer = nullptr;
|
delete this->DesktopBuffer, this->DesktopBuffer = nullptr;
|
||||||
|
223
KThread.cpp
223
KThread.cpp
@ -8,6 +8,14 @@
|
|||||||
#include <exec.hpp>
|
#include <exec.hpp>
|
||||||
#include <cwalk.h>
|
#include <cwalk.h>
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#define STBI_NO_STDIO
|
||||||
|
#define STBI_NO_LINEAR
|
||||||
|
#define STBI_NO_THREAD_LOCALS
|
||||||
|
#define STBI_NO_HDR
|
||||||
|
#define STBI_ONLY_TGA
|
||||||
|
#include <stb/image.h>
|
||||||
|
|
||||||
#include "DAPI.hpp"
|
#include "DAPI.hpp"
|
||||||
#include "Fex.hpp"
|
#include "Fex.hpp"
|
||||||
|
|
||||||
@ -24,6 +32,8 @@ VirtualFileSystem::Node *DevFS = nullptr;
|
|||||||
VirtualFileSystem::Node *MntFS = nullptr;
|
VirtualFileSystem::Node *MntFS = nullptr;
|
||||||
VirtualFileSystem::Node *ProcFS = nullptr;
|
VirtualFileSystem::Node *ProcFS = nullptr;
|
||||||
|
|
||||||
|
NewLock(ShutdownLock);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void TreeFS(Node *node, int Depth)
|
void TreeFS(Node *node, int Depth)
|
||||||
{
|
{
|
||||||
@ -31,7 +41,8 @@ void TreeFS(Node *node, int Depth)
|
|||||||
foreach (auto Chld in node->Children)
|
foreach (auto Chld in node->Children)
|
||||||
{
|
{
|
||||||
printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->Name);
|
printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->Name);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
TaskManager->Sleep(100);
|
TaskManager->Sleep(100);
|
||||||
TreeFS(Chld, Depth + 1);
|
TreeFS(Chld, Depth + 1);
|
||||||
}
|
}
|
||||||
@ -102,7 +113,8 @@ void TaskMgr()
|
|||||||
if (sanity > 1000)
|
if (sanity > 1000)
|
||||||
sanity = 0;
|
sanity = 0;
|
||||||
Display->SetBufferCursor(0, tmpX, tmpY);
|
Display->SetBufferCursor(0, tmpX, tmpY);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
CPU::Interrupts(CPU::Enable);
|
CPU::Interrupts(CPU::Enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,10 +142,185 @@ Execute::SpawnData SpawnInit()
|
|||||||
return Execute::Spawn(Config.InitPath, argv, envp);
|
return Execute::Spawn(Config.InitPath, argv, envp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Files: 0.tga 1.tga ... 40.tga */
|
||||||
|
void *Frames[41];
|
||||||
|
uint32_t FrameSizes[41];
|
||||||
|
uint32_t FrameCount = 1;
|
||||||
|
|
||||||
|
void BootLogoAnimationThread()
|
||||||
|
{
|
||||||
|
char BootAnimPath[16];
|
||||||
|
while (FrameCount < 41)
|
||||||
|
{
|
||||||
|
sprintf(BootAnimPath, "%d.tga", FrameCount);
|
||||||
|
std::shared_ptr<File> ba = bootanim_vfs->Open(BootAnimPath);
|
||||||
|
if (ba->Status != FileStatus::OK)
|
||||||
|
{
|
||||||
|
bootanim_vfs->Close(ba);
|
||||||
|
debug("Failed to load boot animation frame %s", BootAnimPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameSizes[FrameCount] = ba->node->Length;
|
||||||
|
Frames[FrameCount] = new uint8_t[ba->node->Length];
|
||||||
|
memcpy((void *)Frames[FrameCount], (void *)ba->node->Address, ba->node->Length);
|
||||||
|
bootanim_vfs->Close(ba);
|
||||||
|
FrameCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DispX = Display->GetBuffer(1)->Width;
|
||||||
|
uint32_t DispY = Display->GetBuffer(1)->Height;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < FrameCount; i++)
|
||||||
|
{
|
||||||
|
int x, y, channels;
|
||||||
|
|
||||||
|
if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels, 4);
|
||||||
|
|
||||||
|
if (img == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int offsetX = DispX / 2 - x / 2;
|
||||||
|
int offsetY = DispY / 2 - y / 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < x * y; i++)
|
||||||
|
{
|
||||||
|
uint32_t pixel = ((uint32_t *)img)[i];
|
||||||
|
uint8_t r = (pixel >> 16) & 0xFF;
|
||||||
|
uint8_t g = (pixel >> 8) & 0xFF;
|
||||||
|
uint8_t b = (pixel >> 0) & 0xFF;
|
||||||
|
uint8_t a = (pixel >> 24) & 0xFF;
|
||||||
|
|
||||||
|
if (a != 0xFF)
|
||||||
|
{
|
||||||
|
r = (r * a) / 0xFF;
|
||||||
|
g = (g * a) / 0xFF;
|
||||||
|
b = (b * a) / 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, (r << 16) | (g << 8) | (b << 0), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(img);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int brightness = 100;
|
||||||
|
while (brightness >= 0)
|
||||||
|
{
|
||||||
|
brightness -= 10;
|
||||||
|
Display->SetBrightness(brightness, 1);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExitLogoAnimationThread()
|
||||||
|
{
|
||||||
|
Display->SetBrightness(100, 1);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
|
||||||
|
/* Files: 26.tga 25.tga ... 1.tga */
|
||||||
|
uint32_t DispX = Display->GetBuffer(1)->Width;
|
||||||
|
uint32_t DispY = Display->GetBuffer(1)->Height;
|
||||||
|
|
||||||
|
// for (size_t i = 26; i > 0; i--)
|
||||||
|
// {
|
||||||
|
// int x, y, channels;
|
||||||
|
|
||||||
|
// if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels))
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels, 4);
|
||||||
|
|
||||||
|
// if (img == NULL)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// int offsetX = DispX / 2 - x / 2;
|
||||||
|
// int offsetY = DispY / 2 - y / 2;
|
||||||
|
|
||||||
|
// for (int i = 0; i < x * y; i++)
|
||||||
|
// {
|
||||||
|
// uint32_t pixel = ((uint32_t *)img)[i];
|
||||||
|
// uint8_t r = (pixel >> 16) & 0xFF;
|
||||||
|
// uint8_t g = (pixel >> 8) & 0xFF;
|
||||||
|
// uint8_t b = (pixel >> 0) & 0xFF;
|
||||||
|
// uint8_t a = (pixel >> 24) & 0xFF;
|
||||||
|
|
||||||
|
// if (a != 0xFF)
|
||||||
|
// {
|
||||||
|
// r = (r * a) / 0xFF;
|
||||||
|
// g = (g * a) / 0xFF;
|
||||||
|
// b = (b * a) / 0xFF;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, (r << 16) | (g << 8) | (b << 0), 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// free(img);
|
||||||
|
// Display->SetBuffer(1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (size_t i = 40; i > 25; i--)
|
||||||
|
{
|
||||||
|
int x, y, channels;
|
||||||
|
|
||||||
|
if (!stbi_info_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint8_t *img = stbi_load_from_memory((uint8_t *)Frames[i], FrameSizes[i], &x, &y, &channels, 4);
|
||||||
|
|
||||||
|
if (img == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int offsetX = DispX / 2 - x / 2;
|
||||||
|
int offsetY = DispY / 2 - y / 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < x * y; i++)
|
||||||
|
{
|
||||||
|
uint32_t pixel = ((uint32_t *)img)[i];
|
||||||
|
uint8_t r = (pixel >> 16) & 0xFF;
|
||||||
|
uint8_t g = (pixel >> 8) & 0xFF;
|
||||||
|
uint8_t b = (pixel >> 0) & 0xFF;
|
||||||
|
uint8_t a = (pixel >> 24) & 0xFF;
|
||||||
|
|
||||||
|
if (a != 0xFF)
|
||||||
|
{
|
||||||
|
r = (r * a) / 0xFF;
|
||||||
|
g = (g * a) / 0xFF;
|
||||||
|
b = (b * a) / 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
Display->SetPixel((i % x) + offsetX, (i / x) + offsetY, (r << 16) | (g << 8) | (b << 0), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(img);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int brightness = 100;
|
||||||
|
while (brightness >= 0)
|
||||||
|
{
|
||||||
|
brightness -= 10;
|
||||||
|
Display->SetBrightness(brightness, 1);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KernelMainThread()
|
void KernelMainThread()
|
||||||
{
|
{
|
||||||
TaskManager->GetCurrentThread()->SetPriority(Tasking::Critical);
|
TaskManager->GetCurrentThread()->SetPriority(Tasking::Critical);
|
||||||
|
|
||||||
|
Tasking::TCB *blaThread = nullptr;
|
||||||
|
|
||||||
|
if (Config.BootAnimation)
|
||||||
|
{
|
||||||
|
blaThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)BootLogoAnimationThread);
|
||||||
|
blaThread->Rename("Logo Animation");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* TODO: This should not be enabled because it may cause a deadlock. Not sure where or how. */
|
/* TODO: This should not be enabled because it may cause a deadlock. Not sure where or how. */
|
||||||
// Tasking::PCB *tskMgr = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), "Debug Task Manager", Tasking::TaskTrustLevel::Kernel);
|
// Tasking::PCB *tskMgr = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), "Debug Task Manager", Tasking::TaskTrustLevel::Kernel);
|
||||||
@ -171,7 +358,8 @@ void KernelMainThread()
|
|||||||
const char *USpace_msg = "Setting up userspace";
|
const char *USpace_msg = "Setting up userspace";
|
||||||
for (size_t i = 0; i < strlen(USpace_msg); i++)
|
for (size_t i = 0; i < strlen(USpace_msg); i++)
|
||||||
Display->Print(USpace_msg[i], 0);
|
Display->Print(USpace_msg[i], 0);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
|
|
||||||
Execute::SpawnData ret = {Execute::ExStatus::Unknown, nullptr, nullptr};
|
Execute::SpawnData ret = {Execute::ExStatus::Unknown, nullptr, nullptr};
|
||||||
Tasking::TCB *ExecuteThread = nullptr;
|
Tasking::TCB *ExecuteThread = nullptr;
|
||||||
@ -182,12 +370,14 @@ void KernelMainThread()
|
|||||||
ExecuteThread->SetPriority(Tasking::Idle);
|
ExecuteThread->SetPriority(Tasking::Idle);
|
||||||
|
|
||||||
Display->Print('.', 0);
|
Display->Print('.', 0);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
|
|
||||||
ret = SpawnInit();
|
ret = SpawnInit();
|
||||||
|
|
||||||
Display->Print('.', 0);
|
Display->Print('.', 0);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
|
|
||||||
if (ret.Status != Execute::ExStatus::OK)
|
if (ret.Status != Execute::ExStatus::OK)
|
||||||
{
|
{
|
||||||
@ -200,7 +390,8 @@ void KernelMainThread()
|
|||||||
|
|
||||||
Display->Print('.', 0);
|
Display->Print('.', 0);
|
||||||
Display->Print('\n', 0);
|
Display->Print('\n', 0);
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
|
|
||||||
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
|
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
|
||||||
TaskManager->GetCurrentThread()->SetPriority(Tasking::Idle);
|
TaskManager->GetCurrentThread()->SetPriority(Tasking::Idle);
|
||||||
@ -213,6 +404,7 @@ Exit:
|
|||||||
KPrint("\eE85230Userspace process exited with code %d", ExitCode);
|
KPrint("\eE85230Userspace process exited with code %d", ExitCode);
|
||||||
KPrint("Dropping to recovery screen...");
|
KPrint("Dropping to recovery screen...");
|
||||||
TaskManager->Sleep(2500);
|
TaskManager->Sleep(2500);
|
||||||
|
TaskManager->WaitForThread(blaThread);
|
||||||
RecoveryScreen = new Recovery::KernelRecovery;
|
RecoveryScreen = new Recovery::KernelRecovery;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -224,9 +416,21 @@ Exit:
|
|||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelShutdownThread(bool Reboot)
|
void __no_stack_protector KernelShutdownThread(bool Reboot)
|
||||||
{
|
{
|
||||||
BeforeShutdown();
|
SmartLock(ShutdownLock);
|
||||||
|
debug("KernelShutdownThread(%s)", Reboot ? "true" : "false");
|
||||||
|
if (Config.BootAnimation && TaskManager)
|
||||||
|
{
|
||||||
|
if (RecoveryScreen)
|
||||||
|
delete RecoveryScreen, RecoveryScreen = nullptr;
|
||||||
|
|
||||||
|
Tasking::TCB *elaThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)ExitLogoAnimationThread);
|
||||||
|
elaThread->Rename("Logo Animation");
|
||||||
|
TaskManager->WaitForThread(elaThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeShutdown(Reboot);
|
||||||
|
|
||||||
trace("%s...", Reboot ? "Rebooting" : "Shutting down");
|
trace("%s...", Reboot ? "Rebooting" : "Shutting down");
|
||||||
if (Reboot)
|
if (Reboot)
|
||||||
@ -235,3 +439,6 @@ void KernelShutdownThread(bool Reboot)
|
|||||||
PowerManager->Shutdown();
|
PowerManager->Shutdown();
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KST_Reboot() { KernelShutdownThread(true); }
|
||||||
|
void KST_Shutdown() { KernelShutdownThread(false); }
|
||||||
|
102
Kernel.cpp
102
Kernel.cpp
@ -15,8 +15,6 @@
|
|||||||
#include "Core/smbios.hpp"
|
#include "Core/smbios.hpp"
|
||||||
#include "Tests/t.h"
|
#include "Tests/t.h"
|
||||||
|
|
||||||
NewLock(ShutdownLock);
|
|
||||||
|
|
||||||
bool DebuggerIsAttached = false;
|
bool DebuggerIsAttached = false;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -49,6 +47,7 @@ LockClass mExtTrkLock;
|
|||||||
* - [ ] Colors in crash screen are not following the kernel color scheme.
|
* - [ ] Colors in crash screen are not following the kernel color scheme.
|
||||||
* - [ ] Find a way to add intrinsics.
|
* - [ ] Find a way to add intrinsics.
|
||||||
* - [ ] Rework PSF1 font loader.
|
* - [ ] Rework PSF1 font loader.
|
||||||
|
* - [ ] The cleanup should be done by a thread (tasking). This is done to avoid a deadlock.
|
||||||
*
|
*
|
||||||
* ISSUES:
|
* ISSUES:
|
||||||
* - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs)
|
* - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs)
|
||||||
@ -160,14 +159,28 @@ PCI::PCI *PCIManager = nullptr;
|
|||||||
Tasking::Task *TaskManager = nullptr;
|
Tasking::Task *TaskManager = nullptr;
|
||||||
Time::time *TimeManager = nullptr;
|
Time::time *TimeManager = nullptr;
|
||||||
VirtualFileSystem::Virtual *vfs = nullptr;
|
VirtualFileSystem::Virtual *vfs = nullptr;
|
||||||
|
VirtualFileSystem::Virtual *bootanim_vfs = nullptr;
|
||||||
|
|
||||||
KernelConfig Config;
|
|
||||||
Time::Clock BootClock;
|
Time::Clock BootClock;
|
||||||
|
|
||||||
|
KernelConfig Config = {
|
||||||
|
.AllocatorType = Memory::MemoryAllocatorType::XallocV1,
|
||||||
|
.SchedulerType = 0,
|
||||||
|
.DriverDirectory = {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
|
||||||
|
.InitPath = {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
|
||||||
|
.InterruptsOnCrash = true,
|
||||||
|
.Cores = 0,
|
||||||
|
.IOAPICInterruptCore = 0,
|
||||||
|
.UnlockDeadLock = false,
|
||||||
|
.SIMD = false,
|
||||||
|
.BootAnimation = false,
|
||||||
|
};
|
||||||
|
|
||||||
extern bool EnableProfiler;
|
extern bool EnableProfiler;
|
||||||
|
|
||||||
// For the Display class. Printing on first buffer as default.
|
// For the Display class. Printing on first buffer as default.
|
||||||
EXTERNC void putchar(char c) { Display->Print(c, 0); }
|
int PutCharBufferIndex = 0;
|
||||||
|
EXTERNC void putchar(char c) { Display->Print(c, PutCharBufferIndex); }
|
||||||
|
|
||||||
EXTERNC void KPrint(const char *Format, ...)
|
EXTERNC void KPrint(const char *Format, ...)
|
||||||
{
|
{
|
||||||
@ -182,7 +195,8 @@ EXTERNC void KPrint(const char *Format, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
Display->SetBuffer(0);
|
if (!Config.BootAnimation)
|
||||||
|
Display->SetBuffer(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERNC NIF void Main(BootInfo *Info)
|
EXTERNC NIF void Main(BootInfo *Info)
|
||||||
@ -204,7 +218,20 @@ EXTERNC NIF void Main(BootInfo *Info)
|
|||||||
Interrupts::Initialize(0);
|
Interrupts::Initialize(0);
|
||||||
|
|
||||||
KPrint("Reading Kernel Parameters");
|
KPrint("Reading Kernel Parameters");
|
||||||
Config = ParseConfig((char *)bInfo->Kernel.CommandLine);
|
ParseConfig((char *)bInfo->Kernel.CommandLine, &Config);
|
||||||
|
|
||||||
|
if (Config.BootAnimation)
|
||||||
|
{
|
||||||
|
Display->CreateBuffer(0, 0, 1);
|
||||||
|
|
||||||
|
Video::ScreenBuffer *buf = Display->GetBuffer(1);
|
||||||
|
Video::FontInfo fi = Display->GetCurrentFont()->GetInfo();
|
||||||
|
Display->SetBufferCursor(1, 0, buf->Height - fi.Height);
|
||||||
|
PutCharBufferIndex = 1;
|
||||||
|
printf("Fennix Operating System - %s [\e058C19%s\eFFFFFF]\n", KERNEL_VERSION, GIT_COMMIT_SHORT);
|
||||||
|
Display->SetBuffer(1);
|
||||||
|
PutCharBufferIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
KPrint("Initializing CPU Features");
|
KPrint("Initializing CPU Features");
|
||||||
CPU::InitializeFeatures(0);
|
CPU::InitializeFeatures(0);
|
||||||
@ -320,7 +347,30 @@ EXTERNC NIF void Main(BootInfo *Info)
|
|||||||
|
|
||||||
KPrint("Initializing Filesystem...");
|
KPrint("Initializing Filesystem...");
|
||||||
vfs = new VirtualFileSystem::Virtual;
|
vfs = new VirtualFileSystem::Virtual;
|
||||||
new VirtualFileSystem::USTAR((uintptr_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
|
||||||
|
if (Config.BootAnimation)
|
||||||
|
bootanim_vfs = new VirtualFileSystem::Virtual;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MAX_MODULES; i++)
|
||||||
|
{
|
||||||
|
if (!bInfo->Modules[i].Address)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(bInfo->Modules[i].CommandLine, "initrd") == 0)
|
||||||
|
{
|
||||||
|
debug("Found initrd at %p", bInfo->Modules[i].Address);
|
||||||
|
static char initrd = 0;
|
||||||
|
if (!initrd++)
|
||||||
|
new VirtualFileSystem::USTAR((uintptr_t)bInfo->Modules[i].Address, vfs);
|
||||||
|
}
|
||||||
|
if (strcmp(bInfo->Modules[i].CommandLine, "bootanim") == 0 && Config.BootAnimation)
|
||||||
|
{
|
||||||
|
debug("Found bootanim at %p", bInfo->Modules[i].Address);
|
||||||
|
static char bootanim = 0;
|
||||||
|
if (!bootanim++)
|
||||||
|
new VirtualFileSystem::USTAR((uintptr_t)bInfo->Modules[i].Address, bootanim_vfs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!vfs->PathExists("/system"))
|
if (!vfs->PathExists("/system"))
|
||||||
vfs->Create("/system", NodeFlags::DIRECTORY);
|
vfs->Create("/system", NodeFlags::DIRECTORY);
|
||||||
@ -404,23 +454,41 @@ EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info)
|
|||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||||
|
|
||||||
EXTERNC __no_stack_protector NIF void BeforeShutdown()
|
EXTERNC __no_stack_protector void BeforeShutdown(bool Reboot)
|
||||||
{
|
{
|
||||||
SmartLock(ShutdownLock);
|
|
||||||
/* TODO: Announce shutdown */
|
/* TODO: Announce shutdown */
|
||||||
|
|
||||||
trace("\n\n\n#################### SYSTEM SHUTTING DOWN ####################\n\n");
|
trace("\n\n\n#################### SYSTEM SHUTTING DOWN ####################\n\n");
|
||||||
delete NIManager, NIManager = nullptr;
|
|
||||||
|
|
||||||
delete DiskManager, DiskManager = nullptr;
|
|
||||||
delete DriverManager, DriverManager = nullptr;
|
|
||||||
TaskManager->SignalShutdown();
|
|
||||||
delete TaskManager, TaskManager = nullptr;
|
|
||||||
if (RecoveryScreen)
|
if (RecoveryScreen)
|
||||||
delete RecoveryScreen, RecoveryScreen = nullptr;
|
delete RecoveryScreen, RecoveryScreen = nullptr;
|
||||||
delete vfs, vfs = nullptr;
|
|
||||||
delete TimeManager, TimeManager = nullptr;
|
if (NIManager)
|
||||||
delete Display, Display = nullptr;
|
delete NIManager, NIManager = nullptr;
|
||||||
|
|
||||||
|
if (DiskManager)
|
||||||
|
delete DiskManager, DiskManager = nullptr;
|
||||||
|
|
||||||
|
if (DriverManager)
|
||||||
|
delete DriverManager, DriverManager = nullptr;
|
||||||
|
|
||||||
|
if (TaskManager)
|
||||||
|
{
|
||||||
|
TaskManager->SignalShutdown();
|
||||||
|
delete TaskManager, TaskManager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vfs)
|
||||||
|
delete vfs, vfs = nullptr;
|
||||||
|
|
||||||
|
if (bootanim_vfs)
|
||||||
|
delete bootanim_vfs, bootanim_vfs = nullptr;
|
||||||
|
|
||||||
|
if (TimeManager)
|
||||||
|
delete TimeManager, TimeManager = nullptr;
|
||||||
|
|
||||||
|
if (Display)
|
||||||
|
delete Display, Display = nullptr;
|
||||||
// PowerManager should not be called
|
// PowerManager should not be called
|
||||||
|
|
||||||
// https://wiki.osdev.org/Calling_Global_Constructors
|
// https://wiki.osdev.org/Calling_Global_Constructors
|
||||||
|
@ -285,17 +285,8 @@ namespace Recovery
|
|||||||
RecoveryScreen->RecoveryThread();
|
RecoveryScreen->RecoveryThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RebootCommandThread()
|
void RebootCommandThread() { KST_Reboot(); }
|
||||||
{
|
void ShutdownCommandThread() { KST_Shutdown(); }
|
||||||
CriticalSection cs;
|
|
||||||
PowerManager->Reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShutdownCommandThread()
|
|
||||||
{
|
|
||||||
CriticalSection cs;
|
|
||||||
PowerManager->Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RebootCommandWrapper() { TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)RebootCommandThread); }
|
void RebootCommandWrapper() { TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)RebootCommandThread); }
|
||||||
void ShutdownCommandWrapper() { TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ShutdownCommandThread); }
|
void ShutdownCommandWrapper() { TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ShutdownCommandThread); }
|
||||||
@ -309,7 +300,7 @@ namespace Recovery
|
|||||||
|
|
||||||
gui = new GraphicalUserInterface::GUI;
|
gui = new GraphicalUserInterface::GUI;
|
||||||
|
|
||||||
TCB *guiThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)GUIWrapper);
|
guiThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)GUIWrapper);
|
||||||
guiThread->Rename("GUI Thread");
|
guiThread->Rename("GUI Thread");
|
||||||
guiThread->SetPriority(Tasking::TaskPriority::Critical);
|
guiThread->SetPriority(Tasking::TaskPriority::Critical);
|
||||||
|
|
||||||
@ -339,12 +330,16 @@ namespace Recovery
|
|||||||
wdgDbgWin = new WidgetCollection(DbgWin);
|
wdgDbgWin = new WidgetCollection(DbgWin);
|
||||||
Video::Font *NewFont = new Video::Font(&_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, Video::FontType::PCScreenFont2);
|
Video::Font *NewFont = new Video::Font(&_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, Video::FontType::PCScreenFont2);
|
||||||
wdgDbgWin->ReplaceFont(NewFont);
|
wdgDbgWin->ReplaceFont(NewFont);
|
||||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)RecoveryThreadWrapper)->SetPriority(Tasking::TaskPriority::Idle);
|
recoveryThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)RecoveryThreadWrapper);
|
||||||
|
recoveryThread->Rename("Recovery Thread");
|
||||||
|
recoveryThread->SetPriority(Tasking::TaskPriority::Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelRecovery::~KernelRecovery()
|
KernelRecovery::~KernelRecovery()
|
||||||
{
|
{
|
||||||
debug("Destructor called");
|
debug("Destructor called");
|
||||||
|
TaskManager->KillThread(guiThread, 0);
|
||||||
|
TaskManager->KillThread(recoveryThread, 0);
|
||||||
delete gui, gui = nullptr;
|
delete gui, gui = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ static int sys_print(SyscallsFrame *Frame, char Char, int Index)
|
|||||||
|
|
||||||
char ret = Display->Print(Char, Index, true);
|
char ret = Display->Print(Char, Index, true);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Display->SetBuffer(Index);
|
if (!Config.BootAnimation && Index != 0)
|
||||||
|
Display->SetBuffer(Index);
|
||||||
#endif
|
#endif
|
||||||
UNUSED(Frame);
|
UNUSED(Frame);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
|
#include <task.hpp>
|
||||||
|
|
||||||
namespace Recovery
|
namespace Recovery
|
||||||
{
|
{
|
||||||
@ -10,6 +11,8 @@ namespace Recovery
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Memory::MemMgr *mem;
|
Memory::MemMgr *mem;
|
||||||
|
Tasking::TCB *guiThread;
|
||||||
|
Tasking::TCB *recoveryThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void RecoveryThread();
|
void RecoveryThread();
|
||||||
|
5
kernel.h
5
kernel.h
@ -38,6 +38,7 @@ extern KernelConfig Config;
|
|||||||
extern Tasking::Task *TaskManager;
|
extern Tasking::Task *TaskManager;
|
||||||
extern Time::time *TimeManager;
|
extern Time::time *TimeManager;
|
||||||
extern VirtualFileSystem::Virtual *vfs;
|
extern VirtualFileSystem::Virtual *vfs;
|
||||||
|
extern VirtualFileSystem::Virtual *bootanim_vfs;
|
||||||
extern Driver::Driver *DriverManager;
|
extern Driver::Driver *DriverManager;
|
||||||
extern Disk::Manager *DiskManager;
|
extern Disk::Manager *DiskManager;
|
||||||
extern NetworkInterfaceManager::NetworkInterface *NIManager;
|
extern NetworkInterfaceManager::NetworkInterface *NIManager;
|
||||||
@ -54,10 +55,12 @@ extern VirtualFileSystem::Node *ProcFS;
|
|||||||
EXTERNC void putchar(char c);
|
EXTERNC void putchar(char c);
|
||||||
EXTERNC void KPrint(const char *format, ...);
|
EXTERNC void KPrint(const char *format, ...);
|
||||||
EXTERNC void Entry(struct BootInfo *Info);
|
EXTERNC void Entry(struct BootInfo *Info);
|
||||||
EXTERNC void BeforeShutdown();
|
EXTERNC void BeforeShutdown(bool Reboot);
|
||||||
EXTERNC void TaskingPanic();
|
EXTERNC void TaskingPanic();
|
||||||
|
|
||||||
EXTERNC void KernelMainThread();
|
EXTERNC void KernelMainThread();
|
||||||
EXTERNC void KernelShutdownThread(bool Reboot);
|
EXTERNC void KernelShutdownThread(bool Reboot);
|
||||||
|
EXTERNC void KST_Reboot();
|
||||||
|
EXTERNC void KST_Shutdown();
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_KERNEL_H__
|
#endif // !__FENNIX_KERNEL_KERNEL_H__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user