Page 1 of 1
End of kernel pointer retrieval without ASM
Posted: Fri Jun 16, 2006 6:42 pm
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
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
Re:End of kernel pointer retrieval without ASM
Posted: Fri Jun 16, 2006 7:47 pm
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
Re:End of kernel pointer retrieval without ASM
Posted: Fri Jun 16, 2006 11:13 pm
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)
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 12:17 am
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
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 12:47 am
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. */
}
}
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 6:37 am
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
)
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 6:49 am
by Bob the Avenger
using magic is a good thing (tm) and theres worse ways to waste almost all a page
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 10:46 am
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)
Re:End of kernel pointer retrieval without ASM
Posted: Sat Jun 17, 2006 11:17 am
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.