You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅编译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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:57:02