Makefile的语法规则:
target: ....:prerequisites.....command
target:目标文件。
prerequisites:生成的目标所需要的文件或目标,即生成目标文件所要的依赖。
command:make时所执行的命令。
GCC:
-c 编译或汇编文件,但是不链接。预处理后的代码送往标准输出。
-o 要求编译器生成制定文件名的目标文件。
-O 要求编译器对代码进行基本的优化。
arm-linux-ld:链接.o文件生成目标文件,通过-Ttext addr、-Tdata addr、-Tbss addr,指明代码段、数据段、bss段。
arm-linux--objcopy:把目标文件转换为所需要的文件格式,如二进制文件。
arm-linux-objdump:进行反汇编。
MINI2440裸机程序,点亮两个LED。
mini2440的cpu内部有4KB的ARM,外部有64MB的SDARM,有2MB的NOR FLASH,256MB的NAND FLASH。如果从NAND FLASH启动,cpu会强制把NAND FLASH 的前4KB代码,读到cpu内部的ARM中并开始取指执行,这都是通过硬件电路实现的。如果从NOR FALSH启动,会直接在NOR FALSH中执行程序。NOR FALSH 拥有完整的数据、地址总线并且其能够一字节为单位进行读取。NAND FALSH数据总线和地址总线串行,并且以块为单位进行数据的读取。所一裸机程序要烧写到NAND FLASH中,在加电启动时前4KB被读取到cpu内部的ARM,完成CPU的初始化。裸机程序如果较小没有函数调用则可以直接下载到NAND FLASH中运行。如果有函数调用并且不超过4KB要初始化堆栈。如果用C写的就必须用启动文件初始化堆栈,因为执行main函数时必须被调用,在操作系统级别操作,系统的库会调用main函数,裸机程序要用启动文件调用main,既然被调用,就需要保护现场,恢复现场,必须要有堆栈保存这些信息。如果大于程序4KB要完成CPU的内存管理等初始化操作。同时一定要关闭看门狗,否则cpu会一直重启。
Makefile文件的内容:
<span style="font-size:14px;">led:start.S led.c
arm-linux-gcc -g -c start.S -o start.o
arm-linux-gcc -g -c led.c -o led.o
arm-linux-ld -Ttext=0x00000000 -g start.o led.o -o led
arm-linux-objcopy -O binary led led.bin
clean:
rm -f led.o led led.bin start.o *~</span>
目标为led,依赖start.c和led.c。ledd.h的内容:
<span style="font-size:14px;">#ifndef _LEDD_H_
#define _LEDD_H_
#define GPIO 0x56000000 /*GPIO的基地址*/
#define GPBCON (*(volatile unsigned long *)(GPIO + 0x10))
#define GPBDAT (*(volatile unsigned long *)(GPIO + 0x14))
#endif</span>
led.c的全部内容:<span style="font-size:14px;">#include "ledd.h"
int main()
{
GPBCON &= (~(0x3 << 12 | 0x3 << 14));
GPBCON |= ( 0x1 << 12 | 0x1 << 14);
GPBDAT &= ~(0x1 << 6 | 0x1 << 7);
while(1);
}</span>
start.c的全部内容:<span style="font-size:14px;">@#############################################################
@ 关闭看门狗,设置堆栈,为调用C做准备
@#############################################################
.text
.global _start
_start:
ldr r0, =0x53000000 @设置看门狗地址
mov r0, #0x00 @关闭看门狗
ldr sp, =0x4*1024 @设置堆栈,4KB
bl main @调用函数
</span>