2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Arch.h>
|
2023-01-25 21:39:03 +02:00
|
|
|
#include <kernel/Debug.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>
|
2022-12-30 19:38:21 +02:00
|
|
|
#include <kernel/Input.h>
|
2023-01-23 20:13:57 +02:00
|
|
|
#include <kernel/InterruptController.h>
|
2022-11-15 00:32:07 +02:00
|
|
|
#include <kernel/kmalloc.h>
|
2022-12-10 00:33:03 +02:00
|
|
|
#include <kernel/kprint.h>
|
2023-01-10 17:50:24 +02:00
|
|
|
#include <kernel/MMU.h>
|
2022-11-15 21:42:14 +02:00
|
|
|
#include <kernel/multiboot.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>
|
|
|
|
#include <kernel/PIT.h>
|
2023-03-16 12:17:04 +02:00
|
|
|
#include <kernel/Process.h>
|
2023-02-16 20:00:31 +02:00
|
|
|
#include <kernel/Scheduler.h>
|
2022-12-10 00:33:03 +02:00
|
|
|
#include <kernel/Serial.h>
|
2022-12-13 21:34:50 +02:00
|
|
|
#include <kernel/Shell.h>
|
2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Syscall.h>
|
2022-12-23 15:55:45 +02:00
|
|
|
#include <kernel/TTY.h>
|
2023-01-23 13:07:52 +02:00
|
|
|
#include <kernel/VesaTerminalDriver.h>
|
2022-11-12 21:04:47 +02:00
|
|
|
|
2023-01-10 17:50:24 +02:00
|
|
|
extern "C" const char g_kernel_cmdline[];
|
2022-11-14 00:27:11 +02: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;
|
2022-12-20 11:57:09 +02:00
|
|
|
};
|
|
|
|
|
2023-01-12 13:20:38 +02:00
|
|
|
ParsedCommandLine ParseCommandLine()
|
2022-12-20 11:57:09 +02:00
|
|
|
{
|
|
|
|
ParsedCommandLine result;
|
2022-12-28 04:17:46 +02:00
|
|
|
|
2023-01-12 13:20:38 +02:00
|
|
|
if (!(g_multiboot_info->flags & 0x02))
|
|
|
|
return result;
|
|
|
|
|
|
|
|
const char* start = g_kernel_cmdline;
|
|
|
|
const char* current = g_kernel_cmdline;
|
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-12 13:20:38 +02:00
|
|
|
if (current - start == 6 && memcmp(start, "noapic", 6) == 0)
|
2022-12-28 04:17:46 +02:00
|
|
|
result.force_pic = true;
|
|
|
|
|
2023-01-25 21:44:09 +02:00
|
|
|
if (current - start == 8 && memcmp(start, "noserial", 8) == 0)
|
|
|
|
result.disable_serial = 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
|
|
|
}
|
|
|
|
|
2022-12-20 11:57:09 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-03-08 21:31:26 +02:00
|
|
|
struct Test
|
|
|
|
{
|
|
|
|
Test() { dprintln("construct (default)"); }
|
|
|
|
Test(const Test&) { dprintln("construct (copy)"); }
|
|
|
|
Test(Test&&) { dprintln("construct (move)"); }
|
|
|
|
~Test() { dprintln("destruct"); }
|
|
|
|
Test& operator=(const Test&) { dprintln("assign (copy)"); return *this; }
|
|
|
|
Test& operator=(Test&&) { dprintln("assign (move)"); return *this; }
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace BAN::Formatter
|
|
|
|
{
|
|
|
|
|
|
|
|
template<typename F>
|
|
|
|
void print_argument(F putc, const Test& test, const ValueFormat& format)
|
|
|
|
{
|
|
|
|
print_argument(putc, &test, format);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-13 15:32:46 +02:00
|
|
|
extern "C" uintptr_t g_rodata_start;
|
|
|
|
extern "C" uintptr_t g_rodata_end;
|
|
|
|
|
|
|
|
extern "C" uintptr_t g_userspace_start;
|
|
|
|
extern "C" uintptr_t g_userspace_end;
|
|
|
|
|
|
|
|
extern void userspace_entry();
|
|
|
|
|
2023-03-16 12:17:04 +02:00
|
|
|
void init2(void*);
|
|
|
|
|
2023-01-12 13:20:38 +02:00
|
|
|
extern "C" void kernel_main()
|
2022-11-15 00:32:07 +02:00
|
|
|
{
|
2023-02-01 01:53:35 +02:00
|
|
|
using namespace Kernel;
|
|
|
|
|
2022-11-15 00:32:07 +02:00
|
|
|
DISABLE_INTERRUPTS();
|
2022-11-14 00:27:11 +02:00
|
|
|
|
2023-01-25 21:44:09 +02:00
|
|
|
auto cmdline = ParseCommandLine();
|
|
|
|
|
|
|
|
if (!cmdline.disable_serial)
|
2023-02-01 21:05:44 +02:00
|
|
|
Serial::initialize();
|
2023-01-12 13:20:38 +02:00
|
|
|
if (g_multiboot_magic != 0x2BADB002)
|
2022-12-15 19:05:07 +02:00
|
|
|
{
|
|
|
|
dprintln("Invalid multiboot magic number");
|
2022-12-10 00:33:03 +02:00
|
|
|
return;
|
2022-12-15 19:05:07 +02:00
|
|
|
}
|
2023-01-13 15:07:24 +02:00
|
|
|
dprintln("Serial output initialized");
|
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-03-01 21:21:08 +02:00
|
|
|
GDT::initialize();
|
|
|
|
dprintln("GDT initialized");
|
|
|
|
|
2022-12-07 02:41:18 +02:00
|
|
|
IDT::initialize();
|
2023-02-22 22:29:31 +02:00
|
|
|
dprintln("IDT initialized");
|
2022-12-07 02:41:18 +02:00
|
|
|
|
2023-02-01 21:05:44 +02:00
|
|
|
MMU::intialize();
|
2023-01-13 15:07:24 +02:00
|
|
|
dprintln("MMU initialized");
|
|
|
|
|
2023-03-07 18:56:08 +02:00
|
|
|
PCI::initialize();
|
|
|
|
dprintln("PCI initialized");
|
|
|
|
|
2023-02-23 01:22:50 +02:00
|
|
|
TerminalDriver* terminal_driver = VesaTerminalDriver::create();
|
|
|
|
ASSERT(terminal_driver);
|
|
|
|
dprintln("VESA initialized");
|
|
|
|
TTY* tty1 = new TTY(terminal_driver);
|
2023-03-16 12:17:04 +02:00
|
|
|
ASSERT(tty1);
|
2023-01-12 13:20:38 +02:00
|
|
|
|
2023-02-01 21:05:44 +02:00
|
|
|
InterruptController::initialize(cmdline.force_pic);
|
2023-01-23 20:13:57 +02:00
|
|
|
dprintln("Interrupt controller initialized");
|
2023-02-01 01:53:35 +02:00
|
|
|
|
2023-01-04 19:22:23 +02:00
|
|
|
PIT::initialize();
|
2023-01-13 15:07:24 +02:00
|
|
|
dprintln("PIT initialized");
|
2023-02-22 22:29:31 +02:00
|
|
|
|
2022-12-30 19:38:21 +02:00
|
|
|
if (!Input::initialize())
|
2023-02-26 03:00:29 +02:00
|
|
|
dprintln("Could not initialize input drivers");
|
|
|
|
dprintln("Input initialized");
|
2022-11-15 21:42:14 +02:00
|
|
|
|
2023-03-07 19:17:49 +02:00
|
|
|
MUST(Scheduler::initialize());
|
2023-02-02 23:27:51 +02:00
|
|
|
Scheduler& scheduler = Scheduler::get();
|
2023-03-16 12:17:04 +02:00
|
|
|
#if 0
|
2023-03-13 15:32:46 +02:00
|
|
|
MUST(scheduler.add_thread(MUST(Thread::create(
|
|
|
|
[] (void*)
|
|
|
|
{
|
|
|
|
MMU::get().allocate_range((uintptr_t)&g_userspace_start, (uintptr_t)&g_userspace_end - (uintptr_t)&g_userspace_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
|
|
|
MMU::get().allocate_range((uintptr_t)&g_rodata_start, (uintptr_t)&g_rodata_end - (uintptr_t)&g_rodata_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
|
|
|
|
|
|
|
void* userspace_stack = kmalloc(4096, 4096);
|
|
|
|
ASSERT(userspace_stack);
|
|
|
|
MMU::get().allocate_page((uintptr_t)userspace_stack, MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
|
|
|
|
|
|
|
|
BOCHS_BREAK();
|
|
|
|
|
|
|
|
#if ARCH(x86_64)
|
|
|
|
asm volatile(
|
|
|
|
"pushq %0;"
|
|
|
|
"pushq %1;"
|
|
|
|
"pushfq;"
|
|
|
|
"pushq %2;"
|
|
|
|
"pushq %3;"
|
|
|
|
"iretq;"
|
|
|
|
:: "r"((uintptr_t)0x20 | 3), "r"((uintptr_t)userspace_stack + 4096), "r"((uintptr_t)0x18 | 3), "r"(userspace_entry)
|
|
|
|
);
|
|
|
|
#else
|
|
|
|
asm volatile(
|
|
|
|
"movl %0, %%eax;"
|
|
|
|
"movw %%ax, %%ds;"
|
|
|
|
"movw %%ax, %%es;"
|
|
|
|
"movw %%ax, %%fs;"
|
|
|
|
"movw %%ax, %%gs;"
|
|
|
|
|
|
|
|
"movl %1, %%esp;"
|
|
|
|
"pushl %0;"
|
|
|
|
"pushl %1;"
|
|
|
|
"pushfl;"
|
|
|
|
"pushl %2;"
|
|
|
|
"pushl %3;"
|
|
|
|
"iret;"
|
|
|
|
:: "r"((uintptr_t)0x20 | 3), "r"((uintptr_t)userspace_stack + 4096), "r"((uintptr_t)0x18 | 3), "r"(userspace_entry)
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
))));
|
|
|
|
#else
|
2023-03-16 12:17:04 +02:00
|
|
|
MUST(scheduler.add_thread(MUST(Thread::create(init2, tty1, nullptr))));
|
|
|
|
#endif
|
|
|
|
scheduler.start();
|
|
|
|
ASSERT(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void init2(void* tty1_ptr)
|
|
|
|
{
|
|
|
|
using namespace Kernel;
|
|
|
|
|
|
|
|
TTY* tty1 = (TTY*)tty1_ptr;
|
|
|
|
|
|
|
|
MUST(VirtualFileSystem::initialize());
|
2023-03-19 05:51:25 +02:00
|
|
|
if (auto res = VirtualFileSystem::get().mount_test(); res.is_error())
|
|
|
|
dwarnln("{}", res.error());
|
2023-03-16 12:17:04 +02:00
|
|
|
|
|
|
|
MUST(Process::create_kernel(
|
|
|
|
[](void* tty1)
|
2023-02-23 01:22:50 +02:00
|
|
|
{
|
2023-03-16 12:17:04 +02:00
|
|
|
Shell* shell = new Shell((TTY*)tty1);
|
2023-02-23 01:22:50 +02:00
|
|
|
ASSERT(shell);
|
|
|
|
shell->run();
|
2023-03-09 15:25:39 +02:00
|
|
|
}, tty1
|
2023-03-16 12:17:04 +02:00
|
|
|
));
|
2022-11-12 21:04:47 +02:00
|
|
|
}
|