I'm using Linux.
I found a 0.9.7 GRUB but the problem stays the same.
The kernel doesn't get the memory map right.
I know it should be simple but it seams it isn't.
As seen on my screenshot in the last posting, the magic number from GRUB is right, so
the address of the memory info structure should be right too.
I'm still searching the error.
get memory map from grub 2
Re: get memory map from grub 2
I didn't see you printing this magic in your kernel_main though. Are you sure it's passed in correctly?
Learn to read.
Re: get memory map from grub 2
I think the two arguments passed from the kernel loader to the C kernel are in right order.
Here is my kernel start:
I don't know what is wrong here. It just looks to me like the code in the tutorial here.
But it wont work right.
Here is my kernel start:
Code: Select all
typedef struct memory_map_t_kernel
{
u32int size;
//unsigned long base_addr_low;
//unsigned long base_addr_high;
u64int addr;
// unsigned long length_low;
// unsigned long length_high;
u64int len; //holds both halves.
u32int type;
} memory_map_t_kernel;
struct memory_map_kernel memory_map_kernel[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;
u64int mmap_address = mbt->mmap_addr;
u64int mmap_length = mbt->mmap_length;
u64int memory_kb;
/* memory_kb = get_memory_size_64mb (); */
/* get memory map from grub */
terminal_initialize ();
terminal_writestring ("sizeof u32int: ");
ltoa (sizeof (u32int), buf, 10);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("sizeof u64int: ");
ltoa (sizeof (u64int), buf, 10);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("mbt: ");
ltoa (mbt, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("magic: ");
ltoa (magic, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("memory map address: ");
memory_map_t_kernel *mmap;
mmap = (memory_map_t_kernel *) mbt->mmap_addr;
ltoa (mbt->mmap_addr, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
terminal_writestring ("mmap_addr + mmap_length: ");
ltoa (mbt->mmap_addr + mbt->mmap_length, buf, 16);
terminal_writestring (buf);
terminal_writestring ("\n");
if ((u64int) mmap >= (u64int) (mmap_address + mmap_length))
{
terminal_writestring ("ERROR mmap greater or equal mmap_addr + mmap_length!\n");
}
while ((u64int) mmap < (u64int) (mmap_address + mmap_length))
{
terminal_writestring ("memory map: ");
/* mmap = (multiboot_memory_map_t*) ( (unsigned int)mmap + mmap->size + sizeof(unsigned int) ); */
mmap = (memory_map_t_kernel*) ( (u32int)mmap + mmap->size + sizeof(u32int));
ltoa (mmap->addr, buf, 16);
terminal_writestring (buf);
terminal_writestring (" ");
ltoa (mmap->len, buf, 16);
terminal_writestring (buf);
terminal_writestring (" ");
ltoa (mmap->type, buf, 10);
terminal_writestring (buf);
terminal_writestring ("\n");
}
But it wont work right.
- darkinsanity
- Member
- Posts: 45
- Joined: Wed Sep 17, 2008 3:59 am
- Location: Germany
Re: get memory map from grub 2
I also use GRUB 2 and I recommend using this header just to be sure that you don't have any errors in your structs (I translated it to FreeBASIC to use it).
Looking at your code this caught my eye:
Where does that sizeof(u32int) come from? Replacing that line with this should work:
Also, this should happen AFTER the debug output, otherwise you're skipping the first entry of the map! To me it seems that you're destroying your mmap-Pointer with that sizeof(u32int) before the output.
edit: To minimize the chance that this is the fault of GRUB, try copying your kernel into this image. It's an outdated test-image of my kernel but the memory-map stuff worked 100%, so if it fails with this image, the problem is most likely hidden in your code.
Looking at your code this caught my eye:
Code: Select all
mmap = (memory_map_t_kernel*) ( (u32int)mmap + mmap->size + sizeof(u32int));
Code: Select all
mmap++;
edit: To minimize the chance that this is the fault of GRUB, try copying your kernel into this image. It's an outdated test-image of my kernel but the memory-map stuff worked 100%, so if it fails with this image, the problem is most likely hidden in your code.
Re: get memory map from grub 2
I tried it with your ISO grub image, but I got still no memory map.
Thanks for your tipp with the ++mmap;.
I tried a different loader + loader linker and got a different output of the kernel.
I think my kernel loader + link table are not right:
So the error is here I think.
If someone could look at it, this would help me.
Thanks for your tipp with the ++mmap;.
I tried a different loader + loader linker and got a different output of the kernel.
I think my kernel loader + link table are not right:
Code: Select all
[BITS 32]
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 dword eax ; pass Multiboot magic number
push dword ebx ; ebx pass Multiboot info structure
;hlt
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
; linker table =======================================================================
/* The bootloader will look at this image and start execution at the symbol
designated as the entry point. */
ENTRY(_loader)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS
{
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
loaded at by the bootloader. */
. = 1M;
/* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.MultiBootHeader)
*(.text)
}
/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
/* The compiler may produce other sections, by default it will put them in
a segment with the same name. Simply add stuff here as needed. */
}
If someone could look at it, this would help me.
Re: get memory map from grub 2
I putted the following lines in my kernel C file:
The if statement executes and prints out 8 KB of RAM!!!
I think my mbt pointer got from GRUB contains nothing but trash.
This _is_ the problem.
How can I fix this?
Code: Select all
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) /* Check if the bit BIT in FLAGS is set. */
if (CHECK_FLAG (mbt->flags, 0))
{
ltoa ((u32int) mbt->mem_lower + (u32int) mbt->mem_upper, buf, 10);
terminal_writestring ("memory in KB: ");
terminal_writestring (buf);
terminal_writestring ("\n");
}
I think my mbt pointer got from GRUB contains nothing but trash.
This _is_ the problem.
How can I fix this?
Re: get memory map from grub 2
Stop! this was the wrong output.
It shows 523836 KB RAM. I setted 512 MB RAM in Bochs.
But the memory map is still not valid.
It shows 523836 KB RAM. I setted 512 MB RAM in Bochs.
But the memory map is still not valid.
Re: get memory map from grub 2
I found a correct i64toa () function and now the right memory map values are shown!
This is solved now.
I checked the output of my kernel with the GRUB memory map printed with:
lsmmap.
They are the same.
This is solved now.
I checked the output of my kernel with the GRUB memory map printed with:
lsmmap.
They are the same.