- 论坛徽章:
- 0
|
本帖最后由 草根老师 于 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代码
实验没有任何效果,不知道哪里错了,请大家帮忙看看,先谢谢了。 |
|