韦东山Linux嵌入式课程社区
直播中

吴思莹

7年用户 207经验值
私信 关注

重定位报错undefined

注意:如果点击空白处无法输入,则点击字会有输入提示符 | 则可以使用键盘进行输入!

此板块为  [ARM裸机加强版]
  • 问题所在章节:13
  • 发生问题的运行环境:
  • 问题发生描述:
  •     make时报错 ,undefined reference to `data_load_addrdata'
  •     是需要申明变量么
  • cpu.o(.text+0x9c): In function `HandleIRQ':
  • : undefined reference to `data_load_addrdata'
  • cpu.o(.text+0xa0): In function `HandleIRQ':
  • : undefined reference to `data_startdata'
  • makefile:3: recipe for target 'start' failed
  • make: *** [start] Error 1
  • 代码如下
    • lds文件
    • SECTIONS {
    •     . = 0x00000000;
    •     .start_init : AT(0){cpu.o nand.o sysclock.o}
    •     . = 0x30000000;
    •     .text    ALIGN(4)  :  AT(4096) { *(.text) }
    •     .rodata ALIGN(4) : {*(.rodata)}
    •     .data 0x33000000  :AT(0x2000)
    •                         {
    •           data_load_addr = LOADADDR(.data);
    •          data_start = . ;
    •       *(.data)
    •       data_end = . ;
    •                         }
    •     .bss ALIGN(4)  : { *(.bss)  *(COMMON) }
    • }
    • makefile
    • start:  cpu.o main.o inter.o nand.o sysclock.o uart.o
    •         arm-linux-ld -Tint2.lds   -o bin $^
    •         arm-linux-objcopy  -O binary -S bin int.bin
    •         arm-linux-objdump -D -m arm bin>int.dis
    • %.o:%.c
    •         arm-linux-gcc    -c -o $@ $^
    • %.o:%.S
    •         arm-linux-gcc   -c -o $@ $^
    • clean:
    •         rm -f *.o *.dis *.bin
    • 汇编文件
    • @******************************************************************************
    • @ File:head.S
    • @ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数
    • @******************************************************************************
    • .extern     data_startdata
    • .extern     main
    • .text
    • .global _start
    • .equ watchdogaddr, 0x53000000
    • _start:
    • @******************************************************************************
    • @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
    • @******************************************************************************
    •     b   Reset
    • @ 0x04: 未定义指令中止模式的向量地址
    • HandleUndef:
    •     b   HandleUndef
    • @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
    • HandleSWI:
    •     b   HandleSWI
    • @ 0x0c: 指令预取终止导致的异常的向量地址
    • HandlePrefetchAbort:
    •     b   HandlePrefetchAbort
    • @ 0x10: 数据访问终止导致的异常的向量地址
    • HandleDataAbort:
    •     b   HandleDataAbort
    • @ 0x14: 保留
    • HandleNotUsed:
    •     b   HandleNotUsed
    • @ 0x18: 中断模式的向量地址
    •     b   HandleIRQ
    • @ 0x1c: 快中断模式的向量地址
    • HandleFIQ:
    •     b   HandleFIQ
    • Reset:
    •        ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈
    •        ldr r0,=watchdogaddr
    •        mov r1,#0x00000000
    •        str r1,[r0]           @关闭看门狗
    •            bl clock_init
    •         bl memsetup                                @SDRAM
    •             bl nand_init               @初始化NAND Flash
    •                                             @将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中
    •                                             @nand_read_ll函数需要3个参数:
    •         ldr     r0,     =0x30000000     @1. 目标地址=0x30000000,这是SDRAM的起始地址
    •         mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处
    •         ldr     r2,     =0x4000         @3.  复制长度= 2048(bytes),对于本实验的main.c,这是足够了
    •         bl      nand_read               @调用C函数nand_read
    •         ldr     sp, =0x34000000         @设置栈
    •         ldr r1, =data_load_addrdata /* 段在bin文件中的地址, 加载地址 0x2000 */
    •         ldr r2, =data_startdata         /*0x33000000 段在重定位地址, 运行时的地址 */
    •         ldr r3, =data_end /*0x33001000*/
    •         cpy:
    •                 ldrb r4,[r1]
    •                 strb r4,[r2]
    •                 add r1,r1,#1
    •                 add r2,r2,#1
    •                 cmp r2,r3
    •                 bne cpy
    •         msr cpsr_c, #0xd2       @ 进入中断模式
    •     ldr sp, =0x33000000         @ 设置中断模式栈指针 4000000= 64M
    •     msr cpsr_c, #0xd3       @ 进入管理模式
    •     msr cpsr_c, #0x5f       @ 设置I-bit=0,开IRQ中断
    •     ldr lr, =halt_loop      @ 设置返回地址
    •     ldr pc, =main           @ 调用main函数
    • halt_loop:
    •     b   halt_loop
    • HandleIRQ:
    •     sub lr, lr, #4                  @ 计算返回地址
    •     stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器
    •                                     @ 注意,此时的sp是中断模式的sp
    •                                     @ 初始值是上面设置的3072
    •    ldr lr, =int_return             @ 设置调用ISR即IRQ_Handle函数后的返回地址
    •     ldr pc, =IRQ_Handle            @ 调用中断服务函数,在interrupt.c中
    • int_return:
    •     ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr




  • 输出的错误信息:
  • arm-linux-ld -Tint2.lds   -o bin cpu.o main.o inter.o nand.o sysclock.o uart.o
  • cpu.o(.text+0xa4): In function `int_return':
  • : undefined reference to `data_load_addrdata'
  • cpu.o(.text+0xa8): In function `int_return':
  • : undefined reference to `data_startdata'
  • makefile:3: recipe for target 'start' failed
  • make: *** [start] Error 1

回帖(3)

王莹

2019-4-11 13:50:53
lds里面的 data_load_addr 不用     

为什么用data_startdata data_load_addrdata 参考的哪里啊?

看下老师视频 或者对比下老师代码 很容易定位
举报

潘小旋

2019-4-11 14:09:35
  . = 0x00000000;
    .start_init : AT(0){cpu.o nand.o sysclock.o}
    . = 0x30000000;
    .text    ALIGN(4)  :  AT(4096) { *(.text) }
应该是lds有问题,最开始这样写的是想把启动的文件放0地址,  后面代码文件放4096后地址,
如果删除前两行  . = 0x00000000;
                          .start_init : AT(0){cpu.o nand.o sysclock.o},就不会报错
举报

元办叙

2019-4-11 14:26:54
好吧。。变量名写错了
举报

更多回帖

发帖
×
20
完善资料,
赚取积分