作为学校项目,我正在为 Raspberry Pi 开发一个小内核。我们遇到了静态变量初始化的问题:似乎那些根本没有初始化。我找到了一些相关主题,但到目前为止还没有人提出解决方案,尽管 this帮助我理解了这个问题(至少,我认为)。
所有代码都可以找到on this repository ,但我会尝试在这里总结相关代码。
从显示问题的项目中提取的代码:(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
//...
}
然后使用(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
并使用相同的选项构建成二进制文件,最后使用
组装成kernel.imgarm-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
(您可以直接阅读 Makefile 以获取更多详细信息:github.com/tobast/sysres-pikern/blob/staticNotWorking/kernel/Makefile)。
使用的链接器脚本也可能是问题所在,因为我们试图在不知道自己在做什么的情况下弄清楚如何编写一个可以工作的链接器脚本(我们使用来自另一个项目的修改后的链接器脚本): github.com/tobast/sysres-pikern/blob/staticNotWorking/kernel/kernel.ld
_start = 0x8000;
ENTRY(_start)
SECTIONS {
.init 0x8000 : {
*(.init)
}
.text : {
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
以这种方式生成的程序显示了一个明显的随机值(无论如何,它与期望值 42 无关)。
到目前为止,我所了解的是操作系统应该负责在实际启动程序之前初始化静态变量,但是由于我们正在编写操作系统,所以没有人为我们做这件事。当然,我们可以手动初始化这些变量(通过为此目的调用启动函数),但这将是一个丑陋而痛苦的解决方案......
我们是否缺少任何 g++/链接器选项,或者我们的链接器脚本有问题?
谢谢!
最佳答案
我看到了几个问题:
您的部分未与页面对齐,即链接器脚本中的
ALIGN(0x1000)
您没有设置堆栈和清零
bss
部分的“启动”ASM 脚本。
我不知道这样的脚本在 ARM 上会是什么样子(我习惯了 x86),但这里有一个例子:
.section "vectors"
reset: b start
undef: b undef
swi: b swi
pabt: b pabt
dabt: b dabt
nop
irq: b irq
fiq: b fiq
.text
start:
@@ Copy data to RAM.
ldr r0, =flash_sdata
ldr r1, =ram_sdata
ldr r2, =data_size
@@ Handle data_size == 0
cmp r2, #0
beq init_bss
copy:
ldrb r4, [r0], #1
strb r4, [r1], #1
subs r2, r2, #1
bne copy
init_bss:
@@ Initialize .bss
ldr r0, =sbss
ldr r1, =ebss
ldr r2, =bss_size
@@ Handle bss_size == 0
cmp r2, #0
beq init_stack
mov r4, #0
zero:
strb r4, [r0], #1
subs r2, r2, #1
bne zero
init_stack:
@@ Initialize the stack pointer
ldr sp, =0xA4000000
bl main
stop: b stop
当然,您需要修改它以匹配内核的语义。
关于c++ - 静态变量未初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37137064/