Ahh... Added support for x86_64 PAE paging. But realized that I need to add support for loading elf64, which hopefully will be done by tomorrow.

This commit is contained in:
HyperAssembler 2015-01-31 23:36:32 -08:00
parent 250299c378
commit 7568cb5890
5 changed files with 144 additions and 51 deletions

View File

@ -1,13 +1,9 @@
OUTPUT_FORMAT(binary)
SECTIONS
{
.text.start (0x1000000):
.text.start(0x100000) :
{
*(.multiboot)
}
.text :
{
*(.text)
}

View File

@ -1,32 +1,33 @@
global kernel_stack
extern hk_main
global kernel_addr
[SECTION .multiboot]
[BITS 32]
GRUB_LOADED_FLAG equ 0x2BADB002
GRUB_MAGIC_NUMBER equ 0x1BADB002
GRUB_FLAGS equ 0x10003
GRUB_CHECK_SUM equ -(GRUB_MAGIC_NUMBER + GRUB_FLAGS)
GRUB_HEADER_ADDR:
dd GRUB_MAGIC_NUMBER
dd GRUB_FLAGS
dd GRUB_CHECK_SUM
GRUB_MAGIC equ 0x2BADB002
MULTIBOOT_MAGIC_NUMBER equ 0x1BADB002
MULTIBOOT_FLAGS equ 0x10003
MULTIBOOT_CHECK_SUM equ -(MULTIBOOT_MAGIC_NUMBER + MULTIBOOT_FLAGS)
MULTIBOOT_HEADER:
dd MULTIBOOT_MAGIC_NUMBER
dd MULTIBOOT_FLAGS
dd MULTIBOOT_CHECK_SUM
dd GRUB_HEADER_ADDR
dd GRUB_HEADER_ADDR
dd MULTIBOOT_HEADER
dd MULTIBOOT_HEADER
dd 0
dd 0
dd GRUB_ENTRY_ADDR
dd hk_grub_main
times 4096 db 0
kernel_stack:
GRUB_ENTRY_ADDR:
hk_grub_main:
cli
cmp eax,GRUB_LOADED_FLAG
jmp LOADED_BY_GRUB
cmp eax,GRUB_MAGIC
jmp hk_grub_main.loaded_by_grub
hlt
LOADED_BY_GRUB:
.loaded_by_grub:
mov eax,kernel_stack
mov esp,eax
@ -35,6 +36,5 @@ push dword 0
popfd
push ebx
;jmp since we are not coming back here :D
call hk_main
add esp,4
add esp,4 ; We are actually not coming back here. But out of courtesy...

View File

@ -9,8 +9,6 @@ gdt_ptr g_gdt_ptr;
uint8 g_idt[8 * 256];
idt_ptr g_idt_ptr;
extern uint32 text_pos;
extern int32* kernel_stack;
void HYPKERNEL32 hk_delay(uint32 i)
@ -32,27 +30,30 @@ void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
uint32 i = 0;
text_pos = 0;
hk_print_str("Welcome to HYP OS! Please wait while we are gathering information...\n\n");
hk_print_str("Kernel loaded to address ");
// hk_print_hex(*kernel_addr);
hk_print_str(".\n\n");
segment_descriptor desc_dummy = {.DPL = 0, .Pr = 0, .x64 = 0, .Sys = 0, .type = 0, .Sz = 0, .limit = 0, .Gr = 0, .base = 0, .Avl = 0};
segment_descriptor desc = {.Gr = 1, .Pr = 1, .Sz = 1, .Avl = 0, .Sys = 1, .x64 = 0, .base = 0, .limit = 0xFFFFF};
segment_descriptor desc_dummy = {.DPL = 0, .Pr = 0, .x64 = 0, .Sys = 0, .type = 0, .Sz = 0, .limit = 0, .Gr = 0, .base = 0, .Acc = 0};
segment_descriptor desc = {.Gr = 1, .Pr = 1, .Sz = 1, .Acc = 0, .Sys = 1, .x64 = 0, .base = 0, .limit = 0xFFFFF};
hk_print_str("*Setting up GDT...\n\n");
//dummy descriptor
hk_set_segment_descriptor(&g_gdt[0], &desc_dummy);
hk_write_segment_descriptor(&g_gdt[0], &desc_dummy);
//ring 0 code seg, non-conforming
desc.type = 10;
desc.DPL = 0;
hk_set_segment_descriptor(&g_gdt[8], &desc);
hk_write_segment_descriptor(&g_gdt[8], &desc);
//ring 3 code seg
desc.DPL = 3;
hk_set_segment_descriptor(&g_gdt[16], &desc);
hk_write_segment_descriptor(&g_gdt[16], &desc);
//ring 0 data RW
desc.DPL = 0;
desc.type = 2;
hk_set_segment_descriptor(&g_gdt[24], &desc);
hk_write_segment_descriptor(&g_gdt[24], &desc);
//ring 3 data
desc.DPL = 3;
hk_set_segment_descriptor(&g_gdt[32], &desc);
hk_write_segment_descriptor(&g_gdt[32], &desc);
g_gdt_ptr.limit = 8 * 8 - 1;
g_gdt_ptr.base = (uint32) g_gdt;
hk_load_gdt(&g_gdt_ptr, SEGMENT_SELECTOR(1, 0), SEGMENT_SELECTOR(3, 0));
@ -135,14 +136,15 @@ void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
hk_print_str("*Checking architecture...\n");
if (hk_support_x64() == 0)
{
hk_print_str("Arch: x86.\n\nInformation obtained. Countinue to x86 mode...");
hk_print_str("Arch: x86.");
x86:
goto x86;
}
else
{
hk_print_str("Arch: x86_64.\n\nInformation obtained. Countinue to x86_64 mode...");
hk_print_str("Arch: x86_64.");
}
//Setup x64
x64:
goto x64;

View File

@ -1,10 +1,71 @@
#include "kdef.h"
#include "mem.h"
int32 HYPKERNEL32 hk_set_segment_descriptor(uint8* const gdt, segment_descriptor const * const seg_desc)
void HYPKERNEL32 hk_write_pml4_entry(uint8 * const base, pml4_entry const * const p_entry)
{
if(base == NULL || p_entry == NULL)
return;
base[0] = (uint8)((p_entry->Pr & 0x1) + ((p_entry->RW & 0x1) << 1) + ((p_entry->USU & 0x1) << 2) + ((p_entry->PWT & 0x1) << 3) + ((p_entry->PCD & 0x1) << 4) + ((p_entry->Acc & 0x1) << 5) + ((p_entry->Sz & 0x1) << 7));
base[1] = (uint8)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pdpt_entry(uint8 * const base, pdpt_entry const * const p_entry)
{
if(base == NULL || p_entry == NULL)
return;
base[0] = (uint8)((p_entry->Pr & 0x1) + ((p_entry->RW & 0x1) << 1) + ((p_entry->USU & 0x1) << 2) + ((p_entry->PWT & 0x1) << 3) + ((p_entry->PCD & 0x1) << 4) + ((p_entry->Acc & 0x1) << 5) + ((p_entry->Sz & 0x1) << 7));
base[1] = (uint8)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pd_entry(uint8 * const base, pd_entry const * const p_entry)
{
if(base == NULL || p_entry == NULL)
return;
base[0] = (uint8)((p_entry->Pr & 0x1) + ((p_entry->RW & 0x1) << 1) + ((p_entry->USU & 0x1) << 2) + ((p_entry->PWT & 0x1) << 3) + ((p_entry->PCD & 0x1) << 4) + ((p_entry->Acc & 0x1) << 5) + ((p_entry->Sz & 0x1) << 7));
base[1] = (uint8)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pt_entry(uint8 * const base, pt_entry const * const p_entry)
{
if(base == NULL || p_entry == NULL)
return;
base[0] = (uint8)((p_entry->Pr & 0x1) + ((p_entry->RW & 0x1) << 1) + ((p_entry->USU & 0x1) << 2) + ((p_entry->PWT & 0x1) << 3) + ((p_entry->PCD & 0x1) << 4) + ((p_entry->Acc & 0x1) << 5) + ((p_entry->dirty & 0x1) << 6) + ((p_entry->PAT & 0x1) << 7));
base[1] = (uint8)((((p_entry->base >> 12) & 0xF) << 4) + (p_entry->Gl & 0x1)); // 4 bits
base[2] = (uint8)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_segment_descriptor(uint8 *const gdt, segment_descriptor const *const seg_desc)
{
if (gdt == NULL || seg_desc == NULL)
return -1;
return;
gdt[0] = (uint8)(seg_desc->limit & 0xFF);
gdt[1] = (uint8)((seg_desc->limit >> 8) & 0xFF);
gdt[6] = gdt[6] | (uint8)((seg_desc->limit >> 16) & 0xFF);
@ -15,14 +76,14 @@ int32 HYPKERNEL32 hk_set_segment_descriptor(uint8* const gdt, segment_descriptor
gdt[7] = (uint8)((seg_desc->base >> 24) & 0xFF);
gdt[5] = (uint8)((seg_desc->type & 0xF) + ((seg_desc->Sys & 0x1) << 4) + ((seg_desc->DPL & 0x3) << 5) + ((seg_desc->Pr & 0x1 ) << 7));
gdt[6] = gdt[6] | (uint8)(((seg_desc->Avl & 0x1) + ((seg_desc->x64 & 0x1) << 1) + ((seg_desc->Sz & 0x1) << 2) + ((seg_desc->Gr & 0x1) << 3)) << 4);
return 0;
gdt[6] = gdt[6] | (uint8)(((seg_desc->Acc & 0x1) + ((seg_desc->x64 & 0x1) << 1) + ((seg_desc->Sz & 0x1) << 2) + ((seg_desc->Gr & 0x1) << 3)) << 4);
return;
}
int32 HYPKERNEL32 hk_set_interrupt_gate(uint8* const dst, interrupt_gate const * int_gate)
void HYPKERNEL32 hk_write_interrupt_gate(uint8 *const dst, interrupt_gate const *int_gate)
{
if(dst == NULL || int_gate == NULL)
return -1;
return;
dst[0] = (uint8)(int_gate->offset & 0xFF);
dst[1] = (uint8)((int_gate->offset >> 8) & 0xFF);
dst[6] = (uint8)((int_gate->offset >> 16) & 0xFF);
@ -31,13 +92,13 @@ int32 HYPKERNEL32 hk_set_interrupt_gate(uint8* const dst, interrupt_gate const *
dst[3] = (uint8)((int_gate->seg_sel >> 8) & 0xFF);;
dst[4] = 0;
dst[5] = (uint8)(6 + ((int_gate->Sz & 0x1) << 3) + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
return 0;
return;
}
int32 HYPKERNEL32 hk_set_trap_gate(uint8* const dst, trap_gate const * tr_gate)
void HYPKERNEL32 hk_write_trap_gate(uint8 *const dst, trap_gate const *tr_gate)
{
if(dst == NULL || tr_gate == NULL)
return -1;
return;
dst[0] = (uint8)(tr_gate->offset & 0xFF);
dst[1] = (uint8)((tr_gate->offset >> 8) & 0xFF);
dst[6] = (uint8)((tr_gate->offset >> 16) & 0xFF);
@ -46,13 +107,13 @@ int32 HYPKERNEL32 hk_set_trap_gate(uint8* const dst, trap_gate const * tr_gate)
dst[3] = (uint8)((tr_gate->seg_sel >> 8) & 0xFF);;
dst[4] = 0;
dst[5] = (uint8)(7 + ((tr_gate->Sz & 0x1) << 3) + ((tr_gate->DPL & 0x3) << 5) + ((tr_gate->Pr & 0x1 ) << 7));
return 0;
return;
}
int32 HYPKERNEL32 hk_set_task_gate(uint8* const dst, task_gate const * int_gate)
void HYPKERNEL32 hk_write_task_gate(uint8 *const dst, task_gate const *int_gate)
{
if(dst == NULL || int_gate == NULL)
return -1;
return;
dst[0] = 0;
dst[1] = 0;
dst[6] = 0;
@ -61,7 +122,7 @@ int32 HYPKERNEL32 hk_set_task_gate(uint8* const dst, task_gate const * int_gate)
dst[3] = (uint8)((int_gate->tss_sel >> 8) & 0xFF);
dst[4] = 0;
dst[5] = (uint8)(5 + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
return 0;
return;
}
void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32 size)

View File

@ -3,6 +3,36 @@
#include "type.h"
#include "kdef.h"
typedef struct __attribute__ ((packed))
{
uint8 Pr;
uint8 RW;
uint8 USU;
uint8 PWT;
uint8 PCD;
uint8 Acc;
uint8 Sz; //must be 0
uint64 base; // Since 4KB-aligned, 12 bits are useless, 52(total) - 12 = 40 bits left
// will ignore the low 12 bits as well as the high 12 bits of this field
uint8 XD;
} pml4_entry, pdpt_entry, pd_entry;
typedef struct __attribute__ ((packed))
{
uint8 Pr;
uint8 RW;
uint8 USU;
uint8 PWT;
uint8 PCD;
uint8 Acc;
uint8 dirty;
uint8 PAT;
uint8 Gl;
uint64 base; // Since 4KB-aligned, 12 bits are useless, 52(total) - 12 = 40 bits left
// will ignore the low 12 bits as well as the high 12 bits of this field
uint8 XD;
} pt_entry;
typedef struct __attribute__ ((packed))
{
uint32 offset;
@ -35,7 +65,7 @@ typedef struct __attribute__ ((packed))
uint8 type;
uint8 DPL;
uint8 Gr;
uint8 Avl;
uint8 Acc;
uint8 Pr;
uint8 Sz; //32 bits = 1, 16 bits = 0
uint8 x64;
@ -55,12 +85,16 @@ typedef struct __attribute__ ((packed))
uint32 base;
} idt_ptr;
int32 HYPKERNEL32 hk_set_segment_descriptor(uint8* const gdt, segment_descriptor const * const seg_desc);
void HYPKERNEL32 hk_write_segment_descriptor(uint8 *const gdt, segment_descriptor const *const seg_desc);
extern void HYPKERNEL32 hk_load_gdt(gdt_ptr const * const ptr, uint16 const sel_code, uint16 const sel_data);
int32 HYPKERNEL32 hk_set_interrupt_gate(uint8* const dst, interrupt_gate const * int_gate);
int32 HYPKERNEL32 hk_set_trap_gate(uint8* const dst, trap_gate const * tr_gate);
int32 HYPKERNEL32 hk_set_task_gate(uint8* const dst, task_gate const * int_gate);
void HYPKERNEL32 hk_write_interrupt_gate(uint8 *const dst, interrupt_gate const *int_gate);
void HYPKERNEL32 hk_write_trap_gate(uint8 *const dst, trap_gate const *tr_gate);
void HYPKERNEL32 hk_write_task_gate(uint8 *const dst, task_gate const *int_gate);
void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32 size);
void HYPKERNEL32 hk_mem_move(void* src, void* dst, uint32 size);
extern int32 HYPKERNEL32 hk_support_x64(void);
void HYPKERNEL32 hk_write_pt_entry(uint8 * const base, pt_entry const * const p_entry);
void HYPKERNEL32 hk_write_pd_entry(uint8 * const base, pd_entry const * const p_entry);
void HYPKERNEL32 hk_write_pdpt_entry(uint8 * const base, pdpt_entry const * const p_entry);
void HYPKERNEL32 hk_write_pml4_entry(uint8 * const base, pml4_entry const * const p_entry);
#endif