Implemented hk_printf and made everything else implicit.
Ahmmm. Also made 64 bit kernel independent(you can call that thing to enter 64 bit kernel as long as you are in protected mode (no setup required.))(not working but will soon work).
This commit is contained in:
parent
8e8d089578
commit
57b0f4a8f1
@ -1,16 +1,84 @@
|
||||
extern hk_main
|
||||
[SECTION .entry]
|
||||
[BITS 32] ;on stack: multiboot_info*
|
||||
; no, no interrupt please.
|
||||
cli
|
||||
global HLT_CPU
|
||||
global BOCHS_MAGIC_BREAKPOINT
|
||||
|
||||
;IMPORTANT: Before entering this, CPU should be in protected mode.
|
||||
;IMPORTANT: This module should be 4k-page aliened
|
||||
[SECTION .entry]
|
||||
[BITS 32]
|
||||
;on stack: multiboot_info*
|
||||
;skip data definition
|
||||
jmp start
|
||||
; here we need to construct a dummy gdt as well as a dummy page table(As simple as possible, maps 1G page sounds good)
|
||||
; for page table we only need 4 gigs since that's the maximum mem one can access in protected mode(without PAE)
|
||||
; flags are hard-coded... highly not recommended but for our purpose it's enough
|
||||
; little-endian assumed
|
||||
times (4096 - 5) db 0; skip the first jmp as well as making it kernel stack, 16 bytes aliened :D
|
||||
KERNEL_STACK:
|
||||
PML4_BASE:
|
||||
times 512 dq 0 ;reserved the rest for page entries
|
||||
PDPT_BASE:
|
||||
times 512 dq 0 ;reserved the rest for page entries
|
||||
|
||||
|
||||
GDT64: ; Global Descriptor Table (64-bit).
|
||||
.NULL: equ $ - GDT64 ; The null descriptor.
|
||||
dw 0 ; Limit (low).
|
||||
dw 0 ; Base (low).
|
||||
db 0 ; Base (middle)
|
||||
db 0 ; Access.
|
||||
db 0 ; Granularity.
|
||||
db 0 ; Base (high).
|
||||
.CODE: equ $ - GDT64 ; The code descriptor.
|
||||
dw 0 ; Limit (low).
|
||||
dw 0 ; Base (low).
|
||||
db 0 ; Base (middle)
|
||||
db 10011000b ; Access.
|
||||
db 00100000b ; Granularity.
|
||||
db 0 ; Base (high).
|
||||
.DATA: equ $ - GDT64 ; The data descriptor.
|
||||
dw 0 ; Limit (low).
|
||||
dw 0 ; Base (low).
|
||||
db 0 ; Base (middle)
|
||||
db 10010000b ; Access.
|
||||
db 00000000b ; Granularity.
|
||||
db 0 ; Base (high).
|
||||
.GDT64_PTR: ; The GDT-pointer.
|
||||
dw $ - GDT64 - 1 ; Limit.
|
||||
dq GDT64 ; Base.
|
||||
|
||||
start:
|
||||
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
|
||||
;pure magic
|
||||
xchg bx,bx
|
||||
|
||||
; write values for pml4
|
||||
mov eax,PML4_BASE
|
||||
mov dword [eax], PDPT_BASE + 3
|
||||
|
||||
; write values for pdpt
|
||||
xor ecx, ecx
|
||||
add ecx, 131
|
||||
|
||||
mov eax, PDPT_BASE
|
||||
mov dword [eax], ecx
|
||||
|
||||
add eax,8
|
||||
add ecx,0x40000000 ;1G
|
||||
mov dword [eax], ecx
|
||||
|
||||
add eax,8
|
||||
add ecx,0x40000000 ;1G
|
||||
mov dword [eax], ecx
|
||||
|
||||
add eax,8
|
||||
add ecx,0x40000000 ;1G
|
||||
mov dword [eax], ecx
|
||||
|
||||
; enable PAE
|
||||
mov eax, cr4 ; Set the A-register to control register 4.
|
||||
@ -24,34 +92,37 @@ 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,0;page table addr
|
||||
mov eax, PML4_BASE
|
||||
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
|
||||
;lgdt [GDT64.GDT64_PTR]
|
||||
jmp GDT64.CODE:entry
|
||||
|
||||
[SECTION .text]
|
||||
[BITS 64]
|
||||
entry_64:
|
||||
entry:
|
||||
cli
|
||||
;hard code for now
|
||||
mov ax,24
|
||||
mov ax,GDT64.DATA
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov fs,ax
|
||||
mov gs,ax
|
||||
mov ss,ax
|
||||
;well align 16 bytes like this for now
|
||||
mov rax,rsp
|
||||
and rax,0xFFFFFFFFFFFFFFF0
|
||||
mov rsp,rax
|
||||
;no params for now
|
||||
|
||||
; align 16 bytes like this for now
|
||||
mov rsp,KERNEL_STACK
|
||||
call hk_main
|
||||
hlt
|
||||
|
||||
HLT_CPU:
|
||||
hlt
|
||||
|
||||
BOCHS_MAGIC_BREAKPOINT:
|
||||
xchg bx,bx
|
||||
ret
|
@ -3,12 +3,14 @@
|
||||
#include "print.h"
|
||||
#include "mem.h"
|
||||
#include "multiboot.h"
|
||||
#include "../../../x86/src/c/print.h"
|
||||
|
||||
extern uint64_t text_pos;
|
||||
extern void HLT_CPU(void);
|
||||
extern void BOCHS_MAGIC_BREAKPOINT();
|
||||
void HYPKERNEL64 hk_main(void)
|
||||
{
|
||||
hk_clear_screen();
|
||||
hk_print_str("Welcome to HYP OS. Kernel is now running in x64 mode.\n");
|
||||
x64:
|
||||
goto x64;
|
||||
hk_printf("Welcome to HYP OS. Kernel is now running in x64 mode.\n");
|
||||
HLT_CPU();
|
||||
}
|
||||
|
@ -83,48 +83,44 @@ void HYPKERNEL64 hk_write_segment_descriptor(void * const gdt, uint32_t const ba
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_map_page(void * const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr, uint64_t const availableRam)
|
||||
uint64_t HYPKERNEL64 hk_map_page(void * const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr, uint64_t const availableRam)
|
||||
{
|
||||
//wait a sec, we actually need maximum memory information here for effectively map crap
|
||||
if(base == NULL || p_addr << 52 || v_addr << 52)
|
||||
return;
|
||||
//ASSUME: little endian
|
||||
//All of the following should be 4K-aliened
|
||||
void * const pml4_base = base;
|
||||
void * const pdpt_base = (void*)((uint64_t)((uint64_t*)pml4_base + PML4_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
|
||||
void * const pd_base = (void*)((uint64_t)((uint64_t*)pdpt_base + PDPT_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
|
||||
void * const pt_base = (void*)((uint64_t)((uint64_t*)pd_base + PD_ENTRY_NUM(availableRam)) & 0xFFF + 0x1000);
|
||||
|
||||
uint64_t const pml4_index = (v_addr >> 39) & 0x1FF;
|
||||
uint64_t const pdpt_index = (v_addr >> 30) & 0x1FF;
|
||||
uint64_t const pd_index = (v_addr >> 21) & 0x1FF;
|
||||
uint64_t const pt_index = (v_addr >> 12) & 0x1FF;
|
||||
|
||||
void * const pml4_entry_addr = (void*)((uint64_t*) pml4_base + pml4_index);
|
||||
if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
|
||||
{
|
||||
//PML4 does not exist
|
||||
hk_write_pml4_entry(pml4_entry_addr, (uint64_t)((uint64_t*)pdpt_base + pml4_index * 512), PML4_PRESENT | PML4_WRITE);
|
||||
}
|
||||
uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
|
||||
|
||||
void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
|
||||
if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
|
||||
{
|
||||
hk_write_pdpt_entry(pdpt_entry_addr, (uint64_t)((uint64_t*)pd_base + pml4_index * 512 * 512 + pdpt_index * 512), PDPT_PRESENT | PDPT_WRITE);
|
||||
}
|
||||
uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
|
||||
|
||||
void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
|
||||
if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
|
||||
{
|
||||
hk_write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
|
||||
}
|
||||
uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
|
||||
|
||||
void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
|
||||
hk_write_pt_entry(pt_entry_addr, p_addr, attr);
|
||||
return;
|
||||
//
|
||||
// void * const pml4_entry_addr = (void*)((uint64_t*) base + pml4_index);
|
||||
// if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
|
||||
// {
|
||||
// //PML4 does not exist
|
||||
// hk_write_pml4_entry(pml4_entry_addr, (uint64_t)((uint64_t*)pdpt_base + pml4_index * 512), PML4_PRESENT | PML4_WRITE);
|
||||
// }
|
||||
// uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
|
||||
//
|
||||
// void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
|
||||
// if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
|
||||
// {
|
||||
// hk_write_pdpt_entry(pdpt_entry_addr, (uint64_t)((uint64_t*)pd_base + pml4_index * 512 * 512 + pdpt_index * 512), PDPT_PRESENT | PDPT_WRITE);
|
||||
// }
|
||||
// uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
|
||||
//
|
||||
// void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
|
||||
// if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
|
||||
// {
|
||||
// hk_write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
|
||||
// }
|
||||
// uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
|
||||
//
|
||||
// void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
|
||||
// hk_write_pt_entry(pt_entry_addr, p_addr, attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_mem_cpy(void* src, void* dst, uint64_t size)
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <stdarg.h>
|
||||
#include "kdef.h"
|
||||
#include "type.h"
|
||||
#include "mem.h"
|
||||
@ -7,7 +8,7 @@ uint64_t text_pos;
|
||||
|
||||
uint64_t HYPKERNEL64 hk_str_len(char const * str)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
uint64_t length = 0;
|
||||
if(str == NULL)
|
||||
return 0;
|
||||
while(*str != 0)
|
||||
@ -22,7 +23,7 @@ uint64_t HYPKERNEL64 hk_str_cmp(char const * str1,char const * str2)
|
||||
{
|
||||
if(str1 == NULL || str2 == NULL)
|
||||
return 0;
|
||||
uint32_t length = hk_str_len(str1);
|
||||
uint64_t length = hk_str_len(str1);
|
||||
if(length != hk_str_len(str2))
|
||||
return 0;
|
||||
while(length--)
|
||||
@ -39,7 +40,7 @@ void HYPKERNEL64 hk_print_scroll()
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_print_str(char const *str)
|
||||
void HYPKERNEL64 _print_str(char const *str)
|
||||
{
|
||||
if(str == NULL)
|
||||
return;
|
||||
@ -74,7 +75,26 @@ void HYPKERNEL64 hk_print_str(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_print_int(int64_t number)
|
||||
void HYPKERNEL64 _print_uint(uint64_t number)
|
||||
{
|
||||
char arr[21]; // do not need to initialize
|
||||
arr[20] = 0; //zero-terminated
|
||||
uint32_t index = 19;
|
||||
uint32_t const div = 10;
|
||||
while (1)
|
||||
{
|
||||
uint64_t quo = number / div;
|
||||
uint64_t rmd = number % div;
|
||||
number = quo;
|
||||
arr[index--] = (char) ('0' + rmd);
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
_print_str(&(arr[index + 1]));
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 _print_int(int64_t number)
|
||||
{
|
||||
char arr[21]; // do not need to initialize
|
||||
arr[20] = 0; //zero-terminated
|
||||
@ -91,24 +111,23 @@ void HYPKERNEL64 hk_print_int(int64_t number)
|
||||
int64_t quo = number / div;
|
||||
int64_t rmd = number % div;
|
||||
number = quo;
|
||||
arr[index] = (char) ('0' + rmd);
|
||||
index--;
|
||||
arr[index--] = (char) ('0' + rmd);
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
if (isNegative)
|
||||
{
|
||||
arr[index] = '-';
|
||||
hk_print_str(&(arr[index]));
|
||||
arr[index--] = '-';
|
||||
}
|
||||
else
|
||||
hk_print_str(&(arr[index+1]));
|
||||
_print_str(&(arr[index + 1]));
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_print_hex(uint64_t number)
|
||||
void HYPKERNEL64 _print_hex(uint64_t number, uint64_t capital)
|
||||
{
|
||||
const char lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
char const * const look_up = capital == 1 ? lookup_table_cap : lookup_table;
|
||||
char arr[19];
|
||||
arr[18] = 0; //zero-terminated
|
||||
uint32_t index = 17;
|
||||
@ -118,13 +137,13 @@ void HYPKERNEL64 hk_print_hex(uint64_t number)
|
||||
uint64_t quo = number / div;
|
||||
uint64_t rmd = number % div;
|
||||
number = quo;
|
||||
arr[index--] = lookup_table[rmd];
|
||||
arr[index--] = look_up[rmd];
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
arr[index--] = 'x';
|
||||
arr[index] = '0';
|
||||
hk_print_str(&(arr[index]));
|
||||
_print_str(&(arr[index]));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -134,3 +153,61 @@ void HYPKERNEL64 hk_clear_screen(void)
|
||||
hk_mem_set((void*)0xb8000, 0, 25*80*2);
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL64 hk_printf(char const *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char buf[2] = {0, 0};
|
||||
int32_t d;
|
||||
uint32_t u;
|
||||
char* s;
|
||||
char c;
|
||||
for(;*format != '\0';format++)
|
||||
{
|
||||
if (*format != '%')
|
||||
{
|
||||
buf[0] = *format;
|
||||
_print_str(buf);
|
||||
continue;
|
||||
}
|
||||
format++;
|
||||
switch (*format)
|
||||
{
|
||||
case 'd':
|
||||
d = va_arg(args, int64_t);
|
||||
_print_int(d);
|
||||
break;
|
||||
case 'u':
|
||||
u = va_arg(args, uint64_t);
|
||||
_print_uint(u);
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
_print_str(s);
|
||||
break;
|
||||
case 'c':
|
||||
c = va_arg(args, int64_t);
|
||||
buf[0] = c;
|
||||
_print_str(buf);
|
||||
break;
|
||||
case 'x':
|
||||
u = va_arg(args, uint64_t);
|
||||
_print_hex(u, 0);
|
||||
break;
|
||||
case 'X':
|
||||
u = va_arg(args, uint64_t);
|
||||
_print_hex(u, 1);
|
||||
break;
|
||||
case '%':
|
||||
buf[0] = '%';
|
||||
_print_str(buf);
|
||||
break;
|
||||
default:
|
||||
buf[0] = '%';
|
||||
_print_str(buf);
|
||||
format--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,9 @@
|
||||
#define get_row(pos) (pos / 80)
|
||||
#define get_pos(row,col) ((row) * 80 + (col))
|
||||
|
||||
void HYPKERNEL64 hk_print_hex(uint64_t number);
|
||||
void HYPKERNEL64 hk_print_int(int64_t number);
|
||||
void HYPKERNEL64 hk_print_str(char const *str);
|
||||
void HYPKERNEL64 hk_clear_screen(void);
|
||||
uint64_t HYPKERNEL64 hk_str_len(char const * str);
|
||||
uint64_t HYPKERNEL64 hk_str_cmp(char const * str1,char const * str2);
|
||||
void HYPKERNEL64 hk_printf(char const *format, ...);
|
||||
|
||||
#endif
|
@ -1,13 +1,12 @@
|
||||
global kernel_stack
|
||||
global kernel_addr
|
||||
global hk_entry_comp
|
||||
global BOCHS_MAGIC_BREAKPOINT
|
||||
global HLT_CPU
|
||||
global hk_init_x64
|
||||
extern hk_main
|
||||
extern hk_print_str
|
||||
extern hk_print_hex
|
||||
extern hk_print_int
|
||||
extern hk_printf
|
||||
extern hk_enable_paging
|
||||
extern hk_disable_paging
|
||||
extern g_gdt_ptr_64
|
||||
|
||||
[SECTION .entry]
|
||||
[BITS 32]
|
||||
@ -46,3 +45,24 @@ popfd
|
||||
push ebx
|
||||
call hk_main
|
||||
add esp,4 ; We are actually not coming back here. But out of courtesy...
|
||||
hlt
|
||||
|
||||
BOCHS_MAGIC_BREAKPOINT:
|
||||
xchg bx,bx
|
||||
ret
|
||||
|
||||
HLT_CPU:
|
||||
hlt
|
||||
|
||||
;multiboot_info on stack
|
||||
hk_init_x64:
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
cli
|
||||
xchg bx,bx
|
||||
mov edi,[ss:ebp+8] ;System V ABI
|
||||
jmp 0x100000 ;hard-coded
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
|
@ -9,11 +9,13 @@ uint8_t g_idt[8 * 256];
|
||||
idt_ptr_t g_idt_ptr;
|
||||
|
||||
extern uint32_t text_pos;
|
||||
extern void hk_entry_comp(void);
|
||||
extern void hk_init_x64(multiboot_info_t* multiboot_info);
|
||||
extern void BOCHS_MAGIC_BREAKPOINT(void);
|
||||
extern void HLT_CPU(void);
|
||||
|
||||
void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
|
||||
void HYPKERNEL32 hk_init_x86(multiboot_info_t * multiboot_info)
|
||||
{
|
||||
hk_print_str("*Setting up GDT...");
|
||||
hk_printf("*Setting up GDT...");
|
||||
//dummy descriptor
|
||||
hk_write_segment_descriptor((void*)(&g_gdt[0]), 0, 0, 0);
|
||||
//ring 0 code seg, non-conforming
|
||||
@ -27,25 +29,19 @@ void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
|
||||
g_gdt_ptr.limit = 8 * 8 - 1;
|
||||
g_gdt_ptr.base = (uint32_t) g_gdt;
|
||||
hk_load_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(3, 0));
|
||||
hk_print_str(" - Done.\n\n");
|
||||
hk_printf(" - Done.\n\n");
|
||||
//check memory, definitely < 32 so we assume that
|
||||
hk_print_str("*Checking memory information...\n");
|
||||
hk_printf("*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");
|
||||
hk_printf("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++)
|
||||
for (uint32_t 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");
|
||||
hk_printf("0x%x - 0x%X - 0x%x\n",((uint32_t)(mem_map + i)->addr),(uint32_t)((mem_map + i)->len),(uint32_t)(mem_map + i)->type);
|
||||
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
|
||||
{
|
||||
total_reserved_mem += (uint32_t) ((mem_map + i)->len);
|
||||
@ -55,77 +51,50 @@ void HYPKERNEL32 hk_init_x86(multiboot_info_t const * const multiboot_info)
|
||||
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");
|
||||
hk_printf("Total available memory: %uB, %uKB, %uMB.\n",total_available_mem,total_available_mem/1024,total_available_mem/1024/1024);
|
||||
hk_printf("Total reserved memory: %uB, %uKB, %uMB.\n\n", total_reserved_mem, total_reserved_mem/1024, total_reserved_mem/1024/1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
hk_print_str("Memory information is currently unavailable.\n\n");
|
||||
hk_printf("Memory information is currently unavailable.\n\n");
|
||||
}
|
||||
|
||||
//check modules
|
||||
hk_print_str("*Checking loaded kernel modules...\n");
|
||||
hk_printf("*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_printf("%u module(s) loaded:\n", mods_count);
|
||||
hk_printf("Name - StartAddr - EndAddr\n");
|
||||
for (uint64_t 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_printf("%s - 0x%X - 0x%X\n",(char *) (mods_list + i)->cmdline,(mods_list + i)->mod_start,(mods_list + i)->mod_end);
|
||||
}
|
||||
hk_print_str("\n");
|
||||
hk_printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hk_print_str("Module information is currently unavailable.\n\n");
|
||||
hk_printf("Module information is currently unavailable.\n\n");
|
||||
}
|
||||
a:
|
||||
goto a;
|
||||
HLT_CPU();
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_init_x64(multiboot_info_t const * const multiboot_info)
|
||||
{
|
||||
//CHECK MODULE AND LOAD ELF
|
||||
a:
|
||||
goto a;
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_main(multiboot_info_t const * const multiboot_info)
|
||||
void HYPKERNEL32 hk_main(multiboot_info_t* multiboot_info)
|
||||
{
|
||||
//init text_position
|
||||
text_pos = 0;
|
||||
|
||||
//detect architecture
|
||||
hk_print_str("*Checking architecture...\n");
|
||||
hk_printf("*Checking architecture...\n");
|
||||
if (hk_support_x64() == 0)
|
||||
{
|
||||
hk_print_str("Arch: x86.\n\n");
|
||||
hk_printf("Arch: x86.\n\n");
|
||||
hk_init_x86(multiboot_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
hk_print_str("Arch: x86_64.\n\n");
|
||||
hk_printf("Arch: x86_64.\n\n");
|
||||
hk_init_x64(multiboot_info);
|
||||
}
|
||||
return;
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "kdef.h"
|
||||
#include "mem.h"
|
||||
#include "print.h"
|
||||
|
||||
void HYPKERNEL32 hk_write_segment_descriptor(void * const gdt, uint32_t const base, uint32_t const limit, uint64_t const attr)
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <stdarg.h>
|
||||
#include "kdef.h"
|
||||
#include "type.h"
|
||||
#include "mem.h"
|
||||
@ -5,12 +6,12 @@
|
||||
|
||||
uint32_t text_pos;
|
||||
|
||||
uint32_t HYPKERNEL32 hk_str_len(char const * str)
|
||||
uint32_t HYPKERNEL32 hk_str_len(char const *str)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
if(str == NULL)
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
while(*str != 0)
|
||||
while (*str != 0)
|
||||
{
|
||||
str++;
|
||||
length++;
|
||||
@ -18,16 +19,16 @@ uint32_t HYPKERNEL32 hk_str_len(char const * str)
|
||||
return length;
|
||||
}
|
||||
|
||||
uint32_t 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)
|
||||
if (str1 == NULL || str2 == NULL)
|
||||
return 0;
|
||||
uint32_t length = hk_str_len(str1);
|
||||
if(length != hk_str_len(str2))
|
||||
if (length != hk_str_len(str2))
|
||||
return 0;
|
||||
while(length--)
|
||||
while (length--)
|
||||
{
|
||||
if(*(str1+length) != *(str2+length))
|
||||
if (*(str1 + length) != *(str2 + length))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -35,24 +36,24 @@ uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2)
|
||||
|
||||
void HYPKERNEL32 hk_print_scroll()
|
||||
{
|
||||
hk_mem_move((void*)(0xb8000 + get_pos(1,0) * 2), (void*)(0xb8000 + get_pos(0,0) * 2), (80*24)*2);
|
||||
hk_mem_move((void *) (0xb8000 + get_pos(1, 0) * 2), (void *) (0xb8000 + get_pos(0, 0) * 2), (80 * 24) * 2);
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_print_str(char const *str)
|
||||
void HYPKERNEL32 _print_str(char const *str)
|
||||
{
|
||||
if(str == NULL)
|
||||
if (str == NULL)
|
||||
return;
|
||||
while (*str != 0)
|
||||
{
|
||||
if(*str == '\n')
|
||||
if (*str == '\n')
|
||||
{
|
||||
text_pos = 80 * (get_row(text_pos) + 1);
|
||||
if(text_pos > 80 * 25 - 1)
|
||||
if (text_pos > 80 * 25 - 1)
|
||||
{
|
||||
//can't hold
|
||||
hk_print_scroll();
|
||||
hk_mem_set((void*)(0xb8000 + 80*24*2), 0, 80 * 2); // clear last row
|
||||
hk_mem_set((void *) (0xb8000 + 80 * 24 * 2), 0, 80 * 2); // clear last row
|
||||
text_pos = 80 * 24;
|
||||
}
|
||||
str++;
|
||||
@ -65,8 +66,8 @@ void HYPKERNEL32 hk_print_str(char const *str)
|
||||
hk_print_scroll();
|
||||
text_pos = 80 * 24;
|
||||
}
|
||||
*((char*)(0xb8000) + text_pos*2) = *str;
|
||||
*((char*)(0xb8000) + text_pos*2 + 1) = 7;
|
||||
*((char *) (0xb8000) + text_pos * 2) = *str;
|
||||
*((char *) (0xb8000) + text_pos * 2 + 1) = 7;
|
||||
str++;
|
||||
text_pos++;
|
||||
}
|
||||
@ -74,17 +75,12 @@ void HYPKERNEL32 hk_print_str(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_print_int(int32_t number)
|
||||
void HYPKERNEL32 _print_uint(uint32_t number)
|
||||
{
|
||||
char arr[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint32_t index = 10;
|
||||
uint32_t isNegative = 0;
|
||||
char arr[11]; // do not need to initialize
|
||||
arr[10] = 0; //zero-terminated
|
||||
uint32_t index = 9;
|
||||
uint32_t const div = 10;
|
||||
if (number < 0)
|
||||
{
|
||||
isNegative = 1;
|
||||
number *= -1;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
uint32_t quo = number / div;
|
||||
@ -95,41 +91,128 @@ void HYPKERNEL32 hk_print_int(int32_t number)
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
if (isNegative)
|
||||
{
|
||||
arr[index] = '-';
|
||||
hk_print_str(&(arr[index]));
|
||||
}
|
||||
else
|
||||
hk_print_str(&(arr[index+1]));
|
||||
_print_str(&(arr[index + 1]));
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL32 hk_print_hex(uint32_t number)
|
||||
|
||||
void HYPKERNEL32 _print_int(int32_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_t index = 9;
|
||||
char arr[12]; // do not need to initialize
|
||||
arr[11] = 0; //zero-terminated
|
||||
uint32_t index = 10;
|
||||
uint32_t isNegative = 0;
|
||||
uint32_t const div = 10;
|
||||
if (number < 0)
|
||||
{
|
||||
isNegative = 1;
|
||||
number *= -1;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
int32_t quo = number / div;
|
||||
int32_t rmd = number % div;
|
||||
number = quo;
|
||||
arr[index] = (char) ('0' + rmd);
|
||||
index--;
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
if (isNegative)
|
||||
{
|
||||
arr[index] = '-';
|
||||
_print_str(&(arr[index]));
|
||||
}
|
||||
else
|
||||
_print_str(&(arr[index + 1]));
|
||||
return;
|
||||
}
|
||||
|
||||
void HYPKERNEL32 _print_hex(uint32_t number, uint32_t captial)
|
||||
{
|
||||
char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
char const * const look_up = captial == 1 ? lookup_table_cap : lookup_table;
|
||||
char arr[9];
|
||||
arr[8] = 0; //zero-terminated
|
||||
uint32_t index = 7;
|
||||
uint32_t const div = 16;
|
||||
while (1)
|
||||
{
|
||||
uint32_t quo = number / div;
|
||||
uint32_t rmd = number % div;
|
||||
number = quo;
|
||||
arr[index--] = lookup_table[rmd];
|
||||
arr[index--] = look_up[rmd];
|
||||
if (number == 0)
|
||||
break;
|
||||
}
|
||||
arr[index--] = 'x';
|
||||
arr[index] = '0';
|
||||
hk_print_str(&(arr[index]));
|
||||
_print_str(&(arr[index + 1]));
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void HYPKERNEL32 hk_clear_screen(void)
|
||||
{
|
||||
text_pos = 0; // reset text_pos
|
||||
hk_mem_set((void*)0xb8000, 0, 25*80*2);
|
||||
hk_mem_set((void *) 0xb8000, 0, 25 * 80 * 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void HYPKERNEL32 hk_printf(char const *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char buf[2] = {0, 0};
|
||||
int32_t d;
|
||||
uint32_t u;
|
||||
char* s;
|
||||
char c;
|
||||
for(;*format != '\0';format++)
|
||||
{
|
||||
if (*format != '%')
|
||||
{
|
||||
buf[0] = *format;
|
||||
_print_str(buf);
|
||||
continue;
|
||||
}
|
||||
format++;
|
||||
switch (*format)
|
||||
{
|
||||
case 'd':
|
||||
d = va_arg(args, int32_t);
|
||||
_print_int(d);
|
||||
break;
|
||||
case 'u':
|
||||
u = va_arg(args, uint32_t);
|
||||
_print_uint(u);
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
_print_str(s);
|
||||
break;
|
||||
case 'c':
|
||||
c = va_arg(args, int32_t);
|
||||
buf[0] = c;
|
||||
_print_str(buf);
|
||||
break;
|
||||
case 'x':
|
||||
u = va_arg(args, uint32_t);
|
||||
_print_hex(u, 0);
|
||||
break;
|
||||
case 'X':
|
||||
u = va_arg(args, uint32_t);
|
||||
_print_hex(u, 1);
|
||||
break;
|
||||
case '%':
|
||||
buf[0] = '%';
|
||||
_print_str(buf);
|
||||
break;
|
||||
default:
|
||||
buf[0] = '%';
|
||||
_print_str(buf);
|
||||
format--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,9 +7,7 @@
|
||||
#define get_row(pos) (pos / 80)
|
||||
#define get_pos(row,col) ((row) * 80 + (col))
|
||||
|
||||
void HYPKERNEL32 hk_print_hex(uint32_t number);
|
||||
void HYPKERNEL32 hk_print_int(int32_t number);
|
||||
void HYPKERNEL32 hk_print_str(char const *str);
|
||||
void HYPKERNEL32 hk_printf(char const *format, ...);
|
||||
uint32_t HYPKERNEL32 hk_str_len(char const * str);
|
||||
uint32_t HYPKERNEL32 hk_str_cmp(char const * str1,char const * str2);
|
||||
void HYPKERNEL32 hk_clear_screen(void);
|
||||
|
Loading…
Reference in New Issue
Block a user