Page 1 of 1

Finding the end of the kernel

Posted: Tue Mar 22, 2016 4:58 am
by Mikumiku747
Just a quick question, I'm beginning to get into memory management with my kernel, and was wondering if there was a way to make a symbol which points to the end of my kernel, so I can know where in physical memory I can begin managing the computer's memory myself. My kernel gets loaded with GRUB at 1M, do I need to put something in my linker file, or in my bootstrap, or what?

My linker file and bootstrap are pretty similar to bare-bones, just adjusted the stack size and passed in the multiboot bootloader info into the kernel (why isn't that included in the bootstrap part of barebones tutorial any more, most people load the barebones through grub?)

Thanks for reading,
- Mikumiku747

Re: Finding the end of the kernel

Posted: Tue Mar 22, 2016 5:43 am
by Octocontrabass
You can create a symbol in your linker script that always comes last (and therefore points to the end of your kernel). You can then reference that symbol from within your code.

You might also find useful information here.

Re: Finding the end of the kernel

Posted: Tue Mar 22, 2016 5:43 am
by max
Hello Mikumiku747,

add a symbol at the very end of your linker file that denotes the end of your kernel. For example:

Code: Select all

endKernel = ALIGN(4K);
(see https://github.com/maxdev1/ghost/blob/m ... -kernel.ld)

In your code, you can then access this symbol. Take care that you use the address of this symbol as shown below, and not the symbol itself.

Code: Select all

extern "C" void* endKernel;
address = &endKernel;
A little explanation to what this does: when you define a variable in your global scope in your source file, it is a symbol and reserves some space in your executable (depending on its type). The linker will normally just place this inside the bss (if not initialized) or data section (if it has an initial value). Due to our definition in the linker script, the linker knows that we want this symbol to be at the very end of the binary. Therefore it will just be placed somewhere else. The extern "C" is only necessary when you do C++, it tells the compiler to not mangle the variables name.

Greets,
Max

Re: Finding the end of the kernel

Posted: Tue Mar 22, 2016 5:49 am
by iansjack
Alternatively, look at the section headers from the Elf file to see where it is loaded and how big it is.

Re: Finding the end of the kernel

Posted: Wed Mar 23, 2016 11:48 am
by ~
Image >> Watch the text recording for this program << Image


It's very easy with assembly for example. You just need to get the current position at the very end of the code with $ and align it to 16 bytes to have an optimized alignment right after the actual binary.

Below you can see a kernel skeleton source that shows you the overall code structure of a typical basic kernel and how to align it. Then you can also see a text recording which you can replay if you want to see how the code was written it case you find difficult to understand the listing (so you can see the logical sequence and what the code means in a better way):

At the very end:

Code: Select all

align 16
  _KERN_END_STATIC equ $+4+12            ;Symbol for the 16-byte aligned size
         _KERN_END  dd _KERN_END_STATIC  ;DWORD Variable containing the 16-byte aligned size
align 16

Code: Select all

_KERN_START:
bits 32
org  1048576


;Clear the direction flag and skip all of the possible library code
;that we include:
;;
 cli   ;Disable interrupts
 cld
 jmp __KERN_EntryPoint;



align 4
__KERN_EntryPoint:

;;;;INIT: KERNEL.ASM Main Body
;;;;INIT: KERNEL.ASM Main Body
;;;;INIT: KERNEL.ASM Main Body
;;;;INIT: KERNEL.ASM Main Body
;;;;INIT: KERNEL.ASM Main Body
;;;;INIT: KERNEL.ASM Main Body


;;;;END:  KERNEL.ASM Main Body
;;;;END:  KERNEL.ASM Main Body
;;;;END:  KERNEL.ASM Main Body
;;;;END:  KERNEL.ASM Main Body
;;;;END:  KERNEL.ASM Main Body
;;;;END:  KERNEL.ASM Main Body


;Infinite loop in which we will sit:
;;
 .MainKernelLoop:

   ;Halt the CPU until there's an interrupt. It will also
   ;completely halt the CPU until a reset when we only have
   ;the initial kernel skeleton:
   ;;
    hlt

 jmp .MainKernelLoop





;What these lines do is:
;
;- First, it aligns the kernel image to 16 bytes,
;  to place the end-of-image "_KERN_END" variable,
;  in a more "predictable" place.
;
;- Then we actually create the "_KERN_END" variable.
;
;- We align the kernel image to 16 bytes again, by
;  using 12 bytes of padding plus the size of
;  our variable. It will actually make possible to
;  use this control variable and always assemble
;  a kernel image aligned to 16 bytes, which will
;  dynamically create low level system structures,
;  right after the kernel, a little easier.
;
;
;NOTE: Since our image is assembled with a start
;      address of 1048576, first we must substract
;      it from '$', which represents the current
;      offset, from where we use it, into the program
;      image. So whith ($-1048576), we get the actual
;      size of the kernel: an offset with base address of 0.
;
;;
 align 16
  _KERN_END_STATIC equ $+4+12
         _KERN_END  dd _KERN_END_STATIC
 align 16

LowEST_Kernel Level 1 (Just Press Play)Image

Re: Finding the end of the kernel

Posted: Wed Mar 23, 2016 1:11 pm
by max
~, I appeal to you please do not always include a giant screenshot of your HTML-player-thing, it reduces the quality of the forum...

Re: Finding the end of the kernel

Posted: Wed Mar 23, 2016 1:32 pm
by ~
max wrote:~, I appeal to you please do not always include a giant screenshot of your HTML-player-thing, it reduces the quality of the forum...
I don't always include that but when I want to make clear that there's a recording of a very simple or very important thing, I want to make it obvious with no exception for the user who asks to solve it once and for all.

It's intented to indicate a tutorialized schematic with full source code for a standalone and runnable example more than just a nontechnical snapshot.

Re: Finding the end of the kernel

Posted: Wed Mar 23, 2016 2:07 pm
by max
Yeah, but is a link not enough? Whom do you expect to follow 6 minutes of you typing HTML code? Your explanation and code in your answer here are okay, it works depending on how you link your objects, and the thread starter probably has more than a single assembly file. The link and the screenshot are not related to the content of this thread in any kind - that is why I appeal you to not spoil the forum content with that stuff.

Re: Finding the end of the kernel

Posted: Wed Mar 23, 2016 3:41 pm
by ~
Image >> Watch the text recording for this program << Image

I just hope the simple snippet helps the user who asked the question.

I just updated my source code and now you just need to press Play provided that you include the desired file in the anchor (after the # in the URL). It already sets automatically the options above (desired single file selection and locking the playback to that file only):

Or you just need to select the file you want to watch from the directory tree and enable the "Play only this file" checkbox.

And after all, I feel and see that this discussion actually makes understanding of each thread much easier (so we have actually increased the answer quality).

http://archive.org/download/LowEST_Kernel/version_control/LEVEL_1/LowEST_Kernel.html# LowEST_Kernel/src/kernel.asm

Re: Finding the end of the kernel

Posted: Thu Mar 24, 2016 6:53 am
by Schol-R-LEA
Getting back to the original question, I was wondering just what you needed this information for, and what you intended to do with it; while it is certainly important to know the size of the loaded kernel, and where it actually ends in memory, the answer isn't necessarily as simple as it sounds, and how you use it can alter how important it is.

The main things I am wondering are: a) is there anything at run-time that could change the kernel's footprint after it is loaded (unlikely, especially given the current stage of development, but possible), b) are you intending to use the current layout of physical memory, with the kernel below the user space, or do you intend to use a higher-half kernel at some point (usually considered a good idea, but not by any means mandatory), and c) are you intending to support virtual memory now or soon, and will you map the current physical location to a logical high-half location eventually?