Page 1 of 1
end of kernel
Posted: Sun Feb 26, 2006 4:15 pm
by McZ
I have put an kernel_end = .; at the end of my linker script so I know where the end of the kernel is.. but how can I use the kernel_end ?
I have tried this:
Code: Select all
extern void kernel_end;
...
char end = (char)&kernel_end;
kprintf("end of kernel 0x%x", end);
the above prints 0x24, this doesn't look correct to me maybe kernel_start + 0x24 is correct.. I have tried with long and int instead of char for the end variable but then I get nothing.
linker.ld
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS
{
. = 0x100000;
.setup :
{
*(.setup)
}
. += 0xC0000000;
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
}
.data ALIGN (4096) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
*(.rodata*)
}
.bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000)
{
*(COMMON*)
*(.bss*)
}
kernel_end = .;
}
Re:end of kernel
Posted: Sun Feb 26, 2006 9:18 pm
by iammisc
you are getting 0x24 because that is the offset from the base, 0x100000
Re:end of kernel
Posted: Mon Feb 27, 2006 1:32 am
by xenos
Your kernel_end is much larger than 255 bytes, so it won't fit into a char. Try this instead:
Code: Select all
extern void kernel_end;
...
long end = (long)&kernel_end;
kprintf("end of kernel 0x%x", end);
Re:end of kernel
Posted: Mon Feb 27, 2006 1:59 am
by Solar
Ahem...
Code: Select all
void * end = &((char)kernel_end);
printf( "end of kernel: %p\n", end );
IMHO and without testing. But [tt]kernel_end[/tt] is not a [tt]long[/tt], and [tt]end[/tt] is not an integer.
Re:end of kernel
Posted: Mon Feb 27, 2006 6:31 am
by McZ
I user the char because that was what used in some other code I found, altough I have tried with unsigned long/int & signed long/int too but without any success.
I played with objdump and got this with objdump -x kernel.bin
Code: Select all
...
c010a024 g *ABS* 00000000 kernel_end
...
so as someone said the value will not fit in one char (only 24 fits) I thougth so too but if I use a unsigned long I get 0xE (I'm checking my kprintf now to see if there is something wrong there)
Re:end of kernel
Posted: Mon Feb 27, 2006 6:36 am
by Pype.Clicker
okay. whatever you define "kernel_end" in your code, the linker script will just assign the _address_ of that variable. That is, you shouldn't try to retrieve the _value_ of kernel_end.
E.g. Clicker has
Code: Select all
SECTIONS
{
. = 0x00100000;
__start_image = .;
__start_init = .;
...
in "barebones.ld" ... then
Code: Select all
void __end_bss(void);
void __start_system(void);
void __start_image(void);
which lets me cast __start_system to a void pointer as needed. If i had "extern char __start_system;" then the proper use would have been "void* start_of_kernel = &__start_system;"
Re:end of kernel
Posted: Mon Feb 27, 2006 6:57 am
by McZ
Pype.Clicker wrote:
you shouldn't try to retrieve the _value_ of kernel_end.
Why? so I can't print the address of the kernel_end then
So then this code I found somewhere would be valid then
Code: Select all
extern void kernel_end;
...
char *ptr = (char*)&kernel_end;
...
will the ptr actually point to the end of the kernel so I can start write something there?
is there any way to validate so that ptr actually is the correct address?
Re:end of kernel
Posted: Mon Feb 27, 2006 9:04 am
by Pype.Clicker
okay ... let's put it differently.
Code: Select all
// the linker script
SECTIONS {
...
__kernel_end = .; // assign current address to 'kernel_end' symbol
LONG(0xcafebabe); // generate 4 bytes with value "CAFEBABE" in the program
}
now, __kernel_end can be declared as an unsigned long which has the value 0xcafebabe, that is ...
Code: Select all
extern __kernel_end
mov eax,[__kernel_end]
will load eax with 0xcafebabe
and
Code: Select all
extern unsigned long __kernel_end;
void kmain()
{
kprint("__kernel_end = %x",__kernel_end);
}
will print out "cafebabe" on screen.
Pretty cool, but absolutely not what we want. What we want is to know _where_ the kernel ends ... and that is the address of __kernel_end:
Code: Select all
void kmain()
{
kprint("__kernel_end = %x\n",__kernel_end);
kprint("kernel ends at %x\n",&__kernel_end);
}
will now print something like "__kernel_end = cafebabe ... kernel ends at c010a024
Let's say you want to use that in order to initialise some memory manager:
Code: Select all
void mmInit(void *lowest_avl_byte, void* highest_avl_byte);
void kmain()
{
kprint("__kernel_end = %x\n",__kernel_end);
kprint("kernel ends at %x\n",&__kernel_end);
mmInit(&__kernel_end, size_of_RAM);
}
should do it. Hope that makes it clearer.
btw, i'm off for a cup of 0xcoffee ... anyone wants some
Re:end of kernel
Posted: Mon Feb 27, 2006 9:37 am
by McZ
Verry good explaination.
but I can't get LONG(0xcafebabe) to work >:(
Code: Select all
/usr/cross/bin/i586-elf-ld:linker.ld:32: parse error
that is exactly the line where I have LONG(0xcafebabe) am I doing something wrong? I have looked at the manual for LD "using LD, the GNU linker" and there it says I can use LONG(expression)
btw, I don't like 0xc0ffee so I take a 0xbeef instead ::)
EDIT: now I can kprintf the vaule of kernel_end but I can't get the address from it if I do I get a zero value.
Re:end of kernel
Posted: Mon Feb 27, 2006 10:03 am
by Pype.Clicker
hmm ... i may have oversimplified things. actual code i have in clicker is
Code: Select all
SECTIONS
{
// stuff
. = 0x00800000;
__start_system = .;
.system :
{
// other stuff
. = ALIGN(65536);
LONG(0xcafebabe);
}
__end_system = .;
__end_image = .;
}
it might happen that LONG(xxx) is only allowed within an output section (and that would make sense: while you can have symbols pointing "out" of the loadable bits, adding bits in no section sounds like an error).
Re:end of kernel
Posted: Mon Feb 27, 2006 10:56 am
by osbios
Re:end of kernel
Posted: Mon Feb 27, 2006 11:00 am
by McZ
I made my own .end section altough I don't know if I can write like this but the code compiles and if I print kernel_end it will output cafebabe.
BUT I still can't get the correct address of kernel_end all I get is zero.
Code: Select all
.end ALIGN (4096) : AT(ADDR(.end) - 0xC0000000)
{
kernel_end = .;
LONG(0xCAFEBABE);
}
EDIT: Now I have found out that the size of the kernel is 44kb if I calculate kernel_end - 0xC0000000 can this be true? kernel.bin is 21kb
Re:end of kernel
Posted: Mon Feb 27, 2006 4:28 pm
by Pype.Clicker
if your kernel.bin is actually an elf file, that could very well be:
- alignment instructions make the loader insert "padding" bytes that are not present in the binary
- .bss section (that is, uninitialized data) do not need to be present in the binary, but the loader will still allocate it.
In both case, "objdump -x kernel.bin" should give you more hints about what's going on (assuming .bin is not a raw binary as it looks to be). If it's really a binary, try asking your linker for a map of the generated binary: that too could give you more hints on what's going on.
Re:end of kernel
Posted: Mon Mar 13, 2006 8:15 pm
by B.E
McZ wrote:
Code: Select all
extern void kernel_end;
...
char *ptr = (char*)&kernel_end;
...
Isn't better to declare kernel_end as as void* like this
Code: Select all
extern void kernel_end;
...
char *ptr = (char*)&kernel_end;
...