end of kernel

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
McZ

end of kernel

Post 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 = .;
}
iammisc

Re:end of kernel

Post by iammisc »

you are getting 0x24 because that is the offset from the base, 0x100000
xenos

Re:end of kernel

Post 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);
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:end of kernel

Post 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. ;)
Every good solution is obvious once you've found it.
McZ

Re:end of kernel

Post 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)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:end of kernel

Post 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;"
McZ

Re:end of kernel

Post 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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:end of kernel

Post 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 :P
McZ

Re:end of kernel

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:end of kernel

Post 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).
osbios

Re:end of kernel

Post by osbios »

Use ASM:

Code: Select all

Code...
END_OF_KERNEL:
;D
McZ

Re:end of kernel

Post 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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:end of kernel

Post 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.
B.E

Re:end of kernel

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