Page 1 of 1

[SOLVED] GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sat Jan 09, 2016 8:52 am
by prajwal
Hi,

I have developed (and developing) a ELF32 bit OS which I boot from legacy grub in typical 80x25 text console (in QEMU and on my old laptop)

However, as most new computers come with UEFI firmware, to boot from UEFI firmware, I built grub2-efi and was able to boot my elf32 bit kernel under QEMU (using OVMF) - with debug information logged to serial port

But because my kernel doesn't support graphics mode - I am stuck without a display as GRUB2 EFI would land my kernel in graphics mode (legacy 80x25 text console is not supported as I understand). So, I am thinking to develop graphics support in my elf32 bit kernel that's booted from GRUB2 EFI (which uses GOP)

I have got the framebuffer information from GRUB2 as part of multiboot header where the framebuffer_addr is 0x8000000 (2GB) and have valid values for width, height, bpp, pitch etc.. - but I am not sure if this can be used or how to use this framebuffer information returned by GRUB2 EFI in my elf32 bit kernel ? OR What are the possible ways to build graphics support in my case (i.e. GRUB2 EFI booting ELF32 bit kernel)

PS:
1. The RAM size setup in QEMU is 128 MB
2. I am just fine with 80x25 text console but I wonder if GRUB2 EFI would allow that ?

Regards,
- Prajwala

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 3:46 am
by Combuster
where the framebuffer_addr is 0x8000000 (2GB) and have valid values for width, height, bpp, pitch etc.. - but I am not sure if this can be used
Have you tried?

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 4:24 am
by prajwal
Information from multiboot header (as logged via serial port):-
FRAMEBUFFER_ADDR: 0x80000000
FRAMEBUFFER_PITCH: 3200
FRAMEBUFFER_WIDTH: 800
FRAMEBUFFER_HEIGHT: 600
FRAMEBUFFER_BPP: 32
FRAMEBUFFER_RED_POS: 0
FRAMEBUFFER_RED_SIZE: 0
FRAMEBUFFER_GREEN_POS: 16
FRAMEBUFFER_GREEN_SIZE: 8
FRAMEBUFFER_BLUE_POS: 8
FRAMEBUFFER_BLUE_SIZE: 8
I mapped framebuffer_addr 0x80000000 (2GB) in the page table and then ran below code to fill the screen:-

Code: Select all

   unsigned* framebuffer = (unsigned*)(0x80000000);
    for(int y = 0; y < 600; ++y)
    {
      for(int x = 0; x < 800; ++x)
      {
        //unsigned* ptr = (unsigned*)(0x4000000 + y * 3200 + x * 4);
        //*ptr = 0xFFAAAAAA;
        framebuffer[y * 800 + x] = 0xFFAAAA00; //yellow color
      }
    }
and I have attached output (QEMU screenshot)

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 4:54 am
by alexfru
prajwala wrote: FRAMEBUFFER_PITCH: 3200
AFAIR, that's the distance between two consecutive horizontal lines in the frame buffer (I believe, in pixels). You're ignoring it. You need to multiply Y by it and not by 800.

Also this looks odd:
prajwala wrote: FRAMEBUFFER_RED_SIZE: 0

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 5:47 am
by Combuster
I find it especially strange that your horizontal lines increase in distance so I don't trust that your code is actually running as expected. Your compiler and bootloader might not agree on architecture or you have broken the binary or environment in other ways.

Try to draw a 10x10 pixel square and see how that behaves. If it still doesn't you'll at least have reduced the number of memory accesses to the point you can verify the instructions, addresses and values by hand using a debugger.

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 8:22 am
by BrightLight
alexfru wrote:AFAIR, that's the distance between two consecutive horizontal lines in the frame buffer (I believe, in pixels).
Bytes, not pixels.
In general getting the pixel location in the framebuffer really is just:

Code: Select all

(y * pitch) + (x * (bpp/8)) + framebuffer_base

Re: GUI for an ELF32 kernel booted from GRUB2 UEFI

Posted: Sun Jan 10, 2016 9:52 am
by prajwal
Thanks Combuster.. that approach to debug helped - it turned out to be a silly mistake in the code which was mapping LFB into page table. It works now after fixing page table mapping

Thanks everyone else for your time and suggestion

Regards,
- Prajwala