Yay! Get compatibility mode working and everything setup except for just jumping to 64bit code segment. However elf32 cannot hold x64 code. Gonna go in x64 after implementing elf64 loader.

This commit is contained in:
HyperAssembler 2015-02-01 02:31:36 -08:00
parent 7568cb5890
commit 510fd9e116
11 changed files with 362 additions and 212 deletions

View File

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

View File

@ -3,7 +3,7 @@
extern word *kernel_stack;
int64 HYPKERNEL64 hk_main(void)
int64_t HYPKERNEL64 hk_main(void)
{
//Setup x64
x64:

View File

@ -1,15 +1,15 @@
#ifndef _TYPE_H_
#define _TYPE_H_
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned long long uint64;
typedef unsigned char uint8;
typedef int int32;
typedef short int16;
typedef long long int64;
typedef char int8;
typedef uint8 byte;
typedef uint16 word;
typedef uint32 dword;
typedef uint64 qword;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned long long uint64_t;
typedef unsigned char uint8_t;
typedef int int32_t;
typedef short int16_t;
typedef long long int64_t;
typedef char int8_t;
typedef uint8_t byte;
typedef uint16_t word;
typedef uint32_t dword;
typedef uint64_t qword;
#endif

View File

@ -1,5 +1,7 @@
global hk_load_gdt
global hk_support_x64
global hk_disable_paging
global hk_enable_paging
SELECTOR_DATA_0 equ 3*8 + 0
SELECTOR_DATA_3 equ 4*8 + 3
SELECTOR_CODE_0 equ 1*8 + 0

View File

@ -1,6 +1,14 @@
global kernel_stack
extern hk_main
global kernel_addr
global hk_comp
extern hk_main
extern hk_print_str
extern hk_print_hex
extern hk_print_int
extern hk_enable_paging
extern hk_disable_paging
extern g_gdt_ptr_64
[SECTION .multiboot]
[BITS 32]
GRUB_MAGIC equ 0x2BADB002
@ -37,4 +45,53 @@ popfd
push ebx
call hk_main
add esp,4 ; We are actually not coming back here. But out of courtesy...
add esp,4 ; We are actually not coming back here. But out of courtesy...
[SECTION .text]
[BITS 32]
hk_entry_comp:
; no, no interrupt please.
cli
; disable paging first
call hk_disable_paging
xchg bx,bx ; pure magic
; enable PAE
mov eax, cr4 ; Set the A-register to control register 4.
or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5).
mov cr4, eax ; Set control register 4 to the A-register.
; enable x86_64
mov ecx, 0xC0000080 ; Set the C-register to 0xC0000080, which is the EFER MSR.
rdmsr ; Read from the model-specific register.
or eax, 1 << 8 ; Set the LM-bit which is the 9th bit (bit 8).
wrmsr ; Write to the model-specific register.
; let cr3 point at l
mov eax,0x100000
mov cr3,eax
; enable paging, enter compatibility mode
call hk_enable_paging
; enter x64
lgdt [g_gdt_ptr_64]
jmp 8:hk_entry_x64
[SECTION .text]
[BITS 64]
hk_entry_x64:
cli
mov ax,24
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov rax, 0x1F201F201F201F20
mov ecx, 500
rep movsq
hlt

View File

@ -3,17 +3,19 @@
#include "multiboot.h"
#include "mem.h"
#include "print.h"
uint8_t g_gdt_64[8 * 8];
gdt_ptr_64_t g_gdt_ptr_64;
uint8_t g_gdt[8 * 8];
gdt_ptr_t g_gdt_ptr;
uint8_t g_idt[8 * 256];
idt_ptr_t g_idt_ptr;
extern uint32_t text_pos;
extern int32_t * kernel_stack;
extern void hk_entry_comp(void);
uint8 g_gdt[8 * 8];
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)
void HYPKERNEL32 hk_delay(uint32_t i)
{
uint32 j = 100000;
uint32_t j = 100000;
while(i--)
{
while(j > 0)
@ -24,20 +26,91 @@ void HYPKERNEL32 hk_delay(uint32 i)
return;
}
void HYPKERNEL32 hk_init_x64()
{
//Setup x64
segment_descriptor_t desc_dummy = {.DPL = 0, .Pr = 0, .x64 = 0, .Sys = 0, .type = 0, .Sz = 0, .limit = 0, .Gr = 0, .base = 0, .Acc = 0};
segment_descriptor_t desc = {.Gr = 1, .Pr = 1, .Sz = 0, .Acc = 0, .Sys = 1, .x64 = 1, .base = 0, .limit = 0};
hk_print_str("*Setting up GDT for x64...");
//dummy descriptor
hk_write_segment_descriptor(&g_gdt_64[0], &desc_dummy);
//ring 0 code seg, non-conforming
desc.type = 10;
desc.DPL = 0;
hk_write_segment_descriptor(&g_gdt_64[8], &desc);
//ring 3 code seg
desc.DPL = 3;
hk_write_segment_descriptor(&g_gdt_64[16], &desc);
//ring 0 data RW
desc.DPL = 0;
desc.type = 2;
hk_write_segment_descriptor(&g_gdt_64[24], &desc);
//ring 3 data
desc.DPL = 3;
hk_write_segment_descriptor(&g_gdt_64[32], &desc);
g_gdt_ptr_64.limit = 8 * 8 - 1;
g_gdt_ptr_64.base = (uint64_t)g_gdt_64;
hk_print_str(" - Done.\n\n");
//Setup identity x64 PAE paging
hk_print_str("*Setting up x86_64 paging...");
//Setup
//TODO: check for available memory and only allocate stuff needed(should not be really hard)
uint32_t addr = 0x100000;
pml4_entry_t pml4_entry = {.base = 0x101000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
while(addr < 0x101000)
{
hk_write_pml4_entry((uint8_t *) addr,&pml4_entry);
//only map first 512 gigs for obvious reasons.
pml4_entry.base = 0;
pml4_entry.Pr = 0;
addr += 8;
}
addr = 0x101000;
pdpt_entry_t pdpt_entry = {.base = 0x102000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
while(addr < 0x102000)
{
hk_write_pdpt_entry((uint8_t*) addr, &pdpt_entry);
//only map first 1 gig for obvious reasons.
pdpt_entry.Pr = 0;
pdpt_entry.base = 0;
addr += 8;
}
addr = 0x102000;
pd_entry_t pd_entry = {.base = 0x103000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
while(addr < 0x103000)
{
hk_write_pd_entry((uint8_t *) addr, &pd_entry);
//ah. no more laziness. At least we need to map first gig.
pd_entry.base += 0x1000; // increment for every 512 entries * 8 bytes each
addr += 8;
}
addr = 0x103000;
pt_entry_t pt_entry = {.base = 0, .Acc = 0, .Pr = 1, .RW = 1, .USU = 0, .PWT = 1,.PCD = 0, .dirty = 0,.Gl = 0, .PAT = 0,.XD = 0};
while(addr < (0x103000 + 512 * 0x1000))
{
hk_write_pt_entry((uint8_t *) addr, &pt_entry);
pt_entry.base += 0x1000;
addr += 8;
}
hk_print_str(" - Done.\n\n");
hk_entry_comp();
}
void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
{
//initialize text position
uint32 i = 0;
uint32_t 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, .Acc = 0};
segment_descriptor desc = {.Gr = 1, .Pr = 1, .Sz = 1, .Acc = 0, .Sys = 1, .x64 = 0, .base = 0, .limit = 0xFFFFF};
segment_descriptor_t desc_dummy = {.DPL = 0, .Pr = 0, .x64 = 0, .Sys = 0, .type = 0, .Sz = 0, .limit = 0, .Gr = 0, .base = 0, .Acc = 0};
segment_descriptor_t 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");
hk_print_str("*Setting up GDT...");
//dummy descriptor
hk_write_segment_descriptor(&g_gdt[0], &desc_dummy);
//ring 0 code seg, non-conforming
@ -55,35 +128,34 @@ void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
desc.DPL = 3;
hk_write_segment_descriptor(&g_gdt[32], &desc);
g_gdt_ptr.limit = 8 * 8 - 1;
g_gdt_ptr.base = (uint32) g_gdt;
g_gdt_ptr.base = (uint32_t) g_gdt;
hk_load_gdt(&g_gdt_ptr, SEGMENT_SELECTOR(1, 0), SEGMENT_SELECTOR(3, 0));
hk_print_str(" - Done.\n\n");
//check memory, definitely < 32 so we assume that
//TODO: Add check for flags and update print functions to handle 64bit int
hk_print_str("*Checking memory information...\n");
BOCHS_MAGIC_BREAKPOINT;
if(multiboot_info->flags & (1 << 6))
{
multiboot_memory_map_t const *mem_map = (multiboot_memory_map_t *) multiboot_info->mmap_addr;
uint32 const mem_map_size = multiboot_info->mmap_length / sizeof(multiboot_memory_map_t);
uint32_t const mem_map_size = multiboot_info->mmap_length / sizeof(multiboot_memory_map_t);
hk_print_str("BaseAddr - Length - Type\n");
uint32 total_available_mem = 0;
uint32 total_reserved_mem = 0;
uint32_t total_available_mem = 0;
uint32_t total_reserved_mem = 0;
for (i = 0; i < mem_map_size; i++)
{
hk_print_hex((uint32)((mem_map + i)->addr));
hk_print_hex((uint32_t)((mem_map + i)->addr));
hk_print_str(" - ");
hk_print_hex((uint32)((mem_map + i)->len));
hk_print_hex((uint32_t)((mem_map + i)->len));
hk_print_str(" - ");
hk_print_hex((mem_map + i)->type);
hk_print_str("\n");
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
{
total_reserved_mem += (uint32) ((mem_map + i)->len);
total_reserved_mem += (uint32_t) ((mem_map + i)->len);
}
else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE)
{
total_available_mem += (uint32) ((mem_map + i)->len);
total_available_mem += (uint32_t) ((mem_map + i)->len);
}
}
hk_print_str("Total available memory: ");
@ -111,7 +183,7 @@ void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
if(multiboot_info->flags & (1 << 3))
{
multiboot_module_t const * mods_list = (multiboot_module_t *)multiboot_info->mods_addr;
uint32 const mods_count = multiboot_info->mods_count;
uint32_t const mods_count = multiboot_info->mods_count;
hk_print_int(mods_count);
hk_print_str(" module(s) loaded:\n");
hk_print_str("Name - StartAddr - EndAddr\n");
@ -136,18 +208,17 @@ 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.");
hk_print_str("Arch: x86.\n\n");
x86:
goto x86;
}
else
{
hk_print_str("Arch: x86_64.");
hk_print_str("Arch: x86_64.\n\n");
hk_init_x64();
}
//Setup x64
x64:
goto x64;
return;
}

View File

@ -1,116 +1,116 @@
#include "kdef.h"
#include "mem.h"
void HYPKERNEL32 hk_write_pml4_entry(uint8 * const base, pml4_entry const * const p_entry)
void HYPKERNEL32 hk_write_pml4_entry(uint8_t * const base, pml4_entry_t 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);
base[0] = (uint8_t)((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_t)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8_t)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8_t)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8_t)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8_t)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8_t)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8_t)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pdpt_entry(uint8 * const base, pdpt_entry const * const p_entry)
void HYPKERNEL32 hk_write_pdpt_entry(uint8_t * const base, pdpt_entry_t 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);
base[0] = (uint8_t)((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_t)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8_t)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8_t)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8_t)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8_t)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8_t)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8_t)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pd_entry(uint8 * const base, pd_entry const * const p_entry)
void HYPKERNEL32 hk_write_pd_entry(uint8_t * const base, pd_entry_t 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);
base[0] = (uint8_t)((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_t)(((p_entry->base >> 12) & 0xF) << 4); // 4 bits
base[2] = (uint8_t)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8_t)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8_t)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8_t)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8_t)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8_t)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_pt_entry(uint8 * const base, pt_entry const * const p_entry)
void HYPKERNEL32 hk_write_pt_entry(uint8_t * const base, pt_entry_t 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);
base[0] = (uint8_t)((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_t)((((p_entry->base >> 12) & 0xF) << 4) + (p_entry->Gl & 0x1)); // 4 bits
base[2] = (uint8_t)((p_entry->base >> 16) & 0xFF); // 8 bits
base[3] = (uint8_t)((p_entry->base >> 24) & 0xFF); // 8 bits
base[4] = (uint8_t)((p_entry->base >> 32) & 0xFF); // 8 bits
base[5] = (uint8_t)((p_entry->base >> 40) & 0xFF); // 8 bits
base[6] = (uint8_t)((p_entry->base >> 48) & 0xF); // 4 bits
base[7] = (uint8_t)((p_entry->XD & 0x1) << 7);
return;
}
void HYPKERNEL32 hk_write_segment_descriptor(uint8 *const gdt, segment_descriptor const *const seg_desc)
void HYPKERNEL32 hk_write_segment_descriptor(uint8_t *const gdt, segment_descriptor_t const *const seg_desc)
{
if (gdt == NULL || seg_desc == NULL)
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);
gdt[0] = (uint8_t)(seg_desc->limit & 0xFF);
gdt[1] = (uint8_t)((seg_desc->limit >> 8) & 0xFF);
gdt[6] = gdt[6] | (uint8_t)((seg_desc->limit >> 16) & 0xFF);
gdt[2] = (uint8)(seg_desc->base & 0xFF);
gdt[3] = (uint8)((seg_desc->base >> 8) & 0xFF);
gdt[4] = (uint8)((seg_desc->base >> 16) & 0xFF);
gdt[7] = (uint8)((seg_desc->base >> 24) & 0xFF);
gdt[2] = (uint8_t)(seg_desc->base & 0xFF);
gdt[3] = (uint8_t)((seg_desc->base >> 8) & 0xFF);
gdt[4] = (uint8_t)((seg_desc->base >> 16) & 0xFF);
gdt[7] = (uint8_t)((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->Acc & 0x1) + ((seg_desc->x64 & 0x1) << 1) + ((seg_desc->Sz & 0x1) << 2) + ((seg_desc->Gr & 0x1) << 3)) << 4);
gdt[5] = (uint8_t)((seg_desc->type & 0xF) + ((seg_desc->Sys & 0x1) << 4) + ((seg_desc->DPL & 0x3) << 5) + ((seg_desc->Pr & 0x1 ) << 7));
gdt[6] = gdt[6] | (uint8_t)(((seg_desc->Acc & 0x1) + ((seg_desc->x64 & 0x1) << 1) + ((seg_desc->Sz & 0x1) << 2) + ((seg_desc->Gr & 0x1) << 3)) << 4);
return;
}
void HYPKERNEL32 hk_write_interrupt_gate(uint8 *const dst, interrupt_gate const *int_gate)
void HYPKERNEL32 hk_write_interrupt_gate(uint8_t *const dst, interrupt_gate_t const *int_gate)
{
if(dst == NULL || int_gate == NULL)
return;
dst[0] = (uint8)(int_gate->offset & 0xFF);
dst[1] = (uint8)((int_gate->offset >> 8) & 0xFF);
dst[6] = (uint8)((int_gate->offset >> 16) & 0xFF);
dst[7] = (uint8)((int_gate->offset >> 24) & 0xFF);
dst[2] = (uint8)(int_gate->seg_sel & 0xFF);
dst[3] = (uint8)((int_gate->seg_sel >> 8) & 0xFF);;
dst[0] = (uint8_t)(int_gate->offset & 0xFF);
dst[1] = (uint8_t)((int_gate->offset >> 8) & 0xFF);
dst[6] = (uint8_t)((int_gate->offset >> 16) & 0xFF);
dst[7] = (uint8_t)((int_gate->offset >> 24) & 0xFF);
dst[2] = (uint8_t)(int_gate->seg_sel & 0xFF);
dst[3] = (uint8_t)((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));
dst[5] = (uint8_t)(6 + ((int_gate->Sz & 0x1) << 3) + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
return;
}
void HYPKERNEL32 hk_write_trap_gate(uint8 *const dst, trap_gate const *tr_gate)
void HYPKERNEL32 hk_write_trap_gate(uint8_t *const dst, trap_gate_t const *tr_gate)
{
if(dst == NULL || tr_gate == NULL)
return;
dst[0] = (uint8)(tr_gate->offset & 0xFF);
dst[1] = (uint8)((tr_gate->offset >> 8) & 0xFF);
dst[6] = (uint8)((tr_gate->offset >> 16) & 0xFF);
dst[7] = (uint8)((tr_gate->offset >> 24) & 0xFF);
dst[2] = (uint8)(tr_gate->seg_sel & 0xFF);
dst[3] = (uint8)((tr_gate->seg_sel >> 8) & 0xFF);;
dst[0] = (uint8_t)(tr_gate->offset & 0xFF);
dst[1] = (uint8_t)((tr_gate->offset >> 8) & 0xFF);
dst[6] = (uint8_t)((tr_gate->offset >> 16) & 0xFF);
dst[7] = (uint8_t)((tr_gate->offset >> 24) & 0xFF);
dst[2] = (uint8_t)(tr_gate->seg_sel & 0xFF);
dst[3] = (uint8_t)((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));
dst[5] = (uint8_t)(7 + ((tr_gate->Sz & 0x1) << 3) + ((tr_gate->DPL & 0x3) << 5) + ((tr_gate->Pr & 0x1 ) << 7));
return;
}
void HYPKERNEL32 hk_write_task_gate(uint8 *const dst, task_gate const *int_gate)
void HYPKERNEL32 hk_write_task_gate(uint8_t *const dst, task_gate_t const *int_gate)
{
if(dst == NULL || int_gate == NULL)
return;
@ -118,14 +118,14 @@ void HYPKERNEL32 hk_write_task_gate(uint8 *const dst, task_gate const *int_gate)
dst[1] = 0;
dst[6] = 0;
dst[7] = 0;
dst[2] = (uint8)(int_gate->tss_sel & 0xFF);
dst[3] = (uint8)((int_gate->tss_sel >> 8) & 0xFF);
dst[2] = (uint8_t)(int_gate->tss_sel & 0xFF);
dst[3] = (uint8_t)((int_gate->tss_sel >> 8) & 0xFF);
dst[4] = 0;
dst[5] = (uint8)(5 + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
dst[5] = (uint8_t)(5 + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
return;
}
void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32 size)
void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32_t size)
{
if (src == NULL || dst == NULL)
return;
@ -136,7 +136,17 @@ void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32 size)
return;
}
void HYPKERNEL32 hk_mem_move(void* src, void* dst, uint32 size)
void HYPKERNEL32 hk_mem_set(void* src, int8_t const val,uint32_t size)
{
if (src == NULL)
return;
int8_t * cSrc = (int8_t *)src;
while (size--)
*(cSrc++) = val;
return;
}
void HYPKERNEL32 hk_mem_move(void* src, void* dst, uint32_t size)
{
if (src == NULL || dst == NULL)
return;

View File

@ -5,96 +5,105 @@
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
uint8_t Pr;
uint8_t RW;
uint8_t USU;
uint8_t PWT;
uint8_t PCD;
uint8_t Acc;
uint8_t Sz; //must be 0
uint64_t 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;
uint8_t XD;
} pml4_entry_t, pdpt_entry_t, pd_entry_t;
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
uint8_t Pr;
uint8_t RW;
uint8_t USU;
uint8_t PWT;
uint8_t PCD;
uint8_t Acc;
uint8_t dirty;
uint8_t PAT;
uint8_t Gl;
uint64_t 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;
uint8_t XD;
} pt_entry_t;
typedef struct __attribute__ ((packed))
{
uint32 offset;
uint16 seg_sel;
uint8 Pr;
uint8 DPL;
uint8 Sz;
} interrupt_gate;
uint32_t offset;
uint16_t seg_sel;
uint8_t Pr;
uint8_t DPL;
uint8_t Sz;
} interrupt_gate_t;
typedef struct __attribute__ ((packed))
{
uint32 offset;
uint16 seg_sel;
uint8 Pr;
uint8 DPL;
uint8 Sz;
} trap_gate;
uint32_t offset;
uint16_t seg_sel;
uint8_t Pr;
uint8_t DPL;
uint8_t Sz;
} trap_gate_t;
typedef struct __attribute__ ((packed))
{
uint16 tss_sel;
uint8 DPL;
uint8 Pr;
} task_gate;
uint16_t tss_sel;
uint8_t DPL;
uint8_t Pr;
} task_gate_t;
typedef struct __attribute__ ((packed))
{
uint32 base;
uint32 limit;
uint8 type;
uint8 DPL;
uint8 Gr;
uint8 Acc;
uint8 Pr;
uint8 Sz; //32 bits = 1, 16 bits = 0
uint8 x64;
uint8 Sys; //System = 0, code/data = 1
uint32_t base;
uint32_t limit;
uint8_t type;
uint8_t DPL;
uint8_t Gr;
uint8_t Acc;
uint8_t Pr;
uint8_t Sz; //32 bits = 1, 16 bits = 0
uint8_t x64;
uint8_t Sys; //System = 0, code/data = 1
} segment_descriptor;
} segment_descriptor_t;
typedef struct __attribute__ ((packed))
{
uint16 limit;
uint32 base;
} gdt_ptr;
uint16_t limit;
uint32_t base;
} gdt_ptr_t;
typedef struct __attribute__ ((packed))
{
uint16 limit;
uint32 base;
} idt_ptr;
uint16_t limit;
uint64_t base;
} gdt_ptr_64_t;
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);
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);
typedef struct __attribute__ ((packed))
{
uint16_t limit;
uint32_t base;
} idt_ptr_t;
void HYPKERNEL32 hk_write_segment_descriptor(uint8_t *const gdt, segment_descriptor_t const *const seg_desc);
extern void HYPKERNEL32 hk_load_gdt(gdt_ptr_t const * const ptr, uint16_t const sel_code, uint16_t const sel_data);
void HYPKERNEL32 hk_write_interrupt_gate(uint8_t *const dst, interrupt_gate_t const *int_gate);
void HYPKERNEL32 hk_write_trap_gate(uint8_t *const dst, trap_gate_t const *tr_gate);
void HYPKERNEL32 hk_write_task_gate(uint8_t *const dst, task_gate_t const *int_gate);
void HYPKERNEL32 hk_mem_cpy(void* src, void* dst, uint32_t size);
void HYPKERNEL32 hk_mem_move(void* src, void* dst, uint32_t size);
extern int32_t HYPKERNEL32 hk_support_x64(void);
extern void hk_disable_paging(void);
extern void hk_enable_paging(void);
void HYPKERNEL32 hk_mem_set(void* src, int8_t const val,uint32_t size);
void HYPKERNEL32 hk_write_pt_entry(uint8_t * const base, pt_entry_t const * const p_entry);
void HYPKERNEL32 hk_write_pd_entry(uint8_t * const base, pd_entry_t const * const p_entry);
void HYPKERNEL32 hk_write_pdpt_entry(uint8_t * const base, pdpt_entry_t const * const p_entry);
void HYPKERNEL32 hk_write_pml4_entry(uint8_t * const base, pml4_entry_t const * const p_entry);
#endif

View File

@ -3,11 +3,11 @@
#include "mem.h"
#include "print.h"
uint32 text_pos;
uint32_t text_pos;
uint32 HYPKERNEL32 hk_str_len(char const * str)
uint32_t HYPKERNEL32 hk_str_len(char const * str)
{
uint32 length = 0;
uint32_t length = 0;
if(str == NULL)
return 0;
while(*str != 0)
@ -18,11 +18,11 @@ uint32 HYPKERNEL32 hk_str_len(char const * str)
return length;
}
uint32 HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2)
uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2)
{
if(str1 == NULL || str2 == NULL)
return 0;
uint32 length = hk_str_len(str1);
uint32_t length = hk_str_len(str1);
if(length != hk_str_len(str2))
return 0;
while(length--)
@ -52,6 +52,7 @@ void HYPKERNEL32 hk_print_str(char const *str)
{
//can't hold
hk_print_scroll();
hk_mem_set((void*)(0xb8000 + 80*24*2), 0, 80 * 2); // clear last row
text_pos = 80 * 24;
}
str++;
@ -73,12 +74,12 @@ void HYPKERNEL32 hk_print_str(char const *str)
return;
}
void HYPKERNEL32 hk_print_int(int32 number)
void HYPKERNEL32 hk_print_int(int32_t number)
{
char arr[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32 index = 10;
uint32 isNegative = 0;
uint32 const div = 10;
uint32_t index = 10;
uint32_t isNegative = 0;
uint32_t const div = 10;
if (number < 0)
{
isNegative = 1;
@ -86,8 +87,8 @@ void HYPKERNEL32 hk_print_int(int32 number)
}
while (1)
{
uint32 quo = number / div;
uint32 rmd = number % div;
uint32_t quo = number / div;
uint32_t rmd = number % div;
number = quo;
arr[index] = (char) ('0' + rmd);
index--;
@ -104,16 +105,16 @@ void HYPKERNEL32 hk_print_int(int32 number)
return;
}
void HYPKERNEL32 hk_print_hex(uint32 number)
void HYPKERNEL32 hk_print_hex(uint32_t number)
{
const char lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char arr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32 index = 9;
uint32 const div = 16;
uint32_t index = 9;
uint32_t const div = 16;
while (1)
{
uint32 quo = number / div;
uint32 rmd = number % div;
uint32_t quo = number / div;
uint32_t rmd = number % div;
number = quo;
arr[index--] = lookup_table[rmd];
if (number == 0)

View File

@ -7,10 +7,10 @@
#define get_row(pos) (pos / 80)
#define get_pos(row,col) ((row) * 80 + (col))
void HYPKERNEL32 hk_print_hex(uint32 number);
void HYPKERNEL32 hk_print_int(int32 number);
void HYPKERNEL32 hk_print_hex(uint32_t number);
void HYPKERNEL32 hk_print_int(int32_t number);
void HYPKERNEL32 hk_print_str(char const *str);
uint32 HYPKERNEL32 hk_str_len(char const * str);
uint32 HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2);
uint32_t HYPKERNEL32 hk_str_len(char const * str);
uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2);
#endif

View File

@ -1,11 +1,11 @@
#ifndef _TYPE_H_
#define _TYPE_H_
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned long long uint64;
typedef unsigned char uint8;
typedef int int32;
typedef short int16;
typedef long long int64;
typedef char int8;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned long long uint64_t;
typedef unsigned char uint8_t;
typedef int int32_t;
typedef short int16_t;
typedef long long int64_t;
typedef char int8_t;
#endif