Complete refactor of craps I wrote. Especially when constructing GDT / Page table.
Need: 1. Map page depending on current memory 2. ELF loader
This commit is contained in:
parent
7810a74741
commit
c886d569cd
|
@ -1,6 +1,45 @@
|
|||
extern hk_main
|
||||
[SECTION .entry]
|
||||
[BITS 32] ;on stack: multiboot_info*
|
||||
; no, no interrupt please.
|
||||
cli
|
||||
|
||||
; disable paging first
|
||||
mov eax, cr0 ; Set the A-register to control register 0.
|
||||
and eax, 01111111111111111111111111111111b ; Clear the PG-bit, which is bit 31.
|
||||
mov cr0, eax ; Set control register 0 to the A-register.
|
||||
ret
|
||||
|
||||
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 page table
|
||||
mov eax,;page table addr
|
||||
mov cr3,eax
|
||||
|
||||
; enable paging, enter compatibility mode
|
||||
mov eax, cr0 ; Set the A-register to control register 0.
|
||||
or eax, 1 << 31 ; Set the PG-bit, which is bit 31.
|
||||
mov cr0, eax ; Set control register 0 to the A-register.
|
||||
ret
|
||||
|
||||
; enter x64
|
||||
lgdt [g_gdt_ptr_64]
|
||||
jmp 8:entry_64
|
||||
|
||||
[SECTION .text]
|
||||
[BITS 64]
|
||||
entry_64:
|
||||
cli
|
||||
;hard code for now
|
||||
mov ax,24
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "multiboot.h"
|
||||
|
||||
extern uint64_t text_pos;
|
||||
void HYPKERNEL64 hk_main(multiboot_info_t* multiboot_info)
|
||||
void HYPKERNEL64 hk_main(void)
|
||||
{
|
||||
hk_clear_screen();
|
||||
hk_print_str("Welcome to HYP OS. Kernel is now running in x64 mode.\n");
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
#define BOCHS_MAGIC_BREAKPOINT asm("xchg bx,bx");
|
||||
|
||||
#define SEG_SELECTOR(Index,RPL) (((Index) << 3) + (RPL))
|
||||
|
||||
#define HLT_CPU asm("hlt");
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
#endif
|
||||
|
|
127
x64/src/c/mem.c
127
x64/src/c/mem.c
|
@ -1,83 +1,100 @@
|
|||
#include "kdef.h"
|
||||
#include "mem.h"
|
||||
|
||||
void HYPKERNEL64 hk_write_pml4_entry(uint8_t * const base, pml4_entry_t const * const p_entry)
|
||||
|
||||
void HYPKERNEL64 hk_write_pt_entry(void * const base, uint64_t const p_addr, uint64_t const attr)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
if(base == NULL)
|
||||
return;
|
||||
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);
|
||||
uint64_t entry = (p_addr & 0xFFFFFFFFFF000) | attr;
|
||||
((uint8_t*)base)[0] = (uint8_t)(entry & 0xFF);
|
||||
((uint8_t*)base)[1] = (uint8_t)((entry >> 8) & 0xFF);
|
||||
((uint8_t*)base)[2] = (uint8_t)((entry >> 16) & 0xFF);
|
||||
((uint8_t*)base)[3] = (uint8_t)((entry >> 24) & 0xFF);
|
||||
((uint8_t*)base)[4] = (uint8_t)((entry >> 32) & 0xFF);
|
||||
((uint8_t*)base)[5] = (uint8_t)((entry >> 40) & 0xFF);
|
||||
((uint8_t*)base)[6] = (uint8_t)((entry >> 48) & 0xFF);
|
||||
((uint8_t*)base)[7] = (uint8_t)((entry >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_write_pdpt_entry(uint8_t * const base, pdpt_entry_t const * const p_entry)
|
||||
void HYPKERNEL64 hk_write_pd_entry(void * const base, uint64_t const pt_addr, uint64_t const attr)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
if(base == NULL)
|
||||
return;
|
||||
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);
|
||||
uint64_t entry = (pt_addr & 0xFFFFFFFFFF000) | attr;
|
||||
((uint8_t*)base)[0] = (uint8_t)(entry & 0xFF);
|
||||
((uint8_t*)base)[1] = (uint8_t)((entry >> 8) & 0xFF);
|
||||
((uint8_t*)base)[2] = (uint8_t)((entry >> 16) & 0xFF);
|
||||
((uint8_t*)base)[3] = (uint8_t)((entry >> 24) & 0xFF);
|
||||
((uint8_t*)base)[4] = (uint8_t)((entry >> 32) & 0xFF);
|
||||
((uint8_t*)base)[5] = (uint8_t)((entry >> 40) & 0xFF);
|
||||
((uint8_t*)base)[6] = (uint8_t)((entry >> 48) & 0xFF);
|
||||
((uint8_t*)base)[7] = (uint8_t)((entry >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_write_pd_entry(uint8_t * const base, pd_entry_t const * const p_entry)
|
||||
void HYPKERNEL64 hk_write_pdpt_entry(void * const base, uint64_t const pd_addr, uint64_t const attr)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
if(base == NULL)
|
||||
return;
|
||||
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);
|
||||
uint64_t entry = (pd_addr & 0xFFFFFFFFFF000) | attr;
|
||||
((uint8_t*)base)[0] = (uint8_t)(entry & 0xFF);
|
||||
((uint8_t*)base)[1] = (uint8_t)((entry >> 8) & 0xFF);
|
||||
((uint8_t*)base)[2] = (uint8_t)((entry >> 16) & 0xFF);
|
||||
((uint8_t*)base)[3] = (uint8_t)((entry >> 24) & 0xFF);
|
||||
((uint8_t*)base)[4] = (uint8_t)((entry >> 32) & 0xFF);
|
||||
((uint8_t*)base)[5] = (uint8_t)((entry >> 40) & 0xFF);
|
||||
((uint8_t*)base)[6] = (uint8_t)((entry >> 48) & 0xFF);
|
||||
((uint8_t*)base)[7] = (uint8_t)((entry >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void HYPKERNEL64 hk_write_pt_entry(uint8_t * const base, pt_entry_t const * const p_entry)
|
||||
void HYPKERNEL64 hk_write_pml4_entry(void * const base, uint64_t const pdpt_addr, uint64_t const attr)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
if(base == NULL)
|
||||
return;
|
||||
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);
|
||||
uint64_t const entry = (pdpt_addr & 0xFFFFFFFFFF000) | attr;
|
||||
((uint8_t*)base)[0] = (uint8_t)(entry & 0xFF);
|
||||
((uint8_t*)base)[1] = (uint8_t)((entry >> 8) & 0xFF);
|
||||
((uint8_t*)base)[2] = (uint8_t)((entry >> 16) & 0xFF);
|
||||
((uint8_t*)base)[3] = (uint8_t)((entry >> 24) & 0xFF);
|
||||
((uint8_t*)base)[4] = (uint8_t)((entry >> 32) & 0xFF);
|
||||
((uint8_t*)base)[5] = (uint8_t)((entry >> 40) & 0xFF);
|
||||
((uint8_t*)base)[6] = (uint8_t)((entry >> 48) & 0xFF);
|
||||
((uint8_t*)base)[7] = (uint8_t)((entry >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_write_segment_descriptor(uint8_t *const gdt, segment_descriptor_t const *const seg_desc)
|
||||
void HYPKERNEL64 hk_write_segment_descriptor(void * const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr)
|
||||
{
|
||||
if (gdt == NULL || seg_desc == NULL)
|
||||
return;
|
||||
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);
|
||||
if (gdt == NULL)
|
||||
return;
|
||||
uint64_t const seg_desc = (((uint64_t)base & 0xFFFF) << 16) | ((((uint64_t)base >> 16) & 0xFF) << 32) | ((((uint64_t)base >> 24) & 0xFF) << 56) | ((uint64_t)limit & 0xFFFF) | ((((uint64_t)limit >> 16) & 0xF) << 48) | attr;
|
||||
((uint8_t*)gdt)[0] = (uint8_t)(seg_desc & 0xFF);
|
||||
((uint8_t*)gdt)[1] = (uint8_t)((seg_desc >> 8) & 0xFF);
|
||||
((uint8_t*)gdt)[2] = (uint8_t)((seg_desc >> 16) & 0xFF);
|
||||
((uint8_t*)gdt)[3] = (uint8_t)((seg_desc >> 24) & 0xFF);
|
||||
((uint8_t*)gdt)[4] = (uint8_t)((seg_desc >> 32) & 0xFF);
|
||||
((uint8_t*)gdt)[5] = (uint8_t)((seg_desc >> 40) & 0xFF);
|
||||
((uint8_t*)gdt)[6] = (uint8_t)((seg_desc >> 48) & 0xFF);
|
||||
((uint8_t*)gdt)[7] = (uint8_t)((seg_desc >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
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_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 HYPKERNEL64 hk_map_page(void * const pml4_base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr)
|
||||
{
|
||||
//wait a sec, we actually need maximum memory information here for effectively map crap
|
||||
if(pml4_base == NULL || p_addr << 52 || v_addr << 52)
|
||||
return;
|
||||
//ASSUME: little endian
|
||||
uint64_t const pml4_index = (v_addr >> 39) & 0x1FF;
|
||||
void * const pml4_addr = (void*)((uint64_t*)pml4_base + pml4_index);
|
||||
uint64_t const pml4_entry = *(uint64_t*)pml4_addr;
|
||||
if(!(pml4_entry & PML4_PRESENT))
|
||||
{
|
||||
hk_write_pml4_entry(pml4_addr, (uint64_t)pml4_base + 512*8, PML4_PRESENT | PML4_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_mem_cpy(void* src, void* dst, uint64_t size)
|
||||
|
|
|
@ -3,50 +3,49 @@
|
|||
|
||||
#include "type.h"
|
||||
#include "kdef.h"
|
||||
#define PML4_PRESENT ((uint64_t)1 << 0)
|
||||
#define PML4_WRITE ((uint64_t)1 << 1)
|
||||
#define PML4_USER ((uint64_t)1 << 2)
|
||||
#define PML4_WRITE_THROUGH ((uint64_t)1 << 3)
|
||||
#define PML4_CACHE_DISABLED ((uint64_t)1 << 4)
|
||||
#define PML4_ACCESSED ((uint64_t)1 << 5)
|
||||
#define PML4_EXECUTION_DISABLED ((uint64_t)1 << 63)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint64_t Pr;
|
||||
uint64_t RW;
|
||||
uint64_t USU;
|
||||
uint64_t PWT;
|
||||
uint64_t PCD;
|
||||
uint64_t Acc;
|
||||
uint64_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
|
||||
uint64_t XD;
|
||||
} pml4_entry_t, pdpt_entry_t, pd_entry_t;
|
||||
#define PDPT_PRESENT ((uint64_t)1 << 0)
|
||||
#define PDPT_WRITE ((uint64_t)1 << 1)
|
||||
#define PDPT_USER ((uint64_t)1 << 2)
|
||||
#define PDPT_WRITE_THROUGH ((uint64_t)1 << 3)
|
||||
#define PDPT_CACHE_DISABLED ((uint64_t)1 << 4)
|
||||
#define PDPT_ACCESSED ((uint64_t)1 << 5)
|
||||
#define PDPT_EXECUTION_DISABLED ((uint64_t)1 << 63)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint64_t Pr;
|
||||
uint64_t RW;
|
||||
uint64_t USU;
|
||||
uint64_t PWT;
|
||||
uint64_t PCD;
|
||||
uint64_t Acc;
|
||||
uint64_t dirty;
|
||||
uint64_t PAT;
|
||||
uint64_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
|
||||
uint64_t XD;
|
||||
} pt_entry_t;
|
||||
#define PD_PRESENT ((uint64_t)1 << 0)
|
||||
#define PD_WRITE ((uint64_t)1 << 1)
|
||||
#define PD_USER ((uint64_t)1 << 2)
|
||||
#define PD_WRITE_THROUGH ((uint64_t)1 << 3)
|
||||
#define PD_CACHE_DISABLED ((uint64_t)1 << 4)
|
||||
#define PD_ACCESSED ((uint64_t)1 << 5)
|
||||
#define PD_EXECUTION_DISABLED ((uint64_t)1 << 63)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint64_t base;
|
||||
uint64_t limit;
|
||||
uint64_t type;
|
||||
uint64_t DPL;
|
||||
uint64_t Gr;
|
||||
uint64_t Acc;
|
||||
uint64_t Pr;
|
||||
uint64_t Sz; //32 bits = 1, 16 bits = 0
|
||||
uint64_t x64;
|
||||
uint64_t Sys; //System = 0, code/data = 1
|
||||
} segment_descriptor_t;
|
||||
#define PT_PRESENT ((uint64_t)1 << 0)
|
||||
#define PT_WRITE ((uint64_t)1 << 1)
|
||||
#define PT_USER ((uint64_t)1 << 2)
|
||||
#define PT_WRITE_THROUGH ((uint64_t)1 << 3)
|
||||
#define PT_CACHE_DISABLED ((uint64_t)1 << 4)
|
||||
#define PT_ACCESSED ((uint64_t)1 << 5)
|
||||
#define PT_DIRTY ((uint64_t)1 << 6)
|
||||
#define PT_ATTRIBUTE_TABLE ((uint64_t)1 << 7)
|
||||
#define PT_GLOBAL ((uint64_t)1 << 8)
|
||||
#define PT_EXECUTION_DISABLED ((uint64_t)1 << 63)
|
||||
|
||||
#define SEG_GRANULARITY ((uint64_t)1 << 55)
|
||||
#define SEG_LONG ((uint64_t)1 << 53)
|
||||
#define SEG_DPL(dpl) (((uint64_t)(dpl) & 0x3) << 45)
|
||||
#define SEG_PRESENT ((uint64_t)1 << 47)
|
||||
#define SEG_CODE_DATA ((uint64_t)1 << 44)
|
||||
#define SEG_TYPE(type) (((uint64_t)(type) & 0xF) << 40)
|
||||
#define SEG_AVAILABLE ((uint64_t)1 << 52)
|
||||
#define SEG_32_BITS ((uint64_t)1 << 54)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
|
@ -60,7 +59,7 @@ typedef struct __attribute__ ((packed))
|
|||
uint64_t base;
|
||||
} idt_ptr_t;
|
||||
|
||||
void HYPKERNEL64 hk_write_segment_descriptor(uint8_t *const gdt, segment_descriptor_t const *const seg_desc);
|
||||
void HYPKERNEL64 hk_write_segment_descriptor(void *const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr);
|
||||
|
||||
//extern void HYPKERNEL64 hk_load_gdt(gdt_ptr_t const *const ptr, uint16_t const sel_code, uint16_t const sel_data);
|
||||
|
||||
|
@ -70,12 +69,12 @@ void HYPKERNEL64 hk_mem_move(void *src, void *dst, uint64_t size);
|
|||
|
||||
void HYPKERNEL64 hk_mem_set(void *src, int8_t const val, uint64_t size);
|
||||
|
||||
void HYPKERNEL64 hk_write_pt_entry(uint8_t *const base, pt_entry_t const *const p_entry);
|
||||
void HYPKERNEL64 hk_write_pml4_entry(void *const base, uint64_t const pdpt_addr, uint64_t const attr);
|
||||
|
||||
void HYPKERNEL64 hk_write_pd_entry(uint8_t *const base, pd_entry_t const *const p_entry);
|
||||
void HYPKERNEL64 hk_write_pdpt_entry(void *const base, uint64_t const pd_addr, uint64_t const attr);
|
||||
|
||||
void HYPKERNEL64 hk_write_pdpt_entry(uint8_t *const base, pdpt_entry_t const *const p_entry);
|
||||
void HYPKERNEL64 hk_write_pd_entry(void *const base, uint64_t const pt_addr, uint64_t const attr);
|
||||
|
||||
void HYPKERNEL64 hk_write_pml4_entry(uint8_t *const base, pml4_entry_t const *const p_entry);
|
||||
void HYPKERNEL64 hk_write_pt_entry(void *const base, uint64_t const p_addr, uint64_t const attr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,18 @@
|
|||
|
||||
uint64_t text_pos;
|
||||
|
||||
void HYPKERNEL64 hk_map_page(void * base, uint64_t const physcial_addr, uint64_t const linear_addr, uint64_t attr)
|
||||
{
|
||||
|
||||
if(physcial_addr << 52 || linear_addr << 52)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint64_t const pml4_idx = (linear_addr >> 39) & 0x1FF; //9bits
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint64_t HYPKERNEL64 hk_str_len(char const * str)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
|
|
|
@ -4,8 +4,8 @@ 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 signed int int32_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef char int8_t;
|
||||
#endif
|
|
@ -45,37 +45,4 @@ popfd
|
|||
|
||||
push ebx
|
||||
call hk_main
|
||||
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 page table
|
||||
mov eax,0x200000
|
||||
mov cr3,eax
|
||||
|
||||
; enable paging, enter compatibility mode
|
||||
call hk_enable_paging
|
||||
|
||||
; enter x64
|
||||
lgdt [g_gdt_ptr_64]
|
||||
jmp 8:0x100000
|
||||
add esp,4 ; We are actually not coming back here. But out of courtesy...
|
|
@ -5,9 +5,6 @@
|
|||
#include "print.h"
|
||||
uint8_t g_gdt[8 * 8];
|
||||
gdt_ptr_t g_gdt_ptr;
|
||||
gdt_ptr_64_t g_gdt_ptr_64;
|
||||
|
||||
//x86 stuff
|
||||
uint8_t g_idt[8 * 256];
|
||||
idt_ptr_t g_idt_ptr;
|
||||
|
||||
|
@ -16,31 +13,24 @@ extern void hk_entry_comp(void);
|
|||
|
||||
void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
|
||||
{
|
||||
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...");
|
||||
//dummy descriptor
|
||||
hk_write_segment_descriptor(&g_gdt[0], &desc_dummy);
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[0]), 0, 0, 0);
|
||||
//ring 0 code seg, non-conforming
|
||||
desc.type = 10;
|
||||
desc.DPL = 0;
|
||||
hk_write_segment_descriptor(&g_gdt[8], &desc);
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[8]), 0, 0xFFFFF, SEG_TYPE(10) | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL(0));
|
||||
//ring 3 code seg
|
||||
desc.DPL = 3;
|
||||
hk_write_segment_descriptor(&g_gdt[16], &desc);
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[16]), 0, 0xFFFFF, SEG_TYPE(10) | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL(3));
|
||||
//ring 0 data RW
|
||||
desc.DPL = 0;
|
||||
desc.type = 2;
|
||||
hk_write_segment_descriptor(&g_gdt[24], &desc);
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[24]), 0, 0xFFFFF, SEG_TYPE(2) | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL(0));
|
||||
//ring 3 data
|
||||
desc.DPL = 3;
|
||||
hk_write_segment_descriptor(&g_gdt[32], &desc);
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[24]), 0, 0xFFFFF, SEG_TYPE(2) | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL(3));
|
||||
g_gdt_ptr.limit = 8 * 8 - 1;
|
||||
g_gdt_ptr.base = (uint32_t) g_gdt;
|
||||
hk_load_gdt(&g_gdt_ptr, SEGMENT_SELECTOR(1, 0), SEGMENT_SELECTOR(3, 0));
|
||||
hk_load_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(3, 0));
|
||||
hk_print_str(" - Done.\n\n");
|
||||
|
||||
BOCHS_MAGIC_BREAKPOINT
|
||||
|
||||
//check memory, definitely < 32 so we assume that
|
||||
hk_print_str("*Checking memory information...\n");
|
||||
if(multiboot_info->flags & (1 << 6))
|
||||
|
@ -118,154 +108,17 @@ void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
|
|||
|
||||
void HYPKERNEL32 hk_init_x64(multiboot_info_t const * const multiboot_info)
|
||||
{
|
||||
//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 ...");
|
||||
//dummy descriptor
|
||||
hk_write_segment_descriptor(&g_gdt[0], &desc_dummy);
|
||||
//ring 0 code seg, non-conforming
|
||||
desc.type = 10;
|
||||
desc.DPL = 0;
|
||||
hk_write_segment_descriptor(&g_gdt[8], &desc);
|
||||
//ring 3 code seg
|
||||
desc.DPL = 3;
|
||||
hk_write_segment_descriptor(&g_gdt[16], &desc);
|
||||
//ring 0 data RW
|
||||
desc.DPL = 0;
|
||||
desc.type = 2;
|
||||
hk_write_segment_descriptor(&g_gdt[24], &desc);
|
||||
//ring 3 data
|
||||
desc.DPL = 3;
|
||||
hk_write_segment_descriptor(&g_gdt[32], &desc);
|
||||
g_gdt_ptr_64.limit = 8 * 8 - 1;
|
||||
g_gdt_ptr_64.base = (uint64_t)g_gdt;
|
||||
hk_print_str(" - Done.\n\n");
|
||||
|
||||
//check memory, definitely < 32 so we assume that
|
||||
hk_print_str("*Checking memory information...\n");
|
||||
if(multiboot_info->flags & (1 << 6))
|
||||
{
|
||||
multiboot_memory_map_t const *mem_map = (multiboot_memory_map_t *) multiboot_info->mmap_addr;
|
||||
uint32_t const mem_map_size = multiboot_info->mmap_length / sizeof(multiboot_memory_map_t);
|
||||
hk_print_str("BaseAddr - Length - Type\n");
|
||||
uint32_t total_available_mem = 0;
|
||||
uint32_t total_reserved_mem = 0;
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < mem_map_size; i++)
|
||||
{
|
||||
hk_print_hex((uint32_t)((mem_map + i)->addr));
|
||||
hk_print_str(" - ");
|
||||
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_t) ((mem_map + i)->len);
|
||||
}
|
||||
else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||
{
|
||||
total_available_mem += (uint32_t) ((mem_map + i)->len);
|
||||
}
|
||||
}
|
||||
hk_print_str("Total available memory: ");
|
||||
hk_print_int(total_available_mem);
|
||||
hk_print_str("B = ");
|
||||
hk_print_int(total_available_mem/1024);
|
||||
hk_print_str("KB = ");
|
||||
hk_print_int(total_available_mem/1024/1024);
|
||||
hk_print_str("MB\n");
|
||||
hk_print_str("Total reserved memory: ");
|
||||
hk_print_int(total_reserved_mem);
|
||||
hk_print_str("B = ");
|
||||
hk_print_int(total_reserved_mem/1024);
|
||||
hk_print_str("KB = ");
|
||||
hk_print_int(total_reserved_mem/1024/1024);
|
||||
hk_print_str("MB\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hk_print_str("Memory information is currently unavailable.\n\n");
|
||||
}
|
||||
|
||||
//check modules
|
||||
hk_print_str("*Checking loaded kernel modules...\n");
|
||||
if(multiboot_info->flags & (1 << 3))
|
||||
{
|
||||
multiboot_module_t const * mods_list = (multiboot_module_t *)multiboot_info->mods_addr;
|
||||
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");
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < mods_count; i++)
|
||||
{
|
||||
hk_print_str((char *) (mods_list + i)->cmdline);
|
||||
hk_print_str(" - ");
|
||||
hk_print_hex((mods_list + i)->mod_start);
|
||||
hk_print_str(" - ");
|
||||
hk_print_hex((mods_list + i)->mod_end);
|
||||
hk_print_str("\n");
|
||||
}
|
||||
hk_print_str("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hk_print_str("Module information is currently unavailable.\n\n");
|
||||
}
|
||||
|
||||
|
||||
//Setup identity x64 PAE paging
|
||||
hk_print_str("*Setting up paging for x64...");
|
||||
//Setup
|
||||
//TODO: check for available memory and only allocate stuff needed(should not be really hard)
|
||||
uint32_t addr = 0x200000;
|
||||
pml4_entry_t pml4_entry = {.base = 0x201000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
|
||||
while(addr < 0x201000)
|
||||
{
|
||||
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 = 0x201000;
|
||||
pdpt_entry_t pdpt_entry = {.base = 0x202000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
|
||||
while(addr < 0x202000)
|
||||
{
|
||||
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 = 0x202000;
|
||||
pd_entry_t pd_entry = {.base = 0x203000,.Acc = 0, .PWT = 1, .PCD = 0,.Pr = 1,.USU = 0, .XD = 0, .RW = 1, .Sz = 0};
|
||||
while(addr < 0x203000)
|
||||
{
|
||||
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 = 0x203000;
|
||||
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 < (0x203000 + 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();
|
||||
//CHECK MODULE AND LOAD ELF
|
||||
HLT_CPU
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
|
||||
{
|
||||
//init text_position
|
||||
text_pos = 0;
|
||||
hk_load_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(3, 0));
|
||||
hk_print_str(" - Done.\n\n");
|
||||
|
||||
//detect architecture
|
||||
hk_print_str("*Checking architecture...\n");
|
||||
if (hk_support_x64() == 0)
|
||||
|
@ -280,6 +133,3 @@ void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
#define HYPKERNEL32 __attribute__((cdecl))
|
||||
|
||||
#define BOCHS_MAGIC_BREAKPOINT asm("xchg bx,bx");
|
||||
|
||||
#define HLT_CPU asm("hlt");
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
#define SEGMENT_SELECTOR(Index,RPL) (((Index) << 3) + (RPL))
|
||||
#define SEG_SELECTOR(Index,RPL) (((Index) << 3) + (RPL))
|
||||
|
||||
#endif
|
||||
|
|
142
x86/src/c/mem.c
142
x86/src/c/mem.c
|
@ -1,138 +1,20 @@
|
|||
#include "kdef.h"
|
||||
#include "mem.h"
|
||||
#include "print.h"
|
||||
|
||||
void HYPKERNEL32 hk_map_page_64(uint8_t * base, uint64_t const physcial_addr, uint64_t const linear_addr, pml4_entry_t* pml4_entry, pdpt_entry_t* pdpt_entry, pd_entry_t pd_entry_t, pt_entry_t* pt_entry)
|
||||
void HYPKERNEL32 hk_write_segment_descriptor(void * const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr)
|
||||
{
|
||||
// all the paging structures serve as supplementary, i.e. when the page entry does not exist.
|
||||
if(physcial_addr << 52 || linear_addr << 52)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint64_t const pml4_idx = (linear_addr >> 39) & 0x1FF; //9bits
|
||||
|
||||
}
|
||||
|
||||
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_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_t * const base, pdpt_entry_t const * const p_entry)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
return;
|
||||
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_t * const base, pd_entry_t const * const p_entry)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
return;
|
||||
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_t * const base, pt_entry_t const * const p_entry)
|
||||
{
|
||||
if(base == NULL || p_entry == NULL)
|
||||
return;
|
||||
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_t *const gdt, segment_descriptor_t const *const seg_desc)
|
||||
{
|
||||
if (gdt == NULL || seg_desc == NULL)
|
||||
if (gdt == NULL)
|
||||
return;
|
||||
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_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_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_t *const dst, interrupt_gate_t const *int_gate)
|
||||
{
|
||||
if(dst == NULL || int_gate == NULL)
|
||||
return;
|
||||
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_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_t *const dst, trap_gate_t const *tr_gate)
|
||||
{
|
||||
if(dst == NULL || tr_gate == NULL)
|
||||
return;
|
||||
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_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_t *const dst, task_gate_t const *int_gate)
|
||||
{
|
||||
if(dst == NULL || int_gate == NULL)
|
||||
return;
|
||||
dst[0] = 0;
|
||||
dst[1] = 0;
|
||||
dst[6] = 0;
|
||||
dst[7] = 0;
|
||||
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_t)(5 + ((int_gate->DPL & 0x3) << 5) + ((int_gate->Pr & 0x1 ) << 7));
|
||||
uint64_t const seg_desc = (((uint64_t)base & 0xFFFF) << 16) | ((((uint64_t)base >> 16) & 0xFF) << 32) | ((((uint64_t)base >> 24) & 0xFF) << 56) | ((uint64_t)limit & 0xFFFF) | ((((uint64_t)limit >> 16) & 0xF) << 48) | attr;
|
||||
((uint8_t*)gdt)[0] = (uint8_t)(seg_desc & 0xFF);
|
||||
((uint8_t*)gdt)[1] = (uint8_t)((seg_desc >> 8) & 0xFF);
|
||||
((uint8_t*)gdt)[2] = (uint8_t)((seg_desc >> 16) & 0xFF);
|
||||
((uint8_t*)gdt)[3] = (uint8_t)((seg_desc >> 24) & 0xFF);
|
||||
((uint8_t*)gdt)[4] = (uint8_t)((seg_desc >> 32) & 0xFF);
|
||||
((uint8_t*)gdt)[5] = (uint8_t)((seg_desc >> 40) & 0xFF);
|
||||
((uint8_t*)gdt)[6] = (uint8_t)((seg_desc >> 48) & 0xFF);
|
||||
((uint8_t*)gdt)[7] = (uint8_t)((seg_desc >> 56) & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,77 +1,16 @@
|
|||
#ifndef _MEM_32_H_
|
||||
#define _MEM_32_H_
|
||||
#ifndef _MEM_H_
|
||||
#define _MEM_H_
|
||||
#include "type.h"
|
||||
#include "kdef.h"
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t Pr;
|
||||
uint32_t RW;
|
||||
uint32_t USU;
|
||||
uint32_t PWT;
|
||||
uint32_t PCD;
|
||||
uint32_t Acc;
|
||||
uint32_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
|
||||
uint32_t XD;
|
||||
} pml4_entry_t, pdpt_entry_t, pd_entry_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t Pr;
|
||||
uint32_t RW;
|
||||
uint32_t USU;
|
||||
uint32_t PWT;
|
||||
uint32_t PCD;
|
||||
uint32_t Acc;
|
||||
uint32_t dirty;
|
||||
uint32_t PAT;
|
||||
uint32_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
|
||||
uint32_t XD;
|
||||
} pt_entry_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t seg_sel;
|
||||
uint32_t Pr;
|
||||
uint32_t DPL;
|
||||
uint32_t Sz;
|
||||
} interrupt_gate_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t seg_sel;
|
||||
uint32_t Pr;
|
||||
uint32_t DPL;
|
||||
uint32_t Sz;
|
||||
} trap_gate_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t tss_sel;
|
||||
uint32_t DPL;
|
||||
uint32_t Pr;
|
||||
} task_gate_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint32_t type;
|
||||
uint32_t DPL;
|
||||
uint32_t Gr;
|
||||
uint32_t Acc;
|
||||
uint32_t Pr;
|
||||
uint32_t Sz; //32 bits = 1, 16 bits = 0
|
||||
uint32_t x64;
|
||||
uint32_t Sys; //System = 0, code/data = 1
|
||||
|
||||
} segment_descriptor_t;
|
||||
#define SEG_GRANULARITY ((uint64_t)1 << 55)
|
||||
#define SEG_LONG ((uint64_t)1 << 53)
|
||||
#define SEG_DPL(dpl) (((uint64_t)(dpl) & 0x3) << 45)
|
||||
#define SEG_PRESENT ((uint64_t)1 << 47)
|
||||
#define SEG_CODE_DATA ((uint64_t)1 << 44)
|
||||
#define SEG_TYPE(type) (((uint64_t)(type) & 0xF) << 40)
|
||||
#define SEG_AVAILABLE ((uint64_t)1 << 52)
|
||||
#define SEG_32_BITS ((uint64_t)1 << 54)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
|
@ -79,31 +18,18 @@ typedef struct __attribute__ ((packed))
|
|||
uint32_t base;
|
||||
} gdt_ptr_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} gdt_ptr_64_t;
|
||||
|
||||
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);
|
||||
void HYPKERNEL32 hk_write_segment_descriptor(void *const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr);
|
||||
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
|
||||
|
|
|
@ -4,8 +4,8 @@ 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 signed int int32_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef char int8_t;
|
||||
#endif
|
Loading…
Reference in New Issue