I am developping a small kernel for Raspberry Pi as a school project. We are encountering an issue with static variable initialization: it seems that those are not initialized at all. I've found a few related topics, yet none have brought a solution so far, though this helped me understand the issue (at least, I think).
All the code can be found on this repository, but I will try to sum up the related code here.
Code extracted from the project showing the problem: (kernel/src/kernel.cpp)
static int staticVal = 42;
void doStuff() { // Prevent the compiler from optimizing the value of staticVal
staticVal++;
}
__attribute__((section(".init")))
int main(void) {
//...
gpio::blinkValue(staticVal); // Displays the value through LEDs
//...
}
The code is then compiled using (eg)
arm-none-eabi-g++ -O2 -std=c++11 -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -nostartfiles -Wall -Wextra -pedantic -I src/ -I uspi/include -DHW_PI_1B -c src/[file].cpp -o _build/[file].o
and built into a binary file using the same options, and finally assembled into a kernel.img using
arm-none-eabi-ld --no-undefined _build/master.bin -Map _build/kernel.map -o _build/output.elf -T kernel.ld
arm-none-eabi-objcopy _build/output.elf -O binary kernel.img
(you can read the Makefile directly for more details: github.com/tobast/sysres-pikern/blob/staticNotWorking/kernel/Makefile).
The linker script used might as well be the problem, as we have tried to figure out how to write a working one without really knowing what we were doing (we use a modified linker script from another project): github.com/tobast/sysres-pikern/blob/staticNotWorking/kernel/kernel.ld
_start = 0x8000;
ENTRY(_start)
SECTIONS {
.init 0x8000 : {
*(.init)
}
.text : {
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
The program generated this way displays an apparently random value (which has, anyway, nothing to do with the expected value -- 42).
What I've understood so far is that the operating system is supposed to be responsible for initializing static variables before actually starting the program, but as we are writing an operating system, no one is doing it for us. Of course, we could manually initialize those variables (by calling a startup function for this purpose), but it would be an ugly and painful solution...
Is there any g++/linker options we are missing, or a problem in our linker script?
Thanks!