From 2eca761edc5f53abe7102b653fea7321e9d037a4 Mon Sep 17 00:00:00 2001 From: Nigel Date: Mon, 22 Nov 2021 23:01:51 +0100 Subject: [PATCH] VBE graphics mode successfully initialized by grub, can use iso with qemu now --- Makefile | 6 +- README.md | 3 + screenshots/BarinkOS_VBE_GRAPHICS.png | 3 + src/kernel/boot.S | 21 +++++-- src/kernel/bootcheck.h | 85 ++++++++++++++++++++++++++- src/kernel/gdt/gdtc.cpp | 5 +- src/kernel/kernel.cpp | 19 +++++- src/kernel/serial.h | 62 +++++++++++++++++++ src/kernel/tty/kterm.cpp | 4 +- src/kernel/tty/kterm.h | 3 +- 10 files changed, 192 insertions(+), 19 deletions(-) create mode 100644 screenshots/BarinkOS_VBE_GRAPHICS.png diff --git a/Makefile b/Makefile index afa65c7..0dac28f 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,9 @@ iso: clean_iso clean build grub-mkrescue -o build/barinkOS.iso root test: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -monitor stdio -display gtk -m 2G -cpu core2duo + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo # -monitor stdio +test_iso: + $(EMULATOR) -cdrom build/barinkOS.iso -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo build_kernel: $(OBJ_LINK_LIST) $(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \ @@ -50,7 +52,7 @@ clean: rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS) $(BUILD_DIR)/kernel.o: - $(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti + $(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti -fpermissive $(BUILD_DIR)/kterm.o: $(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/README.md b/README.md index ee97592..2001a6c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ ________________________ ### Screenshot(s) +![Graphics mode](screenshots/BarinkOS_VBE_GRAPHICS.png) \ +It may not look like much but I am proud of it! We are in graphics mode. + ![Scrolling the terminal](screenshots/Screenshot1.png) \ The first scrolling boot screen. 😲 diff --git a/screenshots/BarinkOS_VBE_GRAPHICS.png b/screenshots/BarinkOS_VBE_GRAPHICS.png new file mode 100644 index 0000000..60d0535 --- /dev/null +++ b/screenshots/BarinkOS_VBE_GRAPHICS.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:014c45d4d5138dfb026ac484cdebbd0afad5eaa5f8e44d690487d76bc1a3b15f +size 14139 diff --git a/src/kernel/boot.S b/src/kernel/boot.S index 0c79b10..e516c9b 100644 --- a/src/kernel/boot.S +++ b/src/kernel/boot.S @@ -1,18 +1,27 @@ /* * Multiboot */ -.set ALIGN, 1<<0 /* align loaded modules on page boundaries */ -.set MEMINFO, 1<<1 /* provide memory map */ -.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */ -.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ -.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ +.set ALIGN, 1<<0 /* align loaded modules on page boundaries */ +.set MEMINFO, 1<<1 /* provide memory map */ +.set VIDEO, 1<<2 /* provide video mode */ +.set FLAGS, ALIGN | MEMINFO | VIDEO /* this is the Multiboot 'flag' field */ +.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ +.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ .section .multiboot .align 4 .long MAGIC .long FLAGS .long CHECKSUM - +.long 0 # unused +.long 0 # . +.long 0 # . +.long 0 # . +.long 0 # unused +.long 0 # set graphics mode +.long 1280 # screen witdh +.long 720 # screen height +.long 32 # bpp .section .bss .align 16 diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h index 028eeba..0560623 100644 --- a/src/kernel/bootcheck.h +++ b/src/kernel/bootcheck.h @@ -11,7 +11,7 @@ void CheckMBT ( multiboot_info_t* mbt ){ multiboot_info_t * mbi = (multiboot_info_t *) mbt; /* Print out the flags */ - printf("flags = 0x%x\n", (unsigned) mbi->flags); + printf("flags = 0x%8x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if ( CHECK_FLAG(mbi->flags,0)){ @@ -68,9 +68,88 @@ void CheckMBT ( multiboot_info_t* mbt ){ } /* Draw diagonal blue line */ - if (CHECK_FLAG (mbt->flags, 12)){ + if (CHECK_FLAG (mbt->flags, 11)){ printf("Can draw!"); - } + + 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 < 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; + + 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 = 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; + + 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/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index f2624bf..8bb5804 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -48,12 +48,13 @@ void initGDT(){ gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1); gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable; + printf("Hello GDT!\n"); LoadGlobalDescriptorTable(); - while (true) - asm volatile("hlt"); +// while (true) +// asm volatile("hlt"); diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index d30350d..e9a2c02 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,12 +1,18 @@ #include "kernel.h" #define GB4 524288 #define GB2 262144 +extern "C" void kernel_main (void); +extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigned char addr , unsigned char pixelWidth, unsigned pitch ); + + extern "C" void early_main(unsigned long magic, unsigned long addr){ /** initialize terminal interface */ - kterm_init(); + // kterm_init(); + printf("Magic flag 0x%8x\n", magic); + printf("Magic must be 0x%8x\n", MULTIBOOT_BOOTLOADER_MAGIC); if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ - printf("Invalid magic number: 0x%x\n", magic); + printf("Invalid magic number: 0x%8x\n", magic); return; } @@ -28,6 +34,14 @@ 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(); + } @@ -36,6 +50,7 @@ printf("call to init serial\n"); init_serial(); + while (true){ //Read time indefinetely read_rtc(); diff --git a/src/kernel/serial.h b/src/kernel/serial.h index ecc82db..6864364 100644 --- a/src/kernel/serial.h +++ b/src/kernel/serial.h @@ -51,6 +51,68 @@ void print_serial(const char* string ){ } } + +void printf_serial ( const char *format, ...) { + + char **arg = (char **)&format; + int c; + char buf[20]; + + arg++; + + while ((c = *format++) != 0){ + if( c != '%') + write_serial(c); + else{ + char *p, *p2; + int pad0 = 0, pad = 0; + + c = *format++; + if(c =='0'){ + pad0 = 1; + c = *format++; + } + + if ( c >= '0' && c <= '9'){ + pad = c - '0'; + c = *format++; + } + + switch (c) + { + case 'd': + + case 'u': + case 'x': + itoa(buf, c, *((int *) arg++)); + + p = buf; + goto string; + break; + + case 's': + p = *arg++; + if(!p) + p = "(null)"; + + string: + for (p2 = p; *p2; p2++); + for (; p2 < p + pad; p2++) + write_serial(pad0 ? '0': ' '); + while (*p) + write_serial(*p++); + break; + + + default: + write_serial(*((int *)arg++)); + break; + } + } + } +} + + void test_serial(){ /** Serial test **/ kterm_writestring("Writing to COM1 serial port:"); diff --git a/src/kernel/tty/kterm.cpp b/src/kernel/tty/kterm.cpp index 94bc3f1..d3a309e 100644 --- a/src/kernel/tty/kterm.cpp +++ b/src/kernel/tty/kterm.cpp @@ -137,7 +137,7 @@ void kterm_writestring(const char* data ){ } -static void itoa (char *buf, int base, int d) { +void itoa (char *buf, int base, int d) { char *p = buf; char *p1, *p2; unsigned long ud = d; @@ -174,7 +174,7 @@ static void itoa (char *buf, int base, int d) { } void printf ( const char *format, ...) { - + return; char **arg = (char **)&format; int c; char buf[20]; diff --git a/src/kernel/tty/kterm.h b/src/kernel/tty/kterm.h index 4f048d0..a73d2db 100644 --- a/src/kernel/tty/kterm.h +++ b/src/kernel/tty/kterm.h @@ -33,10 +33,9 @@ uint16_t get_cursor_position(); int get_cursor_x (uint16_t cursor_pos); int get_cursor_y (uint16_t cursor_pos); - +extern "C" void itoa (char *buf, int base, int d); void printf ( const char *format, ...); -//static void itoa (char *buf, int base, int d); #define KernelTag "[Kernel]: " #define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\