-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patharm.note
302 lines (270 loc) · 14.9 KB
/
arm.note
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
1.ARM体系结构
ARM(Andvanced RISC Machine) 是一家专注于通用处理器知识产权(Intellectual Property)研究开发的公司,自
身并不直接生产处理器芯片,而是通过向其他芯片和半导体厂商提供设计授权来推广其产品,其产品和CPU技术体系架构在业内被统
称为 ARM处理器。
ARM 处理器在技术体系上属于更为纯正的精简指令集体系,在具体实现上和 X86 有根本的不同: ARM 处理器多数采
用的是 SoC(System on Chip)片上系统架构,CPU、图形图像处理单元、显示单元、存储控制器及其接口、基本通讯单元(UART,SPI
,I2C,I2S...)的控制器以及许多外部总线或接口控制器(如以太网MAC控制器,USB控制器等)都集成在单一芯片上。因此,ARM处理器的计算机一般没有x86体系上独立的南北桥
芯片和图形处理芯片等,整体的架构更为精简,更适合于嵌入式应用市场。
ARM 处理器体系功能除了核心的ARM功能集外,还有如下的常见的功能集:
1.Thumb:采用16位指令集,其中的大部分指令被直接映射成正常的ARM指令,这样使的CPU能够通过运行16位指令来实
现很多需要32位指令才能完成的功能,从而提高代码密度,节省处理器和内存资源。
2.Thumb-2:Thumb功能集的扩展,通过增加的32位指令来扩展指令执行位宽。
3.Jazelle:通过在ARM结构中直接执行JAVA字段代码来提高JAVA程序的运行效率。
4.ThumbEE(Thumb执行环境):又称 Jazelle RCT(runtime compilation target)是对Thumb-2功能集的修订和扩展,
实现了更好的实时编译功能,包括即时编译(Just in time compilation JIT)和动态自
适应编译(Dynamic Adaptive Compilation,DAC).
5.VFP(Vector Floating Point):ARM架构上的矢量浮点处理器扩展,实现满足ANSI/IEEE Std 754-1985标准的单精
度/双精度浮点运算能力。
6.NEON(Advanced SIMD):64位/128位混合SIMD(Single Instruction Multiple Data,单指令多数据)高级扩展功能
,支持8位,16位,32位和64位整数和单精度浮点数据运算能力,以及完整的SMP(对称多处理器)功
能,可同时进行16个运算操作。
7.TrustZone:安全扩展功能
8.DSP指令扩展:对原有算术处理指令进行了一步扩展,并增加了单时钟周期16x16和32x16乘法/加法器指令。
ARM处理器按照其官方分类包括应用处理器(Application processor),嵌入式处理器(Embedded processor),安全内
核(SecureCore)和图形处理器(Graphics processor )以及视频引擎(Vedio engine).
2.ARM架构有一下的RISC处理器的特性
1.读取/存储架构,数据的处理是在register中,而不是内存
2.不支持地址不对齐的内存存取(ARMv6内核已支持)
3.指令可以用任意的寻址方式存取数据
4.大量的统一寄存器阵列
5.固定的指令长度,减轻解码和流水线化的负担
6.指令的执行周期大多数均为一个CPU周期
除此之外,ARM还有一些特别的设计:
1.大部分指令可以条件式地执行,降低在分支时产生的开销,提高执行效率
2.算术指令只会在要求时更改条件编码(condition code)
3.32位筒型移位器(barrel shifter)可用来执行大部分的算术指令和寻址计算而不会损失效率
4.强大的索引寻址模式(address mode)
5.精简而快速的双优先级中断子系统,具有可切换的寄存器组
6.自增/自减地址模式方便优化程序中循环部分
3.ARM的一些特点
1.在ARM架构的机器中,外围设备链接处理器的方式通常是内存映射方式,即把设备的寄存器映射到ARM的内存空间。设备也可以映射到协处理器空间,
或是连接到另外的总线控制器。
2.处理器的地址空间映射
. 处理器设计时就已经确定了地址,比如片内内存资源及片内集成的各设备控制器的寄存器
. 处理器预定义地址空间,提供相关的片选信号,通过系统总线与外部内存芯片连接
4.系统时钟
时钟可以说是处理器的心脏。“处理器实质上是一个很复杂的时序状态机,其正常运作有赖于时钟提供驱动。”
一般来说,处理器刚开启的时候并非马上工作在正常频率,而是在一个较低的频率,然后通过指令(初始执行程序)进行配置,切换到正常工作的
工作频率。同样,处理器内的各个接口的正常工作也有依赖于时钟系统。因此,系统时钟管理是系统非常重要的功能,它与处理器的功耗与电源管
理等密切相关。
5.ARM 的 ATPCS 约定
ATPCS:ARM/Thumb Procedure Call Standard ARM/Thumb过程调用标准。它是ARM公司定义的汇编层次上的统一的调用接口标准。
如果要在操作系统中进行汇编语言级别的开发,就必须了解ATPCS标准,因为系统的各种函数接口都是以C语言的形式提供的。如果编写的
汇编代码不直接与C语言代码相互调用则可以不遵守该规范。
ATPCS 约定包括如下方面:
@寄存器使用规定
@栈使用惯例
@栈回溯结构的格式
@参数传递与结果的返回
@ARM共享库机制
寄存器使用规定:
寄存器 别名 用途
r0 a1 函数参数和返回值
r1 a2 函数参数和返回值
r2 a3 函数参数
r3 a4 函数参数
r5 v1 变量
r6 v2 变量
r7 v3 变量
r8 v4 变量
r9 v6,sb 变量 或 静态数据/全局变量的基址
r10 v7,sl 变量 或 栈限制
r11 v8,fp 变量 或 帧指针
r12 ip 函数调用中间临时寄存器
r13 sp 栈指针
r14 lr 链接寄存器
r15 pc 程序寄存器
================================================================================
r0-r3 这4个寄存器用来传递函数调用的第1个到第4个函数参数,更多的参数必须通过栈来传递。被调用的子程序返回之前
无须恢复这些寄存器的内容;
r4-r11 这8个寄存器可作为一般的临时变量使用。子程序进入时必须先保存这些寄存器的值,返回时必须进行恢复。
参数传递与结果返回规则:
函数参数多于4个的时候,要用栈来传递,入栈的顺序是从后往前,即最后一个参数先入栈。
如果参数类型的长度大于一个字,则将其视为连续多个字数据进行处理。
--------------------------------------------------------------------------------
int v1=1;
static int v2=2;
int main(void)
{
int vr;
int v3=3,v4=4;
vr=(v1+v2)-(v3-v4);
return 0;
}
--------------------------------------------------------------------------------
.cpu arm10tdmi
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "arm.c"
.global v1
.data
.align 2
.type v1, %object
.size v1, 4
v1:
.word 1
.align 2
.type v2, %object
.size v2, 4
v2:
.word 2
.text
.align 2
.global main
.type main, %function
main:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #20
mov r3, #3
str r3, [fp, #-12]
mov r3, #4
str r3, [fp, #-8]
ldr r3, .L3
ldr r2, [r3, #0]
ldr r3, .L3+4
ldr r3, [r3, #0]
add r1, r2, r3
ldr r2, [fp, #-8]
ldr r3, [fp, #-12]
rsb r3, r3, r2
add r3, r1, r3
str r3, [fp, #-16]
mov r3, #0
mov r0, r3
add sp, fp, #0
ldmfd sp!, {fp}
bx lr
.L4:
.align 2
.L3:
.word v1
.word v2
.size main, .-main
.ident "GCC: (Sourcery G++ Lite 2008q3-72) 4.3.2"
.section .note.GNU-stack,"",%progbits
--------------------------------------------------------------------------------
全局变量都被放在数据段上,数据段中保存的是数据的初始值。并且全局变量名就是其初始值的标号。
未用static声明的全局变量被声明为.global,表示它可以链接到其他文件。加载全局变量v1/v2使用了文字池的方法,
即将变量放在代码段中某个不会执行到的位置,使用时先加载变量地址,然后通过变量地址得到变量的值。
非静态的局部变量都会放在栈上,通过帧指针fp加/减偏移量的方式来访问。帧指针在开始的时候设置好,在整个函数执行期间不会
改变。
编译器对于局部数组的处理,这时数组元素是保存在栈上的,但是数组初始化数据被放在只读的数据段上,当数组生成时使用指令
对数组元素一一进行赋值。
--------------------------------------------------------------------------------
代码优化比较:
if(a==0){
b=1;
}
else{
b=2;
}
ldr r3, [fp,#-16]
cmp r3, #0
bne .L2
mov r3, #1
str r3, [fp, #-20]
b .L1
.L2:
mov r3, #2
str r3, [fp, #-20]
.L1:
-----------------------
利用ARM中的指令都有一个条件码,可以大大提高效率:
ldr r3, [fp, #-16]
cmp r3, #0
moveq r3, #1
movne r3, #2
str r3, [fp, #-20]
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
存储器介绍:
ROM 只读存储器有可以分为: 不可编程ROM, 可编程ROM(PROM), 可擦除可编程ROM(EPROM),
电可擦除可编程ROM(EEPROM).
目前,ROM有被Flash代替的趋势, NOR(或非)和NAND(与非) Flash是两种常见的Flash.
NOR Flash和CPU之间的接口属于典型的类SRAM接口,可以直接访问,无须添加任何控制电路.
NOR Flash的特点是 可芯片内执行(XIP eXecute In Place),程序可以直接在NOR Flash中执行.
NAND Flash和CPU的接口必须由相应的控制电路进行转换或者通过地址线或者GPIO产生NAND Flash接口的信号.
NAND Flash的特点是 以块的形式访问,不支持芯片内执行.
总结:
NAND Flash较NOR Flash容量大,价格低; NAND 中每个块的最大擦写次数是一百万次,而NOR的擦写次数只有几十万次;
NAND的擦除,编程速度远超NOR.
由于Flash固有的电器特性,在读写数据的过程中,偶然会产生1位或几位数据错误,即反转,NAND的反转几率远大于NOR.
位反转无法避免,因此,需要使用错误探测/错误更正(EDC/ECC)算法.
Flash的编程原理都是只能将1写为0,而不能将0写成1.所以在FLASH编程之前,必须将对应的块擦除,而擦除过程
就是把所有位写为1的过程,块内所有字节编程0XFF.
公共闪存接口(Common Flash Interface CFI)是一个公开的,标准的从NOR Flash器件中读取数据的接口.
--------------------------------------------------------------------------------
RAM是掉电无法保存记录.
RAM 可以分为静态RAM(SRAM)和动态RAM(DRAM).
DRAM 以电荷的形式进行存储,数据存储在电容里面.由于电容会漏电导致电荷丢失,所以DRAM需要定时刷新.
SRAM 是静态的,只要供电它就会保持一个值,SRAM没有刷新周期.
每个SRAM存储单元由6个晶体管构成; DRAM则由1个晶体管构成.
--------------------------------------------------------------------------------
I^2C(内置集成电路)总线,是由Philips开发的两线式串行总线, 用于连接微控制器及其外围设备.
I2C总线简单有效,占用很少的PCB空间,芯片管脚数量较少,设计成本低.
I2C总线支持多主控multi-mastering模式,任何能够进行发送和接收的设备都可以成为主设备.
主控能够控制数据的传输速率和时钟频率,在任意时刻只能有一个主控.
--------------------------------------------------------------------------------
以太网接口
以太网接口有MAC(以太网媒体接入控制器)和PHY(物理接口收发器)组成. MAC和PHY之间通过MII媒体独立接口连接.
从CPU到最终接口依次为: CPU, MAC, PHY, 以太网隔离变压器, RJ45插座.
--------------------------------------------------------------------------------
ISA 工业标准总线结构
--------------------------------------------------------------------------------
PCI 外围部件互连,是INTEL推出的一种局部总线.其目的是 描述如何将计算机系统中的外围设备以一种结构化
和可控化的方式连接在一起,给出了外围设备在连接时的电气特性和行为,并且详细的定义了计算机系统中的各个
不同不见之间应该如何正确的进行交互.
"突发方式传输"是指取得总线控制权后连续进行多个数据的传输.
--------------------------------------------------------------------------------
奈奎斯特定理即为采样定理, 当采样频率fs大于信号中的最高频率f_max的2倍时,采样之后的数字信号可完整地保留
原始信息.
--------------------------------------------------------------------------------
编译内核到特定的体系结构,我们可以使用默认的配置,比如:
在 arch/x86/configs/x86_64defconfig 中保存这对于x86_64位体系结构的默认配置,
我们只需要运行 : make x86_64defconfig 即可.
然后,执行 make zImage ; make modules
这样就可以在源代码根目录下得到 未压缩的内核映像vmlinux 和 内核符号表文件System.map ,
在对应的arch/*/boot/ 目录下会得到压缩的内核影响zImage.
--------------------------------------------------------------------------------
x86 PC从上电/复位到运行Linux用户空间初始进程的流程:
上电/复位 系统启动 BIOS
|
Bootloader的第一阶段 MBR
|
Bootloader的第二阶段 LILO, GRUB 等
|
启动内核 内核
|
运行init进程 用户空间
当CPU上电/复位时,CPU会将PC指针赋值为 0xFFFF0 ,并执行该地址处的指令.
在PC机中,该地址位于BIOS中, 它保存在主板的ROM或Flash中.
详细介绍一下启动内核的过程:
当内核映像被加载到RAM之后,Bootloader的控制权被释放,内核阶段就开始了.
内核映像不是完全可以直接执行的目标代码,而是一个压缩过的zImage(小内核) 或 bzImage(大内核,big).
实际上,映像中包含未被压缩的部分,这部分中包含解压缩程序,解压缩程序会解压映像中压缩的部分.
zImage/bzImage 都是使用gzip压缩的,它们不仅仅是一个压缩文件,而且在这两个文件的开头部分内嵌有gzip
的解压代码.
当bzImage(i386)被调用时,
start() /arch/i386/boot/head.S
|
startup_32() /arch/i386/boot/compress/head.S
|
deconpress_kernel() /arch/i386/boot/compress/misc.c
|
startup_32() /arch/i386/kernel/head.S
|
start_kernel() /init/main.c
|
cpu_idle() /init/main.c