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:
parent
250299c378
commit
7568cb5890
@ -1,13 +1,9 @@
|
||||
OUTPUT_FORMAT(binary)
|
||||
SECTIONS
|
||||
{
|
||||
.text.start (0x1000000):
|
||||
.text.start(0x100000) :
|
||||
{
|
||||
*(.multiboot)
|
||||
}
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
|
||||
|
@ -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...
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user