Page 2 of 2

Re: Calculate the address spaces my kernel is occupying?

Posted: Sat Jul 30, 2022 1:15 am
by nullplan
Christ, you skip the forum for a day and something like this happens.
nightcrawler wrote:Is `ALIGN(4K)` really needed here? Can it be omitted or the value changed? Also I don't have paging enabled.
Alignment is not needed even with paging. However, you may want to have your writable sections on different pages than your executable section. I personally do that by putting all the read-only sections in one part of the executable, then explicitly align the position counter to the page size. I don't much care for the alignment of the sections themselves; that is for the input sections to declare.

My linker script currently looks like this:

Code: Select all

ENTRY(_kstart)
OUTPUT_FORMAT("elf64-x86-64")

PHDRS {
    headers PT_PHDR PHDRS;
    text PT_LOAD FILEHDR PHDRS;
    data PT_LOAD;
}

SECTIONS {
    . = 0xffffffff80000000 + SIZEOF_HEADERS;
    .text : {
        *(.text)
        *(.text.*)
    } :text
    .rodata : {
        *(.rodata)
        *(.rodata.*)
    }

    .eh_frame_hdr : {
        __eh_frame_hdr = .;
        *(.eh_frame_hdr)
    }
    .eh_frame : {
        *(.eh_frame)
        *(.eh_frame.*)
    }

    /* Normally, the overlap between text and data section is handled by having
     * two different pages for the last bits of text and the first bits of data.
     * That way, if the last bits of text are overwritten, it won't affect the
     * text that is actually used. Unfortunately, for the kernel this is not
     * possible. The whole file is loaded into memory en bloc, so the same page
     * would be mapped twice. Therefore, a write access to the writable page
     * would end up being visible in the non-writable side of things. Therefore,
     * we must actually page-align here.
     */
    . = ALIGN(2M);ENTRY(_kstart)
OUTPUT_FORMAT("elf64-x86-64")

PHDRS {
    headers PT_PHDR PHDRS;
    text PT_LOAD FILEHDR PHDRS;
    data PT_LOAD;
}

SECTIONS {
    . = 0xffffffff80000000 + SIZEOF_HEADERS;
    .text : {
        *(.text)
        *(.text.*)
    } :text
    .rodata : {
        *(.rodata)
        *(.rodata.*)
    }

    .eh_frame_hdr : {
        __eh_frame_hdr = .;
        *(.eh_frame_hdr)
    }
    .eh_frame : {
        *(.eh_frame)
        *(.eh_frame.*)
    }

    /* Normally, the overlap between text and data section is handled by having
     * two different pages for the last bits of text and the first bits of data.
     * That way, if the last bits of text are overwritten, it won't affect the
     * text that is actually used. Unfortunately, for the kernel this is not
     * possible. The whole file is loaded into memory en bloc, so the same page
     * would be mapped twice. Therefore, a write access to the writable page
     * would end up being visible in the non-writable side of things. Therefore,
     * we must actually page-align here.
     */
    . = ALIGN(2M);
    .data : {
        *(.data)
        *(.data.*)
    } :data
    .bss : {
        *(.bss)
        *(COMMON)
        *(.bss.*)
    }
}

    .data : {
        *(.data)
        *(.data.*)
    } :data
    .bss : {
        *(.bss)
        *(COMMON)
        *(.bss.*)
    }
}
The only reason to align the position counter there is to get the writable stuff on a new page. As explained in the comment, in userspace you can typically get away with merely increasing the position counter (which does not increase the file size), but the kernel is not mapped into address space and demand paged in, and therefore I cannot do that.

Re: Calculate the address spaces my kernel is occupying?

Posted: Sat Jul 30, 2022 10:46 am
by nightcrawler
Would you be able to give me an example?

Re: Calculate the address spaces my kernel is occupying?

Posted: Sun Jul 31, 2022 6:51 pm
by nightcrawler
Thanks but where do the "start" and "end" variables go int the linker scripts, that's what I'm trying to confirm.

Re: Calculate the address spaces my kernel is occupying?

Posted: Sun Jul 31, 2022 7:36 pm
by kzinti
They go around the part you are trying to measure the size of.

Re: Calculate the address spaces my kernel is occupying?

Posted: Sun Jul 31, 2022 8:30 pm
by nightcrawler
Would this work:

Code: Select all

ENTRY(_start)
SECTIONS
{
   start = .;	
   . = 1M;
   .text
   {
      *(.text)
   }

   .rodata
   {
      *(.rodata)
   }

   .data
   {
      *(.data)
   }

   .bss
   {
      *(COMMON)
      *(.bss)
   }
   end = .;
} 

Re: Calculate the address spaces my kernel is occupying?

Posted: Sun Jul 31, 2022 9:20 pm
by kzinti
It would set the start symbol 1M bytes before the text (code) of your kernel. Is this what you want?

Re: Calculate the address spaces my kernel is occupying?

Posted: Mon Aug 01, 2022 8:27 am
by nightcrawler
I guess this would be better than?

Code: Select all

ENTRY(_start)
SECTIONS
{
   . = 1M;
   start = .;   
   .text
   {
      *(.text)
   }
basically start is hardcoded to be at 1M.