ARM裸机开发-1.基础知识

本文介绍了ARM裸机开发的基础知识,包括Soc、外设、BSP、地址总线和数据总线的概念。深入探讨了CPU的寄存器类型和作用,特别是通用寄存器与特殊功能寄存器。文章还详细阐述了S5PV210的启动过程,从IROM到BL0、BL1、BL2的加载和执行流程。最后,概述了ARM的编程特点、汇编指令集和伪指令,强调了ARM指令的寻址方式、多级流水线以及异常处理机制。
摘要由CSDN通过智能技术生成

1.基础知识

内核版本号Soc版本号芯片型号(三星)
ARMv1
ARMv4ARM7S3C44B0
ARMv4ARM9S3C2440 S3C2410
ARMv5ARM9+xScale
ARMv6ARM11S3C6410
ARMv7Cortex-M Microcontroller,单片机使用
Cortex-A application 手机,平板电脑使用
Cortex-R real time,实时操作系统

Soc :System on chip (将一部分外设和CPU集成的芯片)
外设(Peripherial) : 外部设备(除了CPU以外的设备)
BSP :board support package 板级支持包(支持硬件的相关软件,官方给的硬件包/驱动,根据板子移植过的)
地址总线和数据总线
CPU通过地址总线寻址,然后通过数据总线与外部设备互换信息,地址总线的位数决定CPU的寻址范围;数据总线的位数决定CPU单次通信能交换的信息数量。总线的速度决定CPU和外设互换信息的速度。CPU的地址总线位数和数据总线可以不同,但一般都相同,CPU的位数指的是数据总线的位数,32位CPU寻址范围是4G,所以最多支持4G内存,数据总线是32位的,所以内存32位的好,所以编程最好用int

可编程逻辑器件 英文全称为:programmable logic device 即 PLD。

对于可编程逻辑器件,设计人员可利用价格低廉的软件工具快速开发、仿真和测试其设计。 然后,可快速将设计编程到器件中,并立即在实际运行的电路中对设计进行测试。
​​​​在这里插入图片描述

CISCRISC
complex instruction set computer复杂指令集CPUReduced Instruction-Set Computer精简指令
用最少的指令来完成任务
设计复杂、工艺复杂
编译器好设计
让软件来完成具体的任务,CPU本身仅提供基本功能指令集
CPU的设计和工艺简单
编译器的设计变难
内存IO
定义程序的运行场所,和CPU之间通过总线连接,内存通过CPU的地址总线来寻址定位,然后通过CPU数据总线来读写。输入输出接口,是CPU和其他外部设备之间通信的道路。一般的,IO就是指CPU的各种内部或外部外设。
与CPU的连接方式直接连接IO与内存统一编址方式 : 类似于访问内存的方式,即把外设的寄存器当作一个内存地址来读写,从而以访问内存相同的方式来操作外设IO与内存独立编址 : 使用专用的CPU指令来访问 某种特定外设
优点效率高访问快IO当作内存来访问,编程简单不占用CPU地址空间
缺点资源有限,扩展性差。IO也需要占用一定的CPU地址空间,而CPU的地址空间是有限资源。CPU设计变复杂了
冯诺依曼结构哈佛结构
定义程序和数据都放在内存中,且不彼此分离程序和数据分开独立放在不同的内存块中,彼此完全分离
优点处理起来简单安全和稳定性高
缺点安全和稳定性低软件处理复杂一些

寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果, 是CPU的硬件设计者制定的,目的是留作外设被编程控制的“ 活动开关 ”,正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。
编程操作寄存器类似于访问内存,每个bit位都有特定含义,因此编程操作时需要位操作。单个寄存器的位宽一般和CPU的位宽一样,以实现最佳访问效率。
SoC中有2类寄存器:
• 通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
• SFR(special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。

ARM体系结构

  • ARM是RISC架构 常用ARM汇编指令只有二三十条,是低功耗CPU
  • SoC中的各种内部外设通过各自的SFR编程访问,这些SFR的访问方式类似于访问普通内存,这叫IO与内存统一编址。
  • ARM是哈佛结构的,保证了ARM CPU运行的稳定性和安全性,因此ARM适用于嵌入式领域,哈佛结构也决定了ARM裸机程序(使用实地址即物理地址)的链接比较麻烦,必须使用复杂的链接脚本告知链接器如何组织程序;对于OS之上的应用(工作在虚拟地址之中)则不需考虑这么多
存储设备含义
ROM只读存储器(read only memory),比如硬盘,flash。这里的不能写指的是CPU不能通过地址总线和数据总线去写。硬盘的写是通过专用的IO接口写。
RAM随机存取存储器(random access memory),可以随机访问,想访问哪个地址就访问哪个地址,存储器当系统断电后,数据会丢失。 flash是顺序访问,按页访问,要访问第四个字节需要从头开始,0,1,2,3,访问完才能访问4
IROMinternal rom 内部ROM,指的是集成到SoC内部的ROM
IRAMinternal ram 内部RAM,指的是集成到SoC内部的RAM
DRAM外部动态随机存储器,需要每隔一段时间就刷新充电一次,否则的话数据会丢失。DRAM的速度比SRAM要慢,但是比ROM快,速度慢那么对应的价格也要比SRAM便宜一些。DRAM分为很多种,常见的有SDRAM,DDRRAM,RDRAM,SGRAM等等
SRAM静态随机存储器,它具有静止存取的功能,也就是可以不需要刷新电路就保存内部的数据。性能高,功耗小,速度快,价格高,它是目前(2017年)最快的存储设备。
SROMCSROM Controler
ONENAND三星发明的一种NAND
NANDNAND flash
SFRspecial function register 特殊功能寄存器

rom最初不能编程,出场什么内容就永远什么内容,不灵活。后来出现了prom,可以自己写入一次,要是写错了,只能换一片。随着不断的进步,出现了可多次擦除写入的EPROM,每次擦除要把芯片拿到紫外线上照一下,想一下你往单片机上下了一个程序之后发现有个地方需要加一句话,为此你要把单片机放紫外灯下照半小时,然后才能再下一次,这么折腾一天也改不了几次。历史的车轮不断前进,伟大的EEPROM出现了,拯救了一大批程序员,终于可以随意的修改rom里的内容了。
EEPROM全称是“电可擦除可编程只读存储器”,即Electrically Reasable Programmable Read-Only Memory,是相对与紫外擦除的rom来讲的,但是今天已经存在多种EEPROM的变种,变成了一类存储器的统称。
侠义的EEPROM:这种rom的特点是可以随机方位和修改任何一个字节,可以往每个bit中写入0或者1,这是传统的一种EEPROM,掉电后数据不丢失,可以保存100年,可以擦写100W次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的EEPROM都是几十千字节到几百千字节的,绝少有超过512K的。
flash属于广义的EEPROM,因为它也是电擦除的rom。但是为了去吧于一般的按字节为单位的擦写的EEPROM,我们都叫它flash。
flash做的改进就是擦除时不再以字节为单位而是以块为单位,一次简化了电路,数据密度更高,降低了成本。上M的rom一般都是flash.
flash一般分为norflash和nand flash,nor flash数据线和地址线分开,可以实现ram一样的随机寻址功能,可以读取任何一个字节,但是擦除仍要按块来擦。
nand flash 同样时是按块擦除,但是数据线和地址线复用,不能利用地址线随机寻址,读取只能按页来读取。
由于nand flash引脚上复用,因此读取速度比nor flash慢一点,但是擦除和写入速度比nor flash快很多。nand flash内部电路更简单,因此数据密度大,体积小,成本也低。因此大容量的flash都是nand型的,小容量的2~12M的flash多是nor型的
使用寿命上,nand flash的擦除次数是nor的数倍,而且nand flash可以标记坏块,从而是软件跳过坏块,nor flash一旦损坏便无法使用。
因为nor flash可以进行字节寻址,所以程序可以再nor flash中运行,嵌入式系统多是用一个小容量的nor flash存储引导代码,用一个大容量的nand flash存放文件系统和内核。

在这里插入图片描述
ROM是放代码的,RAM是放数据的,IROM和IRAM之前有一段不能用的空间是防止越界,覆盖原先的内容。
安全区域:CPU是否对代码做校验
在这里插入图片描述

内存(RAM)外存(ROM)
定义内部存储器外部存储器
作用用来运行程序的用来存储东西的
例子DRAM SRAM DDR 地址总线链接硬盘 flash(Nand iNand U盘 SSD) 光盘
与CPU连接方式地址总线&数据总线的总线式访问方式连接,好处是直接访问,随机访问;坏处是占用CPU的地址空间,大小受限通过CPU的外存接口来连接的,好处是不占用CPU的地址空间,坏处是访问速度没有总线式快,访问时序较复杂

Soc常用外存:

flash(电子存储,嵌入式)NorFlash总线式访问,可以接到地址空间,接到 SROMbank,一般用来启动,小而贵
NandFlash(通过时序访问)NandFlash分为SLC(容量小,价格高,时序简单,不容易坏块)和MLC(容量大,价格低,时序复杂,容易坏块)
eMMC/iNand/moviNandeMMC(embeded MMC),iNand是sanDisk公司出产的eMMC,moviNand是三星公司出产的eMMC
oneNANDoneNand是三星公司出的一种Nand
SD卡/TF卡/MMC卡其实都是SD卡
eSSDembeded SSD,固态硬盘
硬盘(磁存储,台式机)SATA硬盘机械式访问、磁存储原理、SATA指的是接口,价格便宜

x210有2个版本,Nand版和iNand版,分别使用Nandflash和iNand作为外部存储器,我们使用的是iNand版本,板载4GB iNand。
S5PV210共支持4个SD/MMC通道,其中通道0和2依次用作启动。X210开发板中SD/MMC0通道用于连接板载MMC,因此外部启动时只能使用SD/MMC2通道。

2.S5PV210的启动过程详解

特点优缺点
内存SRAM静态内存容量小、价格高,基本没有上兆(M)的优点是不需要软件初始化,直接上电就能用
DRAM动态内存容量大,价格低缺点是上电后不能直接使用,需要软件初始化后才能使用
单片机中:内存需求量小,而且希望开发尽量简单,适合全部用SRAM 嵌入式系统:内存需求量大,而且没有NorFlash等可启动介质 PC机: 内存需求量大,而且软件复杂,不在乎DRAM的初始化开销,适合全部用DRAM
外存NorFlash容量小,价格高优点是可以和CPU直接总线式访问,CPU上电后可以直接读取,所以一般用作启动介质
NandFlash和硬盘一样容量大,价格低缺点是不能总线式访问,也就是说不能上电CPU直接读取,需要CPU先运行一些初始化软件,然后通过时序接口读写。
一般PC机都是很小容量的BIOS(NorFlash) + 很大容量的硬盘(类似于NandFlahs)+ 大容量的DRAM 嵌入式系统:因为NorFlash很贵,所以现在很多嵌入式系统倾向于不用NorFlash,直接用外接的大容量Nand + 外接大容量DRAM + Soc内置SRAM 单片机: 很小容量的NorFlah + 很小容量的SRAM

在这里插入图片描述

  1. CPU上电后先从内部IROM中读取预置的代码(BL0),执行。这段IROM代码首先做了一些基本的初始化(CPU时钟、关看门狗等Soc内部的初始化);
  2. iROM引导代码将第一部分启动代码(BL1,最大为16KB)加载到内部SRAM中。
  3. 通过BL1加载BL2(最大位80KB)
  4. BL2初始化DRAM控制器,然后加载OS到SDRAM
  5. 跳转到OS起始地址,初始化OS运行环境并运行

BL0工作:

  1. 关看门狗
  2. 初始化指令cache
  3. 初始化栈
  4. 初始化堆
  5. 初始化块设备复制函数device copy function
  6. 初始化PLL,设置SoC时钟系统
  7. 复制BL1到内部IRAM(16KB)
  8. 检查BL1的校验和
  9. 跳转到BL1去执行

SoC通过OMpin来识别外部启动介质,目前有下面三种方式启动:

  1. 使用板载的eMMC启动,接在SD0,启动设置为101100
    (收到的开发版本默认就是从eMMC启动,内部预先烧录了Android)
  2. 使用外置SD卡从SD2通道启动,OMpin设置和SD0启动一样,但这需要先破坏板载的eMMC中的android镜像
    (不管OMpin如何设置,Second启动一定时从通道2上启动)
  3. USB调试模式设置为1xxxx1

拨码开关设置我们只需动OM5即可,其他几个根本不需要碰。需要SD启动时OM5打到GND,需要USB启动时OM5打到VCC

3.ARM编程

ARM 采用的是32位架构.

ARM 约定:

  • Byte : 8 bits
  • Halfword :16 bits (2 byte)
  • Word : 32 bits (4 byte)
基本工作模式定义应用
用户模式User非特权模式,大部分任务执行在这种模式用户态应用进程
异常模式FIQ当一个高优先级(fast) 中断产生时将会进入这种模式中断
IRQ 当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor当复位或软中断指令执行时将会进入这种模式bootloader,引导内核
Abort当存取异常时将会进入这种模式异常中的异常
Undef当执行未定义指令时会进入这种模式
系统模式System使用和User模式相同寄存器集的特权模式内核专用

CPU为什么设计这些模式?

  1. CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件需要,便于实现软件特性。
  2. 操作系统有安全级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要。

37个寄存器
在这里插入图片描述
System模式使用user模式寄存器集

寄存器说明:
sp :stack pointer,堆栈指针寄存器,始终指向栈顶
lr : Link Register,连接寄存器,用途有两种,一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。
pc :Program control register 程序控制寄存器,PC指向哪里,CPU就会执行哪条指令(所以程序跳转时就是把目标地址代码放到PC中)
cpsr : Current Program Status Register,程序状态寄存器
在这里插入图片描述
条件位:(ALU 算术逻辑单元)

 - N = Negative result from ALU (负数) 	
 - Z = Zero result from ALU (结果为0) 	
 - C= ALU operation Carried out(有进位) 	
 - V = ALU operation oVerflowed(溢出)

Q 位:(一般不用)

  • 仅ARM 5TE/J架构支持
  • 指示饱和状态

J 位(一般不用)

  • 仅ARM 5TE/J架构支持
  • J = 1: 处理器处于Jazelle状态

中断禁止位:

  • I = 1: 禁止 IRQ.
  • F = 1: 禁止 FIQ.

T Bit

  • 仅ARM xT架构支持
  • T = 0: 处理器处于 ARM 状态
  • T = 1: 处理器处于 Thumb 状态

Mode位:

  • 处理器工作模式位

spsr : Saved Program Status Register 程序状态保存寄存器,用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。SPSR用来进行异常处理,有以下功能:
1.保存ALU中的当前操作信息。
2.控制允许和禁止中断。
3.设置处理器的运行模式。

ARM的异常处理机制:
异常向量表
当异常产生时, ARM core

  1. 拷贝 CPSR 到 SPSR_<mode>
  2. 设置适当的 CPSR 位:
    改变处理器状态进入 ARM 态
    改变处理器模式进入相应的异常模式
    设置中断禁止位禁止相应中断 (如果需要)
  3. 保存返回地址到 LR_<mode>
  4. 设置 PC 为相应的异常向量

返回时, 异常处理需要:

  • 从 SPSR_<mode>恢复CPSR
  • 从LR_<mode>恢复PC
  • Note:这些操作只能在 ARM 态执行.

4.ARM 汇编指令集

  • 汇编指令是CPU指令的助记符,经过编译后得到一串01组成的机器码,可以由CPU读取执行
  • 汇编伪指令本质上不是指令,它是编译环境提供的,目的是为了指导编译环境,经过编译后伪指令不会生成机器码。

两种不同风格的ARM指令

  1. ARM官方汇编风格,windows IDE中常用,例如:LDR R0,[R1]
  2. GNU汇编风格,LINUX中常用,例如:ldr r0,[r1]

ARM汇编的特点:

  1. ARM采用RISC架构,CPU本身不能直接读取内存,需要先将内存中的内容加载入CPU的通用寄存器,然后才能被CPU处理
    ldr (load rigister) : 将内存内容加载入通用寄存器
    str (store rigister) : 将寄存器内容存入内存空间
  2. 8种寻址方式
寻址方式例子解释
寄存器寻址mov r1, r2把寄存器r2的值赋值给寄存器r1
立即寻址mov r0, #0xFF00立即数0xFF00赋值给寄存器r1
寄存器移位寻址mov r0, r1, lsl #3r1逻辑左移3位,结果放入r0
寄存器间接寻址ldr r1, [r2]把r2的值当成地址,取出相应值,赋给r1
基址变址寻址ldr r1, [r2, #4]r2中的值加上4,从这个地址取出值赋给r1
多寄存器寻址ldmia r1!, {r2-r7, r12}将r1指向的地址上连续空间的数据,保存到r2-r7,r12当中,ia后缀表示按WORD递增
堆栈寻址stmfd sp!, {r2-r7, lr}现场保存,将r2~r7,lr入栈
相对寻址beq flag相等跳转
  1. 同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:
    1) B(byte) 功能不变,操作长度变为8位
    2) H(half word) 功能不变,操作长度变为16位
    3) S(signed) 功能不变,操作数变为有符号数
    例如:ldr ldrb(加载8位) ldrh(加载16位) ldrsb(加载有符号数8位) ldrsh(加载有符号数6位)
    4) S(s标记),功能不变,影响CPSR标志位
    如:mov(不会影响CPSR标志位) movs(CPSR标志位会被置位)

  2. 条件执行后缀,如成立则执行,如不成立则不执行

条件码助记符标志含义
EQZ=1相等
NEZ=0不相等
CS/HSC=1无符号数大于或等于
CC/LOC=0无符号数小于
MIN=1负数
PLN=0正数或零
VSV=1溢出
VCV=0没有溢出
HIC=1,Z=0无符号数大于
LSC=0,Z=1无符号数小于或等于
GEN=V有符号数大于或等于
LTN!=V有符号数小于
GTZ=0,N=V有符号数大于
LEZ=1,N!=V有符号数小于或等于
AL任意无条件执行(指令默认条件)
NV任意从不执行(不用使用)
  1. 多级流水线:为增加处理器指令流的速度,ARM使用多级流水线,下图为3级流水线工作示意图(S5PV210使用13级流水线,ARM11为8级),每个时钟周期,取指,解码,执行同时执行,PC指向正被取指的指令,而非正在执行的指令
    在这里插入图片描述
    说明:1) 对于ARM来说每个指令4位
    2)对于thumb来说每个指令2位

协处理器CP15:https://www.cnblogs.com/lifexy/p/7203786.html

ldm(load register multi) 批量读取内存
stm(store registere mlti) 批量写入内存
eg : stmia sp, {r0 - r12}
将r0存入sp指向的内存处(假设为0x30001000);然后地址+4(即指向0x30001004),将r1存入该地址;然后地址再+4(指向0x30001008),将r2存入该地址······直到r12内容放入(0x3001030),指令完成。
一个访存周期同时完成13个寄存器的读写

8种后缀:

  • ia(increase after) 先传输,再地址+4
  • ib(increase before) 先地址+4,再传输
  • da(decrease after) 先传输,在地址-4
  • db(decrease before) 先地址-4,再传输
  • fd(full decrease) 满递减堆栈
  • ed(empty decrease) 空递减堆栈
  • fa(full add) 满递增堆栈
  • ea(empty add) 空递增堆栈

四种栈:

  • 空栈:栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格;而去除时需要先移动一格才能取出
  • 满栈:栈指针指向栈中最后一格数据,每次存入时需要移动栈指针一格再存入;取出时可以直接取出,然后再移动栈指针
  • 增栈:栈指针移动时向地址增加的方向移动的栈
  • 减栈:栈指针移动时向地址减小的方向移动的栈

!的作用
ldmia r0, {r2 - r3} 将r0寄存器中的地址再内存中对应的值取出放入r2,地址+4,将内存中的值取出放入r3
ldmia r0!, {r2 - r3}

感叹号的作用就是r0的值在ldm过程中发生的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值。

^的作用
ldmfd sp!, {r0 - r6, pc} 将栈中的值取出放入r0-r6,pc,fd是满减栈,存放时先-4,再存入,读取时先读出,再+4
ldmfd sp!, {r0 - r6, pc}^

^的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回。

5.ARM汇编伪指令

伪指令的意义:

  • 伪指令和指令的根本区别是经过编译后不会生成机器码
  • 伪指令的意义在于指导编译过程
  • 伪指令是和具体的编译器相关的,这里主要学习gnu下的汇编伪指令

一些符号的含义:

  • @ — 用来注释
  • : —以冒号结尾的是标号
  • . — 点号在gnu汇编中表示当前指令的地址
  • # —— 立即数前面要加#或$,表示这个是个立即数

常用的gnu伪指令:

  • .global _start — 给_start外部链接属性
  • .section .text — 指定当前段为代码段
  • .ascii .byte .short .long .word 定义变量
  • .qua .float .string 定义数据
  • .align 4 — 以16字节对齐 2^4 =16
  • .balignl 16 0xabcdefac —— b表示位填充,align表示要对齐,l表示long, 以4字节为单位填充;16表示16字节对齐,0xabcdefac 表示用来填充的原料

0x00000008: .balignl 16, 0xdeadbeef 0x0000000c 0xdeadbeef
0x00000010: 下一条指令

  • .equ — 类似于C中的宏定义

偶尔用到的gnu伪指令

  • .end — 标识文件结束
  • .include — 头文件包含
  • .arm/ .code 32 — 声明以下为arm指令
  • .thumb / .code16 — 声明以下为thubm指令

最重要的几个伪指令:

  • ldr 大范围的地址加载指令
  • adr 小范围的地址加载指令
  • adrl 中等范围的地址加载指令
  • nop 空操作

ARM中有一个ldr指令,还有一个ldr伪指令,一般都使用ldr伪指令而不用ldr指令

  • ldr指令: ldr r0,#0xff
  • ldr伪指令: ldr r0,=0xff 涉及大合法/非法立即数,涉及到ARM文字池

adr与ldr的区别和联系

  • adr 编译时会被1条sub或add指令替代,而ldr编译时会被一条mov指令替代或者文字池方式处理
  • adr 总是以PC为基准来表示地址,因此指令本身和运行地址有关,可以用来检测程序当前的运行地址在哪里
  • ldr加载的地址和链接时给的的地址有关,由链接脚本决定
  • 差别:ldr加载的地址在链接时确定,而adr加载的地址在运行时确定;所以我们可以通过adr和ldr加载的地址比较来判断当前程序是否在链接时指定的地址运行。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值