Page 1 of 1
Kernel Linking
Posted: Mon Jul 30, 2007 2:49 pm
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?
Posted: Mon Jul 30, 2007 4:31 pm
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)
Posted: Mon Jul 30, 2007 6:14 pm
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)
}
}
Posted: Wed Aug 01, 2007 3:42 am
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!