Page 1 of 2
get memory map from grub 2
Posted: Tue Aug 27, 2013 4:09 am
by jayt
I use Grub 2 as the bootloader. Now I want to get the memory map.
I tried the code from the wiki but the memory map isn't readed:
Code: Select all
#include "multiboot.h"
#include "types.h"
u64int endkernel = 1024 * 10;
#define MAX_MEMORY_MAP 64
struct memory_map
{
u64int addr;
u64int length;
u32int type;
};
struct memory_map memory_map[MAX_MEMORY_MAP];
s32int memory_map_index = -1;
int kernel_main (multiboot_info_t* mbt, unsigned int magic)
{
u8int *first_frame, *second_frame;
u32int size;
u8int buf[256];
u8int color;
/* get memory map from grub */
terminal_initialize ();
terminal_writestring ("memory map\n");
multiboot_memory_map_t* mmap = (multiboot_memory_map_t *) mbt->mmap_addr;
while ((u64int) mmap < mbt->mmap_addr + mbt->mmap_length)
{
mmap = (multiboot_memory_map_t*) ( (unsigned int)mmap + mmap->size + sizeof(unsigned int) );
memory_map_index++;
memory_map[memory_map_index].addr = mmap->addr;
memory_map[memory_map_index].length = mmap->len;
memory_map[memory_map_index].type = mmap->type;
itoa (mmap->addr, buf, 16);
terminal_writestring (buf);
terminal_writestring (" ");
itoa (mmap->len, buf, 16);
terminal_writestring (buf);
terminal_writestring (" ");
itoa (mmap->type, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
}
Maybe something wasn't initialized right?
I used Qemu to run the kernel.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 5:01 am
by dozniak
What's the error?
"isn't readed" is not very descriptive error.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 5:07 am
by jayt
The while loop doesn't work: it isn't "runned" even once.
while ((u64int) mmap < mbt->mmap_addr + mbt->mmap_length)
I think there is some error in the while statement.
Or the mmap pointer isn't initialized right.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 5:49 am
by Combuster
printf debugging to the rescue!
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 6:47 am
by jayt
I putted this debug code in:
Code: Select all
terminal_writestring ("memory map address: ");
multiboot_memory_map_t* mmap = (multiboot_memory_map_t *) mbt->mmap_addr;
itoa (mbt->mmap_addr, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("mmap_addr + mmap_length: ");
itoa (mbt->mmap_addr + mbt->mmap_length, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
if (mmap >= mbt->mmap_addr + mbt->mmap_length)
{
terminal_writestring ("ERROR mmap greater or equal mmap_addr + mmap_length!\n");
}
And got this output:
memory map address: f000c79c
mmap_addr + mmap_length: e0018f38
ERROR mmap greater or equal mmap_addr + mmap_length!
Some pointer stuff seems messed up.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 7:39 am
by Combuster
f000c79c
My crystal ball just claimed that mbt == NULL.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 8:02 am
by jayt
I changed the bootloader. Now I got:
mbt: 101b20
memory map address: ead3d0ad
mmap_addr + mmap_length: facb203a
And for the memory map addresses and lengths the kernel prints 0
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 8:40 am
by Combuster
It looks like you're still doing guesswork...
Get bochs to dump all registers at the start of your kernel, and post the result here. You will probably need to compile bochs to include the debugger for that.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 10:06 am
by jayt
Code: Select all
<bochs:2> registers
eax: 0x2badb002 732803074
ecx: 0x00000000 0
edx: 0x00000000 0
ebx: 0x00010000 65536
esp: 0x02107218 34632216
ebp: 0x02107318 34632472
esi: 0x00000000 0
edi: 0x00000000 0
eip: 0x00100015
eflags 0x00200006: ID vip vif ac vm rf nt IOPL=0 of df if tf sf zf af PF cf
I inserted a:
loop:
goto loop;
at the start of the kernel_main C function. Was this right?
The eax register contains the multiboot magic number.
But I have no clue what the other registers should contain.
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 3:25 pm
by Combuster
That moment's way too late. Besides, you can set a breakpoint by address instead
Re: get memory map from grub 2
Posted: Tue Aug 27, 2013 4:36 pm
by jayt
Code: Select all
<bochs:3> info cpu
eax: 0x2badb002 732803074
ecx: 0x00000001 1
edx: 0x00000000 0
ebx: 0x0002c560 181600
esp: 0x00067f30 425776
ebp: 0x00067f40 425792
esi: 0x0002c6b8 181944
edi: 0x00000000 0
eip: 0x001002fd
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
status word: 0x0000: b c3 TOS0 c2 c1 c0 es sf pe ue oe ze de ie
control word: 0x0040: inf RC_NEAREST PC_32 pm um om zm dm im
tag word: 0x5555
operand: 0x0000
fip: 0x00000000
fcs: 0x0000
fdp: 0x00000000
fds: 0x0000
=>FP0 ST0(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP1 ST1(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP2 ST2(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP3 ST3(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP4 ST4(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP5 ST5(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP6 ST6(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
FP7 ST7(0): raw 0x0000:0000000000000000 (0,0000000000) (ZERO)
MM[0]: 00000000_00000000
MM[1]: 00000000_00000000
MM[2]: 00000000_00000000
MM[3]: 00000000_00000000
MM[4]: 00000000_00000000
MM[5]: 00000000_00000000
MM[6]: 00000000_00000000
MM[7]: 00000000_00000000
The CPU doesn't support AVX state !
I'm trying now grub 0.95.
That is CPU halted at the kernel loader entry point.
I think that is what you wanted?
Re: get memory map from grub 2
Posted: Wed Aug 28, 2013 6:37 am
by jayt
Here is my Bootloader:
Code: Select all
global loader ; making entry point visible to linker
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
global _loader
_loader:
hlt ; debug
mov esp, stack+STACKSIZE ; set up the stack
push eax ; pass Multiboot magic number
push ebx ; pass Multiboot info structure
extern kernel_main
call kernel_main ; call kernel proper
hlt ; halt machine should kernel return
section .bss
align 32
stack:
resb STACKSIZE ; reserve 16k stack on a quadword boundary
Are the
push eax
push ebx
right?
I mean is that correct to set up the data for the C kernel?
Re: get memory map from grub 2
Posted: Wed Aug 28, 2013 6:44 am
by Combuster
Rule 1 of debugging: Stop guessing.
It's good to know that you can at least use a debugger. The next thing you do is determine what mbt should have been, and then test for every step where that value goes and why it doesn't end up in the mbt variable - or on screen.
Re: get memory map from grub 2
Posted: Wed Aug 28, 2013 9:52 am
by jayt
http://diy-2010.net/community/?attachment_id=754
I found out that the memory structure of grub 0.9.5 differs from what my kernel (grub 0.9.7) expects.
The memory info structures are not the same.
Where can I get a floppy image disk with grub 0.9.7 installed?
Re: get memory map from grub 2
Posted: Thu Aug 29, 2013 5:07 am
by AJ
Hi,
What programming environment are you using? You may be best to either build from source or use your package manager and then use Grub's own image utilities.
Cheers,
Adam