Page 1 of 1
Kernel size form linker.
Posted: Wed Jan 03, 2007 11:17 pm
by smbogan
Anyone aware of a way of asking the linker what the total size of my kernel is and having the linker put it in a variable? Or a way of doing something similiar...(asking Grub...or something)?
Posted: Wed Jan 03, 2007 11:25 pm
by JackScott
If you use a linker script, you should be able to (afaik) put a symbol at the start of your kernel image (or very close to it), and one at the end, and then calculate the size at runtime.
I'm not a master of linker scripts (I got mine out of the Wiki, and it's served me well since), so I can't give you an exact answer, I'm sorry. If somebody else can show what you need to do, I would be very interested as well!
Posted: Thu Jan 04, 2007 12:59 am
by Solar
If you took the linker script from
BareBones, that already defines two symbols - _sbss (start bss) and _ebss (end bss). You shoult already know the starting point of your kernel (since you loaded it somewhere, did you?). _sbss - START is the size of your kernel binary, _ebss - START is the total size including BSS section (zero-initialized data).
Posted: Thu Jan 04, 2007 5:00 am
by Ready4Dis
Solar wrote:If you took the linker script from
BareBones, that already defines two symbols - _sbss (start bss) and _ebss (end bss). You shoult already know the starting point of your kernel (since you loaded it somewhere, did you?). _sbss - START is the size of your kernel binary, _ebss - START is the total size including BSS section (zero-initialized data).
Yes, but how do you put that into a variable in the ASM code so you can store the size of the kernel in a variable, i think that's what he's trying to do.
Posted: Thu Jan 04, 2007 5:18 am
by m
Yayyak wrote:If you use a linker script, you should be able to (afaik) put a symbol at the start of your kernel image (or very close to it), and one at the end, and then calculate the size at runtime.
I'm not a master of linker scripts (I got mine out of the Wiki, and it's served me well since), so I can't give you an exact answer, I'm sorry. If somebody else can show what you need to do, I would be very interested as well!
How can you avoid using that symbol accidentally within a certain part of the image?And if you wanna avoid it by using a long (long
) symbol to reduce the rate,it may take long at each runtime.
VESA VBE 3.0 has used a similar "trick" to indicate the protected mode interface location,but the string is short because it's only used within the BIOS code and data.
I think counting with section symbols or simple labels at compiling time may be more reasonable.
Posted: Thu Jan 04, 2007 5:24 am
by Ready4Dis
m wrote:VESA VBE 3.0 has used a similar "trick" to indicate the protected mode interface location,but the string is short because it's only used within the BIOS code and data.
I think counting with section symbols or simple labels at compiling time may be more reasonable.
Umm..they have symbol to tell you where it starts, he wants a symbol from the linker to inform his bootloader how big the kernel is (or maybe a memory manager?). If his bootloader doesn't know anything of the file system, and only loads the kernel as a flat binary file, how does it know how much to load, and even if it loads it from disk, how does it know how large the BSS is, you need to use variables from the linker in this case, since it's the only thing that knows this information before it's lost forever, however I don't know how to use them, I ran into a similar problem, but couldn't find an answer.
Posted: Thu Jan 04, 2007 5:26 am
by Solar
Ready4Dis wrote:Yes, but how do you put that into a variable in the ASM code so you can store the size of the kernel in a variable, i think that's what he's trying to do.
At compile time, not at all (obviously), because the symbol values are not determined before linker time.
Other than that, _sbss and _ebss can be accessed just the same way as _start or _main... just pick your favourite assembler's syntax for substracting one address value from another...
Posted: Thu Jan 04, 2007 5:33 am
by Ready4Dis
Solar wrote:
Other than that, _sbss and _ebss can be accessed just the same way as _start or _main... just pick your favourite assembler's syntax for substracting one address value from another...
I have tried that, it complains that the size isn't defined or some such nonsense. I tried __bss - start or something like that (forget the exact var names off the top of my head), and tried to store it into a DD, wouldn't link. I declared them both as external in my ASM file as well.
Code: Select all
[extern __bss]
start:
Kernelsize DD __bss - start
It was pretty much to that effect, but complained of something and wouldn't link.
Posted: Thu Jan 04, 2007 7:17 am
by urxae
Ready4Dis wrote:Code: Select all
[extern __bss]
start:
Kernelsize DD __bss - start
You have 2 underscores at the start of __bss.
Did you also try with 1 or 0 _s at the start of the symbol?
Posted: Thu Jan 04, 2007 10:10 am
by smbogan
When I use ld, does it link files in the order I tell it to? So could I just make a final.asm that has a label in it, and get that address in my C code?
I know where my kernel starts, obviously, because I loaded it there, but the length of it changes every time I compile the thing. The way I know of getting the length are with a FAT12 driver (which I don't have at this point in time, and don't want to initialize until after my memory manager is up). I will try the above ASM code and let you know if it works.
Posted: Thu Jan 04, 2007 10:46 am
by smbogan
Well, I figured out a solution, I think. At the end of my linker script is:
So, this is sort of a 'duh' situation. It turns out in the AOUT kludge, I tell Grub the size of my kernel. So all I do is push that to the stack to pass it to my C kernel, as such:
Code: Select all
stublet:
extern _main
push ebx ;Address for the multiboot header from GRUB.
push kernel_end
call _main
jmp $
Then, in my C code:
Code: Select all
void main(void * kernel_end_adr, multiboot_info_t* mbd)
{
kernel_end = kernel_end_adr;
Whoala! My kernel size is kernel_end - 0x100000 (where GRUB loaded it).
Posted: Thu Jan 04, 2007 12:33 pm
by Ready4Dis
urxae wrote:Ready4Dis wrote:Code: Select all
[extern __bss]
start:
Kernelsize DD __bss - start
You have 2 underscores at the start of __bss.
Did you also try with 1 or 0 _s at the start of the symbol?
I tried it with only one underscore as well, i typed it exactly as it was in my linker script, I think something else was messing it up maybe, I will try to play with it some more when I get home. I'm not to worried about it, it was actually for my device driver interface, i was going to set the size of the file in it's header, that way I can load my basic drivers consecutively off the disk without knowing the file system, and I can store the size of the BSS as well, but I am going to start using a relocateable file format anyways, so all that information is in the header, so i'm not to worried about it anymore.
Posted: Thu Jan 04, 2007 10:45 pm
by Solar
smbogan wrote:When I use ld, does it link files in the order I tell it to?
Yes it does, but according to the linker script - i.e., different sections of the linked files go different places. Unless you really know what you're doing, your symbols might not end up where you expect them to. (objdump is a real help here.)