本文主要探讨s5pv210裸机基础知识,arm指令,以及210启动刷机相关知识。
Soc与cpu
Soc是cpu与其他外设的集合即SoC<==>cpu+DDR+flash+utral+......
地址总线与数据总线
cpu通过地址总线寻址即传输DDR或flash等地址,通过数据总线与外设进行数据交换即传输DDR或flash等地址中的数据或被修改的数据
地址总线的位数决定cpu的寻址范围即arm32位-—>2^32—->2^32/2^30=4G故寻址范围是4G,可支持最大内存是4G
数据总线的位数决定cpu单次通信的交换的信息数量即arm32为单次可传输32位(int类型)
CPU在固定频率运行,通过总线读取外部存储设备中的二进制指令集解码执行
编程及运行过程
.c文件-->预编译-->.i文件-->编译-->.s文件-->汇编-->.o二进制文件(多个)-->链接-->elf可执行程序-->objcopy工具-->bin文件(可烧录到flash)-->总线-->cpu读入烧录的bin文件解码-->指令流水线-->cpu执行指令
cpu访问内存
IO与内存统一编址方式:外设寄存器当作内存地址来读写操作外设,类似内存访问方式,编程简单,地址空间有限
IO与内存独立编址:专用的CPU指令来访问外设,cpu设计复杂
存储
ROM:外存,只读存储器,硬盘,Flash(Nand iNand···· U盘、SSD),光盘
IROM:SOC内部ROM
NorFlash:总线式相连,CPU上电后可直接读取,用作启动介质,接到SROM bank
NandFlash:不能直接读取,需初始化后通过时序接口读写,eMMC/iNand/moviNand oneNAND SD卡/TF卡/MMC卡 eSSD
RAM:内存,随机访问存储器
IRAM:SOC内部RAM
DRAM:动态RAM,使用前需要初始化
SRAM:静态RAM,上电可使用,无需初始化
注意:嵌入式系统的存储为外接的大容量Nand + 外接大容量DRAM + SoC内置SRAM
寄存器
寄存器是CPU外设,程序操控硬件的接口且每个bit位有特定含义
ARM有37个寄存器,每个寄存器长度为32位,通用寄存器(30),PC(1),CPSR(1),SPSR(5)
cpsr寄存器
31 | 30 | 29 | 28 | 27 | ... | 24 | 23 8 | 7 | 6 | 5 | 4 0 |
N | Z | C | V | Q | ... | J | undefine | I | F | T | model |
条件位:
N :指令运算结果值。1表示结果为负,0表示结果为正或零
Z :1表示运算结果为0,0表示运算结果不为0(cmp指令)
C :加法指令(cmn指令)结果产生进位C=1,其他C为0,减法指令(cmp指令),运算中发生借位C=0其他C=1,移位操作指令,C最后位的值,其他指令,C不变
V:加减指令,运算结果为二进制带符号位的补码,1表示符号位溢出
Q :ARM 5TE/J架构支持,指示饱和状态
J :仅ARM 5TE/J架构支持1表示处理器处于Jazelle状
中断位:
I :1为IRQ.
F :1为FIQ.
T :仅ARM xT架构支持0处于 ARM 状态,1处于Thumb状态
Mode位:处理器模式位(工作模式)
PC(r15)
pc为程序指针,pc的指向为cpu操作的对象,模式跳转时,pc指向目标寄存器地址
lr(r14)
保存子程序返回地址,异常发生时保存发生前的相应位置(lr = PC - 4)
sp(r13)
堆栈寄存器,用于程序保存或恢复数据,用于子程序调用及中断响应时保护与恢复现场
cpu工作模式
User:非特权模式,多数任务执行状态
FIQ:优先级中断模式
IRQ:低优先级中断模式
Supervisor:复位和软中断模式
Abort:读取写入异常模式
Undef:指令异常种模式(未定义指令)
System:特权模式
注意:除user外其他都为特权模式,特权模式中除system外其余特权模式可手动切换(写cpsr)或cpu自发进行(一般)且不同模式下可访问的寄存器不同
中断异常
异常向量表:存储异常处理方式的地址,异常发生时CPU(pc)自发跳转
异常处理流程:产生异常-->拷贝CPSR到SPSR(具体的异常模式下的scpr,CPU自发进行)->设置 CPSR的运行模式(cpsr的model)->处理器进入ARM 态(设置cpsr下的T位为0,CPU自发进行)->改变处理器模式进入相应的异常模式->设置中断禁止位禁止相应中断(设置cpsr的中断位,cpu自发)->保存返回地址到 LR(lr = pc - 4)->设置PC指向异常向量处理异常位置->异常处理返回->拷贝SPSR到CPSR->pc指向lr中的位置(mov pc, lr)
arm汇编指令
ldr:将内存内容加载入通用寄存器中
str:将寄存器内容存入内存空间中
寄存器寻址 mov r1, r2 r1 = r2
立即寻址 mov r0, #0xFF00 r2 = 0xFF00(合法立即数)
寄存器移位寻址 mov r0, r1, lsl #3 r0 = r1<<3
寄存器间接寻址 ldr r1, [r2] r1 = *r2(r2位内存地址)
基址变址寻址 ldr r1, [r2, #4] r1 = *(r2 + 4)
多寄存器寻址 ldmia r1!, {r2-r7, r12}
堆栈寻址 stmfd sp!, {r2-r7, lr}
相对寻址 beq flag if(eq) {flag}
按位取反传递 r1 = 0x000000ff;mvn r0, r1 r0 = 0xffffff00
与 and
或 orr
异或 eor
位清除 bic r0,r1,#0x1f r1中bit0到bit4清零赋给r0
MOV与ldr
MOV r1,r2 r1 = r2;
MOV r0,#0 r0 = 0;
mov r0,#0xFF00 r0 =0xFF00
ldr r0,=0 r0 = 0
ldr r0,r1 r1寄存器中放入r0的值
ldr r0, 0x12345678 r0 = 0x12345678
ldr r2,[r0] r2 = *r0;r0中存储的是地址
LDR伪指令
ldr r0, =0x12345678 0x12345678地址写入r0
ldr r0, =_start 将标号值赋给r0
注意:mov指令限制立即数长度为8位(512),ldr伪指没有,ldr伪指令立即数没超8位,汇编过程中ldr转为mov
比较指令(默认修改cpsr)
cmp r0, r1 == sub r2, r0, r1 (r2 = r0 - r1)
cmn r0, r1 == add r0, r1 (r0 = r0 + r1)
tst r0, #0xf 判断r0的bit0~bit3是否全为0
teq 是否相等,按位异
指令后缀
B(byte)8位
H(half word)16位
S(signed)有符号,影响CPSR标志位
协处理器
CP15协处理器和MMU、cache、TLB等处理有关,功能上和操作系统的虚拟地址映射、cache管理等有关
mrc 读取CP15寄存器
mcr 写入CP15寄存器
mcr p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}
opcode_1:cp15为0
Rd:普通寄存器
Crn:cp15寄存器,合法值是c0~c15
Crm:cp15的寄存器,一般为c0
opcode_2:省略或为0
地址指令后缀
ia(increase after) 先传输,再地址+4
ib(increase before) 先地址+4,再传输
da(decrease after) 先传输,再地址-4
db(decrease before) 先地址-4,再传输
fd(full decrease) 满递减堆栈
ed(empty decrease) 空递减堆栈
fa(full append) 满递增堆栈
ea (empty append) 空递增堆栈
!
ldmia r0, {r2 - r3} r2-r3加载到r0执行,结束后r0值不变
ldmia r0!, {r2 - r3} 修改r0的值为r2-r3执行,结束后r0值为r3
^:目标寄存器有pc,会将spsr写入到cpsr(异常返回过程)
ldmfd sp!, {r0 - r6, pc} 7个寄存器使用
ldmfd sp!, {r0 - r6, pc}^ 9个寄存器使用
gnu伪指令
@ 注释
: 标号
. 指令的地址
# 立即数
nop 空操作
.global _start _start外部链接属性
.section .text 段为代码段
.ascii .byte .short .long .word .quad .float .string 定义数据
.align 4 以2^4字节对齐
.balignl 16 0xabcdefgh 以16字节对齐填充0xabcdefgh
.equ 类似于C中宏定义
.end 文件结束标识
.include 头文件包含
.arm / .code32 声明arm指令
.thumb / .code16 声明thubm指令
b . while(1);
IRQ_STACK_START: .word 0x0badc0de unsigned int IRQ_STACK_START = 0x0badc0de;
adr和ldr
ldr加载地址在链接时确定,adr加载地址在运行时确定
通过adr和ldr加载地址判断程序是否在链接指定地址运行
编译时adr被sub或add替代,ldr被mov替代
adr以PC为基地址,指令和运行地址有关,可以检测程序当前运行地址
ldr加载地址和链接地址有关,由链接脚本决定
210启动过程
210内置96KB SRAM(iRAM),64KB NorFlash(iROM)
CPU上电后从IROM读取代码(BL0)执行,代码做初始化(CPU时钟、关看门狗,初始化icache,初始化栈···)并且判断启动模式(SD2或Uart或USB),读取代码BL1,(16KB)到iSRAM运行代码初始化NandFlash,读BL2到IRAM运行代码初始化DRAM,将OS读到DRAM,启动OS
注意:usb启动usb启动不需要16字节校验头,烧录起始地址为0xd0020010,sd卡启动需要校验,烧录起始地址为0xd0020000
210刷机
linux和android擦除uboot
busybox dd if=/dev/zero of=/dev/block/mmcblk0 bs=512 seek=1 count=1 conv=sync
sync
uboot擦除uboot:
movi write u-boot 0x30000000
官方工具烧录uboot.bin,crt连接,重启进入uboot
按默认分区
fdisk -c 0
启动fastboot
fastboot
windows启动fastboot并安装驱动
查看设备接入
fastboot devices
SMDKC110-01 fastboot
烧录
fastboot flash bootloader uboot.bin
fastboot flash kernel zImage
fastboot flash system rootfs_qt4.ext3
fastboot reboot