Page 1 of 1
Kernel memory usage...
Posted: Fri Jul 07, 2006 1:38 am
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?
Posted: Fri Jul 07, 2006 11:41 am
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
Posted: Sat Jul 08, 2006 12:54 pm
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
Posted: Sat Jul 08, 2006 3:07 pm
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
Posted: Sat Jul 08, 2006 3:52 pm
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
Posted: Mon Jul 10, 2006 3:14 am
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.
Posted: Tue Jul 11, 2006 12:08 pm
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
Posted: Fri Jul 21, 2006 4:09 pm
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'
Posted: Fri Jul 21, 2006 7:41 pm
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
Posted: Fri Jul 21, 2006 8:23 pm
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?
Posted: Sat Jul 22, 2006 8:02 am
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
Posted: Sat Jul 22, 2006 11:44 pm
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!