End of kernel pointer retrieval without ASM

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
Candamir

End of kernel pointer retrieval without ASM

Post by Candamir »

After reading the post http://www.mega-tokyo.com/forum/index.php?board=1;action=display;threadid=9100, I believe to have understood what the proceeding for the retrieval of the position of the end of the kernel is:

1. Declare this at the end of your linker script:

Code: Select all

.endkernel ALIGN(0x1000) : AT(ADDR(.endkernel) - 0xC0000000)
    {
        __kernel_end = .;
   LONG(0xCAFEBABE);
    }
OK, the ALIGN(0x1000) isn't really necessary, but all my sections are aligned, so it's like a kind of tradition :P

2. To actually retrieve the value & position, call the following ASM method:

Code: Select all

extern __kernel_end
mov eax,[__kernel_end]
After this, this ASM stub must invoke a C function:

3. The C-function, with a layout like this:

Code: Select all

extern unsigned long __kernel_end;

void kernel_end()
{
    kprint("__kernel_end = %x\n",__kernel_end);
    kprint("kernel ends at %x\n",&__kernel_end);
}
Note: Thanks to Pype.Clicker, as he was the one that did most of the explaining in that thread.

After studying this code, I came up with a question: Wouldn't it be possible to skip the ASM step in some way? Of course, this only applies if the above code works as I think it does...

Thanks,

Candamir
proxy

Re:End of kernel pointer retrieval without ASM

Post by proxy »

of course it's possible to skip the asm. in fact at first glance your c code seems to do this already, i see no reasy why your ASM code is at all neccessary.

proxy
guest

Re:End of kernel pointer retrieval without ASM

Post by guest »

Note that you don't need to create a new section in the linkscript for this (in fact, doing so is probably going to waste a whole page because of the ALIGN), you can do this instead:

Code: Select all

.data ....
{
      ...
      __kernel_end = .;
      LONG(__end_of_kernel__);
}
...
__end_of_kernel__ = .;
}
This effectively creates a global variable that stores the value of the end of the kernel (ie. "extern intptr_t __kernel_end; printf("%x", __kernel_end);") - because it's a variable you can also modify it if you change the size of the kernel at runtime (eg. deallocate the init code)
Candamir

Re:End of kernel pointer retrieval without ASM

Post by Candamir »

I didn't quite understand the usefulness of what you explained in your last paragraph, but anyway, I removed the ALIGN part. It was there because before this method, I had four consecutive LONG(0xCAFEBABE)'s in a row and the kernel searched for them... (I know it's ridiculous, laugh at me :-[), but to make the search faster, I aligned the bytes... But now I got this variable trick, the symbol doesn't need to be aligned anymore.

Candamir
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:End of kernel pointer retrieval without ASM

Post by Colonel Kernel »

Here's how I do it:

Code: Select all

/// \brief  Returns the physical address of the first byte after the
/// kernel image (including its BSS section).
///
/// \return the physical address of the first byte after the kernel.
static inline phys_addr_t MM_getKernelEndPhysAddr()
{
    extern uint8_t BssEndPhys;

    // MAINTENANCE NOTE: This looks really strange, but it's the
    // way the linker works. BssEndPhys is just a symbol -- it
    // doesn't represent actual storage. The value of the symbol
    // (i.e. -- the address of the variable) is what we're after.
    // Note that it is already a physical address, but it comes in
    // the size of a virtual address. This implementation does not
    // use PAE, so this is ok.
    return (phys_addr_t) &BssEndPhys;   // DON'T FORGET THE
                                                      // ADDRESS-OF
                                                      // OPERATOR!!
}
Here's the linker script (note that I'm using flat binary, not elf):

Code: Select all

ENTRY (StartPrecursor)

OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0xE0000000 + 0x00100000;

    .text :
    {
        *(.text)
        *(.rodata*)
    }

    .data ALIGN (0x1000) :
    {
        *(.data)
    }

    .bss :
    {
        *(COMMON)
        *(.bss)
        BssEndPhys = . - 0xE0000000;   /* We want the physical
                                                        address here. */
    }
}
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
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 pointer retrieval without ASM

Post by Pype.Clicker »

the ASM part can safely be omitted: it was just there to show how to access the stuff if you don't use C but ASM. You can of course very well use a symbol such as "end_bss" rather than my laughable "cafebabe". The advantage of "cafebabe" is that it's magic: if you're at the wrong place you'll show another value. Once you checked it worked and how you can use the extern, address_of, etc. to have it working, you can revert to a more traditional "__endbss=.", of course (that will save room in your kernel :) )
Bob the Avenger

Re:End of kernel pointer retrieval without ASM

Post by Bob the Avenger »

using magic is a good thing (tm) and theres worse ways to waste almost all a page ;)
guest

Re:End of kernel pointer retrieval without ASM

Post by guest »

Bob the Avenger wrote: using magic is a good thing (tm) and theres worse ways to waste almost all a page ;)
You're not leaving me with a good impression. The use of "magic" typically indicates that you couldn't think of a good way to do something so just hacked it on. (Example: Linkscript pointers versus just ramming a random key and incrementally searching for it using a while loop - something which has no runtime cost versus something which has significant runtime costs)
Bob the Avenger

Re:End of kernel pointer retrieval without ASM

Post by Bob the Avenger »

guest wrote: Linkscript pointers versus just ramming a random key and incrementally searching for it using a while loop - something which has no runtime cost versus something which has significant runtime costs
I did not comment on the use of incrimentally searching, just on the use of magic, given that is a good way of verifying certain things. If i were to use such a system i would use a linkscript pointer which points to a magic value, thus adding a method of verification that my label is correct and removing the need for searching the whole executable.
Post Reply