0

I recently got interested in writing a simple kernel. I did some searching on the internet and came across OSDev Wiki. I set up the basic kernel (and after some frustration, the cross-compiler). Now I wanted to take it a step further: I want to start writing values to individual pixels. The only satisfactory and understandable answer I came across was the one on the Wiki, Drawing in Protected Mode. I want to use the functions provided, but still can't seem to understand what I need to pass as the arguments. Below is the code for the function I am using, I can't understand what I need to pass for the first argument. Is there some memory buffer (similar to the terminal_buffer used for text) I need?

/* only valid for 800x600x32bpp */
static void putpixel(unsigned char* screen, int x,int y, int color) {
    unsigned where = x*4 + y*3200;
    screen[where] = color & 255;              // BLUE
    screen[where + 1] = (color >> 8) & 255;   // GREEN
    screen[where + 2] = (color >> 16) & 255;  // RED
}

This is probably a stupid question since I'm very new to OS development.

Thanks in advance,

Javax

BTW: I am doing x86 code. I also saw this question and tried inlining it in C++. This code compiles, but if I call the function, the OS refuses to boot. It only gets to this stage:the stage it boots to before returning to the GRUB menu screen. This may be beside the point, however, if I can find an alternative solution. This is the alternative option:

void setPixel () {
    asm ("mov %ah, 0x0C");
    asm ("mov %al, 0x13");
    asm ("int $0x10");

    asm ("mov %ah, 0x0C");
    asm ("mov %bh, 0");
    asm ("mov %dx, 5");
    asm ("mov %cx, 5");
    asm ("mov %al, 0x04");
    asm ("int $0x10");
}
JkyCosten
  • 23
  • 10

1 Answers1

1

I did not code in protected mode but if I remember correctly in protected mode the interrupts are handled differently and needed some bridge to access so the second interrupt example code will not work (but I might be wrong). Try to google how to access VGA/VESA/VBE BIOS functions from protected mode.

The first example is assuming you got VESA/VBE card present in the system and configured to video mode 800x600x32bpp in LFB mode starting at far pointer screen. I also never did such thing but when you set video mode of VGA/VESA it switch to page mode by default.

So if you just switch to 800x600x32bpp than you got page mode (natively). So the VRAM is mapped at 0xA000:0000 - 0xA000:FFFF in real mode. As you are in protected mode you need to translate/map that to 32 bit space somehow.

Also as you got 32bit mode you should use DWORD for colors and store the pixel with single operation (stosd for example or have DWORD *screen and do not use the 4* from address computation where = x + y*800; ).

so you got 2 options:

  1. LFB linear frame buffer

    VESA/VBE gfx cards has a capability to use LFB (I think from version 1.2 or 2.0) that means you can map VRAM to specified memory space linearly. So in this case the screen is that address you mapped the VRAM to. On how to do it you should consult with VESA and VBE documentation. Without proper configuration your example will never work.

  2. page mode

    In page mode you got only access to 64 KByte of VRAM. for video modes above 320x200x8bpp is this not enough and you need to chose which 64KByte segment of memory you want to work with. that is called paging. Look here #2 VGA GFX mode there is real mode VESA example too. The idea is to compute address and page from the coordinates. In your case (for BYTE pointer):

    BYTE far screen=(BYTE far*)0xA0000000;
    DWORD adr = 4*x + 4*800*y;
    DWORD page = adr>>16; adr &= 0xFFFF;
    VESApage(page);
    screen[adr]=r; adr++;
    screen[adr]=g; adr++;
    screen[adr]=b;
    

    or:

    DWORD far screen=(DWORD far*)0xA0000000;
    DWORD adr = x + 800*y;
    DWORD page = adr>>14; adr &= 0x3FFF;
    VESApage(page);
    screen[adr]=rgba;
    

    The VESApage() source is in the link above. So in this case the screen is fixed VRAM address but as I mentioned before in order to work in protected mode this could change quite a bit. You should also take a look at Graphics mode in assembly 8086

As the link you provided confirms my suspicions that you can not access BIOS functions from protected mode directly so I would go for LFB as it is way faster and does not require any further BIOS function access after the video mode configuration. So you have to set your video mode before switching to protected mode !!!.

Hope parameters color,x,y are clear to you. Also in case you do not know what BYTE and DWORD is than they are unsigned ints 8 and 32 bit wide.

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Hi! Thanks for the reply. Yes, I have been doing some research lately and have discovered that ‘int’ does indeed cause the kernel to crash. I’m interested in using the other functions (from OSDev Wiki). And have tried using them with VGA graphics’ memory reference. It compiles but nothing appears. Does this mean I need to set up VBE? I don’t particularly want to set up any big libraries. Thanks, Javax. – JkyCosten Mar 14 '18 at 14:32
  • Additionally, I am using multiboot, and as far as I can tell, I have no point where I am in real mode. – JkyCosten Mar 14 '18 at 14:35
  • @JavaxCosten I am no expert in the matter but I am afraid that without VBE you can not set LFB and without LFB there is no way (other than accessing gfx IO directly) to use more than 64KB videomodes. But there must be some lib that does that. Try to search demoscene may be 64K or up to 4 MByte limit they are concerned with code size an speed so you might find source code of exactly this in a lightweight form ... Also many pgms where based on `DOS4GW` so its examples might help you too with this – Spektre Mar 14 '18 at 14:54
  • @JavaxCosten Also as I mentioned before 16bit `A000:0000h` address might be very diferent in 32 bit as there might be remapped else where which might be the reason you see nothing. But as Seva Titov pointed out you need to set the videomode first (prior to switching into protected mode). If you see any text on the screen you did not do that yet... see [How do I print SVGA Info on the screen in tasm?](https://stackoverflow.com/a/49025827/2521214) it is real mode VESA test of mine ... – Spektre Mar 14 '18 at 15:00
  • @JavaxCosten this [Protected ModeProgramming: VESA LFB](http://www.zeepedia.com/read.php?protected_mode_programming_vesa_linear_frame_buffer_interrupt_handling_assembly_language_programming&b=5&c=15) and [VBE3 docs](https://pdos.csail.mit.edu/6.828/2011/readings/hardware/vbe3.pdf) looks promising – Spektre Mar 14 '18 at 15:05