forked from Bananymous/banan-os
Kernel: Finally managed to get 64-bit working
I had weird problems with interrupts but everything should work now
This commit is contained in:
parent
c4670f49d4
commit
b315fdc27f
|
@ -0,0 +1,8 @@
|
|||
ARCH_CFLAGS=
|
||||
ARCH_CPPFLAGS=
|
||||
KERNEL_ARCH_CFLAGS=
|
||||
KERNEL_ARCH_CPPFLAGS=
|
||||
|
||||
ARCH_FREEOBJS=\
|
||||
|
||||
ARCH_HOSTEDOBJS=\
|
|
@ -0,0 +1,236 @@
|
|||
#include <BAN/Errors.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <kernel/InterruptController.h>
|
||||
#include <kernel/kmalloc.h>
|
||||
#include <kernel/Panic.h>
|
||||
|
||||
#define REGISTER_ISR_HANDLER(i) register_interrupt_handler(i, isr ## i)
|
||||
#define REGISTER_IRQ_HANDLER(i) register_interrupt_handler(IRQ_VECTOR_BASE + i, irq ## i)
|
||||
|
||||
namespace IDT
|
||||
{
|
||||
|
||||
struct GateDescriptor
|
||||
{
|
||||
uint16_t offset1;
|
||||
uint16_t selector;
|
||||
uint8_t IST;
|
||||
uint8_t flags;
|
||||
uint16_t offset2;
|
||||
uint32_t offset3;
|
||||
uint32_t reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IDTR
|
||||
{
|
||||
uint16_t size;
|
||||
uint64_t offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
static IDTR s_idtr;
|
||||
static GateDescriptor* s_idt = nullptr;
|
||||
|
||||
static void (*s_irq_handlers[0x10])() { nullptr };
|
||||
|
||||
static const char* isr_exceptions[] =
|
||||
{
|
||||
"Division Error",
|
||||
"Debug",
|
||||
"Non-maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound Range Exception",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack-Segment Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"Unknown Exception 0x0F",
|
||||
"x87 Floating-Point Exception",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"SIMD Floating-Point Exception",
|
||||
"Virtualization Exception",
|
||||
"Control Protection Exception",
|
||||
"Unknown Exception 0x16",
|
||||
"Unknown Exception 0x17",
|
||||
"Unknown Exception 0x18",
|
||||
"Unknown Exception 0x19",
|
||||
"Unknown Exception 0x1A",
|
||||
"Unknown Exception 0x1B",
|
||||
"Hypervisor Injection Exception",
|
||||
"VMM Communication Exception",
|
||||
"Security Exception",
|
||||
"Unkown Exception 0x1F",
|
||||
};
|
||||
|
||||
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error)
|
||||
{
|
||||
uint64_t rax, rbx, rcx, rdx, rsp, rbp;
|
||||
uint64_t cr0, cr2, cr3, cr4;
|
||||
asm volatile("":"=a"(rax),"=b"(rbx),"=c"(rcx),"=d"(rdx));
|
||||
asm volatile("movq %%rsp, %%rax":"=a"(rsp));
|
||||
asm volatile("movq %%rbp, %%rax":"=a"(rbp));
|
||||
asm volatile("movq %%cr0, %%rax":"=a"(cr0));
|
||||
asm volatile("movq %%cr2, %%rax":"=a"(cr2));
|
||||
asm volatile("movq %%cr3, %%rax":"=a"(cr3));
|
||||
asm volatile("movq %%cr4, %%rax":"=a"(cr4));
|
||||
|
||||
Kernel::Panic(
|
||||
"{} (error code: 0x{16H})\r\n"
|
||||
"Register dump\r\n"
|
||||
"rax=0x{16H}, rbx=0x{16H}, rcx=0x{16H}, rdx=0x{16H}\r\n"
|
||||
"rsp=0x{16H}, rbp=0x{16H}\r\n"
|
||||
"CR0=0x{16H}, CR2=0x{16H}, CR3=0x{16H}, CR4=0x{16H}\r\n",
|
||||
isr_exceptions[isr], error, rax, rbx, rcx, rdx, rsp, rbp, cr0, cr2, cr3, cr4
|
||||
);
|
||||
}
|
||||
|
||||
extern "C" void cpp_irq_handler(uint64_t irq)
|
||||
{
|
||||
if (s_irq_handlers[irq])
|
||||
s_irq_handlers[irq]();
|
||||
else
|
||||
dprintln("no handler for irq 0x{2H}\n", irq);
|
||||
|
||||
InterruptController::Get().EOI(irq);
|
||||
}
|
||||
|
||||
static void flush_idt()
|
||||
{
|
||||
asm volatile("lidt %0"::"m"(s_idtr));
|
||||
}
|
||||
|
||||
static void register_interrupt_handler(uint8_t index, void (*f)())
|
||||
{
|
||||
GateDescriptor& descriptor = s_idt[index];
|
||||
descriptor.offset1 = (uint16_t)((uint64_t)f >> 0);
|
||||
descriptor.offset2 = (uint16_t)((uint64_t)f >> 16);
|
||||
descriptor.offset3 = (uint32_t)((uint64_t)f >> 32);
|
||||
|
||||
descriptor.selector = 0x08;
|
||||
descriptor.IST = 0;
|
||||
descriptor.flags = 0x8E;
|
||||
}
|
||||
|
||||
void register_irq_handler(uint8_t irq, void (*f)())
|
||||
{
|
||||
s_irq_handlers[irq] = f;
|
||||
}
|
||||
|
||||
extern "C" void isr0();
|
||||
extern "C" void isr1();
|
||||
extern "C" void isr2();
|
||||
extern "C" void isr3();
|
||||
extern "C" void isr4();
|
||||
extern "C" void isr5();
|
||||
extern "C" void isr6();
|
||||
extern "C" void isr7();
|
||||
extern "C" void isr8();
|
||||
extern "C" void isr9();
|
||||
extern "C" void isr10();
|
||||
extern "C" void isr11();
|
||||
extern "C" void isr12();
|
||||
extern "C" void isr13();
|
||||
extern "C" void isr14();
|
||||
extern "C" void isr15();
|
||||
extern "C" void isr16();
|
||||
extern "C" void isr17();
|
||||
extern "C" void isr18();
|
||||
extern "C" void isr19();
|
||||
extern "C" void isr20();
|
||||
extern "C" void isr21();
|
||||
extern "C" void isr22();
|
||||
extern "C" void isr23();
|
||||
extern "C" void isr24();
|
||||
extern "C" void isr25();
|
||||
extern "C" void isr26();
|
||||
extern "C" void isr27();
|
||||
extern "C" void isr28();
|
||||
extern "C" void isr29();
|
||||
extern "C" void isr30();
|
||||
extern "C" void isr31();
|
||||
|
||||
extern "C" void irq0();
|
||||
extern "C" void irq1();
|
||||
extern "C" void irq2();
|
||||
extern "C" void irq3();
|
||||
extern "C" void irq4();
|
||||
extern "C" void irq5();
|
||||
extern "C" void irq6();
|
||||
extern "C" void irq7();
|
||||
extern "C" void irq8();
|
||||
extern "C" void irq9();
|
||||
extern "C" void irq10();
|
||||
extern "C" void irq11();
|
||||
extern "C" void irq12();
|
||||
extern "C" void irq13();
|
||||
extern "C" void irq14();
|
||||
extern "C" void irq15();
|
||||
|
||||
void initialize()
|
||||
{
|
||||
s_idt = (GateDescriptor*)kmalloc_eternal(0x100 * sizeof(GateDescriptor));
|
||||
memset(s_idt, 0x00, 0x100 * sizeof(GateDescriptor));
|
||||
|
||||
s_idtr.offset = (uint64_t)s_idt;
|
||||
s_idtr.size = 0x100 * sizeof(GateDescriptor) - 1;
|
||||
|
||||
REGISTER_ISR_HANDLER(0);
|
||||
REGISTER_ISR_HANDLER(1);
|
||||
REGISTER_ISR_HANDLER(2);
|
||||
REGISTER_ISR_HANDLER(3);
|
||||
REGISTER_ISR_HANDLER(4);
|
||||
REGISTER_ISR_HANDLER(5);
|
||||
REGISTER_ISR_HANDLER(6);
|
||||
REGISTER_ISR_HANDLER(7);
|
||||
REGISTER_ISR_HANDLER(8);
|
||||
REGISTER_ISR_HANDLER(9);
|
||||
REGISTER_ISR_HANDLER(10);
|
||||
REGISTER_ISR_HANDLER(11);
|
||||
REGISTER_ISR_HANDLER(12);
|
||||
REGISTER_ISR_HANDLER(13);
|
||||
REGISTER_ISR_HANDLER(14);
|
||||
REGISTER_ISR_HANDLER(15);
|
||||
REGISTER_ISR_HANDLER(16);
|
||||
REGISTER_ISR_HANDLER(17);
|
||||
REGISTER_ISR_HANDLER(18);
|
||||
REGISTER_ISR_HANDLER(19);
|
||||
REGISTER_ISR_HANDLER(20);
|
||||
REGISTER_ISR_HANDLER(21);
|
||||
REGISTER_ISR_HANDLER(22);
|
||||
REGISTER_ISR_HANDLER(23);
|
||||
REGISTER_ISR_HANDLER(24);
|
||||
REGISTER_ISR_HANDLER(25);
|
||||
REGISTER_ISR_HANDLER(26);
|
||||
REGISTER_ISR_HANDLER(27);
|
||||
REGISTER_ISR_HANDLER(28);
|
||||
REGISTER_ISR_HANDLER(29);
|
||||
REGISTER_ISR_HANDLER(30);
|
||||
REGISTER_ISR_HANDLER(31);
|
||||
|
||||
REGISTER_IRQ_HANDLER(0);
|
||||
REGISTER_IRQ_HANDLER(1);
|
||||
REGISTER_IRQ_HANDLER(2);
|
||||
REGISTER_IRQ_HANDLER(3);
|
||||
REGISTER_IRQ_HANDLER(4);
|
||||
REGISTER_IRQ_HANDLER(5);
|
||||
REGISTER_IRQ_HANDLER(6);
|
||||
REGISTER_IRQ_HANDLER(7);
|
||||
REGISTER_IRQ_HANDLER(8);
|
||||
REGISTER_IRQ_HANDLER(9);
|
||||
REGISTER_IRQ_HANDLER(10);
|
||||
REGISTER_IRQ_HANDLER(11);
|
||||
REGISTER_IRQ_HANDLER(12);
|
||||
REGISTER_IRQ_HANDLER(13);
|
||||
REGISTER_IRQ_HANDLER(14);
|
||||
REGISTER_IRQ_HANDLER(15);
|
||||
|
||||
flush_idt();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
#include <BAN/Errors.h>
|
||||
#include <kernel/kmalloc.h>
|
||||
#include <kernel/MMU.h>
|
||||
|
||||
#define PRESENT (1 << 0)
|
||||
#define READ_WRITE (1 << 1)
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define PAGE_MASK ~(PAGE_SIZE - 1)
|
||||
|
||||
#define CLEANUP_STRUCTURE(s) \
|
||||
for (uint64_t i = 0; i < 512; i++) \
|
||||
if (s[i] & PRESENT) \
|
||||
goto cleanup_done; \
|
||||
kfree(s)
|
||||
|
||||
static MMU* s_instance = nullptr;
|
||||
|
||||
void MMU::Intialize()
|
||||
{
|
||||
ASSERT(s_instance == nullptr);
|
||||
s_instance = new MMU();
|
||||
}
|
||||
|
||||
MMU& MMU::Get()
|
||||
{
|
||||
ASSERT(s_instance);
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
static uint64_t* allocate_page_aligned_page()
|
||||
{
|
||||
void* page = kmalloc(PAGE_SIZE, PAGE_SIZE);
|
||||
ASSERT(page);
|
||||
memset(page, 0, PAGE_SIZE);
|
||||
return (uint64_t*)page;
|
||||
}
|
||||
|
||||
MMU::MMU()
|
||||
{
|
||||
// Identity map from 4 KiB -> 4 MiB
|
||||
m_highest_paging_struct = allocate_page_aligned_page();
|
||||
|
||||
uint64_t* pdpt = allocate_page_aligned_page();
|
||||
m_highest_paging_struct[0] = (uint64_t)pdpt | READ_WRITE | PRESENT;
|
||||
|
||||
uint64_t* pd = allocate_page_aligned_page();
|
||||
pdpt[0] = (uint64_t)pd | READ_WRITE | PRESENT;
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
uint64_t* pt = allocate_page_aligned_page();
|
||||
for (uint64_t j = 0; j < 512; j++)
|
||||
pt[j] = (i << 21) | (j << 12) | READ_WRITE | PRESENT;
|
||||
pd[i] = (uint64_t)pt | READ_WRITE | PRESENT;
|
||||
}
|
||||
|
||||
// Unmap 0 -> 4 KiB
|
||||
uint64_t* pt1 = (uint64_t*)(pd[0] & PAGE_MASK);
|
||||
pt1[0] = 0;
|
||||
|
||||
// Load the new pml4
|
||||
asm volatile("movq %0, %%cr3" :: "r"(m_highest_paging_struct));
|
||||
}
|
||||
|
||||
void MMU::AllocatePage(uintptr_t address)
|
||||
{
|
||||
ASSERT((address >> 48) == 0);
|
||||
|
||||
address &= PAGE_MASK;
|
||||
|
||||
uint64_t pml4e = (address >> 39) & 0x1FF;
|
||||
uint64_t pdpte = (address >> 30) & 0x1FF;
|
||||
uint64_t pde = (address >> 21) & 0x1FF;
|
||||
uint64_t pte = (address >> 12) & 0x1FF;
|
||||
|
||||
uint64_t* pml4 = m_highest_paging_struct;
|
||||
if (!(pml4[pml4e] & PRESENT))
|
||||
{
|
||||
uint64_t* pdpt = allocate_page_aligned_page();
|
||||
pml4[pml4e] = (uint64_t)pdpt | READ_WRITE | PRESENT;
|
||||
}
|
||||
|
||||
uint64_t* pdpt = (uint64_t*)(pml4[pml4e] & PAGE_MASK);
|
||||
if (!(pdpt[pdpte] & PRESENT))
|
||||
{
|
||||
uint64_t* pd = allocate_page_aligned_page();
|
||||
pdpt[pdpte] = (uint64_t)pd | READ_WRITE | PRESENT;
|
||||
}
|
||||
|
||||
uint64_t* pd = (uint64_t*)(pdpt[pdpte] & PAGE_MASK);
|
||||
if (!(pd[pde] & PRESENT))
|
||||
{
|
||||
uint64_t* pt = allocate_page_aligned_page();
|
||||
pd[pde] = (uint64_t)pt | READ_WRITE | PRESENT;
|
||||
}
|
||||
|
||||
uint64_t* pt = (uint64_t*)(pd[pde] & PAGE_MASK);
|
||||
if (!(pt[pte] & PRESENT))
|
||||
pt[pte] = address | READ_WRITE | PRESENT;
|
||||
|
||||
asm volatile("invlpg (%0)" :: "r"(address) : "memory");
|
||||
}
|
||||
|
||||
void MMU::AllocateRange(uintptr_t address, ptrdiff_t size)
|
||||
{
|
||||
uintptr_t s_page = address & PAGE_MASK;
|
||||
uintptr_t e_page = (address + size - 1) & PAGE_MASK;
|
||||
for (uintptr_t page = s_page; page <= e_page; page += PAGE_SIZE)
|
||||
AllocatePage(page);
|
||||
}
|
||||
|
||||
void MMU::UnAllocatePage(uintptr_t address)
|
||||
{
|
||||
ASSERT((address >> 48) == 0);
|
||||
|
||||
address &= PAGE_MASK;
|
||||
|
||||
uint64_t pml4e = (address >> 39) & 0x1FF;
|
||||
uint64_t pdpte = (address >> 30) & 0x1FF;
|
||||
uint64_t pde = (address >> 21) & 0x1FF;
|
||||
uint64_t pte = (address >> 12) & 0x1FF;
|
||||
|
||||
uint64_t* pml4 = m_highest_paging_struct;
|
||||
ASSERT(pml4[pml4e] & PRESENT);
|
||||
|
||||
uint64_t* pdpt = (uint64_t*)(pml4[pml4e] & PAGE_MASK);
|
||||
ASSERT(pdpt[pdpte] & PRESENT);
|
||||
|
||||
uint64_t* pd = (uint64_t*)(pdpt[pdpte] & PAGE_MASK);
|
||||
ASSERT(pd[pde] & PRESENT);
|
||||
|
||||
uint64_t* pt = (uint64_t*)(pd[pde] & PAGE_MASK);
|
||||
ASSERT(pt[pte] & PRESENT);
|
||||
|
||||
pt[pte] = 0;
|
||||
|
||||
CLEANUP_STRUCTURE(pt);
|
||||
pd[pde] = 0;
|
||||
CLEANUP_STRUCTURE(pd);
|
||||
pdpt[pdpte] = 0;
|
||||
CLEANUP_STRUCTURE(pdpt);
|
||||
pml4[pml4e] = 0;
|
||||
cleanup_done:
|
||||
|
||||
asm volatile("invlpg (%0)" :: "r"(address) : "memory");
|
||||
}
|
||||
|
||||
void MMU::UnAllocateRange(uintptr_t address, ptrdiff_t size)
|
||||
{
|
||||
uintptr_t s_page = address & PAGE_MASK;
|
||||
uintptr_t e_page = (address + size - 1) & PAGE_MASK;
|
||||
for (uintptr_t page = s_page; page <= e_page; page += PAGE_SIZE)
|
||||
UnAllocatePage(page);
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
# Declare constants for the multiboot header
|
||||
.set ALIGN, 1<<0 # align loaded modules on page boundaries
|
||||
.set MEMINFO, 1<<1 # provide memory map
|
||||
.set VIDEOINFO, 1<<2 # provide video info
|
||||
.set MB_FLAGS, ALIGN | MEMINFO | VIDEOINFO # this is the Multiboot 'flag' field
|
||||
.set MB_MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
|
||||
.set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS) #checksum of above, to prove we are multiboot
|
||||
|
||||
.set PG_PRESENT, 1<<0
|
||||
.set PG_READ_WRITE, 1<<1
|
||||
.set PG_PAGE_SIZE, 1<<7
|
||||
|
||||
.code32
|
||||
|
||||
# Multiboot header
|
||||
.section .multiboot, "aw"
|
||||
.align 4
|
||||
.long MB_MAGIC
|
||||
.long MB_FLAGS
|
||||
.long MB_CHECKSUM
|
||||
.skip 20
|
||||
|
||||
.long 0
|
||||
.long 800
|
||||
.long 600
|
||||
.long 32
|
||||
|
||||
.section .bss, "aw", @nobits
|
||||
# Create stack
|
||||
stack_bottom:
|
||||
.skip 16384
|
||||
stack_top:
|
||||
|
||||
.global g_kernel_cmdline
|
||||
g_kernel_cmdline:
|
||||
.skip 4096
|
||||
|
||||
# Reserve memory for paging structures,
|
||||
# we will identity map first 4 MiB
|
||||
|
||||
# 0 MiB -> 1 MiB: bootloader stuff
|
||||
# 1 MiB -> 2 MiB: kernel
|
||||
# 2 MiB -> 3 MiB: kmalloc
|
||||
# 3 MiB -> 4 MiB: kmalloc_eternal
|
||||
.align 4096
|
||||
boot_pml4:
|
||||
.skip 512 * 8
|
||||
boot_pdpt1:
|
||||
.skip 512 * 8
|
||||
boot_pd1:
|
||||
.skip 512 * 8
|
||||
|
||||
.section .text, "a"
|
||||
|
||||
.global g_multiboot_info
|
||||
g_multiboot_info:
|
||||
.skip 8
|
||||
.global g_multiboot_magic
|
||||
g_multiboot_magic:
|
||||
.skip 8
|
||||
|
||||
boot_gdt:
|
||||
.quad 0 // null
|
||||
.quad (1<<53) | (1<<47) | (1<<44) | (1<<43) // kernel code P,S,E,L (present, code/data, executable, long mode)
|
||||
boot_gdtr:
|
||||
.short . - boot_gdt - 1
|
||||
.quad boot_gdt
|
||||
|
||||
has_cpuid:
|
||||
pushfl
|
||||
pushfl
|
||||
xorl $0x00200000, (%esp)
|
||||
popfl
|
||||
pushfl
|
||||
popl %eax
|
||||
xorl (%esp), %eax
|
||||
popfl
|
||||
testl $0x00200000, %eax
|
||||
ret
|
||||
|
||||
is_64_bit:
|
||||
movl $0x80000000, %eax
|
||||
cpuid
|
||||
cmpl $0x80000001, %eax
|
||||
jl .no_extension
|
||||
movl $0x80000001, %eax
|
||||
cpuid
|
||||
testl $(1 << 29), %edx
|
||||
ret
|
||||
.no_extension:
|
||||
cmpl %eax, %eax
|
||||
ret
|
||||
|
||||
check_requirements:
|
||||
call has_cpuid
|
||||
jz .exit
|
||||
call is_64_bit
|
||||
jz .exit
|
||||
ret
|
||||
.exit:
|
||||
jmp system_halt
|
||||
|
||||
copy_kernel_commandline:
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
movl g_multiboot_info, %esi
|
||||
addl $16, %esi
|
||||
movl (%esi), %esi
|
||||
movl $1024, %ecx
|
||||
movl $g_kernel_cmdline, %edi
|
||||
rep movsl
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
enable_sse:
|
||||
movl %cr0, %eax
|
||||
andw $0xFFFB, %ax
|
||||
orw $0x0002, %ax
|
||||
movl %eax, %cr0
|
||||
movl %cr4, %eax
|
||||
orw $0x0600, %ax
|
||||
movl %eax, %cr4
|
||||
ret
|
||||
|
||||
initialize_paging:
|
||||
# identity map first 4 MiB
|
||||
movl $(0x00000000 + PG_PAGE_SIZE + PG_READ_WRITE + PG_PRESENT), boot_pd1 + 0
|
||||
movl $(0x00200000 + PG_PAGE_SIZE + PG_READ_WRITE + PG_PRESENT), boot_pd1 + 8
|
||||
|
||||
# set pdpte1 and pml4e1
|
||||
movl $(boot_pd1 + PG_READ_WRITE + PG_PRESENT), boot_pdpt1
|
||||
movl $(boot_pdpt1 + PG_READ_WRITE + PG_PRESENT), boot_pml4
|
||||
|
||||
# enable PAE
|
||||
movl %cr4, %ecx
|
||||
orl $0x20, %ecx
|
||||
movl %ecx, %cr4
|
||||
|
||||
# set long mode enable bit
|
||||
movl $0x100, %eax
|
||||
movl $0x000, %edx
|
||||
movl $0xC0000080, %ecx
|
||||
wrmsr
|
||||
|
||||
# set address of paging structures
|
||||
movl $boot_pml4, %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# enable paging
|
||||
movl %cr0, %ecx
|
||||
orl $0x80000000, %ecx
|
||||
movl %ecx, %cr0
|
||||
|
||||
ret
|
||||
|
||||
.global _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
# Initialize stack and multiboot info
|
||||
movl $stack_top, %esp
|
||||
movl %eax, g_multiboot_magic
|
||||
movl %ebx, g_multiboot_info
|
||||
|
||||
call copy_kernel_commandline
|
||||
call check_requirements
|
||||
call enable_sse
|
||||
|
||||
call initialize_paging
|
||||
|
||||
# flush gdt and jump to 64 bit
|
||||
lgdt boot_gdtr
|
||||
ljmpl $0x08, $long_mode
|
||||
|
||||
.code64
|
||||
long_mode:
|
||||
# clear segment registers
|
||||
movw $0x00, %ax
|
||||
movw %ax, %ss
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
# call global constuctors
|
||||
call _init
|
||||
|
||||
# call to the kernel itself (clear ebp for stacktrace)
|
||||
xorq %rbp, %rbp
|
||||
call kernel_main
|
||||
|
||||
# call global destructors
|
||||
call _fini
|
||||
|
||||
system_halt:
|
||||
xchgw %bx, %bx
|
||||
cli
|
||||
1: hlt
|
||||
jmp 1b
|
|
@ -0,0 +1,16 @@
|
|||
/* x86-64 crti.s */
|
||||
.section .init
|
||||
.global _init
|
||||
.type _init, @function
|
||||
_init:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
|
||||
|
||||
.section .fini
|
||||
.global _fini
|
||||
.type _fini, @function
|
||||
_fini:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */
|
|
@ -0,0 +1,10 @@
|
|||
/* x86-64 crtn.s */
|
||||
.section .init
|
||||
/* gcc will nicely put the contents of crtend.o's .init section here. */
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.section .fini
|
||||
/* gcc will nicely put the contents of crtend.o's .fini section here. */
|
||||
popq %rbp
|
||||
ret
|
|
@ -0,0 +1,128 @@
|
|||
.macro pushaq
|
||||
pushq %rax
|
||||
pushq %rbx
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
pushq %rbp
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %r8
|
||||
pushq %r9
|
||||
pushq %r10
|
||||
pushq %r11
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
.endm
|
||||
|
||||
.macro popaq
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %r11
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
popq %rbp
|
||||
popq %rdx
|
||||
popq %rcx
|
||||
popq %rbx
|
||||
popq %rax
|
||||
.endm
|
||||
|
||||
isr_stub:
|
||||
pushaq
|
||||
movq 120(%rsp), %rdi
|
||||
movq 128(%rsp), %rsi
|
||||
call cpp_isr_handler
|
||||
popaq
|
||||
addq $16, %rsp
|
||||
iretq
|
||||
|
||||
irq_stub:
|
||||
pushaq
|
||||
movq 120(%rsp), %rdi
|
||||
call cpp_irq_handler
|
||||
popaq
|
||||
addq $16, %rsp
|
||||
iretq
|
||||
|
||||
.macro isr n
|
||||
.global isr\n
|
||||
isr\n:
|
||||
cli
|
||||
pushq $0
|
||||
pushq $\n
|
||||
jmp isr_stub
|
||||
.endm
|
||||
|
||||
.macro isr_err n
|
||||
.global isr\n
|
||||
isr\n:
|
||||
cli
|
||||
pushq $\n
|
||||
jmp isr_stub
|
||||
.endm
|
||||
|
||||
.macro irq n
|
||||
.global irq\n
|
||||
irq\n:
|
||||
cli
|
||||
pushq $0
|
||||
pushq $\n
|
||||
jmp irq_stub
|
||||
.endm
|
||||
|
||||
isr 0
|
||||
isr 1
|
||||
isr 2
|
||||
isr 3
|
||||
isr 4
|
||||
isr 5
|
||||
isr 6
|
||||
isr 7
|
||||
isr_err 8
|
||||
isr 9
|
||||
isr_err 10
|
||||
isr_err 11
|
||||
isr_err 12
|
||||
isr_err 13
|
||||
isr_err 14
|
||||
isr 15
|
||||
isr 16
|
||||
isr_err 17
|
||||
isr 18
|
||||
isr 19
|
||||
isr 20
|
||||
isr 21
|
||||
isr 22
|
||||
isr 23
|
||||
isr 24
|
||||
isr 25
|
||||
isr 26
|
||||
isr 27
|
||||
isr 28
|
||||
isr 29
|
||||
isr 30
|
||||
isr 31
|
||||
|
||||
irq 0
|
||||
irq 1
|
||||
irq 2
|
||||
irq 3
|
||||
irq 4
|
||||
irq 5
|
||||
irq 6
|
||||
irq 7
|
||||
irq 8
|
||||
irq 9
|
||||
irq 10
|
||||
irq 11
|
||||
irq 12
|
||||
irq 13
|
||||
irq 14
|
||||
irq 15
|
|
@ -0,0 +1,27 @@
|
|||
ENTRY (_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00100000;
|
||||
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
g_kernel_end = .;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
KERNEL_ARCH_CFLAGS=-mcmodel=large -mno-red-zone -mno-mmx
|
||||
KERNEL_ARCH_CPPFLAGS=
|
||||
KERNEL_ARCH_LDFLAGS=-z max-page-size=4096
|
||||
KERNEL_ARCH_LIBS=
|
||||
|
||||
KERNEL_ARCH_OBJS= \
|
||||
$(ARCHDIR)/boot.o \
|
||||
$(ARCHDIR)/IDT.o \
|
||||
$(ARCHDIR)/MMU.o \
|
||||
$(ARCHDIR)/interrupts.o \
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ARCH_CFLAGS=
|
||||
ARCH_CPPFLAGS=
|
||||
KERNEL_ARCH_CFLAGS=
|
||||
KERNEL_ARCH_CPPFLAGS=
|
||||
|
||||
ARCH_FREEOBJS=\
|
||||
|
||||
ARCH_HOSTEDOBJS=\
|
Loading…
Reference in New Issue