forked from Bananymous/banan-os
Kernel: start work on higher half kernel
This commit is contained in:
parent
79315d318c
commit
0907965dc5
|
@ -125,7 +125,7 @@ if(ENABLE_KERNEL_UBSAN)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if("${BANAN_ARCH}" STREQUAL "x86_64")
|
if("${BANAN_ARCH}" STREQUAL "x86_64")
|
||||||
target_compile_options(kernel PUBLIC -mcmodel=large -mno-red-zone -mno-mmx)
|
target_compile_options(kernel PUBLIC -mcmodel=kernel -mno-red-zone -mno-mmx)
|
||||||
target_link_options(kernel PUBLIC LINKER:-z,max-page-size=4096)
|
target_link_options(kernel PUBLIC LINKER:-z,max-page-size=4096)
|
||||||
target_link_options(kernel PUBLIC LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/x86_64/linker.ld)
|
target_link_options(kernel PUBLIC LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/x86_64/linker.ld)
|
||||||
elseif("${BANAN_ARCH}" STREQUAL "i386")
|
elseif("${BANAN_ARCH}" STREQUAL "i386")
|
||||||
|
|
|
@ -101,6 +101,9 @@ namespace IDT
|
||||||
|
|
||||||
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, const Registers* regs)
|
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, const Registers* regs)
|
||||||
{
|
{
|
||||||
|
pid_t tid = Kernel::Scheduler::current_tid();
|
||||||
|
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
|
||||||
|
|
||||||
dwarnln(
|
dwarnln(
|
||||||
"{} (error code: 0x{16H}), pid {}, tid {}\r\n"
|
"{} (error code: 0x{16H}), pid {}, tid {}\r\n"
|
||||||
"Register dump\r\n"
|
"Register dump\r\n"
|
||||||
|
@ -108,14 +111,14 @@ namespace IDT
|
||||||
"rsp=0x{16H}, rbp=0x{16H}, rdi=0x{16H}, rsi=0x{16H}\r\n"
|
"rsp=0x{16H}, rbp=0x{16H}, rdi=0x{16H}, rsi=0x{16H}\r\n"
|
||||||
"rip=0x{16H}, rflags=0x{16H}\r\n"
|
"rip=0x{16H}, rflags=0x{16H}\r\n"
|
||||||
"cr0=0x{16H}, cr2=0x{16H}, cr3=0x{16H}, cr4=0x{16H}",
|
"cr0=0x{16H}, cr2=0x{16H}, cr3=0x{16H}, cr4=0x{16H}",
|
||||||
isr_exceptions[isr], error, Kernel::Process::current().pid(), Kernel::Thread::current().tid(),
|
isr_exceptions[isr], error, pid, tid,
|
||||||
regs->rax, regs->rbx, regs->rcx, regs->rdx,
|
regs->rax, regs->rbx, regs->rcx, regs->rdx,
|
||||||
regs->rsp, regs->rbp, regs->rdi, regs->rsi,
|
regs->rsp, regs->rbp, regs->rdi, regs->rsi,
|
||||||
regs->rip, regs->rflags,
|
regs->rip, regs->rflags,
|
||||||
regs->cr0, regs->cr2, regs->cr3, regs->cr4
|
regs->cr0, regs->cr2, regs->cr3, regs->cr4
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Kernel::Thread::current().is_userspace() && !Kernel::Thread::current().is_in_syscall())
|
if (tid && Kernel::Thread::current().is_userspace() && !Kernel::Thread::current().is_in_syscall())
|
||||||
{
|
{
|
||||||
auto message = BAN::String::formatted("{}, aborting\n", isr_exceptions[isr]);
|
auto message = BAN::String::formatted("{}, aborting\n", isr_exceptions[isr]);
|
||||||
(void)Kernel::Process::current().write(STDERR_FILENO, message.data(), message.size());
|
(void)Kernel::Process::current().write(STDERR_FILENO, message.data(), message.size());
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
kfree(s); \
|
kfree(s); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
extern uint8_t g_kernel_start[];
|
||||||
extern uint8_t g_kernel_end[];
|
extern uint8_t g_kernel_end[];
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
@ -20,6 +21,20 @@ namespace Kernel
|
||||||
static PageTable* s_kernel = nullptr;
|
static PageTable* s_kernel = nullptr;
|
||||||
static PageTable* s_current = nullptr;
|
static PageTable* s_current = nullptr;
|
||||||
|
|
||||||
|
static inline bool is_canonical(uintptr_t addr)
|
||||||
|
{
|
||||||
|
static constexpr uintptr_t mask = 0xFFFF800000000000;
|
||||||
|
addr &= mask;
|
||||||
|
return addr == mask || addr == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void uncanonicalize(uintptr_t& addr)
|
||||||
|
{
|
||||||
|
static constexpr uintptr_t mask = 0xFFFF800000000000;
|
||||||
|
addr &= mask;
|
||||||
|
ASSERT(addr == mask || addr == 0);
|
||||||
|
}
|
||||||
|
|
||||||
void PageTable::initialize()
|
void PageTable::initialize()
|
||||||
{
|
{
|
||||||
ASSERT(s_kernel == nullptr);
|
ASSERT(s_kernel == nullptr);
|
||||||
|
@ -56,7 +71,7 @@ namespace Kernel
|
||||||
|
|
||||||
// Identity map 4 KiB -> kernel end. We don't map the first page since nullptr derefs should
|
// Identity map 4 KiB -> kernel end. We don't map the first page since nullptr derefs should
|
||||||
// page fault. Also there isn't anything useful in that memory.
|
// page fault. Also there isn't anything useful in that memory.
|
||||||
identity_map_range(PAGE_SIZE, (uintptr_t)g_kernel_end, Flags::ReadWrite | Flags::Present);
|
identity_map_range((uintptr_t)g_kernel_start, (uintptr_t)(g_kernel_end - g_kernel_start), Flags::ReadWrite | Flags::Present);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
||||||
|
@ -169,7 +184,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
ASSERT((address >> 48) == 0);
|
uncanonicalize(address);
|
||||||
|
|
||||||
address &= PAGE_ADDR_MASK;
|
address &= PAGE_ADDR_MASK;
|
||||||
|
|
||||||
|
@ -212,8 +227,8 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
ASSERT((paddr >> 48) == 0);
|
ASSERT(is_canonical(paddr));
|
||||||
ASSERT((vaddr >> 48) == 0);
|
uncanonicalize(vaddr);
|
||||||
|
|
||||||
ASSERT(paddr % PAGE_SIZE == 0);
|
ASSERT(paddr % PAGE_SIZE == 0);
|
||||||
ASSERT(vaddr % PAGE_SIZE == 0);;
|
ASSERT(vaddr % PAGE_SIZE == 0);;
|
||||||
|
@ -257,7 +272,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
ASSERT((address >> 48) == 0);
|
uncanonicalize(address);
|
||||||
ASSERT(address % PAGE_SIZE == 0);
|
ASSERT(address % PAGE_SIZE == 0);
|
||||||
|
|
||||||
uint64_t pml4e = (address >> 39) & 0x1FF;
|
uint64_t pml4e = (address >> 39) & 0x1FF;
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
.set PG_READ_WRITE, 1<<1
|
.set PG_READ_WRITE, 1<<1
|
||||||
.set PG_PAGE_SIZE, 1<<7
|
.set PG_PAGE_SIZE, 1<<7
|
||||||
|
|
||||||
|
#define KERNEL_OFFSET 0xFFFFFFFF80000000
|
||||||
|
#define V2P(vaddr) ((vaddr) - KERNEL_OFFSET)
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
# Multiboot header
|
# Multiboot header
|
||||||
|
@ -49,16 +52,23 @@
|
||||||
# Identity map first GiB
|
# Identity map first GiB
|
||||||
.align 4096
|
.align 4096
|
||||||
boot_pml4:
|
boot_pml4:
|
||||||
.quad boot_pdpt + (PG_READ_WRITE | PG_PRESENT)
|
.quad V2P(boot_pdpt_lo) + (PG_READ_WRITE | PG_PRESENT)
|
||||||
|
.rept 510
|
||||||
|
.quad 0
|
||||||
|
.endr
|
||||||
|
.quad V2P(boot_pdpt_hi) + (PG_READ_WRITE | PG_PRESENT)
|
||||||
|
boot_pdpt_lo:
|
||||||
|
.quad V2P(boot_pd) + (PG_READ_WRITE | PG_PRESENT)
|
||||||
.rept 511
|
.rept 511
|
||||||
.quad 0
|
.quad 0
|
||||||
.endr
|
.endr
|
||||||
boot_pdpt:
|
boot_pdpt_hi:
|
||||||
.quad boot_pd + (PG_READ_WRITE | PG_PRESENT)
|
.rept 510
|
||||||
.rept 511
|
|
||||||
.quad 0
|
.quad 0
|
||||||
.endr
|
.endr
|
||||||
boot_pd:
|
.quad V2P(boot_pd) + (PG_READ_WRITE | PG_PRESENT)
|
||||||
|
.quad 0
|
||||||
|
boot_pd: # 1 GiB
|
||||||
.set i, 0
|
.set i, 0
|
||||||
.rept 512
|
.rept 512
|
||||||
.quad i + (PG_PAGE_SIZE | PG_READ_WRITE | PG_PRESENT)
|
.quad i + (PG_PAGE_SIZE | PG_READ_WRITE | PG_PRESENT)
|
||||||
|
@ -71,7 +81,7 @@ boot_gdt:
|
||||||
.quad 0x00AF92000000FFFF # kernel data
|
.quad 0x00AF92000000FFFF # kernel data
|
||||||
boot_gdtr:
|
boot_gdtr:
|
||||||
.short . - boot_gdt - 1
|
.short . - boot_gdt - 1
|
||||||
.quad boot_gdt
|
.quad V2P(boot_gdt)
|
||||||
|
|
||||||
has_cpuid:
|
has_cpuid:
|
||||||
pushfl
|
pushfl
|
||||||
|
@ -110,11 +120,11 @@ check_requirements:
|
||||||
copy_kernel_commandline:
|
copy_kernel_commandline:
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl g_multiboot_info, %esi
|
movl V2P(g_multiboot_info), %esi
|
||||||
addl $16, %esi
|
addl $16, %esi
|
||||||
movl (%esi), %esi
|
movl (%esi), %esi
|
||||||
movl $1024, %ecx
|
movl $1024, %ecx
|
||||||
movl $g_kernel_cmdline, %edi
|
movl $V2P(g_kernel_cmdline), %edi
|
||||||
rep movsl
|
rep movsl
|
||||||
popl %edi
|
popl %edi
|
||||||
popl %esi
|
popl %esi
|
||||||
|
@ -143,7 +153,7 @@ initialize_paging:
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
# set address of paging structures
|
# set address of paging structures
|
||||||
movl $boot_pml4, %ecx
|
movl $V2P(boot_pml4), %ecx
|
||||||
movl %ecx, %cr3
|
movl %ecx, %cr3
|
||||||
|
|
||||||
# enable paging
|
# enable paging
|
||||||
|
@ -157,9 +167,9 @@ initialize_paging:
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
# Initialize stack and multiboot info
|
# Initialize stack and multiboot info
|
||||||
movl $g_boot_stack_top, %esp
|
movl $V2P(g_boot_stack_top), %esp
|
||||||
movl %eax, g_multiboot_magic
|
movl %eax, V2P(g_multiboot_magic)
|
||||||
movl %ebx, g_multiboot_info
|
movl %ebx, V2P(g_multiboot_info)
|
||||||
|
|
||||||
call copy_kernel_commandline
|
call copy_kernel_commandline
|
||||||
call check_requirements
|
call check_requirements
|
||||||
|
@ -168,8 +178,8 @@ _start:
|
||||||
call initialize_paging
|
call initialize_paging
|
||||||
|
|
||||||
# flush gdt and jump to 64 bit
|
# flush gdt and jump to 64 bit
|
||||||
lgdt boot_gdtr
|
lgdt V2P(boot_gdtr)
|
||||||
ljmpl $0x08, $long_mode
|
ljmpl $0x08, $V2P(long_mode)
|
||||||
|
|
||||||
.code64
|
.code64
|
||||||
long_mode:
|
long_mode:
|
||||||
|
@ -183,6 +193,13 @@ long_mode:
|
||||||
movw %ax, %fs
|
movw %ax, %fs
|
||||||
movw %ax, %gs
|
movw %ax, %gs
|
||||||
|
|
||||||
|
# jump to higher half
|
||||||
|
movq $g_boot_stack_top, %rsp
|
||||||
|
movabsq $higher_half, %rcx
|
||||||
|
jmp *%rcx
|
||||||
|
|
||||||
|
higher_half:
|
||||||
|
|
||||||
# call global constuctors
|
# call global constuctors
|
||||||
call _init
|
call _init
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
ENTRY (_start)
|
ENTRY (_start)
|
||||||
|
|
||||||
|
KERNEL_OFFSET = 0xFFFFFFFF80000000;
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x00100000;
|
. = 0x00100000 + KERNEL_OFFSET;
|
||||||
|
|
||||||
g_kernel_start = .;
|
g_kernel_start = .;
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET)
|
||||||
{
|
{
|
||||||
*(.multiboot)
|
*(.multiboot)
|
||||||
*(.text)
|
*(.text)
|
||||||
}
|
}
|
||||||
.rodata BLOCK(4K) : ALIGN(4K)
|
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||||
{
|
{
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
}
|
}
|
||||||
.data BLOCK(4K) : ALIGN(4K)
|
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET)
|
||||||
{
|
{
|
||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
.bss BLOCK(4K) : ALIGN(4K)
|
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_OFFSET)
|
||||||
{
|
{
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss)
|
*(.bss)
|
||||||
|
|
Loading…
Reference in New Issue