Kernel Linking

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Kernel Linking

Post by Jeko »

I link my kernel at 0xC0000000. But I have a file in assembler called start.asm that I want to link at 0x100000.
I want the kernel and start.o in the same file, kernel.bin. How can I do?
Aali
Member
Member
Posts: 58
Joined: Sat Apr 14, 2007 12:13 pm

Post by Aali »

you'd need a linker script
i'm assuming your code at 0x100000 sets up the necessary paging/segmentation environment for the rest of your kernel

there are a lot of linker scripts floating around, i believe the wiki has one, but you could just aswell make your own, just read up on the AT keyword (since that will allow you to have different physical/virtual addresses)
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

I can show you my linker script if you want. You will have to make some changes that you will have to figure out on your own. I'll give you two hints though my kernel is loaded at 0x1000 and linked to run at 0xD0000000. It has a section at the beginning that is identity linked(ie same physical and virtual address) to set up paging and stuff like that. I tried to put every single thing that I could ever need in here, also it is a C++ linker script so it has some extra C++ only stuff.

Code: Select all

ENTRY( kernel_start )

OUTPUT_FORMAT( binary )

SECTIONS
{
        . = 0x1000;

        startup_start = .;
        
        .start :
        {
                *(.start)

                . = ALIGN( 4096 );
        }
        
        startup_end = .;
        
        kernel_start = 0xD0000000;

        .text 0xD0000000 + SIZEOF( .start ) : AT( ADDR( .start ) + SIZEOF( .start ) )
        {
                *(.text) 
                *(.text.*)
                *(.gnu.linkonce.t*)
                *(.const*)
                *(.ro*)
                *(.gnu.linkonce.r*)

                . = ALIGN( 4096 );

        }
        
        .data ADDR( .text ) + SIZEOF( .text ) : AT( LOADADDR( .text ) + SIZEOF( .text ) )
        {
                *(.data)
                
				. = ALIGN( 32 );

                /* constructors */
                __CTOR_LIST__ = .;
                
                /* the number of constructors */
                LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)

                *(SORT(.ctors.*))
                *(.ctor)
                *(.ctors)

                LONG(0)
                
                __CTOR_END__ = .;
                
   				. = ALIGN( 32 );
                
                
                /* deconstructors */
                __DTOR_LIST__ = .;
                
                /* number of deconstructors */
                LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
                
                *(SORT(.dtors.*))
                *(.dtor)
                *(.dtors)

                LONG(0)
                
                __DTOR_END__ = .;

                *(.gnu.linkonce.d*)

        }
        
        . = ALIGN( 4096 );
        
        .bss ALIGN( ADDR( .data ) + SIZEOF( .data ), 4096 ): AT( LOADADDR( .data ) + SIZEOF( .data ) )
        {
                bss_start = ABSOLUTE( . );
                
                *(.bss .bss.* .gnu.linkonce.b.*)

                *(COMMON)

                . = ALIGN( 4096 );

                bss_end = ABSOLUTE( . );
                
                bss_length = bss_end - bss_start;

        }

        kernel_end = .;
        
        kernel_len = kernel_end - kernel_start;
        
        /* This section is too make sure that those anoying little made by */
        /* GCC comments don't show up in the output */
        DISCARD :
        {
                *(.comment)
        }
}
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Post by Jeko »

frank wrote:I can show you my linker script if you want. You will have to make some changes that you will have to figure out on your own. I'll give you two hints though my kernel is loaded at 0x1000 and linked to run at 0xD0000000. It has a section at the beginning that is identity linked(ie same physical and virtual address) to set up paging and stuff like that. I tried to put every single thing that I could ever need in here, also it is a C++ linker script so it has some extra C++ only stuff.

Code: Select all

ENTRY( kernel_start )

OUTPUT_FORMAT( binary )

SECTIONS
{
        . = 0x1000;

        startup_start = .;
        
        .start :
        {
                *(.start)

                . = ALIGN( 4096 );
        }
        
        startup_end = .;
        
        kernel_start = 0xD0000000;

        .text 0xD0000000 + SIZEOF( .start ) : AT( ADDR( .start ) + SIZEOF( .start ) )
        {
                *(.text) 
                *(.text.*)
                *(.gnu.linkonce.t*)
                *(.const*)
                *(.ro*)
                *(.gnu.linkonce.r*)

                . = ALIGN( 4096 );

        }
        
        .data ADDR( .text ) + SIZEOF( .text ) : AT( LOADADDR( .text ) + SIZEOF( .text ) )
        {
                *(.data)
                
				. = ALIGN( 32 );

                /* constructors */
                __CTOR_LIST__ = .;
                
                /* the number of constructors */
                LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)

                *(SORT(.ctors.*))
                *(.ctor)
                *(.ctors)

                LONG(0)
                
                __CTOR_END__ = .;
                
   				. = ALIGN( 32 );
                
                
                /* deconstructors */
                __DTOR_LIST__ = .;
                
                /* number of deconstructors */
                LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
                
                *(SORT(.dtors.*))
                *(.dtor)
                *(.dtors)

                LONG(0)
                
                __DTOR_END__ = .;

                *(.gnu.linkonce.d*)

        }
        
        . = ALIGN( 4096 );
        
        .bss ALIGN( ADDR( .data ) + SIZEOF( .data ), 4096 ): AT( LOADADDR( .data ) + SIZEOF( .data ) )
        {
                bss_start = ABSOLUTE( . );
                
                *(.bss .bss.* .gnu.linkonce.b.*)

                *(COMMON)

                . = ALIGN( 4096 );

                bss_end = ABSOLUTE( . );
                
                bss_length = bss_end - bss_start;

        }

        kernel_end = .;
        
        kernel_len = kernel_end - kernel_start;
        
        /* This section is too make sure that those anoying little made by */
        /* GCC comments don't show up in the output */
        DISCARD :
        {
                *(.comment)
        }
}
ok. Thank you!
Post Reply