mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Added better kernel arguments reading
This commit is contained in:
parent
8673a73ee4
commit
ea61229b18
@ -84,7 +84,15 @@ namespace SMP
|
|||||||
KPrint("VirtualBox detected, disabling SMP");
|
KPrint("VirtualBox detected, disabling SMP");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uint16_t i = 0; i < ((ACPI::MADT *)madt)->CPUCores + 1; i++)
|
|
||||||
|
int Cores = ((ACPI::MADT *)madt)->CPUCores + 1;
|
||||||
|
|
||||||
|
if (Config.Cores > ((ACPI::MADT *)madt)->CPUCores + 1)
|
||||||
|
KPrint("More cores requested than available. Using %d cores", ((ACPI::MADT *)madt)->CPUCores + 1);
|
||||||
|
else
|
||||||
|
Cores = Config.Cores;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < Cores; i++)
|
||||||
{
|
{
|
||||||
debug("Initializing CPU %d", i);
|
debug("Initializing CPU %d", i);
|
||||||
if ((((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24) != ((ACPI::MADT *)madt)->lapic[i]->ACPIProcessorId)
|
if ((((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24) != ((ACPI::MADT *)madt)->lapic[i]->ACPIProcessorId)
|
||||||
|
317
KConfig.cpp
Normal file
317
KConfig.cpp
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
#include <kconfig.hpp>
|
||||||
|
|
||||||
|
#include <convert.h>
|
||||||
|
#include <cargs.h>
|
||||||
|
#include <printf.h>
|
||||||
|
|
||||||
|
#include "kernel.h"
|
||||||
|
|
||||||
|
// TODO: Implement proper fprintf
|
||||||
|
EXTERNC void fprintf(FILE *stream, const char *Format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, Format);
|
||||||
|
vprintf_(Format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement proper fputs
|
||||||
|
EXTERNC void fputs(const char *s, FILE *stream) { printf_("%s", s); }
|
||||||
|
|
||||||
|
static struct cag_option ConfigOptions[] = {
|
||||||
|
{.identifier = 'a',
|
||||||
|
.access_letters = "aA",
|
||||||
|
.access_name = "alloc",
|
||||||
|
.value_name = "TYPE",
|
||||||
|
.description = "Memory allocator to use"},
|
||||||
|
|
||||||
|
{.identifier = 'c',
|
||||||
|
.access_letters = "cC",
|
||||||
|
.access_name = "cores",
|
||||||
|
.value_name = "VALUE",
|
||||||
|
.description = "Number of cores to use (0 = all; 1 is the first code, not 0)"},
|
||||||
|
|
||||||
|
{.identifier = 't',
|
||||||
|
.access_letters = "tT",
|
||||||
|
.access_name = "tasking",
|
||||||
|
.value_name = "MODE",
|
||||||
|
.description = "Tasking mode (multi, single)"},
|
||||||
|
|
||||||
|
{.identifier = 'h',
|
||||||
|
.access_letters = "h",
|
||||||
|
.access_name = "help",
|
||||||
|
.value_name = NULL,
|
||||||
|
.description = "Show help on screen and halt"}};
|
||||||
|
|
||||||
|
KernelConfig ParseConfig(char *Config)
|
||||||
|
{
|
||||||
|
int argc = 0;
|
||||||
|
char **argv = nullptr;
|
||||||
|
|
||||||
|
struct KernelConfig config = {Memory::MemoryAllocatorType::Pages, 0, 0};
|
||||||
|
|
||||||
|
if (Config == NULL)
|
||||||
|
{
|
||||||
|
KPrint("Warning! Empty kernel parameters! Using default values.");
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto Parse;
|
||||||
|
|
||||||
|
Parse:
|
||||||
|
{
|
||||||
|
// Based on https://stackoverflow.com/a/2568792
|
||||||
|
char *DestinationBuffer;
|
||||||
|
char *TempScan;
|
||||||
|
|
||||||
|
char **TempBuffer = (char **)kmalloc(sizeof(char *) * 10);
|
||||||
|
char **ArgvTemp = TempBuffer;
|
||||||
|
|
||||||
|
while (isspace((unsigned char)*Config))
|
||||||
|
Config++;
|
||||||
|
|
||||||
|
Config = TempScan = strdup(Config);
|
||||||
|
|
||||||
|
int Itr = 10;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (isspace((unsigned char)*TempScan))
|
||||||
|
TempScan++;
|
||||||
|
if (*TempScan == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (++argc >= Itr)
|
||||||
|
{
|
||||||
|
Itr += Itr / 2;
|
||||||
|
TempBuffer = (char **)krealloc(TempBuffer, Itr * sizeof(char *));
|
||||||
|
ArgvTemp = TempBuffer + (argc - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(ArgvTemp++) = DestinationBuffer = TempScan;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char TempChar0 = *(TempScan++);
|
||||||
|
switch (TempChar0)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
goto Completed;
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\n':
|
||||||
|
case '\f':
|
||||||
|
case '\r':
|
||||||
|
case '\v':
|
||||||
|
case '\b':
|
||||||
|
goto EmptyBufferAndComplete;
|
||||||
|
case '\\':
|
||||||
|
{
|
||||||
|
if ((*(DestinationBuffer++) = *(TempScan++)) == '\0')
|
||||||
|
goto Completed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\'':
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char TempChar1 = (*TempScan)++;
|
||||||
|
switch (TempChar1)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
KPrint("\eFF2200Unterminated string constant in kernel parameters.");
|
||||||
|
CPU::Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\'':
|
||||||
|
*DestinationBuffer = '\0';
|
||||||
|
goto OutsideLoop;
|
||||||
|
case '\\':
|
||||||
|
TempChar1 = (*TempScan)++;
|
||||||
|
switch (TempChar1)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
KPrint("\eFF2200Unterminated string constant in kernel parameters.");
|
||||||
|
CPU::Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*(DestinationBuffer++) = '\\';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
case '\'':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
default:
|
||||||
|
*(DestinationBuffer++) = TempChar1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutsideLoop:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '"':
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char TempChar2 = *(TempScan++);
|
||||||
|
switch (TempChar2)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
KPrint("\eFF2200Unterminated string constant in kernel parameters.");
|
||||||
|
CPU::Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '"':
|
||||||
|
(*DestinationBuffer) = '\0';
|
||||||
|
goto OutsideLoop2;
|
||||||
|
case '\\':
|
||||||
|
{
|
||||||
|
char TempChar3 = (*TempScan)++;
|
||||||
|
switch (TempChar3)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
TempChar3 = '\a';
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
TempChar3 = '\b';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
TempChar3 = '\t';
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
TempChar3 = '\n';
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
TempChar3 = '\v';
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
TempChar3 = '\f';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
TempChar3 = '\r';
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
KPrint("\eFF2200Unterminated string constant in kernel parameters.");
|
||||||
|
CPU::Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TempChar2 = TempChar3;
|
||||||
|
[[fallthrough]];
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*(DestinationBuffer++) = TempChar2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
OutsideLoop2:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*(DestinationBuffer++) = TempChar0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyBufferAndComplete:
|
||||||
|
*DestinationBuffer = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrint("Failed to parse kernel parameters string: %s", Config);
|
||||||
|
CPU::Stop();
|
||||||
|
|
||||||
|
Completed:
|
||||||
|
argv = TempBuffer;
|
||||||
|
if (argc == 0)
|
||||||
|
kfree((void *)Config);
|
||||||
|
|
||||||
|
goto ParseSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseSuccess:
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
KPrint("\e22AAFFargv[%d] = %s", i, argv[i]);
|
||||||
|
KPrint("\e22AAFFargc = %d", argc);
|
||||||
|
#endif
|
||||||
|
char identifier;
|
||||||
|
const char *value;
|
||||||
|
cag_option_context context;
|
||||||
|
|
||||||
|
cag_option_prepare(&context, ConfigOptions, CAG_ARRAY_SIZE(ConfigOptions), argc, argv);
|
||||||
|
while (cag_option_fetch(&context))
|
||||||
|
{
|
||||||
|
identifier = cag_option_get(&context);
|
||||||
|
switch (identifier)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
{
|
||||||
|
value = cag_option_get_value(&context);
|
||||||
|
if (strcmp(value, "xallocv1") == 0)
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUsing XallocV1 as memory allocator");
|
||||||
|
config.AllocatorType = Memory::MemoryAllocatorType::XallocV1;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "liballoc11") == 0)
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUsing Liballoc11 as memory allocator");
|
||||||
|
config.AllocatorType = Memory::MemoryAllocatorType::liballoc11;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "pages") == 0)
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUsing Pages as memory allocator");
|
||||||
|
config.AllocatorType = Memory::MemoryAllocatorType::Pages;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUnknown memory allocator: %s", value);
|
||||||
|
config.AllocatorType = Memory::MemoryAllocatorType::None;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
value = cag_option_get_value(&context);
|
||||||
|
KPrint("\eAAFFAAUsing %s cores", atoi(value) ? value : "all");
|
||||||
|
config.Cores = atoi(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 't':
|
||||||
|
{
|
||||||
|
value = cag_option_get_value(&context);
|
||||||
|
if (strcmp(value, "multi") == 0)
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUsing Multi-Tasking Scheduler");
|
||||||
|
config.SchedulerType = 1;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "single") == 0)
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUsing Mono-Tasking Scheduler");
|
||||||
|
config.SchedulerType = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrint("\eAAFFAAUnknown scheduler: %s", value);
|
||||||
|
config.SchedulerType = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'h':
|
||||||
|
{
|
||||||
|
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");
|
||||||
|
cag_option_print(ConfigOptions, CAG_ARRAY_SIZE(ConfigOptions), nullptr);
|
||||||
|
KPrint("\eFF2200System Halted.");
|
||||||
|
CPU::Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
20
Kernel.cpp
20
Kernel.cpp
@ -3,12 +3,13 @@
|
|||||||
#include <boot/protocols/multiboot2.h>
|
#include <boot/protocols/multiboot2.h>
|
||||||
#include <interrupts.hpp>
|
#include <interrupts.hpp>
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
#include <string.h>
|
#include <convert.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <time.hpp>
|
#include <time.hpp>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <smp.hpp>
|
#include <smp.hpp>
|
||||||
|
#include <cargs.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
NEWLOCK(KernelLock);
|
NEWLOCK(KernelLock);
|
||||||
@ -19,6 +20,7 @@ SymbolResolver::Symbols *KernelSymbolTable = nullptr;
|
|||||||
Power::Power *PowerManager = nullptr;
|
Power::Power *PowerManager = nullptr;
|
||||||
PCI::PCI *PCIManager = nullptr;
|
PCI::PCI *PCIManager = nullptr;
|
||||||
|
|
||||||
|
KernelConfig Config;
|
||||||
Time BootClock;
|
Time BootClock;
|
||||||
|
|
||||||
// For the Display class. Printing on first buffer as default.
|
// For the Display class. Printing on first buffer as default.
|
||||||
@ -39,8 +41,8 @@ EXTERNC void KPrint(const char *Format, ...)
|
|||||||
|
|
||||||
EXTERNC void Entry(BootInfo *Info)
|
EXTERNC void Entry(BootInfo *Info)
|
||||||
{
|
{
|
||||||
InitializeMemoryManagement(Info);
|
|
||||||
trace("Hello, World!");
|
trace("Hello, World!");
|
||||||
|
InitializeMemoryManagement(Info);
|
||||||
BootClock = ReadClock();
|
BootClock = ReadClock();
|
||||||
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
||||||
memcpy(bInfo, Info, sizeof(BootInfo));
|
memcpy(bInfo, Info, sizeof(BootInfo));
|
||||||
@ -61,18 +63,20 @@ EXTERNC void Entry(BootInfo *Info)
|
|||||||
CPU::InitializeFeatures();
|
CPU::InitializeFeatures();
|
||||||
KPrint("Loading kernel symbols");
|
KPrint("Loading kernel symbols");
|
||||||
KernelSymbolTable = new SymbolResolver::Symbols((uint64_t)Info->Kernel.FileBase);
|
KernelSymbolTable = new SymbolResolver::Symbols((uint64_t)Info->Kernel.FileBase);
|
||||||
|
KPrint("Reading kernel parameters");
|
||||||
|
Config = ParseConfig((char *)bInfo->Kernel.CommandLine);
|
||||||
KPrint("Initializing Power Manager");
|
KPrint("Initializing Power Manager");
|
||||||
PowerManager = new Power::Power;
|
PowerManager = new Power::Power;
|
||||||
KPrint("Initializing PCI Manager");
|
KPrint("Initializing PCI Manager");
|
||||||
PCIManager = new PCI::PCI;
|
PCIManager = new PCI::PCI;
|
||||||
foreach (auto hdr in PCIManager->GetDevices())
|
foreach (auto Device in PCIManager->GetDevices())
|
||||||
{
|
{
|
||||||
KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
|
KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
|
||||||
PCI::Descriptors::GetVendorName(hdr->VendorID),
|
PCI::Descriptors::GetVendorName(Device->VendorID),
|
||||||
PCI::Descriptors::GetDeviceName(hdr->VendorID, hdr->DeviceID),
|
PCI::Descriptors::GetDeviceName(Device->VendorID, Device->DeviceID),
|
||||||
PCI::Descriptors::DeviceClasses[hdr->Class],
|
PCI::Descriptors::DeviceClasses[Device->Class],
|
||||||
PCI::Descriptors::GetSubclassName(hdr->Class, hdr->Subclass),
|
PCI::Descriptors::GetSubclassName(Device->Class, Device->Subclass),
|
||||||
PCI::Descriptors::GetProgIFName(hdr->Class, hdr->Subclass, hdr->ProgIF));
|
PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF));
|
||||||
}
|
}
|
||||||
KPrint("Enabling interrupts");
|
KPrint("Enabling interrupts");
|
||||||
Interrupts::Enable(0);
|
Interrupts::Enable(0);
|
||||||
|
16
include/kconfig.hpp
Normal file
16
include/kconfig.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __FENNIX_KERNEL_KERNEL_CONFIG_H__
|
||||||
|
#define __FENNIX_KERNEL_KERNEL_CONFIG_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <memory.hpp>
|
||||||
|
|
||||||
|
struct KernelConfig
|
||||||
|
{
|
||||||
|
Memory::MemoryAllocatorType AllocatorType;
|
||||||
|
bool SchedulerType;
|
||||||
|
int Cores;
|
||||||
|
};
|
||||||
|
|
||||||
|
KernelConfig ParseConfig(char *Config);
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_KERNEL_CONFIG_H__
|
2
kernel.h
2
kernel.h
@ -7,6 +7,7 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <display.hpp>
|
#include <display.hpp>
|
||||||
#include <symbols.hpp>
|
#include <symbols.hpp>
|
||||||
|
#include <kconfig.hpp>
|
||||||
#include <power.hpp>
|
#include <power.hpp>
|
||||||
#include <pci.hpp>
|
#include <pci.hpp>
|
||||||
#endif
|
#endif
|
||||||
@ -17,6 +18,7 @@ extern Video::Display *Display;
|
|||||||
extern SymbolResolver::Symbols *KernelSymbolTable;
|
extern SymbolResolver::Symbols *KernelSymbolTable;
|
||||||
extern Power::Power *PowerManager;
|
extern Power::Power *PowerManager;
|
||||||
extern PCI::PCI *PCIManager;
|
extern PCI::PCI *PCIManager;
|
||||||
|
extern KernelConfig Config;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERNC void KPrint(const char *format, ...);
|
EXTERNC void KPrint(const char *format, ...);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user