grub graphics

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

grub graphics

Post by haybame »

how do i use grub graphics mode?:

Code: Select all

menuentry "*****" {
        set root='(hd96)'
        set gfxpayload=1024x768x32
        multiboot /boot/kernel.bin
}
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: grub graphics

Post by klange »

Try moving the "set gfxpayload=1024x768x32" after the "multiboot" command.
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

UPDATE
i got the graphics mode to work. but i cant draw a pixel.
how do i draw a pixel?
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: grub graphics

Post by pvc »

Multiboot compatible loaders (like GRUB) pass boot information structure pointer to your code in EBX register. It's structure is

Code: Select all

        +-------------------+
0       | flags             |    (required)
        +-------------------+
4       | mem_lower         |    (present if flags[0] is set)
8       | mem_upper         |    (present if flags[0] is set)
        +-------------------+
12      | boot_device       |    (present if flags[1] is set)
        +-------------------+
16      | cmdline           |    (present if flags[2] is set)
        +-------------------+
20      | mods_count        |    (present if flags[3] is set)
24      | mods_addr         |    (present if flags[3] is set)
        +-------------------+
28 - 40 | syms              |    (present if flags[4] or
        |                   |                flags[5] is set)
        +-------------------+
44      | mmap_length       |    (present if flags[6] is set)
48      | mmap_addr         |    (present if flags[6] is set)
        +-------------------+
52      | drives_length     |    (present if flags[7] is set)
56      | drives_addr       |    (present if flags[7] is set)
        +-------------------+
60      | config_table      |    (present if flags[8] is set)
        +-------------------+
64      | boot_loader_name  |    (present if flags[9] is set)
        +-------------------+
68      | apm_table         |    (present if flags[10] is set)
        +-------------------+
72      | vbe_control_info  |    (present if flags[11] is set)
76      | vbe_mode_info     |
80      | vbe_mode          |
82      | vbe_interface_seg |
84      | vbe_interface_off |
86      | vbe_interface_len |
        +-------------------+
88      | framebuffer_addr  |    (present if flags[12] is set)
96      | framebuffer_pitch |
100     | framebuffer_width |
104     | framebuffer_height|
108     | framebuffer_bpp   |
109     | framebuffer_type  |
110-115 | color_info        |
        +-------------------+
You're interested in framebuffer_* fields. framebuffer_addr points to memory location where pixel data is stored. Any writes to this buffer will immediately be visible on screen. How exactly pixel offset is calculated depends on your video mode. To get detailed descriptions of these fields read https://www.gnu.org/software/grub/manua ... iboot.html.
p34c3
Posts: 3
Joined: Tue Mar 03, 2020 11:48 am

Re: grub graphics

Post by p34c3 »

They have some nice example kernel right there:
https://www.gnu.org/software/grub/manua ... -code.html
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

how do i compile the code?
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

can someone please get this code to draw a pixel?
it already sets the mode to 800x600x32 and i am using this: https://wiki.osdev.org/Drawing_In_Protected_Mode

kernel.c

Code: Select all

kmain()
{
        
}
kernel.asm

Code: Select all

bits    32
section .text
   align 4
   
   dd 0x1BADB002
   dd 0x04
   dd -(0x1BADB002 + 0x04)
   
   dd 0 ; skip some flags
   dd 0
   dd 0
   dd 0
   dd 0
   
   dd 0 ; sets it to graphical mode
   dd 800 ; sets the width
   dd 600 ; sets the height
   dd 32 ; sets the bits per pixel
        
push ebx
global start
extern kmain
start:
        cli
        call kmain
        hlt
thanks in advance
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: grub graphics

Post by pvc »

Haven't tested it, but should work:

Code: Select all

bits    32
section .text
   align 4
   
   dd 0x1BADB002
   dd 0x04
   dd -(0x1BADB002 + 0x04)
   
   dd 0 ; skip some flags
   dd 0
   dd 0
   dd 0
   dd 0
   
   dd 0 ; sets it to graphical mode
   dd 800 ; sets the width
   dd 600 ; sets the height
   dd 32 ; sets the bits per pixel
       
global start
extern kmain
start:
    mov edi, dword [ebx + 88] ; edi <- framebuffer_addr
    mov dword [edi], 0x00FFFFFF ; white pixel should appear in top left corner
    mov esp, stack.end
    push ebx
    call kmain
    pop ebx
    cli
    hlt

stack: resb 4096
.end:
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

it works! but is there a way to make a function in C?

Code: Select all

vesa_clear();

Code: Select all

vesa_drawpixel(x,y,colour)
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: grub graphics

Post by pvc »

Haven't tested this either. But it should be something along these lines.

Code: Select all

typedef struct
{
    char skip[88];                // there are some interesting fields here but
	                               // we skip them for simplicity

    unsigned framebuffer_addr_lo; // separated these fields to avoid 64 bit
    unsigned framebuffer_addr_hi; // arithmetic (which may need some extra code)
    unsigned framebuffer_pitch;   // this is basically bytes per line
    unsigned framebuffer_width;
    unsigned framebuffer_height;
    unsigned char framebuffer_bpp;
} multiboot_info_t;

multiboot_info_t *mbinfo;

void vesa_drawpixel(unsigned x, unsigned y, unsigned color)
{   // assuming 32bpp
    unsigned *line = (unsigned *)(mbinfo->framebuffer_addr_lo + y * mbinfo->framebuffer_pitch);
    line[x] = color;
}

void vesa_clear(unsigned color)
{   // slow but simple
    for(unsigned y = 0; y < mbinfo->framebuffer_height; ++y)
    {
        for(unsigned x = 0; x < mbinfo->framebuffer_width; ++x)
            vesa_drawpixel(x, y, color);
    } 
}

void kmain(multiboot_info_t *mboot_info)
{
    mbinfo = mboot_info;
    vesa_clear(0x00203040);
    vesa_drawpixel(400, 300, 0x00FFFFFF);
}
For different color depths, you have to change data type of line in vesa_drawpixel. For 16 bit it would be unsigned short and unsigned char for 8 bit.
TBH. These are the basics of the basics. If you want to be able to write something more than 'Hello, World!' for your OS, you really need to be fluent in regular programming as well.
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

How would i implement a double buffer?
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: grub graphics

Post by Love4Boobies »

I think this thread should be locked. It's all "How do I compile, how do I this, how do I that?" Pick up a programming book if you don't know how to do anything.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
haybame
Posts: 16
Joined: Mon Mar 09, 2020 5:06 pm
Libera.chat IRC: haybame

Re: grub graphics

Post by haybame »

how do i close a thread? 8)
Post Reply