Kernel End

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
pacman
Posts: 17
Joined: Sun Jul 08, 2007 10:23 am

Kernel End

Post 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
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post 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
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

:) You beat me on the stack switching one, though!
zerosum
Member
Member
Posts: 63
Joined: Wed Apr 09, 2008 6:57 pm

Post 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 ;-)
pietro10
Posts: 12
Joined: Wed Feb 13, 2008 10:06 pm

Post 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!
PGOS. It's my hand-written OS. Deal with it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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
pietro10
Posts: 12
Joined: Wed Feb 13, 2008 10:06 pm

Post 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! :-P
PGOS. It's my hand-written OS. Deal with it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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.
pietro10
Posts: 12
Joined: Wed Feb 13, 2008 10:06 pm

Post 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

Code: Select all

end = .; _end = .; __end = .;
in the linker script,

Code: Select all

extern int end;

p = &end
doesn't work, but

Code: Select all

p = end;
does.

The V7 manuals win again!
(and maybe I should go to my normal, bloated man pages)
PGOS. It's my hand-written OS. Deal with it.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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

Code: Select all

end = .; _end = .; __end = .;
in the linker script,

Code: Select all

extern int end;

p = &end
doesn't work, but

Code: Select all

p = end;
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.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Post 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.
froggey
Member
Member
Posts: 38
Joined: Tue Oct 17, 2006 10:21 pm
Location: Hampshire, UK

Post 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.
Post Reply