免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2256 | 回复: 2

[BootLoader] 链接脚本问题 [复制链接]

论坛徽章:
0
发表于 2012-11-02 16:21 |显示全部楼层
本帖最后由 草根老师 于 2012-11-02 16:22 编辑

各位大牛,帮小弟看个裸机代码

运行平台:s3c2410

目标: 测试链接脚本

第一阶段:

.text
.global _start
_start:

#define pWTCON                         0x53000000
#define CLKDIVN                 0x4c000014
#define MPLLCON                 0x4c000004
#define MEMBASE                 0x48000000
#define SRAM_2_ADDR         0
#define SDRAM_2_ADDR        0x30000000
#define SRAM_SIZE                4096

start_code:
        @set the cpu to SVC32 mode
        mrs r0,cpsr
        bic r0,r0,#0x1f
        orr r0,r0,#0xd3
        msr cpsr,r0

        @打开指令cache
        mrc p15,0,r0,c1,c0,0
        @orr        r0,r0,#0x1000
        mcr p15,0,r0,c1,c0,0
        
        @关看门狗
        bl disable_watchdog

        @初始化系统时钟
        bl init_sys_clock
               
        @初始化内存
        bl init_sdram
        
        @拷贝SRAM的代码到SDRAM
        bl copy_to_sdram
        
        @运行led程序
        ldr sp,=0x33000000 @重设sp指针,mmu之后,
                                           @cpu操作的地址都是虚拟地址  
        ldr pc,_main

_main:
        .word main
        
disable_watchdog:
        @关看门狗,不然cpu会不断重启
        ldr r0,=pWTCON
        mov r1,#0
        str r1,[r0]
        mov pc,lr
        
        
init_sys_clock:
        @目前为止,cpu工作在12MHZ频率下
        @提升cpu工作频率FCLK:HCLKCLK=1:2:4
        ldr r0,=CLKDIVN
        mov r1,#3
        str r1,[r0]
        
        @ifHDIVN=1,must asynchronous buf mode
        mrc p15,0,r0,c1,c0,0
        orr r0,r0,#0xc0000000
        mcr p15,0,r0,c1,c0,0

        @设置MPLL,使cpu工作在202.80MHZ
        ldr r0,=MPLLCON
        ldr r1,=0x000a1031
        str r1,[r0]        
        mov pc,lr

copy_to_sdram:
        ldr r0,=2048                   @第二阶段代码起始地址(204
        ldr r1,=0x30004000   @第二阶段代码存放的物理地址(0x30004000)
1:
        ldr r2,[r0],#4
        str r2,[r1],#4
        cmp r0,#4096
        bne 1b
        
        mov pc,lr

init_sdram:
        @初始化sdram
        ldr r0,=MEMBASE                @13个寄存器的首地址
        adrl r1,SMRDATA                @13个寄存器值存放的地址
        mov r2,#52                        @13 * 4 = 52
        
        add r2,r2,r1

1:
        ldr r3,[r1],#4
        str r3,[r0],#4
        cmp r1,r2
        bne        1b
        
        /*every thing is fine now*/
        mov pc,lr
        
        .ltorg                        @声明一个数据缓冲池的开始

SMRDATA:
        .word        0x2201d110                    @BWSCON 设置BANK3位宽16,使能nWait,使能UB/LB
        .word        0x0700                                        @BANKCON0
        .word        0x700                                        @BANKCON1
        .word        0x700                                        @BANKCON2
        .word        0x700                                        @BANKCON3
        .word        0x700                                        @BANKCON4
        .word        0x700                                        @BANKCON5
        .word        (3 << 15) + (1 << 0)        @BANKCON6
        .word        0x18001                                        @BANKCON7
        .word        (1 << 23) + (2 << 1 + (1256 << 0) @REFRESH
        .word        (1 << 7) + (1 << 0)                @BANKSIZE
        .word        (3 << 4)                                 @MRSRB6
        .word        (3 << 4)                                @MRSRB7

第二阶段:

#define GPFCON               (*(volatile unsigned long *) 0x56000050)
#define GPFDAT               (*(volatile unsigned long *) 0x56000054)

//初始化
static inline void led_init()
{
        //GPFCON -> [8:15]清零
        GPFCON &= ~(0xff << ;
        //GPF4 GPF5 GPF6 GPF7设为输出模式
        GPFCON |= 0x55 << 8;
        //输出高低平,关闭四路LED灯
        GPFDAT |= 0xf << 4;

        return;
}

//关闭LED
static inline int led_off()
{
        GPFDAT |= 0xf << 4;
        
        return 0;
}

//延时函数
static inline int delay_time(int time)
{
        int i,j;
        
        //让两个for循环作为延时
        for(i = 0;i < time;i ++)
                for(j = 0;j < time;j ++);

        return 0;
}

//流水灯
static inline int run_water_led(int count)
{
        int i = 0;
        
        while(count --)
        {
                led_off();
                delay_time(500);

                for(i = 4;i < 8;i ++)
                {
                        GPFDAT &= ~(0x1 << i);
                        delay_time(500);
                }
        }

        return 0;
}

int main()
{               
        led_init();
        run_water_led(5);
        led_off();         

        return 0;
}


链接脚本:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm"
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm"*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
        firtst 0x00000000:{start.o}
        second 0x30004000:AT(204{led.o}
}

Makefile:

led.bin:start.S led.c
        arm-none-linux-gnueabi-gcc -c  start.S -o start.o
        arm-none-linux-gnueabi-gcc -c -O led.c -o led.o
        arm-none-linux-gnueabi-ld -Tmap.lds start.o led.o -o led_elf
        arm-none-linux-gnueabi-objcopy -O binary -S led_elf led.bin
        cp led.bin /tftpboot

clean:
        rm -rf *.o led_elf led.bin


内存初始化,时钟,led的操作都已经验证通过
开发板从nand启动,会自动把nand的前4k拷贝到sram中,运行起来之后,我想把从sram地址2048开始的代码搬移到sdram的地址0x30004000处,然后将pc跳过去执行led代码

实验没有任何效果,不知道哪里错了,请大家帮忙看看,先谢谢了。

论坛徽章:
0
发表于 2012-11-07 15:22 |显示全部楼层
你下载一个支持S3C4210的uboot的最原始版本,看看它是怎么做的,你有什么没有考虑到。

论坛徽章:
0
发表于 2012-11-07 19:54 |显示全部楼层
回复 1# 草根老师
第一步:
     把生成的elf文件dump出来看下,是不是按照想象的那样,start.o生成的text段是从0开始的吗?led.o是不是从0x30004000开始的?
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP