2023-03-27 03:38:55 +03:00
|
|
|
#include <kernel/ACPI.h>
|
2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Arch.h>
|
2023-11-17 18:54:59 +02:00
|
|
|
#include <kernel/BootInfo.h>
|
2023-01-25 21:39:03 +02:00
|
|
|
#include <kernel/Debug.h>
|
2023-11-22 21:57:17 +02:00
|
|
|
#include <kernel/Device/FramebufferDevice.h>
|
2023-07-10 23:17:14 +03:00
|
|
|
#include <kernel/FS/DevFS/FileSystem.h>
|
2023-09-30 21:19:36 +03:00
|
|
|
#include <kernel/FS/ProcFS/FileSystem.h>
|
2023-02-26 03:00:29 +02:00
|
|
|
#include <kernel/FS/VirtualFileSystem.h>
|
2023-03-01 21:21:08 +02:00
|
|
|
#include <kernel/GDT.h>
|
2022-11-16 19:49:09 +02:00
|
|
|
#include <kernel/IDT.h>
|
2024-01-10 14:43:19 +02:00
|
|
|
#include <kernel/Input/KeyboardLayout.h>
|
2024-01-04 11:00:10 +02:00
|
|
|
#include <kernel/Input/PS2/Controller.h>
|
2023-01-23 20:13:57 +02:00
|
|
|
#include <kernel/InterruptController.h>
|
2022-12-10 00:33:03 +02:00
|
|
|
#include <kernel/kprint.h>
|
2023-04-14 15:16:38 +03:00
|
|
|
#include <kernel/Memory/Heap.h>
|
2023-04-14 13:30:21 +03:00
|
|
|
#include <kernel/Memory/kmalloc.h>
|
2023-05-29 21:06:09 +03:00
|
|
|
#include <kernel/Memory/PageTable.h>
|
2024-02-01 23:38:06 +02:00
|
|
|
#include <kernel/Networking/NetworkManager.h>
|
2023-02-26 03:00:29 +02:00
|
|
|
#include <kernel/PCI.h>
|
2022-12-07 02:41:18 +02:00
|
|
|
#include <kernel/PIC.h>
|
2023-03-16 12:17:04 +02:00
|
|
|
#include <kernel/Process.h>
|
2024-03-03 02:17:24 +02:00
|
|
|
#include <kernel/Processor.h>
|
2024-02-12 04:25:06 +02:00
|
|
|
#include <kernel/Random.h>
|
2023-02-16 20:00:31 +02:00
|
|
|
#include <kernel/Scheduler.h>
|
2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Syscall.h>
|
2024-03-03 02:17:24 +02:00
|
|
|
#include <kernel/Terminal/FramebufferTerminal.h>
|
2023-09-04 19:34:18 +03:00
|
|
|
#include <kernel/Terminal/Serial.h>
|
|
|
|
#include <kernel/Terminal/VirtualTTY.h>
|
2023-08-04 10:22:20 +03:00
|
|
|
#include <kernel/Timer/Timer.h>
|
2023-04-12 22:20:18 +03:00
|
|
|
|
2022-12-20 11:57:09 +02:00
|
|
|
struct ParsedCommandLine
|
|
|
|
{
|
2023-01-25 21:44:09 +02:00
|
|
|
bool force_pic = false;
|
|
|
|
bool disable_serial = false;
|
2023-09-04 19:34:18 +03:00
|
|
|
BAN::StringView console = "tty0"sv;
|
2023-03-30 16:37:53 +03:00
|
|
|
BAN::StringView root;
|
2022-12-20 11:57:09 +02:00
|
|
|
};
|
|
|
|
|
2023-11-17 18:54:59 +02:00
|
|
|
static bool should_disable_serial(BAN::StringView full_command_line)
|
2022-12-20 11:57:09 +02:00
|
|
|
{
|
2023-11-17 18:54:59 +02:00
|
|
|
const char* start = full_command_line.data();
|
2023-10-17 01:06:24 +03:00
|
|
|
const char* current = start;
|
2022-12-28 04:17:46 +02:00
|
|
|
while (true)
|
|
|
|
{
|
2023-01-12 13:20:38 +02:00
|
|
|
if (!*current || *current == ' ' || *current == '\t')
|
2022-12-28 04:17:46 +02:00
|
|
|
{
|
2023-01-25 21:44:09 +02:00
|
|
|
if (current - start == 8 && memcmp(start, "noserial", 8) == 0)
|
2023-03-30 16:37:53 +03:00
|
|
|
return true;
|
2023-01-12 13:20:38 +02:00
|
|
|
if (!*current)
|
2022-12-28 04:17:46 +02:00
|
|
|
break;
|
2023-01-12 13:20:38 +02:00
|
|
|
start = current + 1;
|
2022-12-28 04:17:46 +02:00
|
|
|
}
|
2023-01-12 13:20:38 +02:00
|
|
|
current++;
|
2022-12-28 04:17:46 +02:00
|
|
|
}
|
|
|
|
|
2023-03-30 16:37:53 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ParsedCommandLine cmdline;
|
|
|
|
|
|
|
|
static void parse_command_line()
|
|
|
|
{
|
2023-11-17 18:54:59 +02:00
|
|
|
auto full_command_line = Kernel::g_boot_info.command_line.sv();
|
2023-03-30 16:37:53 +03:00
|
|
|
auto arguments = MUST(full_command_line.split(' '));
|
|
|
|
for (auto argument : arguments)
|
|
|
|
{
|
|
|
|
if (argument == "noapic")
|
|
|
|
cmdline.force_pic = true;
|
|
|
|
else if (argument == "noserial")
|
|
|
|
cmdline.disable_serial = true;
|
|
|
|
else if (argument.size() > 5 && argument.substring(0, 5) == "root=")
|
|
|
|
cmdline.root = argument.substring(5);
|
2023-09-04 19:34:18 +03:00
|
|
|
else if (argument.size() > 8 && argument.substring(0, 8) == "console=")
|
|
|
|
cmdline.console = argument.substring(8);
|
2023-03-30 16:37:53 +03:00
|
|
|
}
|
2022-12-20 11:57:09 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 03:31:36 +03:00
|
|
|
TerminalDriver* g_terminal_driver = nullptr;
|
|
|
|
|
2023-03-30 16:37:53 +03:00
|
|
|
static void init2(void*);
|
2023-03-16 12:17:04 +02:00
|
|
|
|
2023-11-17 18:54:59 +02:00
|
|
|
extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
2022-11-15 00:32:07 +02:00
|
|
|
{
|
2023-02-01 01:53:35 +02:00
|
|
|
using namespace Kernel;
|
|
|
|
|
2023-11-17 18:54:59 +02:00
|
|
|
if (!validate_boot_magic(boot_magic))
|
2023-06-12 22:37:34 +03:00
|
|
|
{
|
2023-02-01 21:05:44 +02:00
|
|
|
Serial::initialize();
|
2023-11-17 18:54:59 +02:00
|
|
|
dprintln("Unrecognized boot magic {8H}", boot_magic);
|
|
|
|
return;
|
2023-06-12 22:37:34 +03:00
|
|
|
}
|
2023-09-04 19:34:18 +03:00
|
|
|
|
2023-11-17 18:54:59 +02:00
|
|
|
if (!should_disable_serial(get_early_boot_command_line(boot_magic, boot_info)))
|
2022-12-15 19:05:07 +02:00
|
|
|
{
|
2023-11-17 18:54:59 +02:00
|
|
|
Serial::initialize();
|
|
|
|
dprintln("Serial output initialized");
|
2022-12-15 19:05:07 +02:00
|
|
|
}
|
2022-12-07 02:41:18 +02:00
|
|
|
|
2023-01-12 13:20:38 +02:00
|
|
|
kmalloc_initialize();
|
|
|
|
dprintln("kmalloc initialized");
|
2022-12-20 11:57:09 +02:00
|
|
|
|
2023-11-17 18:54:59 +02:00
|
|
|
parse_boot_info(boot_magic, boot_info);
|
|
|
|
dprintln("boot info parsed");
|
|
|
|
|
2024-03-07 16:05:29 +02:00
|
|
|
Processor::create(0);
|
|
|
|
Processor::initialize();
|
2024-03-03 22:30:06 +02:00
|
|
|
dprintln("BSP initialized");
|
|
|
|
|
2023-05-29 21:06:09 +03:00
|
|
|
PageTable::initialize();
|
2024-03-06 02:19:59 +02:00
|
|
|
PageTable::kernel().initial_load();
|
2023-05-29 21:06:09 +03:00
|
|
|
dprintln("PageTable initialized");
|
2023-01-13 15:07:24 +02:00
|
|
|
|
2023-06-18 23:27:00 +03:00
|
|
|
Heap::initialize();
|
|
|
|
dprintln("Heap initialzed");
|
|
|
|
|
2023-09-04 19:34:18 +03:00
|
|
|
parse_command_line();
|
|
|
|
dprintln("command line parsed, root='{}', console='{}'", cmdline.root, cmdline.console);
|
2023-04-14 23:55:05 +03:00
|
|
|
|
2023-08-04 11:12:16 +03:00
|
|
|
MUST(ACPI::initialize());
|
|
|
|
dprintln("ACPI initialized");
|
|
|
|
|
|
|
|
InterruptController::initialize(cmdline.force_pic);
|
|
|
|
dprintln("Interrupt controller initialized");
|
|
|
|
|
2023-08-10 22:01:30 +03:00
|
|
|
SystemTimer::initialize(cmdline.force_pic);
|
2023-08-04 11:12:16 +03:00
|
|
|
dprintln("Timers initialized");
|
|
|
|
|
2023-07-10 23:17:14 +03:00
|
|
|
DevFileSystem::initialize();
|
|
|
|
dprintln("devfs initialized");
|
|
|
|
|
2023-11-22 21:57:17 +02:00
|
|
|
auto framebuffer_device = FramebufferDevice::create_from_boot_framebuffer();
|
|
|
|
if (!framebuffer_device.is_error())
|
2023-11-28 23:51:28 +02:00
|
|
|
{
|
|
|
|
DevFileSystem::get().add_device(framebuffer_device.value());
|
2023-11-22 21:57:17 +02:00
|
|
|
g_terminal_driver = FramebufferTerminalDriver::create(framebuffer_device.value());
|
2023-11-28 23:51:28 +02:00
|
|
|
}
|
2023-11-22 21:57:17 +02:00
|
|
|
if (g_terminal_driver)
|
|
|
|
dprintln("Framebuffer terminal initialized");
|
|
|
|
|
2024-03-06 16:00:19 +02:00
|
|
|
InterruptController::get().initialize_multiprocessor();
|
|
|
|
|
2023-09-30 21:19:36 +03:00
|
|
|
ProcFileSystem::initialize();
|
|
|
|
dprintln("procfs initialized");
|
|
|
|
|
2023-09-04 19:34:18 +03:00
|
|
|
if (Serial::has_devices())
|
|
|
|
{
|
|
|
|
Serial::initialize_devices();
|
|
|
|
dprintln("Serial devices initialized");
|
|
|
|
}
|
|
|
|
|
2023-10-16 01:41:01 +03:00
|
|
|
if (g_terminal_driver)
|
|
|
|
{
|
|
|
|
auto vtty = MUST(VirtualTTY::create(g_terminal_driver));
|
|
|
|
dprintln("Virtual TTY initialized");
|
|
|
|
}
|
2023-09-04 19:34:18 +03:00
|
|
|
|
2024-02-12 04:25:06 +02:00
|
|
|
Random::initialize();
|
|
|
|
dprintln("RNG initialized");
|
|
|
|
|
2023-03-07 19:17:49 +02:00
|
|
|
MUST(Scheduler::initialize());
|
2023-07-10 23:17:14 +03:00
|
|
|
dprintln("Scheduler initialized");
|
|
|
|
|
2023-02-02 23:27:51 +02:00
|
|
|
Scheduler& scheduler = Scheduler::get();
|
2023-09-04 19:34:18 +03:00
|
|
|
Process::create_kernel(init2, nullptr);
|
2023-03-16 12:17:04 +02:00
|
|
|
scheduler.start();
|
2023-04-19 00:41:24 +03:00
|
|
|
|
2023-04-12 17:51:36 +03:00
|
|
|
ASSERT_NOT_REACHED();
|
2023-03-16 12:17:04 +02:00
|
|
|
}
|
|
|
|
|
2023-09-04 19:34:18 +03:00
|
|
|
static void init2(void*)
|
2023-03-16 12:17:04 +02:00
|
|
|
{
|
|
|
|
using namespace Kernel;
|
2023-03-29 03:05:16 +03:00
|
|
|
using namespace Kernel::Input;
|
2023-03-16 12:17:04 +02:00
|
|
|
|
2023-07-10 23:17:14 +03:00
|
|
|
dprintln("Scheduler started");
|
2023-03-29 11:50:46 +03:00
|
|
|
|
2023-09-28 12:30:27 +03:00
|
|
|
InterruptController::get().enter_acpi_mode();
|
|
|
|
|
2023-09-09 22:45:27 +03:00
|
|
|
auto console = MUST(DevFileSystem::get().root_inode()->find_inode(cmdline.console));
|
|
|
|
ASSERT(console->is_tty());
|
|
|
|
((TTY*)console.ptr())->set_as_current();
|
|
|
|
|
2023-07-10 23:17:14 +03:00
|
|
|
DevFileSystem::get().initialize_device_updater();
|
|
|
|
|
2024-01-10 14:43:19 +02:00
|
|
|
#if 0
|
|
|
|
dprintln("sleeping for 5 seconds");
|
|
|
|
SystemTimer::get().sleep(5000);
|
|
|
|
#endif
|
|
|
|
|
2024-01-13 17:11:26 +02:00
|
|
|
// Initialize empty keymap
|
|
|
|
MUST(Input::KeyboardLayout::initialize());
|
|
|
|
if (auto res = PS2Controller::initialize(); res.is_error())
|
|
|
|
dprintln("{}", res.error());
|
|
|
|
|
2024-02-01 23:38:06 +02:00
|
|
|
MUST(NetworkManager::initialize());
|
|
|
|
|
2024-01-13 17:11:26 +02:00
|
|
|
// NOTE: PCI devices are the last ones to be initialized
|
|
|
|
// so other devices can reserve predefined interrupts
|
2023-09-18 13:53:10 +03:00
|
|
|
PCI::PCIManager::initialize();
|
2023-07-10 23:17:14 +03:00
|
|
|
dprintln("PCI initialized");
|
2023-09-09 22:52:03 +03:00
|
|
|
|
2023-06-11 19:52:13 +03:00
|
|
|
VirtualFileSystem::initialize(cmdline.root);
|
2023-10-07 15:46:30 +03:00
|
|
|
dprintln("VFS initialized");
|
2023-03-16 12:17:04 +02:00
|
|
|
|
2023-09-04 19:34:18 +03:00
|
|
|
TTY::initialize_devices();
|
2023-04-05 00:56:09 +03:00
|
|
|
|
2023-06-11 21:01:02 +03:00
|
|
|
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"sv));
|
2023-04-12 17:51:36 +03:00
|
|
|
}
|
2024-03-03 02:17:24 +02:00
|
|
|
|
|
|
|
extern "C" void ap_main()
|
|
|
|
{
|
|
|
|
using namespace Kernel;
|
|
|
|
|
2024-03-07 16:05:29 +02:00
|
|
|
Processor::initialize();
|
2024-03-06 02:19:59 +02:00
|
|
|
PageTable::kernel().initial_load();
|
2024-03-08 23:24:18 +02:00
|
|
|
Processor::allocate_idle_thread();
|
2024-03-09 23:53:38 +02:00
|
|
|
InterruptController::get().enable();
|
2024-03-06 02:19:59 +02:00
|
|
|
|
2024-03-06 00:02:18 +02:00
|
|
|
dprintln("ap{} initialized", Processor::current_id());
|
2024-03-03 02:17:24 +02:00
|
|
|
|
2024-04-03 14:21:55 +03:00
|
|
|
// wait until scheduler is started and we get irq for reschedule
|
|
|
|
Processor::set_interrupt_state(InterruptState::Enabled);
|
|
|
|
while (true)
|
|
|
|
asm volatile("hlt");
|
|
|
|
ASSERT_NOT_REACHED();
|
2024-03-03 02:17:24 +02:00
|
|
|
}
|