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.
Reference Linker Script Varaible from Source File
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)
Example Assembly Code (init_i386.S)
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 = .;
}
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
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.
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.
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.