Page 1 of 1
Kernel End
Posted: Wed Apr 09, 2008 4:37 pm
by pacman
Hi
By using GRUB as my bootloader, is there any way for my kernel, during run time, to determine the physical address of where it 'ends' (the address which, if incremented by 1, would point to the beginning of free space which extends untill the end of physical memory).
Thanks
Posted: Wed Apr 09, 2008 4:59 pm
by AJ
Hi,
It's not specifically using GRUB, but the easiest way is probably to insert a symbol at the end of your linker script and reference that.
Cheers,
Adam
Posted: Wed Apr 09, 2008 5:03 pm
by Combuster
Tried using a linker script? there are many examples available on the forum that help you do what you want.
edit: AJ beat me to the point... that's a first
Posted: Wed Apr 09, 2008 5:07 pm
by AJ
You beat me on the stack switching one, though!
Posted: Wed Apr 09, 2008 7:16 pm
by zerosum
If you use a linker script, just remember that you need to get the ADDRESS of the symbol, not the contents..... I was having a rather blonde day when I tried this and it took me a while to figure it out
Posted: Thu Apr 10, 2008 11:03 am
by pietro10
Here's an attempt to explain.
In the UNIX system, the linker (ld) placed a symbol end (_end in Assembly) whose value is defined as the first address above the end of the program:
Code: Select all
extern int end;
main()
{
printf("highest address in progrram memory: %d\n", end - 1);
}
The GNU linker lets you do something like this with the linker script:
Code: Select all
SECTIONS
{
.text : { /* ... */ }
.data : { /* ... */ }
.bss : { /* ... */ }
end = .; _end = .; __end = .;
}
Now you can do the same thing with your kernel.
Hope that helps!
Posted: Thu Apr 10, 2008 6:22 pm
by pcmattman
Hi,
It's not
Code: Select all
printf("highest address in progrram memory: %d\n", end - 1);
That gives you the value at the end of the kernel, not the address (which is what you want).
This is correct (and also hex is better for addresses):
Code: Select all
printf("highest address in progrram memory: %d\n", *((uint32_t*) &end) );
Just thought I'd mention that small detail.
EDIT: This is basically what this line means:
If you use a linker script, just remember that you need to get the ADDRESS of the symbol, not the contents
Posted: Mon Apr 14, 2008 6:18 pm
by pietro10
pcmattman wrote:Hi,
It's not
Code: Select all
printf("highest address in progrram memory: %d\n", end - 1);
That gives you the value at the end of the kernel, not the address (which is what you want).
This is correct (and also hex is better for addresses):
Code: Select all
printf("highest address in progrram memory: %d\n", *((uint32_t*) &end) );
Just thought I'd mention that small detail.
EDIT: This is basically what this line means:
If you use a linker script, just remember that you need to get the ADDRESS of the symbol, not the contents
Stupid V7 manuals!
Posted: Mon Apr 14, 2008 6:38 pm
by pcmattman
Stupid V7 manuals!
It might be that you can access end and that the symbol holds the correct address in V7, but if you do it in your own linker script way don't expect the same.
Posted: Sat Apr 19, 2008 11:37 am
by pietro10
pcmattman wrote:Stupid V7 manuals!
It might be that you can access end and that the symbol holds the correct address in V7, but if you do it in your own linker script way don't expect the same.
Guess what: you're wrong. Given
in the linker script,
doesn't work, but
does.
The V7 manuals win again!
(and maybe I should go to my normal, bloated man pages)
Posted: Sat Apr 19, 2008 2:40 pm
by JamesM
pietro10 wrote:pcmattman wrote:Stupid V7 manuals!
It might be that you can access end and that the symbol holds the correct address in V7, but if you do it in your own linker script way don't expect the same.
Guess what: you're wrong. Given
in the linker script,
doesn't work, but
does.
The V7 manuals win again!
(and maybe I should go to my normal, bloated man pages)
That's very strange, because it shouldn't. Methinks theres something else going on here.
Posted: Sat Apr 19, 2008 9:09 pm
by thepowersgang
the _end symbol is not an address like a label in an assembler file, it is a value that is set to the end of kernel address by the linker and so therefore taking the address of it is pointless. What you want is the value.
Posted: Sun Apr 20, 2008 3:21 am
by froggey
thepowersgang wrote:the _end symbol is not an address like a label in an assembler file, it is a value that is set to the end of kernel address by the linker and so therefore taking the address of it is pointless. What you want is the value.
Wrong, assuming you're using binutils. Symbols created by the linker are exactly like labels in asm.
From the ld manual
http://sourceware.org/binutils/docs-2.1 ... rence.html
Linker scripts symbol declarations, by contrast, create an entry in the symbol table but do not assign any memory to them. Thus they are an address without a value. ... Hence when you are using a linker script defined symbol in source code you should always take the address of the symbol, and never attempt to use its value.