diff --git a/KConfig.cpp b/KConfig.cpp index 62b4bdd..f6a0f08 100644 --- a/KConfig.cpp +++ b/KConfig.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "kernel.h" @@ -78,225 +79,57 @@ static struct cag_option ConfigOptions[] = { .value_name = "BOOL", .description = "Enable SIMD instructions"}, + {.identifier = 'b', + .access_letters = NULL, + .access_name = "bootanim", + .value_name = "BOOL", + .description = "Enable boot animation"}, + {.identifier = 'h', .access_letters = "h", .access_name = "help", .value_name = NULL, .description = "Show help on screen and halt"}}; -KernelConfig ParseConfig(char *Config) +void ParseConfig(char *ConfigString, KernelConfig *ModConfig) { + if (ConfigString == NULL) + { + KPrint("Empty kernel parameters!"); + return; + } + else if (strlen(ConfigString) == 0) + { + KPrint("Empty kernel parameters!"); + return; + } + + if (ModConfig == NULL) + { + KPrint("ModConfig is NULL!"); + return; + } + + KPrint("Kernel parameters: %s", ConfigString); + debug("Kernel parameters: %s", ConfigString); + + char *argv[32]; int argc = 0; - char **argv = nullptr; + /* Not sure if the quotes are being parsed correctly. */ + targp_parse(ConfigString, argv, &argc); - struct KernelConfig config = {Memory::MemoryAllocatorType::XallocV1, - 0, - {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'}, - {'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'}, - true, - 0, - 0, - false, - false}; - - if (Config == NULL) - { - KPrint("Warning! Empty kernel parameters! Using default values."); - return config; - } - else - { - KPrint("Kernel parameters: %s", Config); - 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. (0)"); - CPU::Stop(); - break; - } - case '\'': - *DestinationBuffer = '\0'; - goto OutsideLoop; - case '\\': - TempChar1 = (*TempScan)++; - switch (TempChar1) - { - case '\0': - { - KPrint("\eFF2200Unterminated string constant in kernel parameters. (1)"); - 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. (2)"); - 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. (3)"); - 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); + debug("argv[%d] = %s", i, argv[i]); + debug("argc = %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); @@ -308,22 +141,22 @@ ParseSuccess: if (strcmp(value, "xallocv1") == 0) { KPrint("\eAAFFAAUsing XallocV1 as memory allocator"); - config.AllocatorType = Memory::MemoryAllocatorType::XallocV1; + ModConfig->AllocatorType = Memory::MemoryAllocatorType::XallocV1; } else if (strcmp(value, "liballoc11") == 0) { KPrint("\eAAFFAAUsing Liballoc11 as memory allocator"); - config.AllocatorType = Memory::MemoryAllocatorType::liballoc11; + ModConfig->AllocatorType = Memory::MemoryAllocatorType::liballoc11; } else if (strcmp(value, "pages") == 0) { KPrint("\eAAFFAAUsing Pages as memory allocator"); - config.AllocatorType = Memory::MemoryAllocatorType::Pages; + ModConfig->AllocatorType = Memory::MemoryAllocatorType::Pages; } else { KPrint("\eAAFFAAUnknown memory allocator: %s", value); - config.AllocatorType = Memory::MemoryAllocatorType::None; + ModConfig->AllocatorType = Memory::MemoryAllocatorType::None; } break; } @@ -331,14 +164,14 @@ ParseSuccess: { value = cag_option_get_value(&context); KPrint("\eAAFFAAUsing %s cores", atoi(value) ? value : "all"); - config.Cores = atoi(value); + ModConfig->Cores = atoi(value); break; } case 'p': { value = cag_option_get_value(&context); KPrint("\eAAFFAARedirecting I/O APIC interrupts to %s%s", atoi(value) ? "core " : "", atoi(value) ? value : "BSP"); - config.IOAPICInterruptCore = atoi(value); + ModConfig->IOAPICInterruptCore = atoi(value); break; } case 't': @@ -347,55 +180,62 @@ ParseSuccess: if (strcmp(value, "multi") == 0) { KPrint("\eAAFFAAUsing Multi-Tasking Scheduler"); - config.SchedulerType = 1; + ModConfig->SchedulerType = 1; } else if (strcmp(value, "single") == 0) { KPrint("\eAAFFAAUsing Mono-Tasking Scheduler"); - config.SchedulerType = 0; + ModConfig->SchedulerType = 0; } else { KPrint("\eAAFFAAUnknown scheduler: %s", value); - config.SchedulerType = 0; + ModConfig->SchedulerType = 0; } break; } case 'd': { value = cag_option_get_value(&context); - strncpy(config.DriverDirectory, value, strlen(value)); + strncpy(ModConfig->DriverDirectory, value, strlen(value)); KPrint("\eAAFFAAUsing %s as driver directory", value); break; } case 'i': { value = cag_option_get_value(&context); - strncpy(config.InitPath, value, strlen(value)); + strncpy(ModConfig->InitPath, value, strlen(value)); KPrint("\eAAFFAAUsing %s as init program", value); break; } case 'o': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? config.InterruptsOnCrash = true : config.InterruptsOnCrash = false; + strcmp(value, "true") == 0 ? ModConfig->InterruptsOnCrash = true : ModConfig->InterruptsOnCrash = false; KPrint("\eAAFFAAInterrupts on crash: %s", value); break; } case 'l': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? config.UnlockDeadLock = true : config.UnlockDeadLock = false; + strcmp(value, "true") == 0 ? ModConfig->UnlockDeadLock = true : ModConfig->UnlockDeadLock = false; KPrint("\eAAFFAAUnlocking the deadlock after 10 retries"); break; } case 's': { value = cag_option_get_value(&context); - strcmp(value, "true") == 0 ? config.SIMD = true : config.SIMD = false; + strcmp(value, "true") == 0 ? ModConfig->SIMD = true : ModConfig->SIMD = false; KPrint("\eAAFFAASingle Instruction, Multiple Data (SIMD): %s", value); break; } + case 'b': + { + value = cag_option_get_value(&context); + strcmp(value, "true") == 0 ? ModConfig->BootAnimation = true : ModConfig->BootAnimation = false; + KPrint("\eAAFFAABoot animation: %s", value); + break; + } case 'h': { KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration."); @@ -405,7 +245,5 @@ ParseSuccess: } } } - return config; -} - return config; + debug("Config loaded"); } diff --git a/include/kconfig.hpp b/include/kconfig.hpp index 0a979a9..e64ecd1 100644 --- a/include/kconfig.hpp +++ b/include/kconfig.hpp @@ -15,8 +15,9 @@ struct KernelConfig int IOAPICInterruptCore; bool UnlockDeadLock; bool SIMD; + bool BootAnimation; }; -KernelConfig ParseConfig(char *Config); +void ParseConfig(char *ConfigString, KernelConfig *ModConfig); #endif // !__FENNIX_KERNEL_KERNEL_CONFIG_H__