So, I recently got into operating system development a while ago, and I've made some good progress. I'm working in assembly language, C, and C++, with C++ as the language of my main kernel and drivers. Also, I'm using Grub2 as my bootloader.
I've begun writing my graphics driver now, and I can easily draw pixels in 320x200x8 resolution. Unfortunately, I'm unable to do so in 1024x768x32 resolution (which I definitely need to do for my operating system graphics to be at least be standard quality).
This is my grub.cfg file:
set timeout=0
set default=0
insmod normal
insmod multiboot2
insmod all_video
set background_image=/boot/res/background.jpg
set gfxpayload=1024x768x32
menuentry "Alaric OS" {
multiboot2 /boot/kernel.bin
set gfxmode=1024x768x32
set gfxpayload=1024x768x32
insmod all_video
boot
}
This is my header.asm file:
section .multiboot_header
header_start:
; magic number used for multiboot2
dd 0xe85250d6
; architecture
dd 0 ; protected mode i386
; header length
dd header_end - header_start
; checksum
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
; ===
dw 5
dw 0
dd 20
dd 1024
dd 768
dd 32
; end tag
;dw 0
;dw 0
;dd 8
header_end:
This is part of my io.h file (my I/O and graphics driver file):
unsigned char *VIDEO_MEMORY = (unsigned char*) 0xa0000;
unsigned char *FRAMEBUFFER = (unsigned char*) 0xa0000;
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const unsigned char BITS_PER_PIXEL = 32;
const unsigned char PIXEL_STRIDE = (BITS_PER_PIXEL | 7) >> 3;
const unsigned char BYTES_PER_PIXEL = (BITS_PER_PIXEL | 7) >> 3;
const unsigned char PIXEL_WIDTH = (BITS_PER_PIXEL | 7) >> 3;
const int PITCH = SCREEN_WIDTH * PIXEL_STRIDE;
const int BYTES_PER_SCAN_LINE = SCREEN_WIDTH * PIXEL_STRIDE;
void draw_pixel(unsigned int x, unsigned int y, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char* framebuffer = (unsigned char*)FRAMEBUFFER; // Replace with your framebuffer address
unsigned int bytes_per_pixel = SYSTEM::VIDEO::BYTES_PER_PIXEL; // Replace with your bytes per pixel
unsigned int bytes_per_scanline = SYSTEM::VIDEO::SCREEN_WIDTH * bytes_per_pixel; // Replace with your bytes per scanline
uint8_t* pixel_address = framebuffer + y * bytes_per_scanline + x * bytes_per_pixel;
pixel_address[0] = blue; // blue
pixel_address[1] = green; // Green
pixel_address[2] = red; // red
}
The problem is, I can easily draw to coordinates (0,0) to (1024, 20), but anything beyond that doesn't print at all and most times causes the system to crash. Also, I know I could have assigned variables like FRAMEBUFFER with already existing variables like VIDEO_MEMORY, but my compiler started tripping lately and setting variables like such was the only thing that got the compiler to start working again. By the way, I'm using Netbeans as my IDE and I'm compiling using nasm (for assembly), gcc (for C), g++ (for C++), ld (for linking binaries) and grub-mkrescue (to bind everything into a bootable ISO image).
As for the error, this is the error I get when I try to run the operating system in VirtualBox. The error pops up after a second or two of the OS running, or when the screen is scrolled:
I've tried switching up the code as best I can, but nothing is working. Any help will be highly appreciated.
Simply enough, as was suggested, I just needed to get the address of the video memory from the GRUB bootloader...