How to set the Multiboot Information Flag

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
sds2017
Member
Member
Posts: 61
Joined: Tue Jul 05, 2011 10:05 am

How to set the Multiboot Information Flag

Post by sds2017 »

I know this might sound a little silly but, how do you set the flags you want on the multiboot info flag variable. I've read the grub manuals for the multiboot information structure and have implemented it in to a structure in c but, when I try to get the mem_high and mem_low values I can't, because the first bit (0 bit in a array) has to be set. Do you just set it in you entry point for the kernel because I tried it and it didn't work. Is there someway to do that before the bootloader puts it in ebx besides manually changing the code in grub and yes I did type in google how to set the flags for the grub multiboot information structure. I also read through the manual but couldn't find anything on it; maybe I missed something but I doubt it.
Here's the Multiboot manual [urlhttp://www.gnu.org/software/grub/manual/multiboot/multiboot.html.][/url]


Thanks,
Jackson
Rudster816
Member
Member
Posts: 141
Joined: Thu Jun 17, 2010 2:36 am

Re: How to set the Multiboot Information Flag

Post by Rudster816 »

You don't set the flags in the multiboot info structure, GRUB does to indicate what information it could provide. In order to tell GRUB what information you want, and what information you need, you must set the appropriate flags in your kernel's multiboot header.

Example:
http://wiki.osdev.org/Bare_Bones

The format of the flags can be found in the multiboot spec:
http://www.gnu.org/software/grub/manual ... gic-fields
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: How to set the Multiboot Information Flag

Post by Solar »

You set things in the Multiboot header, you read things from the info structure.

From the Multiboot docs:
The first longword indicates the presence and validity of other fields in the Multiboot information structure. [...] If bit 0 in the ‘flags’ word is set, then the ‘mem_*’ fields are valid. ‘mem_lower’ and ‘mem_upper’ indicate the amount of lower and upper memory, respectively, in kilobytes.
I.e., you check bit 0 in the ‘flags’ word, and if it is set, you can assume the ‘mem_*’ fields as valid. If it is not set, GRUB was unable to provide the information.

What you have to set in order to receive the information is bit 1 in the ‘flags’ field of the Multiboot header.
Every good solution is obvious once you've found it.
sds2017
Member
Member
Posts: 61
Joined: Tue Jul 05, 2011 10:05 am

Re: How to set the Multiboot Information Flag

Post by sds2017 »

Thanks for the info but, I guess grub was unable to pass the info because when I try to print the value of of anything besides the flags it's 0 and the the correct values of the flag is set if you want to see my code here it is:

//main.c
#include <console.h>
#include <system.h>
#include <HAL.h>
#include <./Devices/PIT/pit.h>
#include <./Devices/Keyboard/keyboard.h>
#include <./Devices/ATA/ATA.h>
#include <./Devices/FDC/FDC.h>
#include <mm.h>
#include <Multiboot.h>

void kmain(Multiboot_Info_t Multiboot_Information)
{
ClearScreen();
printf("Welcome to my OS++\n");
printf("Copyright (C) 2012 Jackson Harmon\n");
printf("Recieved Multiboot Information...\n");
printf_dec(Multiboot_Information.mem_upper);
printf("\n");
init_hal();

asm volatile("sti");
init_keyboard();
init_pit(50);

if(ata_detect_controllers() == 0)
{
ata_sector sector=0;
sector[4]=0x62;
ata_lba28_write_sector(0x1F0, 0, sector);
print_c(sector[4]);
sector[4] = 0;
ata_lba28_read_sector(0x1F0, 0, sector);
print_c(sector[4]);
}
}

//Multiboot.h
#ifndef __MULTIBOOT_H
#define __MULTIBOOT_H

typedef struct Multiboot_Header
{
uint32 magic;
uint32 flags;
uint32 checksum;
uint32 header_addr;
uint32 load_addr;
uint32 load_end_addr;
uint32 bss_end_addr;
uint32 entry_addr;
uint32 mode_type;
uint32 width;
uint32 height;
uint32 depth;
} Multiboot_Header_t;

typedef struct Multiboot_aout_symbol_table
{
uint32 tabsize;
uint32 strsize;
uint32 addr;
uint32 reserved;
} Multiboot_aout_symbol_table_t;

typedef struct Multiboot_elf_section_header_table
{
uint32 num;
uint32 size;
uint32 addr;
uint32 shndx;
} Multiboot_elf_section_header_table_t;

typedef struct Multiboot_Info
{
uint32 flags;
uint32 mem_lower;
uint32 mem_upper;
uint32 boot_device;
uint32 cmdline;
uint32 mods_count;
uint32 mods_addr;
union
{
Multiboot_aout_symbol_table_t aout_sym;
Multiboot_elf_section_header_table_t elf_sec;
} u;
uint32 mmap_length;
uint32 mmap_addr;
uint32 drives_length;
uint32 drives_addr;
uint32 config_table;
uint32 boot_loader_name;
uint32 apm_table;
uint16 vbe_control_info;
uint16 vbe_mode_info;
uint16 vbe_mode;
uint16 vbe_interface_seg;
uint16 vbe_interface_off;
uint16 vbe_interface_len;
} Multiboot_Info_t;

#endif

;loader.asm
bits 32

global loader
extern kmain

section .__mbHeader
;Multiboot Header
align 4
MODULEALIGN equ 1<<0
MEMINFO equ 1<<1
FLAGS equ MODULEALIGN | MEMINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)

MultibootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM

STACKSIZE equ 0x4000 ;16 KB

loader:
cmp eax, 0x2BADB002
jne .bad

mov esp, STACKSIZE + stack
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

push ebx
call kmain

.bad:
cli
hlt

align 4
stack:
TIMES STACKSIZE db 0

and my results were...
Welcome to OS++
Copyright (C) 2012 Jackson Harmon
Recieved Multiboot Information...
0
Installing GDT... [done]
Enabling IRQ... [done]
Installing IDT... [done]
Initializing the Keyboard... [done]
Initializing PIT... [done]
Drive detected...
Primary Controller Exists...
bb

by the way when I print the flags variable as a decimal it is 179488 (101011110100100000 in binary) which is odd because based on my code only the first 2 bits should be set.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: How to set the Multiboot Information Flag

Post by neon »

Hello,

There are multiple potential problems with the provided code. You would have to verify if these are errors or not based on compiler settings or code that is executed prior to kmain:

1. Are you getting the multiboot info structure from ebx? It is not passed on the stack;
2. Is your structures packed properly?
3. I also notice the lack of error detection. Should verify eax contains the right magic number and ebx points to a valid structure
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
sds2017
Member
Member
Posts: 61
Joined: Tue Jul 05, 2011 10:05 am

Re: How to set the Multiboot Information Flag

Post by sds2017 »

I think I've found my problem. I haven't tested the code but ebx only contains the physical address of where the multiboot information is stored so the reason I got this random number when I printed the flags variable is because it was the address of the information.
User avatar
brain
Member
Member
Posts: 234
Joined: Thu Nov 05, 2009 5:04 pm
Location: UK
Contact:

Re: How to set the Multiboot Information Flag

Post by brain »

sds2017 wrote:I think I've found my problem. I haven't tested the code but ebx only contains the physical address of where the multiboot information is stored so the reason I got this random number when I printed the flags variable is because it was the address of the information.
Yup, this was item 1 on neons list... it wasn't a pointer :-)
sds2017
Member
Member
Posts: 61
Joined: Tue Jul 05, 2011 10:05 am

Re: How to set the Multiboot Information Flag

Post by sds2017 »

Last question, does it sound reasonable that the flags variable would be 2023 in decimal?
User avatar
brain
Member
Member
Posts: 234
Joined: Thu Nov 05, 2009 5:04 pm
Location: UK
Contact:

Re: How to set the Multiboot Information Flag

Post by brain »

Convert it to binary and compare it to what you expect?
sds2017
Member
Member
Posts: 61
Joined: Tue Jul 05, 2011 10:05 am

Re: How to set the Multiboot Information Flag

Post by sds2017 »

Another strange thing was that I was comparing eax to the wrong value I changed the code to comparing the magic value to 0x1BADB002, I ended up finding the magic value is 0x2BAD0010; I've tried finding what that means (specifically, obviously it's an error) and couldn't find what the error means. I'll keep looking. Let me know if you know or find what it means. Anyway, I compared the flag to what I expected and concluded that the value was correct.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: How to set the Multiboot Information Flag

Post by neon »

Its not on error code; I personally have the suspicion the low word or eax is just overwritten by your software. You would have to view the disassembly of this to verify. As for the value of 2023 decimal: if this value was from the multiboot info structure passed from the bootloader, then it is plausible and can be correct.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply