Code: Select all
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif
typedef struct{
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
} multiboot_info;
/* Hardware text mode color constants. */
enum vga_color
{
COLOR_BLACK = 0,
COLOR_BLUE = 1,
COLOR_GREEN = 2,
COLOR_CYAN = 3,
COLOR_RED = 4,
COLOR_MAGENTA = 5,
COLOR_BROWN = 6,
COLOR_LIGHT_GREY = 7,
COLOR_DARK_GREY = 8,
COLOR_LIGHT_BLUE = 9,
COLOR_LIGHT_GREEN = 10,
COLOR_LIGHT_CYAN = 11,
COLOR_LIGHT_RED = 12,
COLOR_LIGHT_MAGENTA = 13,
COLOR_LIGHT_BROWN = 14,
COLOR_WHITE = 15,
};
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 24;
uint16_t* terminal_buffer;
uint16_t make_vgaentry(char c, enum vga_color fg, enum vga_color bg)
{
uint16_t c16 = c;
uint16_t color16 = fg | bg << 4;
return c16 | color16 << 8;
}
size_t strlen(const char* str)
{
size_t ret = 0;
while ( str[ret] != 0 )
ret++;
return ret;
}
void terminal_initialize()
{
terminal_buffer = (uint16_t*) 0xB8000;
for ( size_t y = 0; y < VGA_HEIGHT; y++ )
{
for ( size_t x = 0; x < VGA_WIDTH; x++ )
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = make_vgaentry(' ', COLOR_LIGHT_GREY, COLOR_BLACK);
}
}
}
void terminal_putchar(char c, enum vga_color fg, enum vga_color bg, size_t row, size_t column)
{
const size_t index = row * VGA_WIDTH + column;
terminal_buffer[index] = make_vgaentry(c, fg, bg);
}
void terminal_writestring(const char* data, enum vga_color fg, enum vga_color bg, size_t row, size_t column)
{
size_t current_row = row;
size_t current_column = column;
size_t datalen = strlen(data);
size_t i = 0;
while (i < datalen){
terminal_putchar(data[i], fg, bg, current_row, current_column);
i++;
if ( ++current_column == VGA_WIDTH ){
current_column = 0;
if ( ++current_row == VGA_HEIGHT )
{
current_row = 0;
}
}
}
}
void print_pointer(void *p, size_t row)
{
size_t len = sizeof(void *) * 2;
char str[20]="0x";
size_t w = (size_t)p;
size_t index = 2;
size_t i = len;
/*every time change the 16^(i-1) bit into a character*/
while(i != 0){
size_t tmp = (i-1)*4;
size_t tmp2 = (w & (15<<tmp) ) >> tmp;
if(tmp2 < 0xA) str[index]=(char)(tmp2 + '0');
else str[index]=(char)(tmp2 + 55);
++index;
--i;
}
str[index]='\0';
terminal_writestring(str, COLOR_BLUE, COLOR_RED, row ,0);
}
void kernel_main(multiboot_info *p)
{
print_pointer(p, 1);
terminal_initialize();
terminal_writestring("Hello, kernel World!", COLOR_BLUE, COLOR_RED, 0, 0);
ROLL:
goto ROLL;
}