以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。
程序结构:程序由sdram.S和main.c两个文件组成,sdram.S文件完成一些初始化工作,如时钟初始化,内存控制器初始化,拷贝第二阶段代码到sdram等;main.c负责循环点亮、熄灭四个LED。
程序流程:上电时,cpu自动跳到复位异常向量入口,在复位异常处理里首先关闭看门狗,接着初始化系统时钟,初始化内存控制器,拷贝第二阶段代码到sdram,最后跳转到sdram里执行main()函数。
sdram.S:
1 #define MEM_REG_START 0x48000000 2 #define SDRAM_BASE 0x30000000 3 4 #define LOCKTIME 0x4C000000 5 #define MPLLCON 0x4C000004 6 #define UPLLCON 0x4C000008 7 #define CLKDIVN 0x4C000014 8 #define CAMDIVN 0x4C000018 9 10 #define WTCON 0x53000000 11 12 13 .section .text 14 .global _start 15 _start: 16 b reset 17 18 @复位异常处理 19 reset: 20 @关闭看门狗 21 bl disable_watchdog 22 @初始化时钟 23 bl init_clock 24 @初始化内存控制器 25 bl init_sdram 26 @拷贝第二阶段代码到SDRAM 27 bl copy_to_sdram 28 29 ldr pc,=on_sdram 30 on_sdram: 31 @设置栈指针 32 ldr sp,=0x34000000 33 @跳到main()函数 34 bl main 35 loop: 36 b loop @死循环 37 38 39 disable_watchdog: 40 ldr r0,=WTCON 41 bic r1,r0,#0x20 42 str r1,[r0] 43 44 mov pc,lr 45 46 init_clock: 47 ldr r0,=LOCKTIME 48 ldr r1,=0x00ffffff 49 str r1,[r0] 50 @时钟分频1:4:8 51 ldr r0,=CLKDIVN 52 ldr r1,=0x05 53 str r1,[r0] 54 @异步总线模式 55 mrc p15,0,r1,c1,c0,0 56 orr r1,r1,#0xc0000000 57 mcr p15,0,r1,c1,c0,0 58 @FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ 59 ldr r0,=MPLLCON 60 ldr r1,=0x5c011 61 str r1,[r0] 62 @UPLL=48MHZ 63 ldr r0,=UPLLCON 64 ldr r1,=0x38022 65 str r1,[r0] 66 67 mov pc,lr 68 69 copy_to_sdram: 70 ldr r0,=2048 @要拷贝的代码的起始地址 (源地址) 71 ldr r1,=SDRAM_BASE @要拷贝到的地址(目的地址) 72 add r3,r0,#2*1024 @拷贝大小(2K) 73 copy_loop: 74 ldr r2,[r0],#4 75 str r2,[r1],#4 76 cmp r0,r3 77 bne copy_loop 78 79 mov pc,lr 80 81 init_sdram: 82 ldr r0,=MEM_REG_START 83 adrl r1,mem_cfg_val 84 add r2,r0,#52 //13个寄存器,每个占4字节(13*4) 85 mem_cfg_loop: 86 ldr r3,[r1],#4 87 str r3,[r0],#4 88 cmp r0,r2 89 bne mem_cfg_loop 90 91 mov pc,lr 92 93 @寄存器配置值 94 .align 4 95 mem_cfg_val: 96 .long 0x22011110 //BWSCON 97 .long 0x00000700 //BANKCON0 98 .long 0x00000700 //BANKCON1 99 .long 0x00000700 //BANKCON2100 .long 0x00000700 //BANKCON3101 .long 0x00000700 //BANKCON4102 .long 0x00000700 //BANKCON5103 .long 0x00018005 //BANKCON6104 .long 0x00018005 //BANKCON7105 .long 0x008c04f4 //REFRESH(HCLK=100MHZ)106 .long 0x000000b1 //BANKSIZE107 .long 0x00000030 //MRSRB6108 .long 0x00000030 //MRSRB7
main.c:
1 #define GPBCON (*(volatile unsigned long *)0x56000010) 2 #define GPBDAT (*(volatile unsigned long *)0x56000014) 3 #define GPBUP (*(volatile unsigned long *)0x56000018) 4 5 #define nGPB_OUTPUT ((1<<10)|(1<<12)|(1<<14)|(1<<16)) 6 7 //延时函数 8 void delay() 9 {10 int i = 0xffff;11 int j;12 for(j=0;j
Makefile:
1 objs := sdram.S main.c 2 3 sdram.bin:$(objs) 4 arm-linux-gcc -c -o sdram.o sdram.S 5 arm-linux-gcc -c -o main.o main.c 6 arm-linux-ld -Tsdram.lds -o sdram_elf 7 arm-linux-objcopy -O binary -S sdram_elf sdram.bin 8 9 clean:10 rm -f sdram_elf sdram.bin *.o
链接脚本sdram.lds:
1 SECTIONS2 {3 nand 0x00000000 : {sdram.o}4 sdram 0x30000000 : AT(2048) {main.o}5 }
执行make之后通过BIOS将sdram.bin文件下载到nand flash,从nand flash启动。