如何仅编译C语言的_start函数?解决RISC-V入口地址偏移问题
问题:RISC-V程序入口地址偏移,NOTE段导致_start未落在预期地址
我正在测试自研RISC-V核心上的UART实现,编写了用于验证的_start函数:
#define UART_BASE 0x10000000L #define UART_TX 0 void _start() { *(volatile char *)(UART_BASE + UART_TX) = 'A'; *(volatile char *)(UART_BASE + UART_TX) = '\n'; while (1); }
以下是设置的编译标志及Makefile:
CFLAGS = -nostartfiles -fno-builtin -ffreestanding -march=rv32e_zicsr -mabi=ilp32e -fno-pic -mcmodel=medany -mstrict-align -static LDFLAGS = -e _start -T linker.ld COPYFLAGS = --only-section=.text uart_test.bin:uart_test.elf riscv64-linux-gnu-objcopy -O binary $^ $@ $(COPYFLAGS) riscv64-linux-gnu-objdump -d $^ > uart_test.txt uart_test.elf:uart_test.c riscv64-linux-gnu-gcc $(CFLAGS) -o $@ $^ $(LDFLAGS)
linker.ld内容如下:
ENTRY(_start) SECTIONS { . = 0X20000000; .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
检查uart_test.txt文件时,发现入口地址为0x20000024,而非预期的0x20000000:
Disassembly of section .text: 20000024 <_start>: 20000024: ffc10113 addi sp,sp,-4 20000028: 00812023 sw s0,0(sp) 2000002c: 00410413 addi s0,sp,4 20000030: 100007b7 lui a5,0x10000 20000034: 04100713 li a4,65 20000038: 00e78023 sb a4,0(a5) # 10000000 <_start-0x10000024> 2000003c: 100007b7 lui a5,0x10000 20000040: 00a00713 li a4,10 20000044: 00e78023 sb a4,0(a5) # 10000000 <_start-0x10000024> 20000048: 0000006f j 20000048 <_start+0x24>
使用readelf工具查看段头时,发现在0x20000024之前存在一个NOTE段:
$ riscv64-linux-gnu-readelf -S char-test.elf There are 8 section headers, starting at offset 0x1170: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .note.gnu.bu[...] NOTE 20000000 001000 000024 00 A 0 0 4 [ 2] .text PROGBITS 20000024 001024 00001c 00 AX 0 0 4 [ 3] .comment PROGBITS 00000000 001040 00002b 01 MS 0 0 1 [ 4] .riscv.attributes RISCV_ATTRIBUTE 00000000 00106b 00001a 00 0 0 1 [ 5] .symtab SYMTAB 00000000 001088 000080 10 6 7 4 [ 6] .strtab STRTAB 00000000 001108 000017 00 0 0 1 [ 7] .shstrtab STRTAB 00000000 00111f 00004f 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), p (processor specific)
我认为移除该NOTE段即可解决问题。
内容的提问来源于stack exchange,提问作者Young
相关产品推荐
相关产品推荐

