Kernel memory usage...

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
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Kernel memory usage...

Post by mike13 »

Hey, I have a basic kernel booting from grub in an ELF format at location: 0x00100000 and I was wondering... how do I go about obtaining the amount of memory my kernel is using up... I figured I could get this info from grub, but it seems that some of the bits in the 'flags' section aren't being set (specifically bits 3,4,5) I can understand why '3' isn't set, because I'm not loading any other kernel modules... but can someone help me with this?
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

Hello mike,
I hope you did ask GRUB for the memory map ? Unless you set bit one of the multiboot header it is assumed that a map isn't needed..

regards,
gaf
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Post by mike13 »

Um, yes... I do have the GRUB memory map... how would I go about translating those seemingly random-looking addresses into something I can understand? like where my kernel ends (to name one example).

Thanks in advance :)
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

Ah, I guess I just got you wrong..
How would I go about translating those seemingly random-looking addresses into something I can understand?
That really depends on your system design. The most common way is probably to feed the physical memory-manager with the map, so that only non-reserved regions are used for allocations. You can do this by walking through the memory-map and adding each entry to your memory-manager's stack/list/bitmap.
Like where my kernel ends (to name one example).
From what I know you can't get such information from the memory map: It's just meant to describe which areas of memory are available and which are reserved. To get your kernel's size, the linker-script can be used:

Code: Select all

SECTIONS
{
  kernel_start = .;

  .text  {}
  .data  {}
  .bss   {} 

  kernel_end = .;
}
Both symbols can be accessed from your code if you declare them as extern in your source-files. By substracting kernel_end from kernel_start, the size of the image can be calculated.

regards,
gaf
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Post by mike13 »

Ah, ok... I noticed that the borealis OS did that but I wasn't sure if it was that simple... I'll try that out and let ya know how it turns out. Thanks
User avatar
Daedalus
Member
Member
Posts: 74
Joined: Sun Oct 16, 2005 11:00 pm
Location: Australia
Contact:

Post by Daedalus »

A little off topic, but you're working off Borealis too ?

I've done a fair bit of work based on that kernel, put my own MM in (still working on it), edited the MultibootLoader, implemented IPC, and have a template daemon skeleton and some of my own daemons (mouse, vga graphics.)

Also worked in a bit more to the libc, but thats negligable.
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Post by carbonBased »

gaf wrote: Both symbols can be accessed from your code if you declare them as extern in your source-files. By substracting kernel_end from kernel_start, the size of the image can be calculated.
Actually, you'd subtract the addresses of these, if I recall correctly, as they are not actually variables, but just symbols. They occupy no space.

In other words:
kernelSize = (uint32)&kernelEnd - (uint32)&kernelStart;

Cheers,
Jeff
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Post by mike13 »

Hey, it's me again :) yeah I finally had some time today to fiddle with this issue, but I'm still somewhat unsure as to how I can access these symbols in my C code here is my linker script, I am working off of bran's kernel tutorial on osdever.net

linker.ld:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
kernel_start = 0x100000;
SECTIONS
{
  .text kernel_start : AT(kernel_start) {
    code = .;
    *(.text)
    . = ALIGN(4096);
  }
  .data : AT(kernel_start + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(kernel_start + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  kernel_end = .;
}
If someone could provide me with some more explanation as to how I can access these values, that would be awesome, I tried to declare them as externs in my C code, but I would always get a compiler error reporting that I was referencing an undefinded symbol. Thanks in advance!

Code: Select all

extern unsigned long kernel_start;
extern unsigned long kernel_end;

Code: Select all

obj\main.o(.text+0x13f8):main.c: undefined reference to `_kernel_end'
obj\main.o(.text+0x13fd):main.c: undefined reference to `_kernel_start'
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Post by carbonBased »

What steps are you taking to build and link?

The linker script should define those symbols... you shouldn't be getting undefined symbols. You're sure you're specifying -T <script> when linking all the objects together (including the one that references these variables)?

Are you linking elf, coff, or what object format? The ABI for ELF states no prepending underscores, and your compiler appears to be looking for them (so I assume you're using coff?)... in that case, you probably need to prepend underscores in your symbols as well, perhaps? I'm not sure if LD will do this for you... I would suspect not (objdump would tell for sure).

--Jeff
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Post by mike13 »

Ok, I got rid of the undefined symbol error by adding an underscore to my vars in my linker script, however... The values for the start and end of my kernel are incorrect:

_kernel_start = 0x107000BC (according to my script it should be 0x100000)
_kernel_end = 0x0 (I don't see how this could be)

Code: Select all

nasm -f aout -o obj\start.o start.asm
nasm -f aout -o obj\ints.o ints.asm

gcc -Wall -O -nostdlib -fstrength-reduce -fomit-frame-pointer -finline-functions -fno-builtin -I./include -c -o main.o main.c

copy main.o obj\
del main.o

ld -T link.ld -o obj\kernel.bin obj\start.o obj\ints.o obj\main.o
Oh, and my kernel is linked together as a flat binary, but GRUB reads it as an ELF, so... not exactly sure why that is, but it works so far :) So any ideas as to why I'm receiving the wrong values? Thanks in advance.

*EDIT: Ok, I wasn't thinking, I know why _kernel_end is 0, and thats because I'm not setting it to anything in my linker script, but how exactly should I set it? how do I figure out how long my text, data and bss sections are?
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Post by carbonBased »

How have you determined their values? Are you printing them out as if they are integers?

As I mentioned above, these are actually just labels. They contain no value, but they do, however, have a location. As such, you shouldn't be printing/using their value, but rather their address:

kernelSize = (uint32)&kernelEnd - (uint32)&kernelStart;

--Jeff
mike13
Posts: 11
Joined: Sat Jun 24, 2006 8:38 am

Post by mike13 »

Hey, yeah... I forgot that they didn't actually store the value, and tried to access them directly, but now its working great my kernel currently takes up 34KB of memory! Ok, now that that is resolved... should I also be trying to get the values of the text, data, and bss sections? and if so, what is their importance and can you refer me to a document or article that goes a bit more in depth about their purposes? I've tried some searches but I'm not entirely sure what I'm looking for, I really appriciate it!
Post Reply