diff --git a/makefile b/makefile index c87007f..7d37811 100644 --- a/makefile +++ b/makefile @@ -50,12 +50,12 @@ toolchain: tar xf $(TOOLCHAIN_FILE) iso: kernel.elf initrd - mkdir -p iso/boot/grub cp kernel.elf iso/boot/kernel.elf cp grub.cfg iso/boot/grub/grub.cfg grub-mkrescue iso -o blankos.iso initrd: + mkdir -p iso/boot/grub tar -cf $(OBJ_DIR)/initrd.tar -C $(SRC_DIR)/initrd . cp $(OBJ_DIR)/initrd.tar iso/boot diff --git a/src/initrd/flower.bmp b/src/initrd/flower.bmp new file mode 100644 index 0000000..4f434c1 Binary files /dev/null and b/src/initrd/flower.bmp differ diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index d0d0177..a478f71 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -15,6 +15,7 @@ #include "multiboot2.h" #include "kheap.h" #include "initrd.h" +#include "../programs/programs.h" void kmain(multiboot2_info *mb_info) { @@ -41,24 +42,25 @@ void kmain(multiboot2_info *mb_info) tags += ((tag_size + 7) & ~7); } - serial_printf(3, "Framebuffer Address: 0x%x", fb_info->framebuffer_addr); - serial_printf(3, "Framebuffer Width: %u", fb_info->framebuffer_width); - serial_printf(3, "Framebuffer Height: %u", fb_info->framebuffer_height); - serial_printf(3, "Framebuffer Pitch: %u", fb_info->framebuffer_pitch); - serial_printf(3, "Framebuffer BPP: %u", fb_info->framebuffer_bpp); - if (fb_info) { // fb setup framebuffer = (uint32_t *)(uintptr_t) fb_info->framebuffer_addr; uint32_t width = fb_info->framebuffer_width; uint32_t height = fb_info->framebuffer_height; - uint32_t bpp = fb_info->framebuffer_bpp; + bpp = fb_info->framebuffer_bpp; + pitch = fb_info->framebuffer_pitch; //8x16 font, not padded VGA_WIDTH = width/8; VGA_HEIGHT = height/16; serial_printf(3, "VGA_WIDTH=%d, VGA_HEIGHT=%d", VGA_WIDTH, VGA_HEIGHT); scanline = width * (bpp/8); + + serial_printf(3, "Framebuffer Address: 0x%x", fb_info->framebuffer_addr); + serial_printf(3, "Framebuffer Width: %u", fb_info->framebuffer_width); + serial_printf(3, "Framebuffer Height: %u", fb_info->framebuffer_height); + serial_printf(3, "Framebuffer Pitch: %u", fb_info->framebuffer_pitch); + serial_printf(3, "Framebuffer BPP: %u", fb_info->framebuffer_bpp); } printf("[kernel] multiboot2 info at 0x%x, size=%u\n", mb_info, mb_info->total_size); @@ -116,6 +118,11 @@ void kmain(multiboot2_info *mb_info) printf("[debug] malloc test ptr1=0x%x, ptr2=0x%x\n", ptr1, ptr2); free(ptr1); free(ptr2); + + //display_bmp(framebuffer, pitch, bpp, (uint8_t*)initrd_addr); + + //putpixel(framebuffer, pitch, bpp, i, j, yellow); + timer_install(); keyboard_install(); printf("[kernel] spawning shell...\n"); diff --git a/src/kernel/kmain.h b/src/kernel/kmain.h index 0cf54ba..9475f4d 100644 --- a/src/kernel/kmain.h +++ b/src/kernel/kmain.h @@ -6,6 +6,8 @@ #ifndef KMAIN_H #define KMAIN_H +#include + typedef struct { uint32_t type; uint32_t size; @@ -34,4 +36,7 @@ uint32_t initrd_addr; uint32_t VGA_WIDTH; uint32_t VGA_HEIGHT; +uint32_t bpp; +uint32_t pitch; + #endif diff --git a/src/programs/bmp.c b/src/programs/bmp.c new file mode 100644 index 0000000..f3f89d2 --- /dev/null +++ b/src/programs/bmp.c @@ -0,0 +1,81 @@ +// Bitmap image renderer +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#include "../kernel/kmain.h" +#include +#include "../kernel/initrd.h" +#include "../drivers/framebuffer.h" +#include "../libc/stdio.h" + +typedef struct +{ + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +} BMPHeader; + +typedef struct +{ + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +} BMPInfoHeader; + +void display_bmp(uint32_t* fb, int pitch, int bpp, uint8_t* initrd) +{ + char buffer[1024*1024]; + int file_status = tar_file_to_buffer(initrd, "./flower.bmp", buffer); + + if (file_status != 0) + { + puts("Error loading BMP\n"); + return; + } + + BMPHeader* bmp_header = (BMPHeader*)buffer; + BMPInfoHeader* bmp_info = (BMPInfoHeader*) (buffer+sizeof(BMPHeader)); + + if (bmp_header->bfType != 0x4D42) + { + puts("Not a valid BMP\n"); + return; + } + + int width = bmp_info->biWidth; + int height = bmp_info->biHeight; + int pixel_offset = bmp_header->bfOffBits; + + if (bmp_info->biBitCount != 24) + { + puts("Not a 24-bit BMP\n"); + return; + } + + uint8_t* pixel_data = (uint8_t*)(buffer + pixel_offset); + + for (int y=0; y