How to set the Multiboot Information Flag
How to set the Multiboot Information Flag
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
Here's the Multiboot manual [urlhttp://www.gnu.org/software/grub/manual/multiboot/multiboot.html.][/url]
Thanks,
Jackson
-
- Member
- Posts: 141
- Joined: Thu Jun 17, 2010 2:36 am
Re: How to set the Multiboot Information Flag
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
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
Re: How to set the Multiboot Information Flag
You set things in the Multiboot header, you read things from the info structure.
From the Multiboot docs:
What you have to set in order to receive the information is bit 1 in the ‘flags’ field of the Multiboot header.
From the Multiboot docs:
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.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.
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.
Re: How to set the Multiboot Information Flag
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.
//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.
Re: How to set the Multiboot Information Flag
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
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: How to set the Multiboot Information Flag
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.
Re: How to set the Multiboot Information Flag
Yup, this was item 1 on neons list... it wasn't a pointersds2017 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.
Re: How to set the Multiboot Information Flag
Last question, does it sound reasonable that the flags variable would be 2023 in decimal?
Re: How to set the Multiboot Information Flag
Convert it to binary and compare it to what you expect?
Re: How to set the Multiboot Information Flag
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.
Re: How to set the Multiboot Information Flag
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}