diff --git a/Makefile b/Makefile index 0dac28f..8d3982d 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/vesa.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o SRC_DIR = src BUILD_DIR = build @@ -87,3 +87,6 @@ $(BUILD_DIR)/string.o: $(BUILD_DIR)/PhysicalMemoryManager.o: $(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/vesa.o: + $(CPP) -c $(SRC_DIR)/kernel/vesa.cpp -o $(BUILD_DIR)/vesa.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/boot.S b/src/kernel/boot.S index e516c9b..c05f65d 100644 --- a/src/kernel/boot.S +++ b/src/kernel/boot.S @@ -19,8 +19,8 @@ .long 0 # . .long 0 # unused .long 0 # set graphics mode -.long 1280 # screen witdh -.long 720 # screen height +.long 800 # screen witdh +.long 600 # screen height .long 32 # bpp .section .bss diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h index 0560623..aa22d63 100644 --- a/src/kernel/bootcheck.h +++ b/src/kernel/bootcheck.h @@ -3,153 +3,84 @@ #define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) #include "tty/kterm.h" - - +#include "vesa.h" void CheckMBT ( multiboot_info_t* mbt ){ - /* Set MBI to the addresss of the multiboot information structure*/ - multiboot_info_t * mbi = (multiboot_info_t *) mbt; + /* Set MBI to the addresss of the multiboot information structure*/ + multiboot_info_t * mbi = (multiboot_info_t *) mbt; - /* Print out the flags */ - printf("flags = 0x%8x\n", (unsigned) mbi->flags); + /* Print out the flags */ + printf("flags = 0x%8x\n", (unsigned) mbi->flags); - /* Are mem_* valid? */ - if ( CHECK_FLAG(mbi->flags,0)){ - printf("mem_lower = %uKB, mem_upper = %uKB\n"); - } + /* Are mem_* valid? */ + if ( CHECK_FLAG(mbi->flags,0)){ + printf("mem_lower = %uKB, mem_upper = %uKB\n"); + } - /* is boot device valid ? */ - if (CHECK_FLAG (mbi->flags, 1)){ - printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); - } + /* is boot device valid ? */ + if (CHECK_FLAG (mbi->flags, 1)){ + printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); + } - /* is the command line passed? */ - if (CHECK_FLAG ( mbi->flags,2)){ - printf("cmdline = %s\n", (char *) mbi->cmdline); - } + /* is the command line passed? */ + if (CHECK_FLAG ( mbi->flags,2)){ + printf("cmdline = %s\n", (char *) mbi->cmdline); + } - /* Are mods_* valid? */ - if(CHECK_FLAG ( mbi->flags, 3)){ - multiboot_module_t *mod; - uint32_t i; + /* Are mods_* valid? */ + if(CHECK_FLAG ( mbi->flags, 3)){ + multiboot_module_t *mod; + uint32_t i; - printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); + printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); - for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ - printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); - } - } + for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ + printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); + } + } - /* Bits 4 and 5 are mutually exclusive! */ - if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ - printf("Both bits 4 and 5 are set.\n"); - return; - } + /* Bits 4 and 5 are mutually exclusive! */ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ + printf("Both bits 4 and 5 are set.\n"); + return; + } - /* Is the symbol table of a.out valid? */ - if (CHECK_FLAG(mbi->flags, 4)){ - multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); + /* Is the symbol table of a.out valid? */ + if (CHECK_FLAG(mbi->flags, 4)){ + multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); - printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", - (unsigned) multiboot_aout_sym->tabsize, - (unsigned) multiboot_aout_sym->strsize, - (unsigned) multiboot_aout_sym->addr); + printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", + (unsigned) multiboot_aout_sym->tabsize, + (unsigned) multiboot_aout_sym->strsize, + (unsigned) multiboot_aout_sym->addr); - } + } - /* Is the section header table of ELF valid? */ - if (CHECK_FLAG(mbi->flags, 5)){ - multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); + /* Is the section header table of ELF valid? */ + if (CHECK_FLAG(mbi->flags, 5)){ + multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); - printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", - (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, - (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); - - } + printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, + (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); + + } - /* Draw diagonal blue line */ - if (CHECK_FLAG (mbt->flags, 11)){ - printf("Can draw!"); - - multiboot_uint32_t color; - unsigned i; - void *fb = (void *) (unsigned long) mbt->framebuffer_addr; + /* Draw diagonal blue line */ + if (CHECK_FLAG (mbt->flags, 11)){ + printf("Can draw!"); - switch (mbt->framebuffer_type) - { - case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: - { - unsigned best_distance, distance; - struct multiboot_color *palette; - - palette = (struct multiboot_color *) mbt->framebuffer_palette_addr; - color = 0; - best_distance = 4*256*256; - - for (i = 0; i < mbi->framebuffer_palette_num_colors; i++) - { - distance = (0xff - palette[i].blue) * (0xff - palette[i].blue) - + palette[i].red * palette[i].red - + palette[i].green * palette[i].green; - if (distance < best_distance) - { - color = i; - best_distance = distance; - } - } - } - break; - case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: - color = ((1 << mbt->framebuffer_blue_mask_size) - 1) - << mbt->framebuffer_blue_field_position; - break; + // Init vesa driver + initVBEDevice(mbt); - case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: - color = '\\' | 0x0100; - break; + // Turn pixel on in the middle of the screen; + putPixel( 50, 50 , 0x00FFFFFF); - default: - color = 0xffffffff; - break; - } - for (i = 0; i < mbt->framebuffer_width - && i < mbt->framebuffer_height; i++) - { - switch (mbt->framebuffer_bpp) - { - case 8: - { - multiboot_uint8_t *pixel = fb + mbt->framebuffer_pitch * i + i; - *pixel = color; - } - break; - case 15: - case 16: - { - multiboot_uint16_t *pixel - = fb + mbt->framebuffer_pitch * i + 2 * i; - *pixel = color; - } - break; - case 24: - { - multiboot_uint32_t *pixel - = fb + mbt->framebuffer_pitch * i + 3 * i; - *pixel = (color & 0xffffff) | (*pixel & 0xff000000); - } - break; + putPixel(VbeModeInfo->width / 2 , VbeModeInfo->height / 2 , 0x00FF0000); + drawLine(50,10, 150, 8, 0x00FF00FF); - case 32: - { - multiboot_uint32_t *pixel - = fb + mbt->framebuffer_pitch * i + 4 * i; - *pixel = color; - } - break; - } - } - } + } } \ No newline at end of file diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index e9a2c02..88733a0 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -35,11 +35,6 @@ extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigne initGDT(); - - print_serial("Video mode enabled!\n"); - printf_serial("VBE mode: 0x%x\n", mbt->vbe_mode); - printf_serial("width: %d height: %d bpp: %d\n" , mbt->framebuffer_width, mbt->framebuffer_height, mbt->framebuffer_bpp); - kernel_main(); diff --git a/src/kernel/serial.h b/src/kernel/serial.h index 6864364..97fcaa2 100644 --- a/src/kernel/serial.h +++ b/src/kernel/serial.h @@ -1,9 +1,10 @@ #pragma once - #include "tty/kterm.h" #include "io.h" + #define PORT 0x3f8 -static int init_serial() { + +inline static int init_serial() { outb(PORT + 1, 0x00); // Disable all interrupts outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud @@ -25,34 +26,34 @@ static int init_serial() { return 0; } -int is_transmit_empty() { +inline int is_transmit_empty() { return inb(PORT + 5) & 0x20; } -void write_serial(char a) { +inline void write_serial(char a) { while (is_transmit_empty() == 0); outb(PORT,a); } -int serial_received() { +inline int serial_received() { return inb(PORT + 5) & 1; } -char read_serial() { +inline char read_serial() { while (serial_received() == 0); return inb(PORT); } -void print_serial(const char* string ){ +inline void print_serial(const char* string ){ for(size_t i = 0; i < strlen(string); i ++){ write_serial(string[i]); } } -void printf_serial ( const char *format, ...) { +inline void printf_serial ( const char *format, ...) { char **arg = (char **)&format; int c; @@ -113,7 +114,7 @@ void printf_serial ( const char *format, ...) { } -void test_serial(){ +inline void test_serial(){ /** Serial test **/ kterm_writestring("Writing to COM1 serial port:"); init_serial(); diff --git a/src/kernel/vesa.cpp b/src/kernel/vesa.cpp new file mode 100644 index 0000000..9b87df4 --- /dev/null +++ b/src/kernel/vesa.cpp @@ -0,0 +1,128 @@ +#include "vesa.h" +VbeInfoBlock* vbeInfo; +vbe_mode_info_structure* VbeModeInfo; + +void initVBEDevice(multiboot_info_t* mbt){ + print_serial("initVBEDevice"); + + vbeInfo = (VbeInfoBlock*) mbt->vbe_control_info; + printf_serial("Signature: %s, V0x%x\n", vbeInfo->VbeSignature, vbeInfo->VbeVersion); + + VbeModeInfo = (vbe_mode_info_structure*) mbt->vbe_mode_info; + + printf_serial("VESA video mode info: Width: %d Height: %d BPP: %d\n", VbeModeInfo->width, VbeModeInfo->height , VbeModeInfo->bpp); + printf_serial("VideoMemory Location: 0x%x \n", VbeModeInfo->framebuffer ); +} + +void putPixel( int x, int y , uint32_t colour){ + printf_serial("putPixel x: %d, y: %d\n", x, y); + ///fb + mbt->framebuffer_pitch * y + 4 * x ,NOTE: this calculation is very important + *(uint32_t*) ( VbeModeInfo->framebuffer + VbeModeInfo->pitch * y + 4 * x ) = colour; +} +void drawLine(int x1, int y1, int x2, int y2, uint32_t colour ){ + print_serial("drawline\n"); + // Bresenham's line algorithm?? + int deltaX = x2 - x1; + int deltaY = y2 - y1; + int D = 2 * deltaY - deltaX; + int y = y1; + + for ( int x = x1; x < x2; x++){ + putPixel(x,y, colour); + if( D > 0){ + y +=1; + D = D - 2 * deltaX; + } + D = D + 2 * deltaY; + } + + + +} +void drawRect ( int x, int y, int width, int height, uint32_t colour ){ + print_serial("drawRect\n"); +} + + +void blueDiagnalLineTest(multiboot_info_t* mbt){ + multiboot_uint32_t color; + unsigned i; + void *fb = (void *) (unsigned long) mbt->framebuffer_addr; + + switch (mbt->framebuffer_type) + { + case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: + { + unsigned best_distance, distance; + struct multiboot_color *palette; + + palette = (struct multiboot_color *) mbt->framebuffer_palette_addr; + + color = 0; + best_distance = 4*256*256; + + for (i = 0; i < mbt->framebuffer_palette_num_colors; i++) + { + distance = (0xff - palette[i].blue) * (0xff - palette[i].blue) + + palette[i].red * palette[i].red + + palette[i].green * palette[i].green; + if (distance < best_distance) + { + color = i; + best_distance = distance; + } + } + } + break; + + case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: + color = ((1 << mbt->framebuffer_blue_mask_size) - 1) + << mbt->framebuffer_blue_field_position; + break; + + case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: + color = '\\' | 0x0100; + break; + + default: + color = 0xffffffff; + break; + } + for (i = 0; i < mbt->framebuffer_width + && i < mbt->framebuffer_height; i++) + { + switch (mbt->framebuffer_bpp) + { + case 8: + { + multiboot_uint8_t *pixel = (multiboot_uint8_t*)fb + mbt->framebuffer_pitch * i + i; + *pixel = color; + } + break; + case 15: + case 16: + { + multiboot_uint16_t *pixel + = (multiboot_uint16_t*)fb + mbt->framebuffer_pitch * i + 2 * i; + *pixel = color; + } + break; + case 24: + { + multiboot_uint32_t *pixel + = (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 3 * i; + *pixel = (color & 0xffffff) | (*pixel & 0xff000000); + } + break; + + case 32: + { + multiboot_uint32_t *pixel + = (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 4 * i; + *pixel = color; + } + break; + } + } +} + diff --git a/src/kernel/vesa.h b/src/kernel/vesa.h new file mode 100644 index 0000000..30bd2a8 --- /dev/null +++ b/src/kernel/vesa.h @@ -0,0 +1,66 @@ +#pragma once +#include +#include "bootloader/multiboot.h" +#include "serial.h" + +struct vbe_mode_info_structure{ + uint16_t attributes; + uint8_t window_a; + uint8_t window_b; + uint16_t granularity; + uint16_t window_size; + uint16_t segment_a; + uint16_t segment_b; + uint32_t win_func_ptr; + uint16_t pitch; + uint16_t width; + uint16_t height; + uint8_t w_char; + uint8_t y_char; + uint8_t planes; + uint8_t bpp; + uint8_t banks; + uint8_t memory_model; + uint8_t bank_size; + uint8_t image_pages; + uint8_t reserved0; + + uint8_t red_mask; + uint8_t red_position; + uint8_t green_mask; + uint8_t green_position; + uint8_t blue_mask; + uint8_t blue_position; + uint8_t reserved_mask; + uint8_t reserved_position; + uint8_t direct_color_attributes; + + uint32_t framebuffer; + uint32_t off_screen_mem_off; + uint16_t off_screen_mem_size; + uint8_t reserved1[206]; + }__attribute__((packed)); + +struct VbeInfoBlock { + char VbeSignature[4]; + uint16_t VbeVersion; + uint16_t OemStringPtr; + uint8_t Capabilities; + uint16_t VideoModePtr; + uint16_t TotalMemory; + }__attribute__((packed)); + +extern VbeInfoBlock* vbeInfo; +extern vbe_mode_info_structure* VbeModeInfo; + + + +void initVBEDevice(multiboot_info_t* mbt); + +void blueDiagnalLineTest(multiboot_info_t* mbt); + + +// Primitive drawing functions +void putPixel( int x, int y , uint32_t colour); +void drawLine(int x1, int y1, int x2, int y2, uint32_t colour ); +void drawRect ( int x, int y, int width, int height, uint32_t colour );