diff --git a/iso.sh b/iso.sh index b597040ef..99f6bfbca 100755 --- a/iso.sh +++ b/iso.sh @@ -11,5 +11,8 @@ cat > isodir/boot/grub/grub.cfg << EOF menuentry "banan-os" { multiboot /boot/banan-os.kernel } +menuentry "banan-os (no apic)" { + multiboot /boot/banan-os.kernel noapic +} EOF grub-mkrescue -o banan-os.iso isodir diff --git a/kernel/arch/i386/APIC.cpp b/kernel/arch/i386/APIC.cpp index 026b4ee3a..dc8a8b346 100644 --- a/kernel/arch/i386/APIC.cpp +++ b/kernel/arch/i386/APIC.cpp @@ -379,7 +379,7 @@ namespace APIC return true; } - void Initialize() + void Initialize(bool force_pic) { for (uint32_t i = 0x00; i <= 0xFF; i++) s_overrides[i] = i; @@ -387,7 +387,12 @@ namespace APIC PIC::MaskAll(); PIC::Remap(); - if (!InitializeAPIC()) + if (force_pic) + { + kprintln("Using PIC instead of APIC"); + s_using_fallback_pic = true; + } + else if (!InitializeAPIC()) { kprintln("Could not initialize APIC. Using PIC as fallback"); s_using_fallback_pic = true; diff --git a/kernel/include/kernel/APIC.h b/kernel/include/kernel/APIC.h index 8b21f0d2d..59908d71f 100644 --- a/kernel/include/kernel/APIC.h +++ b/kernel/include/kernel/APIC.h @@ -5,7 +5,7 @@ namespace APIC { - void Initialize(); + void Initialize(bool force_pic = false); void EOI(); void GetISR(uint32_t[8]); void EnableIRQ(uint8_t irq); diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 8f22715f5..83580e64a 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -18,10 +20,26 @@ #define DISABLE_INTERRUPTS() asm volatile("cli") #define ENABLE_INTERRUPTS() asm volatile("sti") + multiboot_info_t* s_multiboot_info; -extern "C" -void kernel_main(multiboot_info_t* mbi, uint32_t magic) +using namespace BAN; + +struct ParsedCommandLine +{ + bool force_pic = false; +}; + +ParsedCommandLine ParseCommandLine(const char* command_line) +{ + auto args = MUST(StringView(command_line).Split([](char c) { return c == ' ' || c == '\t'; })); + + ParsedCommandLine result; + result.force_pic = args.Has("noapic"); + return result; +} + +extern "C" void kernel_main(multiboot_info_t* mbi, uint32_t magic) { DISABLE_INTERRUPTS(); @@ -43,7 +61,12 @@ void kernel_main(multiboot_info_t* mbi, uint32_t magic) kmalloc_initialize(); - APIC::Initialize(); + + ParsedCommandLine cmdline; + if (mbi->flags & 0x02) + cmdline = ParseCommandLine((const char*)mbi->cmdline); + + APIC::Initialize(cmdline.force_pic); gdt_initialize(); IDT::initialize();