Calculate the address spaces my kernel is occupying?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
nullplan
Member
Member
Posts: 1779
Joined: Wed Aug 30, 2017 8:24 am

Re: Calculate the address spaces my kernel is occupying?

Post 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.
Carpe diem!
nightcrawler
Posts: 17
Joined: Thu Aug 08, 2019 8:21 am

Re: Calculate the address spaces my kernel is occupying?

Post by nightcrawler »

Would you be able to give me an example?
nightcrawler
Posts: 17
Joined: Thu Aug 08, 2019 8:21 am

Re: Calculate the address spaces my kernel is occupying?

Post by nightcrawler »

Thanks but where do the "start" and "end" variables go int the linker scripts, that's what I'm trying to confirm.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Calculate the address spaces my kernel is occupying?

Post by kzinti »

They go around the part you are trying to measure the size of.
nightcrawler
Posts: 17
Joined: Thu Aug 08, 2019 8:21 am

Re: Calculate the address spaces my kernel is occupying?

Post by nightcrawler »

Would this work:

Code: Select all

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

   .rodata
   {
      *(.rodata)
   }

   .data
   {
      *(.data)
   }

   .bss
   {
      *(COMMON)
      *(.bss)
   }
   end = .;
} 
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Calculate the address spaces my kernel is occupying?

Post by kzinti »

It would set the start symbol 1M bytes before the text (code) of your kernel. Is this what you want?
nightcrawler
Posts: 17
Joined: Thu Aug 08, 2019 8:21 am

Re: Calculate the address spaces my kernel is occupying?

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