6.内存映射与启动寻址方式
1)S3C2440(ARM920T)
启动方式:Nor Flash 启动。
地址范围:0x0 - 0x200000(2MB)。
特性:代码、指令可被直接寻址(支持片内执行 XIP)。
PC指针:指向 0x0,从 Nor Flash 起始地址开始执行。
2)IMX6ULL(Cortex-A7)
存储设备:Nand Flash(EMMC 8GB),不可被寻址(不能直接运行代码)。
运行内存:DDR3(512MB),地址范围 0x80000000 - 0xA0000000。
运行机制:需将代码从 Nand Flash 拷贝到 DDR3 中运行。
链接地址:通过链接器脚本指定 ld -Ttext 0x87800000,PC指针指向此地址开始执行。

7.编译工具链与构建流程
1. 常用工具命令(交叉编译工具链:arm-linux-gnueabihf-)
GCC:编译源码。
arm-linux-gnueabihf-gcc -g -c start.S -o start.o(编译汇编文件,-g带调试信息,-c只编译不链接)
arm-linux-gnueabihf-gcc -g -c main.c -o main.o(编译C文件)
LD:链接目标文件,生成 ELF 文件。
arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o main.o -o start.elf(-Ttext指定代码段链接起始地址)
OBJCOPY:格式转换,提取二进制文件。
arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin(-O binary输出纯二进制,-S去掉符号表,-g去掉调试信息)
OBJDUMP:反汇编工具。
补充选项:-I 指定头文件路径,-L 指定库文件路径。
2)程序段(Sections)概念
.text段:存放代码、指令(链接时通过 -Ttext 87800000 指定起始位置)。
.bss段:存放初始化为0的全局变量和静态变量。
.common段:存放未初始化的全局变量。
.data段:存放已经初始化的全局变量和静态变量。
.rodata段:存放只读常量。
链接脚本:文件(特殊语法格式),用于控制链接过程,决定各个段在内存中的布局。
3)工程目录结构
project:存放主入口文件 main.c、启动文件 start.S。
imx6ull:存放官方或自编的库文件。
bsp:外设驱动文件,如 led.c / led.h、beep.c / beep.h。
obj:存放编译生成的 .o 目标文件。
8.Makefile 基础
三要素:
目标(目标文件):要生成的文件。
依赖(源文件):生成目标所需的文件。
规则:如何从依赖生成目标的命令。
9.C语言操作寄存器
1)寄存器宏定义
通过指针直接访问物理地址:
c
#define CCM_CCGR0 (*(unsigned int *)0x020C4068)
CCM_CCGR0 = 0xFFFFFFFF; // 打开所有外设时钟
硬件特性:写1清0(常见于中断状态寄存器或GPIO状态寄存器,写1来清除标志位)。
2)volatile 关键字
作用:防止编译器优化代码。
变量前加 volatile:表示编译器对该变量的任何操作不会被优化(每次访问都直接从内存读取,而不是使用寄存器缓存)。
指针加 volatile:表示通过该指针访问的内存空间中的内容不会被优化。
裸机开发中操作寄存器必须使用 volatile,防止因为编译器优化导致硬件操作失效。
10.点灯实验实现方式
汇编点灯:直接操作寄存器地址。
C点灯:使用C语言封装寄存器操作。
NXP提供固件库点灯:使用官方SDK提供的接口函数,开发效率高但代码体积大。