发 帖  
原厂入驻New
发烧友10周年庆典,全网超值优惠来袭!千元现金券,下单抽奖赶紧参与》》
为什么程序分段后就不好用了?
171 韦东山 代码 编译
分享
在ok6410上,程序在lds文件里面指定了分段,如下:
mmu.lds:

SECtiONS {
  first    0 : { head.o init.o }
  second    3072 : AT(2048) { LEDs.o }
}
---------------------------
head.S:
     
.text
.global _start
_start:

ldr r0, =0x70000013        
mcr p15, 0, r0, c15, c2, 4

ldr sp, =8192                       
bl  disable_watch_dog                                       
////////        bl  copy_2048_to_3072              
////////        ldr pc, =2048
////////        ldr pc, =3072

bl main

halt_loop:
    b   halt_loop
---------------------------
init.c:

void copy_2048_to_3072(void)
{
unsigned int *pdwSrc  = (unsigned int *)2048;
unsigned int *pdwDest = (unsigned int *)3072;        
   
while(pdwSrc < (unsigned int *)(2048+512))        
{
*pdwDest = *pdwSrc;
        pdwDest++;
        pdwSrc++;
}
}
---------------------------
leds.c:

int main()
{
volatile unsigned int k;
volatile unsigned int i,j;      
    GPMCON = 0x11111;  
    GPMDAT = 0x00000000;  

    while(1)
    {
            for(k=0;k<4;k++)
            {
                GPMDAT=~(1<<k);
for(i=0;i<20000;i++)
                    for(j=0;j<3;j++)
                    ;
            }
    }
return 0;
}
---------------------------

main函数在leds.c里面,用来点亮led   

程序烧到板子led不亮,是从nand flash-steppingstone启动的

然后我把head.S的bl main 改成 ldr pc, =2048试试,因为第二段代码存储在镜像2048的位置,但还是不亮

接着把head.S的bl main 改成 ldr pc, =3072试试,因为第二段代码在3072位置运行,但还是不亮

最后加上 bl  copy_2048_to_3072,把2048处的代码拷贝到运行地址3072,bl main 改成 ldr pc, =3072,还是不亮

相同的程序,我不用分段,在makefile里面用
ARM-linux-ld -Ttext 0x50000000 -o mmu_elf $^
连接后编译的程序,led可以点亮,说明main点亮函数是没有问题的。

现在能试的都试了,不知道为什么程序分段后,就不好用了,麻烦各位大神帮看看,十分感谢!
0
2019-8-14 19:34:22   评论 分享淘帖 邀请回答
29个回答
arm-linux-ld -Ttext 0x50000000 -o mmu_elf $^ 是指定链接地址 0x50000000,你LDS又来个链接地址 那它到底听谁的?
2019-8-15 04:17:17 评论

举报

谢谢韦老师的回答^_^
可能您没太懂我的意思,我的意思是说:
如果我makefile里面这么写:
arm-linux-ld -Ttext 0x50000000 -o mmu_elf $^   #不用lds文件
灯是可以亮的,没有问题
如果把makefile这么写,用lds文件:
arm-linux-ld -Tmmu.lds -o mmu_elf $^  #使用lds文件,lds内容请看1楼
那么led就是不亮的
很奇怪为什么用lds文件分段,led就不亮了?

谢谢韦老师^_^
分析两种方式的反汇编,看看有什么不一样
2019-8-15 04:32:49 评论

举报

谢谢 劳动力再生产 的回复 ^_^
请看反汇编的文件,好像没有什么问题吧,在chinaunix上面也有人帮看了, 说没有问题的
谢谢!
2019-8-15 04:43:52 评论

举报

我看了2个程序的反汇编,他们的main函数的链接地址是不一样的。
实在不懂你的用意: 使用了链接脚本,为什么多了一个程序搬运的过程?2048->3072
2019-8-15 05:00:32 评论

举报

谢谢回复^^
我是在实验,因为不"搬运"不亮,所以我就"搬运"一下试试,结果还是不亮
2019-8-15 05:13:11 评论

举报

嗯,main函数的链接地址是不一样
但不明白为什么? 为什么分段情况下 bl main就"找不到"main函数了?  分段情况下如何找到main函数?
谢谢^^
2019-8-15 05:30:51 评论

举报

韦老师的《嵌入式Linux应用开发》的第123页的程序就是用分段的, 但是在我的ok6410上不行, 在我的ok6410上只有 不用分段 才能调试通过这个程序, 实在搞不明白了.
2019-8-15 05:44:06 评论

举报

你可以把这个程序再弄简单一点:MAIN函数主体里面其他什么都不做,就一条点灯指令。
如果这个灯亮了,说明能够进入MAIN函数,如果这个灯都不亮说明还是地址的问题。
2019-8-15 05:51:32 评论

举报

谢谢超版回复^^
现在main函数里面如下:
int main()
{      
    GPMCON = 0x11111;      //配置为输出
    GPMDAT = 0x00000000;  //点亮

    return 0;
}
分段后还是不亮的.  不用分段还是能亮的.
其实原来的main也没啥代码, 就是循环点灯

真是奇怪啊.....
2019-8-15 06:03:57 评论

举报

2019-8-15 06:10:45 评论

举报

我来看看,新手……慢慢来
2019-8-15 06:18:32 评论

举报

谢谢yoyoball的回复
问题还没搞定, 不知道当时韦老师是怎么调试过的,难道只有在2440上面好用, ok6410调不通吗? 感觉不应该啊, 奇怪奇怪......
2019-8-15 06:31:45 评论

举报

我猜测 你6410的IO地址有改吗
2019-8-15 06:47:13 评论

举报

ldr     pc, =main 试试
2019-8-15 07:00:22 评论

举报

谢谢linyuetian的回复^^
6410的io地址没有问题,因为在不分段的情况下是好用的,可以亮
2019-8-15 07:12:07 评论

举报

刚刚我试过了, 还是不亮的
之前我也试过这条语句的, 是不能亮的
所以问题真的很奇怪啊 ^^
2019-8-15 07:25:15 评论

举报

要不把程序打包上来看看
2019-8-15 07:42:21 评论

举报

2019-8-15 08:01:35 评论

举报

只有小组成员才能发言,加入小组>>

12下一页

131个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表