ARM裸机全集之ARM体系结构(学习笔记)

ARM体系结构与汇编指令
1.2.1 可编程器件的编程原理
1.2.1.1 电子器件的发展方向
模拟器件-数字器件
ASIC-可编程器件

1.2.1.2.可编程期间的特点
CPU在固定频率的时钟控制下节奏运行
CPU可以通过总线读取外部存储设备中的二进制指令集,然后解码执行
这些可以被CPU解码执行的二进制指令集是CPU设计的时候确定的,是CPU的设计者(ARM公司)定义的
本质是一串由0和1组成的数字,这就是CPU的汇编指令集


1.2.2 指令集对CPU的意义
1.2.2.1 汇编语言与C等高级语言的差别
汇编难写,C好写
汇编无可移植性,C语言有一定可移植性,Java等更高级语言移植性更强。
汇编语言效率最高,C语言次之,Java等更高级语言效率更低。
汇编不适合完成大型复杂的项目,更高级语言更适合完成更大、更复杂的项目。

1.2.2.2 编程语言的发展过程
纯机器码编程
汇编语言编程
C语言编程
C++语言编程
Java C#等语言编程
脚本语言编程

1.2.2.3 汇编语言的本质
汇编的实质是机器指令(机器码)的助记符,是一种低级符号语言。
机器指令集是一款CPU的编程特征,是这款CPU的设计者制定的。
CPU的内部电路设计就是为了实现这些指令集的功能。机器指令集就好象CPU的API接口一样。


总结:

1.可移植性
CPU的机器码(机器指令集)在CPU的设计阶段就已经定死了,不同的CPU拥有不同的机器码。
而汇编语言的本质就是机器码的助记符,通过汇编器翻译成机器码,所以汇编没有可移植性。
C语言的可移植性是由编译器决定的,在不同的操作系统上用不同的编译器,就可以的到相同效果的汇编代码。
2.何为高级语言,何为低级语言
语言越高级,越接近人的思维;越低级,越接近机器的思维。
语言越低级,工作效率越高(机器),语言越高级,工作效率越低,但越接近应用层(方便程序员使用),
相当于要完成同样的机器动作,越高级的语言可以使用跟少的代码,大大减轻了程序员的劳动。


1.2.3 RISC和CISC的区别
1.2.3.1 什么是RISC、CISC
CISC(300条指令左右,Intel的奔腾)complex instruction computer复杂指令集计算机
最少的指令完成任务,一个功能一个指令,功耗高。
RISC(30条指令,ARM)Reduced Instruction-Set computer 精简指令集计算机最基本的功能指令集,功耗低,让软件来完成具体的任务。


1.2.3.2 CPU的发展与RISC和CISC的关系
早期简单CPU,指令和功能都很有限
CISC年代 —— CPU功能扩展依赖于指令集的扩展,实质是CPU内部组合逻辑电路的扩展。
RISC年代 —— CPU仅提供基础功能指令(譬如内存与寄存器通信指令,基本运算与判断指令等),功能扩展由使用CPU的人利用基础架构来灵活实现。
总结:
RISC和CISC慢慢的趋向大一统.



1.2.4 统一编址&独立编址&哈佛结构&冯诺依曼结构
1.2.4.1 IO(IO其实是CPU与外设的接口,可以习惯的认为就是外设)
何为内部或外部外设(本质就是有没有在芯片内部)
IO与内存统一编址方式(把外设寄存器当作一个内存地址来读写,以访问内存的方式访问外设)
IO与内存独立编址方式(通过CPU专用的指令来访问外设,这就是CISC为什么有这么多的指令了,每多一个外设,就要增加相应的指令。)


1.2.4.2 内存
ROM(Flash)、RAM
前者用来存放程序,后者用来存放数据
内存与CPU的关系
通过总线直接连接,能达到访问的最大效率。

1.2.4.3 程序与数据
程序运行时两大核心元素:程序 + 数据
程序是我们写好的源代码经过编译、汇编之后得到的机器码,这些机器码可以拿给CPU去解码执行,CPU不会也不应该去修改程序,所以程序是只读的。
数据是程序运行过程中定义和产生的变量的值,是可以读写的,程序运行实际就是为了改变数据的值。

1.2.4.4 冯诺依曼结构与哈佛结构
冯诺依曼结构:程序与数据放在同样的内存空间里,彼此没有界限,容易产生误差,例如Intel的CPU就是采用的
冯诺依曼结构,所以它的内部程序是可以修改,计算机病毒就是利用了这一点
哈佛结构:程序与数据放在不同的内存块中,虽然都在内存中,但他们的地址范围都是固定的、彼此分离(ROM/RAM),CPU设计时
规定哪个范围的内存地址中的二进制码是可以读写,而哪个是只读的。譬如大部分的单片机(MCS51、ARM9等)均采用哈佛结构。



1.2.4.5 优劣对比
冯诺依曼结构中程序和数据不区分的放在一起,因此安全和稳定性是个问题,好处是处理起来简单。
哈佛结构中程序(一般放在ROM、flash中)和数据(一般放在RAM中)独立分开存放,因此好处是安全和稳定性高,缺点是软件处理复杂一些(需要统一规划链接地址等



1.2.5 软件编程控制硬件的关键---寄存器
1.2.5.1 什么是寄存器(他是外设的硬件组成部分,不是软件)
寄存器属于CPU外设的硬件组成部分
CPU可以像访问内存一样访问寄存器
寄存器是CPU的硬件设计者制定的,目的是留作外设被编程控制的“活动开关”
正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。
使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。

1.2.5.2 寄存器分类
SoC中有2类寄存器:通用寄存器和SFR
通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
SFR(special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,
我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。

1.2.5.3 怎样通过寄存器来控制硬件
编程操作寄存器类似于访问内存
寄存器中每个bit位都有特定含义,因此编程操作时需要位操作。
单个寄存器的位宽一般和CPU的位宽一样,以实现最佳访问效率


1.2.6 ARM体系结构总结
ARM是RISC
常用ARM汇编指令只有二三十条
ARM是低功耗CPU
ARM的架构非常适合单片机、嵌入式,尤其是物联网领域;而服务器等高性能领域目前主导还是Intel
ARM采用的是I/O与内存统一编址
ARM采用的是哈佛结构

1.2.7 S5PV210的地址映射详解
1.2.7.1 什么是地址映射
CPU的设计决定了他的地址总线,地址总线决定了寻址空间,寻址空间大小就是理想状态的内存大小

1.2.7.2 专业术语
ROM:read only memory 只读存储器
RAM:ramdom access memory 随机访问存储器
IROM:internal rom 内部ROM,指的是集成到SoC内部的ROM
IRAM:internal ram 内部RAM,指的是集成到SoC内部的RAM
DRAM:dynamic ram 动态RAM
SRAM,STATIC RANDOM ACCESS MEMORY  就是静态随即存储器
SROM static read only memory 静态只读存储器
ONENAND/NAND: 集合了NANDFlash和NORFlansh的有点(NOR Flash 和 NAND Flash 是现在市场上两种主要的非易失闪存技术。)
SFR:special function register
总结:

会看memorry map ,
S5PV210:(记忆)
0x2000_0000 0x3FFF_FFFF  512MB  DRAM 0
0x4000_0000 0x7FFF_FFFF  1024MB DRAM 1
0xD000_0000 0xD000_FFFF  64KB   IROM


1.2.8 CPU和外部存储器的接口
1.2.8.1 SoC常用外部存储器
NorFlash
NandFlash
eMMC/iNand/moviNand
oneNAND
SD卡/TF卡/MMC卡
eSSD
SATA硬盘

1.2.8.2 X210开发板支持的外部存储器
X210有2个版本,Nand版和iNand版,分别使用Nandflash和iNand为外部存储器。我们使用的是iNand版本,板载4GB iNand
S5PV210共支持4个SD/MMC通道,其中通道0和2依次用作启动。X210开发板中SD/MMC0通道用于连接板载MMC,因此外部启动时只能使用SD/MMC2通道(注意通道3不能启动)。见《S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf》中P6

总结:

1、现代SoC支持多种外部存储器
2、外部存储器主要用来存储程序(可执行代码),相当于电脑的硬盘。
3、各种不同外部存储器原理不同,大小、性价比不同,一般产品厂家根据需要选择适合自己产品的外存使用。
4、外部存储器和CPU连接一般不是通过地址&数据总线直接相连,因为地址空间不够用。一般都是通过专门的接口来连接的



1.2.9 S5PV210的启动过程详解
内存:
SRAM 静态内存特点是容量小、价格高,优点是不需要软件初始化直接上电就能用
DRAM 动态内存特点是容量大、价格低,缺点是上电后不能直接使用,需要软件初始化才可以使用
单片机中:内存需求量小,而且希望开发简单,适合全部用SRAM 
嵌入式系统:内存需求量大,而且没有NorFlash等启动介质
PC机:内存需求量大,而且软件复杂,不在乎DRAM的初始开销,适合全部用DRAM

外存:
NorFlash:特点是容量小,价格高,优点是可以和CPU直接总线式相连,CPU上电后可以直接读取,所以一般用作启动介质
NandFlash(跟硬盘一样):特点是容量大,价格低,缺点是不也不知道我们板子上将来接的是能总线式访问,也就是说不能上电后CPU直接读取,需要CPU运行一些初始化软件,然后通过时序接口读写。

所以一般PC机都是:很小容量的BIOS(Norflash)+很大容量的硬盘(类似于NandFlash)+大容量的DRAM
一般的单片机:很小容量的NorFlash + 很小容量的SRAM
嵌入式系统:因为NorFlash很贵,所以现在很多嵌入式系统倾向于不用NorFlash,直接用:外接的大容量Nand + 外接大容量DRAM + SoC内置SRAM


S5PV210的启动过程: 外接的大容量Nand + 外接大容量DRAM + SoC内置SRAM210,还内置了一块96KB的SRAM(IRAM),同时还有一块内置64KB的NorFlash(IROM)

第一步:CPU上电后先从内部IROM中读取预先设置的代码,执行。这一段IROM代码做了一些基本初始化(CPU时钟、看门狗。。)(这一段IROM代码是三星出厂前设置的,三星也不知道我们的板子将来接的是什么DRAM);然后这段代码会判断我们的启动模式(通过硬件跳线可以更改板子的启动模式),然后从相应的外部存储器去读取第一部分代码(BL1,大小为16KB);到内部SRAM
第二步:从IRAM去运行刚上一步读取来BL1,然后执行。BL1负责初始化NandFlash,然后将BL2读取到I
RAM(剩余的80kb),然后运行
第三步:从IRAM运行BL2,BL2初始化DRAM,然后将OS读取到DRAM中,然后启动os,启动过程结束。

ARM裸机全集之ARM体系结构(学习笔记)

1.2.11 如何在开发板上选择不同的启式
SoC通过OMpin来识别外部启动介质
 

体验从SD0的eMMC启动

开发板收到默认就是从eMMC启动,内部预先烧录了android。

 

 

从SD2启动
可以使用外置SD卡从SD2通道启动,但这需要先破坏板载的eMMC中的android镜像。破坏方法见九鼎官方的裸机教程文档《x210v3开发板裸机教程.pdf》中2.5.2节(P19)
OMpin设置和SD0启动一样

USB调试模式(101101 1xxxx1)


 

总结:
拨码开关设置我们只需动OM5即可,其他几个根本不需要碰。需要SD启动时OM5打到GND,需要USB启动时OM5打到VCC
可以先不销毁eMMC中的android,而使用USB启动来做裸机调试。之后课程中我们会使用USB启动和SD卡启动两种方式共同来完成实验,让大家对比学习。

 

 

1.2.12 ARM的编程模式和7种模式
为什么要分7种模式

1.2.12.1 ARM的基本设定
ARM 采用的是32位架构.
ARM 约定:(不同的CPU有不同的约定,但Byte :8 bits是统一的)
Byte : 8 bits
Halfword :16 bits (2 byte)
Word : 32 bits (4 byte)


大部分ARM core 提供:
ARM 指令集(32-bit) 
Thumb 指令集(16-bit )
Thumb2指令集(16 & 32bit)
Jazelle cores 支持 Java bytecode

1.2.12.2 ARM处理器工作模式
ARM 有7个基本工作模式:
User : 非特权模式,大部分任务执行在这种模式


FIQ :   当一个高优先级(fast) 中断产生时将会进入这种模式
IRQ :   当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor :当复位或软中断指令执行时将会进入这种模式
Abort : 当存取异常时将会进入这种模式
Undef : 当执行未定义指令时会进入这种模式


System : 使用和User模式相同寄存器集的特权模式
注意: 
除User(用户模式)是Normal(普通模式)外,其他6种都是Privilege(特权模式)
Privilege中除Sys模式外,其余5种为异常模式。
各种模式的切换,可以是程序员通过代码主动切换(通过写CPSR寄存器);也可以是CPU在某些情况下自动切换。
各种模式下权限和可以访问的寄存器不同。

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


1.2.13 ARM的37个寄存器详解
1.2.13.1 ARM寄存器

       ARM裸机全集之ARM体系结构(学习笔记)                                     

这里看到的就是ARM内核里面的所有寄存器了,一共有37个。我们前面说过,ARM体系一共有7种模式,其中用户模式和系统模式拥有物理空间上完全相同的寄存器,而其它5种异常模式都有一些自己独立的寄存器。
我们看图中左边显示的是当前模式的可见的寄存器,右边显示的是其它模式备用的寄存器。其中深蓝色的部分为当前模式与用户模式共用的寄存器,而彩色部分为各个寄存器独立物理空间的寄存器。
这样安排的好处是当各种异常发生的时候,每种异常模式都可以保存一些重要的数据,使异常处理程序完成之后返回异常前的程序时不会破坏原有的寄存器或状态。
System模式使用user模式寄存器集
总结:
ARM共有37个寄存器,都是32位长度
37个寄存器中30个为“通用”型,1个固定用作PC,一个固定用作CPSR,5个固定用作5种异常模式下的SPSR。


1.2.13.2 CPSR程序状态寄存器

ARM裸机全集之ARM体系结构(学习笔记)
条件位:
N = Negative result from ALU 
Z = Zero result from ALU
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位:处理器模式位


注意:
CPSR中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E就和CPSR中的Z标志位有关)
CPSR中的I、F位和开中断、关中断有关
CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置。


1.2.13.3 PC(r15)程序控制寄存器
PC(Program control register)为程序指针,PC指向哪里,CPU就会执行哪条指令(所以程序跳转时就是把目标地址代码放到PC中)
整个CPU中只有一个PC(CPSR也只有一个,但SPSR有5个)。



1.2.14 ARM的异常处理方式简单介绍


1.2.14.1 什么是异常 
正常工作之外的流程都叫异常
异常会打断正在执行的工作,并且一般我们希望异常处理完成后继续回来执行原来的工作
中断是异常的一种


1.2.14.2 什么是异常向量表
所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的。
当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作)
异常向量表是硬件向软件提供的处理异常的支持。


1.2.14.3异常的处理机制
当异常产生时, ARM core:
拷贝 CPSR 到 SPSR_<mode>(保存了Tbit的值,用于异常处理结束返回时,回到这个处理器状态)
设置适当的 CPSR 位: 
改变处理器状态进入 ARM 态
改变处理器模式进入相应的异常模式
设置中断禁止位禁止相应中断 (如果需要)
保存返回地址到 LR_<mode>
设置 PC 为相应的异常向量

返回时, 异常处理需要:
从 SPSR_<mode>恢复CPSR
从LR_<mode>恢复PC 
Note:这些操作只能在 ARM 态执行.


总结:
异常处理中有一些是硬件自动做的,有一些是程序员需要自己做的。需要搞清楚哪些是需要自己做的,才知道如何写代码。
以上说的是CPU设计时提供的异常向量表,一般成为一级向量表。有些CPU为了支持多个中断,还会提供二级中断向量表,处理思路类似于这里说的一级中断向量表。