Page 1 of 1

Bit 2 in GRUB flags

Posted: Fri Apr 09, 2010 2:18 am
by Neolander
Hi, and first thanks to everyone working on this site and on the wiki !

I have some issues with GRUB : if I take a look at the Multiboot doc, it reads :
If bit 0 in the `flags' word is set, then all boot modules loaded
along with the operating system must be aligned on page (4KB)
boundaries. Some operating systems expect to be able to map the
pages containing boot modules directly into a paged address space
during startup, and thus need the boot modules to be page-aligned.

If bit 1 in the `flags' word is set, then information on available
memory via at least the `mem_*' fields of the Multiboot information
structure (*note Boot information format::) must be included. If
the boot loader is capable of passing a memory map (the `mmap_*'
fields) and one exists, then it may be included as well.

If bit 2 in the `flags' word is set, information about the video
mode table (*note Boot information format::) must be available to
the kernel.
I used to set flags = 3, but now I want to take a look at VBE modes, so I set flags = 1+2+4 = 7
Here's the assembly code :

Code: Select all

  .text
  .globl  bootstrap
bootstrap:
  jmp     multiboot_entry
  /* Align 32 bits boundary. */
  .align  4
  /* Multiboot header. */
multiboot_header:
  /* magic */
  .long   0x1BADB002
  /* flags */
  .long   0x00000007
  /* checksum */
  .long   -(0x1BADB002 + 0x00000007)
  /* reserved */
  .long 0x0
  .long 0x0
  .long 0x0
  .long 0x0
  .long 0x0
  /* Graphics mode. 0 = linear graphics
                    1 = EGA color text */
  .long 0x00000001
  /* Preferred width in pixels/characters of the screen : 80 */
  .long 0x00000050
  /* Preferred height in pixels/characters of the screen : 25 */
  .long 0x00000019
  /* Color depth of the screen. 0 in text mode */
  .long 0x00000000

multiboot_entry:
  /* Initialize the stack pointer. */
  movl    $(stack + 0x4000), %esp

  /* Reset EFLAGS. */
  pushl   $0
  popf

  /* Push the pointer to the Multiboot information structure. */
  pushl   %eax
  /* Push the magic value. */
  pushl   %ebx

  /* Now enter the C main function... */
  call    bootstrap_longmode

loop:   hlt
  jmp     loop

stack:
  /* Our stack area (16kB). */
  .space   0x4000
And here's the C code it runs (It reads multiboot info flags and displays what they mean using debug routines) :

Code: Select all

#include "../include/multiboot.h"
#include "../debug/txt_videomem.h"
#include "../debug/wait.h"

int bootstrap_longmode(multiboot_info_t* mbd, unsigned int magic) {  
  dbg_init_videomem();
  dbg_clear_screen();
  
  if(magic!=MULTIBOOT_BOOTLOADER_MAGIC) {
    //Not launched by GRUB. Freezing...
    dbg_print_str("Error : GRUB not found !");
    return -1;
  }
  
  dbg_print_str("Hello and welcome to ");
  dbg_set_attr(DBG_TXT_LIGHTBLUE);
  dbg_print_str("SpockOS\n\n");
  dbg_set_attr(DBG_TXT_LIGHTGRAY);
  dbg_print_str("Here's what GRUB tells us :\n");
  
  if((mbd->flags & 1) == 1) dbg_print_str("*We know how much memory we have\n");
  else dbg_print_str("*We don't know how much memory we have\n");
  if((mbd->flags & 2) == 2) dbg_print_str("*We know where we boot from\n");
  else dbg_print_str("*We don't know where we boot from\n");  
  if((mbd->flags & 4) == 4) dbg_print_str("*We know the command line\n");
  else dbg_print_str("*We don't know the command line\n");
  if((mbd->flags & 8) == 8) dbg_print_str("*We know about modules\n");
  else dbg_print_str("*We don't know about modules\n");
  if((mbd->flags & 16) == 16) dbg_print_str("*HORROR ! GRUB has mistaken us for an a.out kernel !\n");
  else dbg_print_str("*Grub knows we're not an a.out kernel\n");
  if((mbd->flags & 32) == 32) dbg_print_str("*We know anything about our symbol table\n");
  else dbg_print_str("*We don't know anything about our symbol table\n");
  if((mbd->flags & 64) == 64) dbg_print_str("*We have a map of memory\n");
  else dbg_print_str("*We don't have a map of memory\n");  
  if((mbd->flags & 128) == 128) dbg_print_str("*We know about physical drives\n");
  else dbg_print_str("*We don't know about physical drives\n");
  if((mbd->flags & 256) == 256) dbg_print_str("*We know about ROM configuration\n");
  else dbg_print_str("*We don't know about ROM configuration\n");
  if((mbd->flags & 512) == 512) dbg_print_str("*We know our bootloader by name\n");
  else dbg_print_str("*We don't know our bootloader by name\n");
  if((mbd->flags & 1024) == 1024) dbg_print_str("*We know about the APM table\n");
  else dbg_print_str("*We don't know about the APM table\n");  
  if((mbd->flags & 2048) == 2048) dbg_print_str("*We know about VBE graphics capabilities\n");
  else dbg_print_str("*We don't know about VBE graphics capabilities\n");
  
  dbg_print_str("\nAnd for the rest, ");
  dbg_set_attr(DBG_TXT_RED);
  dbg_print_str("we're on our own...");
  dbg_set_attr(DBG_TXT_LIGHTGRAY);
  
  //Done ^_^
  
  return 0;
}
But something went wrong, apparently : since I did that, mbchk keeps warning me about reserved flags being set...
gralouf@nutella-pardus Code $ mbchk bin/bs_kernel.bin
bin/bs_kernel.bin: The Multiboot header is found at the offset 4100.
bin/bs_kernel.bin: Non-zero is found in reserved flags (0x7).
...and GRUB doesn't seem to care about what I say (see attachment).
I don't understand : why won't grub (0.97) have a look at bit 2 of my flags ?

Re: Bit 2 in GRUB flags

Posted: Fri Apr 09, 2010 4:20 am
by JamesM
Hi,

I've tried to get GRUB's video modes to work and have failed every time, similar to yourself. In the end I gave up and wrote my own mode switching code.

Cheers,

James

Re: Bit 2 in GRUB flags

Posted: Fri Apr 09, 2010 4:40 am
by Neolander
Thanks ;) Anyway I'm far from actually using this information, I just wanted to see what GRUB was able to tell me before relying on features that don't work in later code...

Re: Bit 2 in GRUB flags

Posted: Fri Apr 09, 2010 6:18 am
by Selenic
Apparently vanilla GRUB doesn't actually do anything with graphics info, even setting the mode you ask for, yet it accepts the flag for it, in direct violation of the Multiboot standard. You can get patched versions that *do* set graphics mode, but you're better off writing your own code to get the BIOS to do it, as the pmode interfaces on some real cards don't work (read: lock up the system or similar)