Page 1 of 1

A 'ninja' linker script to include a user section in kernel

Posted: Mon Apr 06, 2020 11:57 pm
by sunnysideup
Check out this linker script:

Code: Select all

OUTPUT_FORMAT(elf32-i386)
ENTRY(kmain)

SECTIONS {

. = 0xC0000000;

__begin = .;

.text : AT(0x100000) 
    {
        *(.text.entry)       /* Ensure .text.entry appears first */
        *(.text*)
    }

.user 0x0 : AT(0x100000 + SIZEOF (.text)) /*I WANT TO ALIGN THIS LOAD ADDRESS TOO!!!
    {
        __user_load_begin =  LOADADDR(.user);
        *(.user);
        __user_load_end =  LOADADDR(.user) + SIZEOF(.user);
    }

.data ADDR(.text) + SIZEOF(.text) : AT(0x100000 + SIZEOF(.user) + SIZEOF(.text)) 
    {
        *(.rodata)
        *(.data)
    }
    __debug =.;

.bss : SUBALIGN(16)
    {
        __bss_start = .;
        *(COMMON)            /* all COMMON sections from all files */
        *(.bss)              /* all BSS sections from all files */
    }

. = ALIGN(4k);
__VGA_text_memory = .;

    /DISCARD/ : {            /* Remove Unneeded sections */
        *(.eh_frame);
        *(.comment);
    }

     __end = .; 
}
Well, I'm doing OsDev, and want do start off with user mode modules. However, I don't have a filesystem driver yet, and I want to test these modules as shown in the linker script. (With the .user section being continuous with the kernel as per the LMAs, but the .user section having a VMA of 0.

The above linker script is ALMOST what I want. There are a few issues.
I don't use the location counter (.) here. Surely, it is not advisable to do that. I manually fill in the virtual and physical addresses of .user and .text.
The other issue is that I need to align the load address as well as virtual address of .user and I'm not sure what's the best way to do that.
Right now, the load address is LOADADDR(.text) + SIZEOF(.text). Maybe I want SIZEOF(.text) to be 4k aligned

Re: A 'ninja' linker script to include a user section in ker

Posted: Tue Apr 07, 2020 2:35 am
by nullplan
Here's what I would do in your stead: Create the user application completely standalone. So you get an ELF file, let's call it "user.bin". Then you write an assembly file "user.s" with:

Code: Select all

.section ".rodata","a",@progbits
.align 4096
.global user_program
.type user_program,@object
user_program:
.incbin "user.bin"
.size user_program,.-user_program
And boom, you have a page-aligned ELF image inside of your kernel. So long as you put the following declaration into a header file somewhere:

Code: Select all

extern unsigned char user_program[];
This is almost exactly what Linux is doing to put the VDSO inside of the kernel image. So it should be well supported.