Working on the PMM
parent
f096be37a2
commit
e04c28f1be
|
@ -3,36 +3,93 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
struct S_PAGING_PAGE {
|
// Some helpful macros
|
||||||
u8 Present : 1;
|
#define PAGING_GET_ML4_INDEX(x) (((u64)x >> 39) & 0x1FF)
|
||||||
u8 RW : 1;
|
#define PAGING_GET_DPT_INDEX(x) (((u64)x >> 30) & 0x1FF)
|
||||||
u8 User : 1;
|
#define PAGING_GET_DIR_INDEX(x) (((u64)x >> 21) & 0x1FF)
|
||||||
u8 Accessed : 1;
|
#define PAGING_GET_TAB_INDEX(x) (((u64)x >> 12) & 0x1FF)
|
||||||
u8 Misc : 8;
|
#define PAGING_GET_PAGE_OFFSET(x) (x & 0xFFF)
|
||||||
u32 Physical : 20;
|
|
||||||
|
// Intel-defined entries - strict!
|
||||||
|
struct S_PAGING_TAB_ENTRY {
|
||||||
|
u8 Present : 1;
|
||||||
|
u8 RW : 1;
|
||||||
|
u8 User : 1;
|
||||||
|
u8 Accessed : 1;
|
||||||
|
u8 Misc : 8;
|
||||||
|
u64 Physical : 40; // The physical address is limited by MAXPHYADDR
|
||||||
|
u16 Zero : 12;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
typedef struct S_PAGING_TAB_ENTRY T_PAGING_TAB_ENTRY;
|
||||||
|
|
||||||
typedef struct S_PAGING_PAGE T_PAGING_PAGE;
|
struct S_PAGING_DIR_ENTRY {
|
||||||
|
u8 Present : 1;
|
||||||
|
u8 RW : 1;
|
||||||
|
u8 User : 1;
|
||||||
|
u8 Accessed : 1;
|
||||||
|
u8 Misc : 8;
|
||||||
|
u64 Physical : 40; // The physical address is limited by MAXPHYADDR
|
||||||
|
u64 Zero : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
typedef struct S_PAGING_DIR_ENTRY T_PAGING_DIR_ENTRY;
|
||||||
|
|
||||||
|
struct S_PAGING_DPT_ENTRY {
|
||||||
|
u8 Present : 1;
|
||||||
|
u8 RW : 1;
|
||||||
|
u8 User : 1;
|
||||||
|
u8 Accessed : 1;
|
||||||
|
u8 Misc : 8;
|
||||||
|
u64 Physical : 40; // The physical address is limited by MAXPHYADDR
|
||||||
|
u64 Zero : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
typedef struct S_PAGING_DPT_ENTRY T_PAGING_DPT_ENTRY;
|
||||||
|
|
||||||
|
struct S_PAGING_ML4_ENTRY {
|
||||||
|
u8 Present : 1;
|
||||||
|
u8 RW : 1;
|
||||||
|
u8 User : 1;
|
||||||
|
u8 Accessed : 1;
|
||||||
|
u8 Misc : 8;
|
||||||
|
u64 Physical : 40; // The physical address is limited by MAXPHYADDR
|
||||||
|
u64 Zero : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
typedef struct S_PAGING_ML4_ENTRY T_PAGING_ML4_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
// OS-defined structures - semi-loose.
|
||||||
|
typedef struct {
|
||||||
|
T_PAGING_TAB_ENTRY Entries[512];
|
||||||
|
u64 PhysicalAddress;
|
||||||
|
} T_PAGING_TAB;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
T_PAGING_PAGE Pages[1024];
|
T_PAGING_DIR_ENTRY Entries[512]; // For use by CPU
|
||||||
} T_PAGING_TABLE;
|
T_PAGING_TAB *Children[512]; // For use by OS
|
||||||
|
u64 PhysicalAddress; // FOr use by OS when setting CPU
|
||||||
|
} T_PAGING_DIR;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 Entries[1024];
|
T_PAGING_DPT_ENTRY Entries[512];
|
||||||
T_PAGING_TABLE *Tables[1024];
|
T_PAGING_DIR *Children[512];
|
||||||
u32 PhysicalAddress;
|
u64 PhysicalAddress;
|
||||||
} T_PAGING_DIRECTORY;
|
} T_PAGING_DPT;
|
||||||
|
|
||||||
void paging_init_simple(void);
|
typedef struct {
|
||||||
u8 paging_get_physical(u64 Virtual, u64 *Physical);
|
T_PAGING_ML4_ENTRY Entries[512];
|
||||||
u8 paging_get_physical_ex(u64 Virtual, u64 *Physical,
|
T_PAGING_DPT *Children[512];
|
||||||
T_PAGING_DIRECTORY *Directory);
|
u64 PhysicalAddress;
|
||||||
void paging_map_kernel_page(u64 Virtual, u64 Physical);
|
} T_PAGING_ML4;
|
||||||
|
|
||||||
|
void paging_init_simple(u64 PhysicalVirtualOffset);
|
||||||
|
T_PAGING_ML4 * paging_get_ml4(void);
|
||||||
|
u8 paging_get_physical(u64 Virtual, u64 *Physical);
|
||||||
|
u8 paging_get_physical_ex(u64 Virtual, u64 *Physical,T_PAGING_ML4 *ML4);
|
||||||
|
|
||||||
|
/*void paging_map_kernel_page(u64 Virtual, u64 Physical);
|
||||||
void paging_map_kernel_table(u64 Virtual, u64 Physical);
|
void paging_map_kernel_table(u64 Virtual, u64 Physical);
|
||||||
void paging_map_page(u64 Virtual, u64 Physical, T_PAGING_DIRECTORY *Directory,
|
void paging_map_page(u64 Virtual, u64 Physical, T_PAGING_DIRECTORY *Directory,
|
||||||
u8 User, u8 RW);
|
u8 User, u8 RW);
|
||||||
void paging_use_directory(T_PAGING_DIRECTORY *Directory);
|
void paging_use_directory(T_PAGING_DIRECTORY *Directory);
|
||||||
T_PAGING_DIRECTORY *paging_get_directory(void);
|
T_PAGING_DIRECTORY *paging_get_directory(void);*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,13 +3,24 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void physmem_init(void);
|
#define PHYSALLOC_PAGE_SIZE 4096
|
||||||
|
#define PHYSALLOC_NUM_BITMAPS ((4096 * 8 / 64) - 1)
|
||||||
|
|
||||||
void physmem_mark_as_used(u32 Page);
|
struct S_PHYSALLOC_NODE {
|
||||||
u32 physmem_allocate_page(void);
|
u64 Bitmaps[PHYSALLOC_NUM_BITMAPS];
|
||||||
void physmem_free_page(u32 Page);
|
struct S_PHYSALLOC_NODE *Next;
|
||||||
|
};
|
||||||
|
|
||||||
u32 physmem_page_to_physical(u32 Page);
|
typedef struct S_PHYSALLOC_NODE T_PHYSALLOC_NODE;
|
||||||
u32 physmem_physical_to_page(u32 Physical);
|
|
||||||
|
void physmem_init(u64 MemorySize);
|
||||||
|
void physmem_set_node_space(u64 Space);
|
||||||
|
|
||||||
|
void physmem_mark_as_used(u64 Page);
|
||||||
|
u64 physmem_allocate_page(void);
|
||||||
|
void physmem_free_page(u64 Page);
|
||||||
|
|
||||||
|
u64 physmem_page_to_physical(u64 Page);
|
||||||
|
u64 physmem_physical_to_page(u64 Physical);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,24 +3,22 @@
|
||||||
|
|
||||||
struct S_SYSTEM_MLTBT_MMAP {
|
struct S_SYSTEM_MLTBT_MMAP {
|
||||||
u32 Size;
|
u32 Size;
|
||||||
u32 BaseLow;
|
u64 Base;
|
||||||
u32 BaseHigh;
|
u64 Length;
|
||||||
u32 LengthLow;
|
|
||||||
u32 LengthHigh;
|
|
||||||
u32 Type;
|
u32 Type;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
typedef struct S_SYSTEM_MLTBT_MMAP T_SYSTEM_MLTBT_MMAP;
|
typedef struct S_SYSTEM_MLTBT_MMAP T_SYSTEM_MLTBT_MMAP;
|
||||||
|
|
||||||
struct S_SYSTEM_INVALID_RAM {
|
struct S_SYSTEM_INVALID_RAM {
|
||||||
u32 Base;
|
u64 Base;
|
||||||
u32 Size;
|
u64 Size;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
typedef struct S_SYSTEM_INVALID_RAM T_SYSTEM_INVALID_RAM;
|
typedef struct S_SYSTEM_INVALID_RAM T_SYSTEM_INVALID_RAM;
|
||||||
|
|
||||||
void system_parse_multiboot_header(void *Header);
|
void system_parse_multiboot_header(void *Header);
|
||||||
u32 system_get_memory_upper(void);
|
u64 system_get_memory_upper(void);
|
||||||
u32 system_get_memory_lower(void);
|
u64 system_get_memory_lower(void);
|
||||||
s8 *system_get_bootloader_name(void);
|
s8 *system_get_bootloader_name(void);
|
||||||
u8 system_memory_available(u32 Start, u32 Length);
|
u8 system_memory_available(u64 Start, u64 Length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
/*#include "Tier0/gdt.h"
|
//#include "Tier0/gdt.h"
|
||||||
#include "Tier0/paging.h"
|
#include "Tier0/paging.h"
|
||||||
#include "Tier0/acpi.h"
|
//#include "Tier0/acpi.h"
|
||||||
#include "Tier0/interrupts.h"
|
//#include "Tier0/interrupts.h"
|
||||||
#include "Tier0/ps2.h"
|
//#include "Tier0/ps2.h"
|
||||||
#include "Tier0/system.h"
|
#include "Tier0/system.h"
|
||||||
#include "Tier0/pic.h"
|
//#include "Tier0/pic.h"
|
||||||
#include "Tier0/kbd_layout.h"
|
//#include "Tier0/kbd_layout.h"
|
||||||
#include "Tier0/physical_alloc.h"
|
//#include "Tier0/physical_alloc.h"
|
||||||
#include "Tier0/heap.h"
|
//#include "Tier0/heap.h"
|
||||||
#include "Tier0/cpp.h"
|
//#include "Tier0/cpp.h"
|
||||||
#include "Tier0/exceptions.h"
|
//#include "Tier0/exceptions.h"
|
||||||
#include "Tier0/panic.h"
|
//#include "Tier0/panic.h"
|
||||||
#include "Tier0/prng.h"*/
|
//#include "Tier0/prng.h"
|
||||||
|
|
||||||
|
extern u64 _end;
|
||||||
|
|
||||||
// Real kernel entry point, called from loader
|
// Real kernel entry point, called from loader
|
||||||
void kmain(u32 current_line, u32 cursor_x, u32 cursor_y)
|
void kmain(u32 current_line, u32 cursor_x, u32 cursor_y, u32 MultibootHeader)
|
||||||
{
|
{
|
||||||
kstdio_init();
|
kstdio_init();
|
||||||
kstdio_set_globals(current_line, cursor_x, cursor_y);
|
kstdio_set_globals(current_line, cursor_x, cursor_y);
|
||||||
|
@ -26,19 +28,18 @@ void kmain(u32 current_line, u32 cursor_x, u32 cursor_y)
|
||||||
" | _| | | _| | | | . | -_| _|\n"
|
" | _| | | _| | | | . | -_| _|\n"
|
||||||
" |___|___|___|___|_|_|_|___|___|_| \n\n");
|
" |___|___|___|___|_|_|_|___|___|_| \n\n");
|
||||||
kprintf("[i] Welcome to Cucumber (x86-64)!\n");
|
kprintf("[i] Welcome to Cucumber (x86-64)!\n");
|
||||||
//kprintf("%x %x %x\n", current_line, cursor_x, cursor_y);
|
|
||||||
|
kprintf("[i] Multiboot header @%x\n", MultibootHeader);
|
||||||
|
system_parse_multiboot_header((void*)((u64)MultibootHeader));
|
||||||
|
kprintf("[i] Booting via %s.\n", system_get_bootloader_name());
|
||||||
|
kprintf("[i] Memory available: %uk.\n", system_get_memory_upper());
|
||||||
|
kprintf("[i] Kernel end: %x.\n", &_end);
|
||||||
|
|
||||||
|
//paging_init_simple();
|
||||||
|
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
|
|
||||||
/*if (Magic != 0x2BADB002)
|
|
||||||
{
|
|
||||||
kprintf("[e] Fatal! Boot via incompatible bootloader.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*gdt_create_flat();
|
||||||
paging_init_simple();
|
|
||||||
gdt_create_flat();
|
|
||||||
|
|
||||||
physmem_init();
|
physmem_init();
|
||||||
system_parse_multiboot_header(MultibootHeader);
|
system_parse_multiboot_header(MultibootHeader);
|
||||||
|
|
|
@ -1,43 +1,72 @@
|
||||||
#include "Tier0/paging.h"
|
#include "Tier0/paging.h"
|
||||||
#include "Tier0/system.h"
|
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
#include "Tier0/kstdlib.h"
|
#include "Tier0/kstdlib.h"
|
||||||
#include "Tier0/interrupts.h"
|
|
||||||
#include "Tier0/heap.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
T_PAGING_DIRECTORY g_kernel_page_directory __attribute__ ((aligned (4096)));
|
// The basic structures for the first kernel thread...
|
||||||
T_PAGING_TABLE g_kernel_page_tables[1024] __attribute__ ((aligned (4096)));
|
// Since they are < 2Mib, their virtual addresses = their physical addresses -
|
||||||
|
// some offset given by the loader
|
||||||
|
//T_PAGING_ML4 g_paging_basic_ml4;
|
||||||
|
// These are the structures for mapping the lowest 2MiB
|
||||||
|
//T_PAGING_ML4 g_paging_basic_dpt_lowmap;
|
||||||
|
//T_PAGING_ML4 g_paging_basic_dir_lowmap;
|
||||||
|
//T_PAGING_ML4 g_paging_basic_tab_lowmap;
|
||||||
|
// These are the structures for mapping the kernel memory (2Mib)
|
||||||
|
//T_PAGING_ML4 g_paging_basic_dpt_kernel;
|
||||||
|
//T_PAGING_ML4 g_paging_basic_dir_kernel;
|
||||||
|
//T_PAGING_ML4 g_paging_basic_tab_kernel;
|
||||||
|
|
||||||
u8 paging_get_physical_ex(u32 Virtual, u32 *Physical,
|
T_PAGING_ML4 *paging_get_ml4(void)
|
||||||
T_PAGING_DIRECTORY *Directory)
|
|
||||||
{
|
{
|
||||||
u16 DirectoryIndex = (Virtual >> 22) & 0x3FF;
|
u64 Address;
|
||||||
u32 DirectoryEntry = Directory->Entries[DirectoryIndex];
|
__asm__ volatile("mov %%cr3, %0\n" : "=r"(Address));
|
||||||
|
return (T_PAGING_ML4*)Address;
|
||||||
u8 TablePresent = DirectoryEntry & 0b1;
|
|
||||||
if (!TablePresent)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
T_PAGING_TABLE *Table = Directory->Tables[DirectoryIndex];
|
|
||||||
|
|
||||||
u16 TableIndex = (Virtual >> 12) & 0x3FF;
|
|
||||||
T_PAGING_PAGE Page = (Table->Pages[TableIndex]);
|
|
||||||
if (!Page.Present)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*Physical = (Page.Physical << 12);
|
|
||||||
*Physical |= (Virtual & 0xFFF);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 paging_get_physical(u32 Virtual, u32 *Physical)
|
u8 paging_get_physical_ex(u64 Virtual, u64 *Physical, T_PAGING_ML4 *ML4)
|
||||||
{
|
{
|
||||||
return paging_get_physical_ex(Virtual, Physical, &g_kernel_page_directory);
|
u16 ML4Index = PAGING_GET_ML4_INDEX(Virtual);
|
||||||
|
u16 DPTIndex = PAGING_GET_DPT_INDEX(Virtual);
|
||||||
|
u16 DirIndex = PAGING_GET_DIR_INDEX(Virtual);
|
||||||
|
u16 TabIndex = PAGING_GET_TAB_INDEX(Virtual);
|
||||||
|
|
||||||
|
if (!ML4->Entries[ML4Index].Present)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
T_PAGING_DPT *DPT = ML4->Children[ML4Index];
|
||||||
|
|
||||||
|
if (!DPT->Entries[DPTIndex].Present)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
T_PAGING_DIR *Dir = DPT->Children[DPTIndex];
|
||||||
|
|
||||||
|
if (!Dir->Entries[DirIndex].Present)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
T_PAGING_TAB *Tab = Dir->Children[DirIndex];
|
||||||
|
|
||||||
|
if (!Tab->Entries[TabIndex].Present)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
(*Physical) = (Tab->Entries[TabIndex].Physical << 12) + PAGING_GET_PAGE_OFFSET(Virtual);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paging_dump_directory(void)
|
u8 paging_get_physical(u64 Virtual, u64 *Physical)
|
||||||
|
{
|
||||||
|
T_PAGING_ML4 *ml4 = paging_get_ml4();
|
||||||
|
return paging_get_physical_ex(Virtual, Physical, ml4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This initializes a very basic paging structure for the first kernel thread
|
||||||
|
void paging_init_simple(u64 PhysicalVirtualOffset)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void paging_dump_directory(void)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 10; i++)
|
for (u32 i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
|
@ -167,5 +196,5 @@ void paging_init_simple(void)
|
||||||
paging_map_kernel_table(0xC0400000, 0x00400000);
|
paging_map_kernel_table(0xC0400000, 0x00400000);
|
||||||
|
|
||||||
paging_use_directory(&g_kernel_page_directory);
|
paging_use_directory(&g_kernel_page_directory);
|
||||||
}
|
}*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "Tier0/panic.h"
|
#include "Tier0/panic.h"
|
||||||
#include "Tier0/kstdio.h"
|
#include "Tier0/kstdio.h"
|
||||||
#include "Tier0/prng.h"
|
//#include "Tier0/prng.h"
|
||||||
#include "preprocessor_hacks.h"
|
#include "preprocessor_hacks.h"
|
||||||
|
|
||||||
#define KPANIC_HEADER(n) KPANIC_HEADER##n
|
#define KPANIC_HEADER(n) KPANIC_HEADER##n
|
||||||
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
char *kpanic_get_random_message(void)
|
char *kpanic_get_random_message(void)
|
||||||
{
|
{
|
||||||
u16 N = krand() % 10;
|
//u16 N = krand() % 10;
|
||||||
|
u16 N = 0;
|
||||||
switch (N)
|
switch (N)
|
||||||
{
|
{
|
||||||
PPHAX_DO10(KPANIC_CASE);
|
PPHAX_DO10(KPANIC_CASE);
|
||||||
|
@ -71,7 +72,7 @@ void kpanic_ex(const s8 *Error, const s8 *File, u32 Line, T_ISR_REGISTERS R)
|
||||||
|
|
||||||
// Dumping registers
|
// Dumping registers
|
||||||
|
|
||||||
u32 ds, cr0, cr3;
|
/*u32 ds, cr0, cr3;
|
||||||
|
|
||||||
__asm__ volatile("mov %%cr0, %0": "=r"(cr0));
|
__asm__ volatile("mov %%cr0, %0": "=r"(cr0));
|
||||||
__asm__ volatile("mov %%cr3, %0": "=r"(cr3));
|
__asm__ volatile("mov %%cr3, %0": "=r"(cr3));
|
||||||
|
@ -84,13 +85,13 @@ void kpanic_ex(const s8 *Error, const s8 *File, u32 Line, T_ISR_REGISTERS R)
|
||||||
kprintf(" eax: 0x%X ebx: 0x%x ecx: 0x%x edx: 0x%x\n",
|
kprintf(" eax: 0x%X ebx: 0x%x ecx: 0x%x edx: 0x%x\n",
|
||||||
R.eax, R.ebx, R.ecx, R.edx);
|
R.eax, R.ebx, R.ecx, R.edx);
|
||||||
kprintf(" esi: 0x%X edi: 0x%x ebp: 0x%x esp: 0x%x\n",
|
kprintf(" esi: 0x%X edi: 0x%x ebp: 0x%x esp: 0x%x\n",
|
||||||
R.esi, R.edi, R.ebp, R.esp);
|
R.esi, R.edi, R.ebp, R.esp);*/
|
||||||
|
|
||||||
//s32 FrameSize = R.ebp - R.esp;
|
//s32 FrameSize = R.ebp - R.esp;
|
||||||
|
|
||||||
/*if (FrameSize > 0 && FrameSize < 0x100)
|
/*if (FrameSize > 0 && FrameSize < 0x100)
|
||||||
{*/
|
{*/
|
||||||
kprintf("\n stack frame looks promising...\n");
|
/*kprintf("\n stack frame looks promising...\n");
|
||||||
kprintf(" attempting stack dump:\n");
|
kprintf(" attempting stack dump:\n");
|
||||||
|
|
||||||
u32 Number = 80;
|
u32 Number = 80;
|
||||||
|
@ -98,7 +99,7 @@ void kpanic_ex(const s8 *Error, const s8 *File, u32 Line, T_ISR_REGISTERS R)
|
||||||
{
|
{
|
||||||
kprintf(" %x %x %x %x %x %x %x %x\n",
|
kprintf(" %x %x %x %x %x %x %x %x\n",
|
||||||
*v, *(v+1), *(v+2), *(v+3), *(v+4), *(v+5), *(v+6), *(v+7));
|
*v, *(v+1), *(v+2), *(v+3), *(v+4), *(v+5), *(v+6), *(v+7));
|
||||||
}
|
}*/
|
||||||
/*}
|
/*}
|
||||||
else
|
else
|
||||||
kprintf("\n stack looks unusable, not dummping.\n");*/
|
kprintf("\n stack looks unusable, not dummping.\n");*/
|
|
@ -0,0 +1,153 @@
|
||||||
|
// Kinda like a heap, but not really.
|
||||||
|
// (the following sizes are for x86)
|
||||||
|
// Based on a very large number of 4k pages. They are kept in a linear list
|
||||||
|
// of 512 64-bit (4kbyte) bitmaps. If there aren't any free pages in the
|
||||||
|
// bitmap, oh we want to mark a page as reserved further down in the list,
|
||||||
|
// then we create a new one and link the together. Freeing pages does not
|
||||||
|
// (yet?) free bitmaps. We always reserve one page for extending the list.
|
||||||
|
|
||||||
|
#include "Tier0/physical_alloc.h"
|
||||||
|
#include "Tier0/kstdio.h"
|
||||||
|
#include "Tier0/panic.h"
|
||||||
|
|
||||||
|
T_PHYSALLOC_NODE g_physalloc_root_node;
|
||||||
|
T_PHYSALLOC_NODE *g_physalloc_top_node;
|
||||||
|
u64 g_physalloc_list_size = 1;
|
||||||
|
u64 g_physalloc_space_for_next = 0;
|
||||||
|
u64 g_physalloc_mem_max = 0;
|
||||||
|
|
||||||
|
void physmem_zero_node(T_PHYSALLOC_NODE *Node)
|
||||||
|
{
|
||||||
|
for (u64 i = 0; i < PHYSALLOC_NUM_BITMAPS; i++)
|
||||||
|
Node->Bitmaps[i] = 0;
|
||||||
|
|
||||||
|
Node->Next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void physmem_init(u64 MemorySize)
|
||||||
|
{
|
||||||
|
// Create the first node
|
||||||
|
physmem_zero_node(&g_physalloc_root_node);
|
||||||
|
g_physalloc_top_node = &g_physalloc_root_node;
|
||||||
|
g_physalloc_mem_max = MemorySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void physmem_create_node(void)
|
||||||
|
{
|
||||||
|
if (!g_physalloc_space_for_next)
|
||||||
|
PANIC("No space for next physmem node! :o");
|
||||||
|
|
||||||
|
T_PHYSALLOC_NODE *NewNode = (T_PHYSALLOC_NODE *)g_physalloc_space_for_next;
|
||||||
|
physmem_zero_node(NewNode);
|
||||||
|
|
||||||
|
g_physalloc_top_node->Next = NewNode;
|
||||||
|
g_physalloc_top_node = NewNode;
|
||||||
|
|
||||||
|
g_physalloc_space_for_next = physmem_allocate_page();
|
||||||
|
g_physalloc_list_size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
T_PHYSALLOC_NODE *physmem_traverse_list(u64 Index)
|
||||||
|
{
|
||||||
|
if (Index > g_physalloc_list_size)
|
||||||
|
PANIC("Tried to traverse list too far!");
|
||||||
|
|
||||||
|
u32 Current = 0;
|
||||||
|
T_PHYSALLOC_NODE *Node = &g_physalloc_root_node;
|
||||||
|
|
||||||
|
while (Current < Index)
|
||||||
|
Node = Node->Next;
|
||||||
|
Current++;
|
||||||
|
|
||||||
|
return Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void physmem_set_node_space(u64 Space)
|
||||||
|
{
|
||||||
|
g_physalloc_space_for_next = Space;
|
||||||
|
}
|
||||||
|
|
||||||
|
void physmem_mark_as_used(u64 Page)
|
||||||
|
{
|
||||||
|
T_PHYSALLOC_NODE *Node;
|
||||||
|
|
||||||
|
if (g_physalloc_list_size * PHYSALLOC_NUM_BITMAPS * 64 >= Page)
|
||||||
|
Node = physmem_traverse_list(Page / (PHYSALLOC_NUM_BITMAPS * 64));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (g_physalloc_list_size * PHYSALLOC_NUM_BITMAPS * 64 < Page)
|
||||||
|
{
|
||||||
|
physmem_create_node();
|
||||||
|
}
|
||||||
|
Node = g_physalloc_top_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 OffsetInBitmaps = Page / (PHYSALLOC_NUM_BITMAPS * 64);
|
||||||
|
u8 OffsetInBitmap = Page % 64;
|
||||||
|
|
||||||
|
//kprintf("p: marking %i (%i %i)\n", Page, OffsetInBitmaps, OffsetInBitmap);
|
||||||
|
|
||||||
|
u64 Bitmap = Node->Bitmaps[OffsetInBitmaps];
|
||||||
|
Bitmap |= (1 << OffsetInBitmap);
|
||||||
|
Node->Bitmaps[OffsetInBitmaps] = Bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 physmem_allocate_page(void)
|
||||||
|
{
|
||||||
|
T_PHYSALLOC_NODE *Node = &g_physalloc_root_node;
|
||||||
|
for (u64 nNode = 0; nNode < g_physalloc_list_size; nNode++)
|
||||||
|
{
|
||||||
|
for (u16 nBitmap = 0; nBitmap < PHYSALLOC_NUM_BITMAPS; nBitmap++)
|
||||||
|
{
|
||||||
|
u64 Bitmap = Node->Bitmaps[nBitmap];
|
||||||
|
if (Bitmap != 0xFFFFFFFFFFFFFFFF)
|
||||||
|
{
|
||||||
|
for (u8 nBit = 0; nBit < 64; nBit++)
|
||||||
|
{
|
||||||
|
if ((Bitmap & (1 << nBit)) == 0)
|
||||||
|
{
|
||||||
|
Bitmap |= (1 << nBit);
|
||||||
|
Node->Bitmaps[nBitmap] = Bitmap;
|
||||||
|
kprintf("physmem: allocated %i\n", nNode * PHYSALLOC_NUM_BITMAPS + nBitmap * 64 + nBit);
|
||||||
|
return nNode * PHYSALLOC_NUM_BITMAPS + nBitmap * 64 + nBit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Node = Node->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still no space? Create a new node, if there is still space left in the memory
|
||||||
|
if (g_physalloc_mem_max && ((g_physalloc_list_size + 1) * PHYSALLOC_NUM_BITMAPS * 64 * PHYSALLOC_PAGE_SIZE > g_physalloc_mem_max))
|
||||||
|
{
|
||||||
|
kprintf("physmem: extending\n");
|
||||||
|
physmem_create_node();
|
||||||
|
Node = g_physalloc_top_node;
|
||||||
|
Node->Bitmaps[0] = 0x1;
|
||||||
|
return ((g_physalloc_list_size - 1) * PHYSALLOC_NUM_BITMAPS * 64) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PANIC("Out of memory!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void physmem_free_page(u64 Page)
|
||||||
|
{
|
||||||
|
T_PHYSALLOC_NODE *Node = physmem_traverse_list(Page / (PHYSALLOC_NUM_BITMAPS * 64));
|
||||||
|
u16 OffsetInBitmaps = Page % (PHYSALLOC_NUM_BITMAPS * 64);
|
||||||
|
u8 OffsetInBitmap = Page % 64;
|
||||||
|
|
||||||
|
u64 Bitmap = Node->Bitmaps[OffsetInBitmaps];
|
||||||
|
Bitmap ^= (1 << OffsetInBitmap);
|
||||||
|
Node->Bitmaps[OffsetInBitmaps] = Bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 physmem_page_to_physical(u64 Page)
|
||||||
|
{
|
||||||
|
return Page * PHYSALLOC_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 physmem_physical_to_page(u64 Physical)
|
||||||
|
{
|
||||||
|
return Physical / PHYSALLOC_PAGE_SIZE;
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
// Basic information gathere about system
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "Tier0/system.h"
|
||||||
|
#include "Tier0/kstdio.h"
|
||||||
|
#include "Tier0/physical_alloc.h"
|
||||||
|
|
||||||
|
u64 g_system_memory_lower = 0;
|
||||||
|
u64 g_system_memory_upper = 0;
|
||||||
|
s8* g_system_bootloader = "Unknown Multiboot Bootloader";
|
||||||
|
|
||||||
|
// Just a guess...
|
||||||
|
T_SYSTEM_INVALID_RAM g_system_invalid_areas[256];
|
||||||
|
u8 g_system_num_invalid_areas;
|
||||||
|
extern u64 _end;
|
||||||
|
|
||||||
|
void system_parse_multiboot_header(void *Header)
|
||||||
|
{
|
||||||
|
u8 Flags = *((u8*)Header);
|
||||||
|
|
||||||
|
if (Flags & 1)
|
||||||
|
{
|
||||||
|
g_system_memory_lower = (u64)((u8*)Header)[4];
|
||||||
|
g_system_memory_upper = (u64)((u8*)Header)[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Flags >> 9) & 1)
|
||||||
|
g_system_bootloader = (s8*)(u64)((u32*)Header)[16];
|
||||||
|
|
||||||
|
u64 HighestUnavailable = 0;
|
||||||
|
|
||||||
|
if ((Flags >> 6) & 1)
|
||||||
|
{
|
||||||
|
// Memory map from bootloader...
|
||||||
|
u64 MapStart = ((u32*)Header)[12];
|
||||||
|
u64 MapLength = ((u32*)Header)[11];
|
||||||
|
|
||||||
|
g_system_num_invalid_areas = 0;
|
||||||
|
u64 AvailableMemory = 0;
|
||||||
|
|
||||||
|
T_SYSTEM_MLTBT_MMAP *Node = (T_SYSTEM_MLTBT_MMAP*)MapStart;
|
||||||
|
|
||||||
|
while ((u64)Node + 4 - MapStart < MapLength)
|
||||||
|
{
|
||||||
|
u32 Size = Node->Size;
|
||||||
|
if (Size == 0)
|
||||||
|
Size = sizeof(T_SYSTEM_MLTBT_MMAP);
|
||||||
|
|
||||||
|
if (Node->Type == 1)
|
||||||
|
AvailableMemory += Node->Length;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not available!
|
||||||
|
T_SYSTEM_INVALID_RAM *Area = \
|
||||||
|
&g_system_invalid_areas[g_system_num_invalid_areas];
|
||||||
|
|
||||||
|
Area->Base = Node->Base;
|
||||||
|
Area->Size = Node->Length;
|
||||||
|
|
||||||
|
if (Area->Base > HighestUnavailable)
|
||||||
|
HighestUnavailable = Area->Base;
|
||||||
|
|
||||||
|
g_system_num_invalid_areas++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node = (T_SYSTEM_MLTBT_MMAP*)((u64)Node + Size + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_system_memory_upper = AvailableMemory / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("[i] Highest unavailable address is %x.\n", HighestUnavailable);
|
||||||
|
physmem_init(HighestUnavailable);
|
||||||
|
|
||||||
|
|
||||||
|
for (u8 i = 0; i < g_system_num_invalid_areas; i++)
|
||||||
|
{
|
||||||
|
T_SYSTEM_INVALID_RAM *Area = &g_system_invalid_areas[i];
|
||||||
|
if (Area->Base < HighestUnavailable)
|
||||||
|
{
|
||||||
|
u64 Page = physmem_physical_to_page(Area->Base);
|
||||||
|
kprintf("[i] %x - %x unavailable\n", Area->Base, Area->Base + Area->Size);
|
||||||
|
for (int j = 0; j <= Area->Size / PHYSALLOC_PAGE_SIZE; j++)
|
||||||
|
physmem_mark_as_used(Page + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark BIOS (1MB) as used
|
||||||
|
//u64 BIOSSize = 1024*1024;
|
||||||
|
//for (u16 i = 0; i < BIOSSize / PHYSALLOC_PAGE_SIZE; i++)
|
||||||
|
// physmem_mark_as_used(i);
|
||||||
|
|
||||||
|
// Mark kernel memory as used
|
||||||
|
//u64 KernelSize = ((u64)&_end) - 0xFF000000;
|
||||||
|
//for (u16 i = 0; i < KernelSize / PHYSALLOC_PAGE_SIZE; i++)
|
||||||
|
// physmem_mark_as_used(i);
|
||||||
|
|
||||||
|
// Set the new node space for physmem
|
||||||
|
u64 Page = physmem_allocate_page();
|
||||||
|
u64 Memory = physmem_page_to_physical(Page);
|
||||||
|
|
||||||
|
// TODO: Fix relying on identity paging for low memory addresses
|
||||||
|
physmem_set_node_space(Memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 system_get_memory_upper(void)
|
||||||
|
{
|
||||||
|
return g_system_memory_upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 system_get_memory_lower(void)
|
||||||
|
{
|
||||||
|
return g_system_memory_lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
s8 *system_get_bootloader_name(void)
|
||||||
|
{
|
||||||
|
return g_system_bootloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 system_memory_available(u64 Start, u64 Length)
|
||||||
|
{
|
||||||
|
for (u8 i = 0; i < g_system_num_invalid_areas; i++)
|
||||||
|
{
|
||||||
|
T_SYSTEM_INVALID_RAM Area = g_system_invalid_areas[i];
|
||||||
|
|
||||||
|
// If the start address is somwhere in the invalid area
|
||||||
|
if (Area.Base <= Start && Area.Base + Area.Size > Start)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If the end address is somewhere in the invalid area
|
||||||
|
if (Area.Base <= Start + Length && Area.Base + Area.Size > Start + Length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If the request spans accross an invalid area
|
||||||
|
if (Area.Base >= Start && Start + Length < Area.Base + Area.Size)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
// Kinda like a heap, but not really.
|
|
||||||
// Based on 1024 4MB superpages. You can't allocate anything lower than that,
|
|
||||||
// but who cares. The only time this is going to be called is by lower parts of
|
|
||||||
// the kernel, anyway.
|
|
||||||
|
|
||||||
#include "Tier0/physical_alloc.h"
|
|
||||||
#include "Tier0/kstdio.h"
|
|
||||||
#include "Tier0/panic.h"
|
|
||||||
|
|
||||||
u32 g_physmem_directory[32 * 1024];
|
|
||||||
|
|
||||||
void physmem_init(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 32; i++)
|
|
||||||
g_physmem_directory[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void physmem_mark_as_used(u32 Page)
|
|
||||||
{
|
|
||||||
u32 Entry = Page / 32;
|
|
||||||
u8 Bit = Page % 32;
|
|
||||||
|
|
||||||
g_physmem_directory[Entry] |= (1 << Bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 physmem_allocate_page(void)
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < 32 * 1024; i++)
|
|
||||||
{
|
|
||||||
u32 Entry = g_physmem_directory[i];
|
|
||||||
if (Entry != 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
// Ooh, there's a page in this entry
|
|
||||||
for (int j = 0; j < 32; j++)
|
|
||||||
{
|
|
||||||
u8 Available = (~Entry & (1 << j)) > 0;
|
|
||||||
if (Available)
|
|
||||||
{
|
|
||||||
u32 Page = i * 32 + j;
|
|
||||||
physmem_mark_as_used(Page);
|
|
||||||
return Page;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PANIC("Could not allocate page!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void physmem_free_page(u32 Page)
|
|
||||||
{
|
|
||||||
u8 Entry = Page / 32;
|
|
||||||
u8 Bit = Page % 32;
|
|
||||||
|
|
||||||
g_physmem_directory[Entry] &= ~(1 << Bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 physmem_page_to_physical(u32 Page)
|
|
||||||
{
|
|
||||||
return Page * 1024 * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 physmem_physical_to_page(u32 Physical)
|
|
||||||
{
|
|
||||||
return Physical / (1024 * 4);
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
// Basic information gathere about system
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "Tier0/system.h"
|
|
||||||
#include "Tier0/kstdio.h"
|
|
||||||
#include "Tier0/physical_alloc.h"
|
|
||||||
|
|
||||||
u32 g_system_memory_lower = 0;
|
|
||||||
u32 g_system_memory_upper = 0;
|
|
||||||
s8* g_system_bootloader = "Unknown Multiboot Bootloader";
|
|
||||||
|
|
||||||
// Just a guess...
|
|
||||||
T_SYSTEM_INVALID_RAM g_system_invalid_areas[256];
|
|
||||||
u8 g_system_num_invalid_areas;
|
|
||||||
|
|
||||||
void system_parse_multiboot_header(void *Header)
|
|
||||||
{
|
|
||||||
u8 Flags = *((u8*)Header);
|
|
||||||
|
|
||||||
if (Flags & 1)
|
|
||||||
{
|
|
||||||
g_system_memory_lower = ((u8*)Header)[4];
|
|
||||||
g_system_memory_upper = ((u8*)Header)[8];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Flags >> 9) & 1)
|
|
||||||
g_system_bootloader = (s8*)((u32*)Header)[16];
|
|
||||||
|
|
||||||
if ((Flags >> 6) & 1)
|
|
||||||
{
|
|
||||||
// Memory map from bootloader...
|
|
||||||
u32 MapStart = ((u32*)Header)[12];
|
|
||||||
u32 MapLength = ((u32*)Header)[11];
|
|
||||||
|
|
||||||
g_system_num_invalid_areas = 0;
|
|
||||||
u32 AvailableMemory = 0;
|
|
||||||
|
|
||||||
T_SYSTEM_MLTBT_MMAP *Node = (T_SYSTEM_MLTBT_MMAP*)MapStart;
|
|
||||||
|
|
||||||
while ((u32)Node + 4 - MapStart < MapLength)
|
|
||||||
{
|
|
||||||
u32 Size = Node->Size;
|
|
||||||
if (Size == 0)
|
|
||||||
Size = sizeof(T_SYSTEM_MLTBT_MMAP);
|
|
||||||
|
|
||||||
if (Node->Type == 1)
|
|
||||||
AvailableMemory += Node->LengthLow;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not available!
|
|
||||||
T_SYSTEM_INVALID_RAM Area = \
|
|
||||||
g_system_invalid_areas[g_system_num_invalid_areas];
|
|
||||||
|
|
||||||
Area.Base = Node->BaseLow;
|
|
||||||
Area.Size = Node->LengthLow;
|
|
||||||
|
|
||||||
g_system_num_invalid_areas++;
|
|
||||||
|
|
||||||
u32 Page = physmem_physical_to_page(Area.Base);
|
|
||||||
for (int i = 0; i <= Area.Size / (4 * 1024); i++)
|
|
||||||
physmem_mark_as_used(Page + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node = (T_SYSTEM_MLTBT_MMAP*)((u32)Node + Size + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_system_memory_upper = AvailableMemory / 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark first 8 MB as used (that's where our kernel binary is loaded)
|
|
||||||
for (u16 i = 0; i < 1024 * 8; i++)
|
|
||||||
physmem_mark_as_used(i);
|
|
||||||
|
|
||||||
// Mark all memory > memory size as used.
|
|
||||||
u16 StartPage = g_system_memory_upper / (1024 * 4);
|
|
||||||
u16 NumPages = (0xFFFFFFFF / 1024 - g_system_memory_upper) / (1024 * 4);
|
|
||||||
for (int i = 0; i < NumPages; i++)
|
|
||||||
physmem_mark_as_used(StartPage + i);
|
|
||||||
|
|
||||||
if (g_system_memory_upper % (1024 * 4) != 0)
|
|
||||||
physmem_mark_as_used(0xFFFFFFFF / (1024 * 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 system_get_memory_upper(void)
|
|
||||||
{
|
|
||||||
return g_system_memory_upper;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 system_get_memory_lower(void)
|
|
||||||
{
|
|
||||||
return g_system_memory_lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
s8 *system_get_bootloader_name(void)
|
|
||||||
{
|
|
||||||
return g_system_bootloader;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 system_memory_available(u32 Start, u32 Length)
|
|
||||||
{
|
|
||||||
for (u8 i = 0; i < g_system_num_invalid_areas; i++)
|
|
||||||
{
|
|
||||||
T_SYSTEM_INVALID_RAM Area = g_system_invalid_areas[i];
|
|
||||||
|
|
||||||
// If the start address is somwhere in the invalid area
|
|
||||||
if (Area.Base <= Start && Area.Base + Area.Size > Start)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If the end address is somewhere in the invalid area
|
|
||||||
if (Area.Base <= Start + Length && Area.Base + Area.Size > Start + Length)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If the request spans accross an invalid area
|
|
||||||
if (Area.Base >= Start && Start + Length < Area.Base + Area.Size)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ static inline void cpuid(u32 code, u32 *a, u32 *d) {
|
||||||
// This will be replaced later on by the kernel code.
|
// This will be replaced later on by the kernel code.
|
||||||
|
|
||||||
u64 pml4[512] __attribute__((aligned(0x1000)));
|
u64 pml4[512] __attribute__((aligned(0x1000)));
|
||||||
|
|
||||||
u64 page_dir_ptr_tab_low[512] __attribute__((aligned(0x1000)));
|
u64 page_dir_ptr_tab_low[512] __attribute__((aligned(0x1000)));
|
||||||
u64 page_dir_low[512] __attribute__((aligned(0x1000)));
|
u64 page_dir_low[512] __attribute__((aligned(0x1000)));
|
||||||
u64 page_tab_low[512] __attribute__((aligned(0x1000)));
|
u64 page_tab_low[512] __attribute__((aligned(0x1000)));
|
||||||
|
@ -276,21 +277,25 @@ u32 create_ia32e_paging(u64 KernelPhysicalStart, u64 KernelVirtualStart, u64 Ker
|
||||||
for (u16 i = GET_TAB_ENTRY(KernelVirtualStart); i < GET_TAB_ENTRY(KernelVirtualStart) + NumPages; i++)
|
for (u16 i = GET_TAB_ENTRY(KernelVirtualStart); i < GET_TAB_ENTRY(KernelVirtualStart) + NumPages; i++)
|
||||||
{
|
{
|
||||||
page_tab_high[i] = Address | 3;
|
page_tab_high[i] = Address | 3;
|
||||||
print_hex(KernelVirtualStart + i * 0x1000);
|
/*print_hex(KernelVirtualStart + i * 0x1000);
|
||||||
puts(" -> ");
|
puts(" -> ");
|
||||||
print_hex(Address);
|
print_hex(Address);
|
||||||
puts("\n");
|
puts("\n");*/
|
||||||
Address += 0x1000;
|
Address += 0x1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 g_multiboot_header;
|
||||||
|
|
||||||
u32 load(void *Multiboot, unsigned int Magic)
|
u32 load(void *Multiboot, unsigned int Magic)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
puts("Cucumber x86-64 loader...\n");
|
puts("Cucumber x86-64 loader...\n");
|
||||||
|
|
||||||
|
g_multiboot_header = (u32)Multiboot;
|
||||||
|
|
||||||
|
|
||||||
if (Magic != 0x2BADB002)
|
if (Magic != 0x2BADB002)
|
||||||
{
|
{
|
||||||
|
@ -437,5 +442,5 @@ u32 load(void *Multiboot, unsigned int Magic)
|
||||||
|
|
||||||
puts("Now in 32-bit compability mode, jumping to the kernel...\n");
|
puts("Now in 32-bit compability mode, jumping to the kernel...\n");
|
||||||
|
|
||||||
return (u32)Header->Entry;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ extern puts
|
||||||
extern stdio_current_line
|
extern stdio_current_line
|
||||||
extern stdio_cur_x
|
extern stdio_cur_x
|
||||||
extern stdio_cur_y
|
extern stdio_cur_y
|
||||||
|
extern g_multiboot_header;
|
||||||
global _loader
|
global _loader
|
||||||
|
|
||||||
; Multiboot-related constants
|
; Multiboot-related constants
|
||||||
|
@ -81,6 +82,7 @@ _loader_gdt:
|
||||||
movzx edi, byte [stdio_current_line]
|
movzx edi, byte [stdio_current_line]
|
||||||
movzx esi, byte [stdio_cur_x]
|
movzx esi, byte [stdio_cur_x]
|
||||||
movzx edx, byte [stdio_cur_y]
|
movzx edx, byte [stdio_cur_y]
|
||||||
|
mov ecx, dword [g_multiboot_header]
|
||||||
|
|
||||||
; 64-bit, here we come!
|
; 64-bit, here we come!
|
||||||
call 0x18:0xFF000000
|
call 0x18:0xFF000000
|
||||||
|
|
Loading…
Reference in New Issue