Today I created debug system. I kinda made it very flexible, easy and efficient to use(realistically,, it might not be.) This also was quite different than my ugly codes of past, because I actually considered the portability of the code. I separated between the parts that is implemented specifically to some architecture and the parts that is considered essential throughout all the architecture.
...
namespace debug {
namespace out {
void init(void);
void clear_screen(unsigned char color);
void vprintf(debug_m mode , const char *fmt , va_list ap);
void printf(debug_m mode , const char *fmt , ...);
void printf(const char *fmt , ...);
void print_str(const char *str);
void raw_printf(const char *fmt , ...);
void set_position(int x , int y);
void move_position(int relative_x , int relative_y);
void get_scr_info(int &x , int &y , unsigned char &background_color , unsigned char &foreground_color);
unsigned char get_char(int y , int x);
void set_background_color(unsigned char background_color);
void set_foreground_color(unsigned char foreground_color);
unsigned char debugcolor(debug_m mode);
const char *debugstr(debug_m mode);
}
}
As you can see, code above is left unimplemented in kernel; it is implemented in hardware-specific source codes(say, function that prints the character to hardware)

Directory entry of debug system
debugout.cpp :
void debug::out::print_str(const char *str) {
int i;
int j;
int off;
for(i = 0; str[i] != 0; i++) {
off = (scrinfo.y*scrinfo.width*2)+scrinfo.x*2;
switch(str[i]) {
case '\n':
scrinfo.x = 0;
scrinfo.y++;
if(scrinfo.y > 24) {
memcpy(scrinfo.vmem , scrinfo.vmem+(scrinfo.width*2) , scrinfo.width*(scrinfo.height-1)*2);
for(j = scrinfo.width*(scrinfo.height-1)*2; j < scrinfo.width*scrinfo.height*2; j += 2) {
scrinfo.vmem[j] = 0x00;
scrinfo.vmem[j+1] = (scrinfo.color_background << 4)+scrinfo.color_foreground;
}
scrinfo.y = 24;
}
...
Functions in "debug::out" are implemented especially in consideration of hardware; that is, those codes only work with specific hardware(In this case, It would be BIOS VGA)
Aside from the tediously-elaborated debug system, I made the draft of kernel's physical memory allocator. As I elaborated in previous journal, it basically separates kernel's physical memory into separate pieces of segment and manages them in one management structure.
Also, I cleaned up some messes of kernel's memory structure. Basically, I came up with "Kernel Structure" that bootloader is obligated to make. The bootloader sends basic information about kernel(such as location of stack, or location of memory map) via function argument when calling the final state kernel function.

Kernel Info Structure
struct KernelInfoStructure {
unsigned int signature; // 0
unsigned int kernel_address; // 4
unsigned int kernel_size; // 8
unsigned int memmap_count; // 12
unsigned int memmap_ptr; // 16
unsigned int kernel_stack_location; // 20
unsigned int kernel_stack_size; // 24
unsigned int pml4t_entry_location; // 28
};
This structure is sent to argument of kernel_main function by bootloader so that kernel can understand where he is (lol.)
extern "C" void kernel_main(unsigned long kernel_info_struct_addr) {
...
struct KernelInfoStructure *kinfostruct = (struct KernelInfoStructure *)kernel_info_struct_addr;
if(kinfostruct->signature != KERNELINFO_STRUCTURE_SIGNATURE) {
debug::out::printf("Kernel structure not found!\n");
debug::panic("kernel structure not found");
}
...
Now I'm planning to implement the higher-half kernel (for future.) I hope all of these works repay me in future....