Reference Linker Script Varaible from Source File

Programming, for all ages and all languages.
Post Reply
Jeffrey
Posts: 20
Joined: Fri Jul 27, 2007 1:35 pm
Location: Virginia, USA

Reference Linker Script Varaible from Source File

Post by Jeffrey »

Hey guys,

I am having a problem where I am not able to access a compile-time constant that I have defined in my linker script. I am using a Cygwin i386 ELF cross compiler w/ Gnu AS.

Anyways, I defined my kernel's load address to be at 0x100000 when paging isn't yet enabled and at 0xC0000000 when it has. Well the problem is that in my startup source (init_i386.S) I have an external reference to the virtual address variable in my linker script, yet when I goto compile my startup source it complains about an "undefined" variable. Should this be happening? So I then replace the external variable with a constant 0xC0000000 and recompile and everything is fine. So what am I doing wrong?

Do I need to define the variable as a macro during compilation and have it passed to the linker script instead of the linker script defining it and my source trying to acquire it?

Thanks in advance.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

Should work straight off - check you havent got the compiler attempting to link too (as it wouldn't be using the script) and of course you need to define the variable as extern in your source.

Any chance of seeing your linker script and a relevant source code snippet?

Cheers,
Adam
Jeffrey
Posts: 20
Joined: Fri Jul 27, 2007 1:35 pm
Location: Virginia, USA

Post by Jeffrey »

I am going to take a look at my makefile and see what switches I am passing, but will have to do that later today. Provided below is my linker script and a portion of my init_i386.S startup source).

Linker Script (sentrix-i386.ld)

Code: Select all

OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386)
ENTRY(init_i386)

/*    
    PHYSICAL	= 0x100000;
    VIRTUAL		= 0xC0000000;
 */ 

_kernel_phys_base	= 0x100000;
_kernel_virt_base	= 0xC0000000;
_kernel_virt_addr	= _kernel_phys_base + _kernel_virt_base;
_align_4kb	= 0x1000;

SECTIONS
{
    . = _kernel_virt_addr;

	_kernel_start = .;

    .text ALIGN(_align_4kb) : AT(ADDR(.text) - _kernel_virt_base)
    {
    	_text_start = .;
    	
        *(.text)
        *(.rodata)
                
        _text_end = .;
    }

    .data ALIGN(_align_4kb) : AT(ADDR(.data) - _kernel_virt_base)
    {
    	_data_start = .;
    	
        *(.data)
        
        _data_end = .;
    }

    .bss ALIGN(_align_4kb) : AT(ADDR(.bss) - _kernel_virt_base)
    {
        _bss_start = .;
        
        *(COMMON)
        *(.bss)
        
        _bss_end = .;
    }
    
    _kernel_end = .;
}
Example Assembly Code (init_i386.S)

Code: Select all

.extern _kernel_start, _kernel_end, _bss_end, _kernel_phys_base, _kernel_virt_base

.equ _kernel_page_number, 0xC0000000 >> 22
//.equ _kernel_page_number, _kernel_virt_base >> 22
Jeffrey
Posts: 20
Joined: Fri Jul 27, 2007 1:35 pm
Location: Virginia, USA

Post by Jeffrey »

It works if I use the variable provided that I have defined it using the -D switch. I shouldn't have to do this though.

Could there be something wrong with my version of GCC/Binutils? I am using 4.2.1 and 2.18.


P.S: I am also passing the .S source file to the compiler itself instead of as, so that could have something to do with it, but I am also passing -c so that it only compiles and assembles, but not links.
Jeffrey
Posts: 20
Joined: Fri Jul 27, 2007 1:35 pm
Location: Virginia, USA

Post by Jeffrey »

I think I figured it out.

It's not complaining about me using the external variable, it is complaining because I am using it to define the value of a preprocessor definition that is being used to set the size of a .fill section. I will rewrite it to not nest them. I think that will fix it.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

You are on the right track. To summarize:
  • The chance that a problem is the result of a bug in the toolchain is extremly small, to the point where I wouldn't even consider the possibility.
  • The sequence is preprocessing - compiling - linking. Whatever you do in the linker script is not available to the preprocessor.
Every good solution is obvious once you've found it.
Post Reply