Linux 学习记录51(ARM篇)
本文目录
- Linux 学习记录51(ARM篇)
- 一、计算机的组成
- 二、编译的原理
- 三、指令和指令集
- 1. 机器指令
- 2. 汇编指令
- 3. 指令集
- (1. RISC:精简指令集
- (2. CISC:复杂指令集
- (3. 精简指令集补充
- 四、ARM相关介绍
- 1. Arm发展简介
- 2. ARM架构
- 3. ARM内核
- 4. SOC (system on chip)
- 5. ARM的产品分布
- (1. cortex-A系列
- (2. Cortex-R系列
- (3. Cortex-M系列
- (4. SecurCore系列
- 6. arm的数据约定
- 7. ARMv7架构和ARMv8架构的区别
- 8. ARM处理器的工作模式
- (1. cortex-a的模式
- (2. cortex-M系列的工作模式
- 9. ARM的寄存器组织
- (1. armv7架构寄存器组织
- (2. ARM v8架构的寄存器组织
- 10. ARM v7架构下的特殊功能寄存器
- (1. R15(PC/ program counter)
- (2. R14(LR)寄存器
- (3. R13寄存器
- (4. CPSR和SPSR寄存器
- 11. ARM的流水线工作
- 五、环境搭建
- 1. 搭建keil5汇编环境
- 2. linux虚拟机安装交叉编译工具链
一、计算机的组成
计算机主要由这几部分组成:输入设备 输出设备 控制器 运算器 存储器
- 输入设备:把比较原始的数据以及编写好的程序输送到计算机中,转换成计算机能够识别、接收的信息。鼠标、键盘、扫描仪、传感器
- 输出设备:将计算机处理后的结果转换成人或者其他设备能够识别的形式输出到计算机外部.。投影仪、打印机
- 运算器:CPU对于信息的处理和运算单元,主要进行算数和逻辑运算,它的核心是ALU(算数逻辑运算单元)
- 控制器:计算机的指挥中心
- 存储器:计算机中御用存放程序和数据的模块,也是计算机能够实现"程序存储控制的基础"
存储器分为:内部存储器,外部存储器,寄存器
- 内部存储器:内存,对内存中的每一个部件进行编号,这个编号就是地址,内存分为RAM、ROM
- RAM:上电后加载计算机运行的各种数据,掉电丢失
- ROM:内部主要存放一些固化好的一些启动引导程序,掉电不丢失
- 外部存储器:计算机外部加装的外部存储设备,主要用于存储各类数据,数据不会随着系统的关闭而丢失
- 寄存器组织:基本上都是在CPU内部交给CPU使用的存储设备,这类 存储设备没有地址的概念cpu可以直接读取上面的数据
二、编译的原理
CPU能够识别的唯一的语言是机器语言,一个CPU能够识别那些机器码是由处理器的硬件(运算器种类)决定
不同的机器码代表不同的运算,不同的CPU的机器码是不通用的。
汇编是用一个标识符来代表一个机器码,不同CPU的汇编也是不通用的.我们可以采用不同的编译器把c程序编译成不同机器上可以执行的可执行文件
三、指令和指令集
1. 机器指令
由二进制的0和1组成的一条机器码,计算机解析这条机器码就可以让运算器做出相应的运算处理
2. 汇编指令
每一条汇编指令都是一条机器指令的标志,执行汇编指令也可以让运算器做出相应的运算处理
3. 指令集
很多条汇编指令的集合
【RISC和CISC】
(1. RISC:精简指令集
1. 精简指令集相关的架构主要用于嵌入式的设备上
ARM指令集 RISC-V指令集 MIPS指令集都属于RISC.
2. 精简指令集在复杂指令集上选取一些相对比较简单,使用频率较高的指令,
精简指令集的指令的周期和指令的宽度是固定的。
指令的周期 :执行一条汇编指令需要几个时钟周期。
时钟周期 : cpu的主频最终决定了你的处理器的执行速度
周期 = 1s / 频率
指令的宽度 : 指令编译生成一条机器码,机器码在代码段占用的空间
对于ARM指令来说,大多数指令都是单周期的指令,指令的宽度为32位。
3. 查看ARM指令的机器码
3.1 编译一个最简单的程序
3.2 使用交叉编译工具链进行编译 arm-linux-gnueabihf-gcc
交叉编译工具链 : 在x64系统下将程序编译生成arm的可执行程序
arm-linux-gnueabihf-gcc -marm 1.c
-marm : 编译生成arm指令的可执行程序
3.3 反汇编:将elf的可执行程序反汇编生成dis的反汇编文件
$ arm-linux-gnueabihf-objdump -D a.out > a.dis
(2. CISC:复杂指令集
1. 复杂指令集相关的架构主要用于PC端。
x86架构和X64架构使用的都是CISC。
2. 复杂指令集更加注重指令的功能性,
复杂指令集的指令的周期和指令的宽度不固定。
3. 查看x86架构指令的机器码
3.1 编译一个最简单的程序
3.2 使用gcc进行编译
3.3 反汇编:将elf的可执行程序反汇编生成dis的反汇编文件
$ objdump -D a.out > a.dis
(3. 精简指令集补充
1. ARM内核 ----> 主流嵌入式使用的内核, 不是开源 需要arm公司授权
2. RISC-V内核 ---> 未来可能会比较火, RISC-V属于开源的内核
3. MIPS内核 ---> 完全闭源,龙芯科技将mips架构买断,不受版权控制
4. 龙芯科技在mips架构的基础之上进行了扩展优化。
四、ARM相关介绍
1. Arm发展简介
点击此查看ARM发展史
ARM :Advanced RISC Machines(最初命名为Acorn RISC Machine)简称ARM。对ARM可以有三种理解:1)ARM公司:Advanced RISC Machines Limited;2)ARM处理器架构;3)一种技术——ARM技术。
里程碑1——ARM成立
ARM前身为艾康电脑(Acorn),于1978年,英国剑桥成立,大学的孵化物。
1980年代晚期,苹果开始与艾康合作,开发新版ARM核心。
1985年,艾康开发出全球第一款商用RISC处理器,即ARM1,针对于PC市场,还没有嵌入式呢!!!
1990年,艾康财务危机,受苹果和VLSI(最早做超大规模集成电路的公司)的投资,成立独立子公司:Advanced RISC Machines(ARM),ARM公司正式成立面世。
里程碑2——嵌入式RSIC处理器
1991年,ARM推出第一款嵌入式RISC处理器,即ARM6。
1993年,发布ARM7。
1997年,发布ARM9TDMI,三星2440基于此内核。
1999年,发布ARM9E,增强型ARM9。
2001年,ARMv6架构。
2002年,发布ARM11微架构。
里程碑3——微控制器
2004年,发布ARMv7架构的Cortex系列处理器,同时推出Cortex-M3。
2005年,发布Cortex-A8处理器。
2007年,发布Cortex-M1和Cortex-A9
2009年,实现Cortex-A9、发布Cortex-M0
2010年,推出Cortex-M4(F)、成立Linaro(ARM公司牵头成立的公共组织,专门做ARM处理器在Linux平台上的一些软件的开发和移植),推出Cortex-A15 MPcore高性能处理器(性能比较高了,但是发热量很大)
里程碑4——64位处理器时代
2011年,推出32位 Cortex-A7 处理器,ARMv8发布
2012年,开始推出64位处理器。推出 Cortex-M0+、ARM 首款64位处理器架构 Cortex-A53、Cortex-A57 架构。全球第一款64位ARM手机iPhone5s。
2013年,推出32位 Cortex-A12 处理器架构
2014年,推出 Cortex-M7(F) 微控制器架构;32位 Cortex-A17处理器架构。
2015年,推出64位 Cortex-A35、Cortex-A72 处理器架构。
2016年,推出 Cortex-M23 、Cortex-M33(F) 微控制器架构;32位 Cortex-A32 处理器架构;64位 Cortex-A73 处理器架构。
2017年,推出64位 Cortex-A55 、Cortex-A75 处理器架构。
2018年,推出微控制器 Cortex-M35P;64位 Cortex-A76 处理器架构。
ARM的商业模式:设计与生产分离
ARM只负责设计IC,并且出卖自己的设计IP(只是产权)
ARM自己不生产芯片,而是把设计IP授权给其他半导体厂商来生产芯片。
另外也提供基于ARM架构的开发设计技术
软件工具, 评估板, 调试工具,应用软件,总线架构, 外围设备单元,等等
2. ARM架构
arm不同版本的指令集名字就叫做ARM的架构
ARMV1--ARMV6 已经被淘汰
ARMV7架构:支持32位的指令集 每一条指令的大小是32位
ARMv8架构:支持64位的指令集,同时向下兼容32位指令
armv9架构: 支持64位的指令集 2011年发布
3. ARM内核
基于不同的架构生产出来的处理器核心叫做内核
cortex-A7 ---> ARM-v7
cortex-A53 --> ARM-v8
cortex-A55 --> ARM-v8
cortex-A77 --> ARM-v8
cortex-A78 --> ARM-v8
cortex-x1 --> ARM-v8
cortex-x2 --> ARM-v9
cortex-A710 -> ARM-v9
cortex-A510 -> ARM-v9
4. SOC (system on chip)
ARM公司不生产芯片,ARM公司将ARM的内核授权给第三方的芯片厂商,芯片厂商基于ARM的内核再设计添加合适的外围设备,设计出不同的ARM芯片,这种芯片可以称为SOC(片上系统)
公司 SOC ARM内核 架构
st stm32mp157 cortex-A7 arm-v7
高通 骁龙888 plus cortex-x1 arm-v8
cortex-a78*3
cortex-a55*4
海思 麒麟9000 cortex-a77*4 arm-v8
cortex-a55*4
NXP imx6 cortex-a7 arm-v7
imx8 cortex-a55 arm-v8
紫光展锐 T770 cortex-a76*4 arm-v8
cortex-a55*4
5. ARM的产品分布
(1. cortex-A系列
cortex-A系列的处理器主要用于高端的处理器:
可以运行linux系统,Android系统,鸿蒙OS.
嵌入式开发中主要使用的都是cortex-A系列处理器。
(2. Cortex-R系列
cortex-R系列的处理器主要针对于实时性能:
对数据的实时性要求比较高的场合使用cortex-R系列的处理器。
(3. Cortex-M系列
cortex-M系列属于低端产品,处理器的主频比较低在24MHz ~ 256MHz直接。
cortex-M系列的处理器一般称为单片机(MCU:微控制单元),
cortex-M系列的处理器主要运行的是裸机程序,
cortex-M系列的处理器也可以运行实时性的操作系统。
实时性的操作系统:FreeRTOS ucos-II liteOS AliOS-things RT-Thread
cortex-M系列的处理器主要用于物联网相关的电子产品上。
(4. SecurCore系列
SecurCore系列对数据安全要求比较高的电子产品。
6. arm的数据约定
32架构的数据约定
Byte 8 bits.
Halfword 16 bits.
Word 32 bits.
Doubleword 64 bits.
大部分ARM core 提供:
ARM 指令集(32-bit):每一条指令占据的空间大小是32位
Thumb 指令集(16-bit )
Cortex-A处理器:
16位和32位Thumb-2指令集
16位和32位ThumbEE指令集
7. ARMv7架构和ARMv8架构的区别
1. arm-v7架构支持的是arm32位的汇编指令集
arm-v8架构支持的是arm64位的汇编指令集,向下兼容arm-v7架构的指令集
2. arm-v7架构的arm汇编指令的宽度为32位(4字节)
arm-v8架构的arm汇编指令的宽度为32位(4字节)
3. arm32位的处理器指令,1条指令执行可以完成32位数据的运算
eg : add r0, r0, r1 // r0 = r0 + r1
r0和r1寄存器是32位的寄存器最大存储一个32位的数据。
arm64位的处理器指令,1条指令执行可以完成64位数据的运算
eg : add x0, x0, x1 // x0 = x0 + x1
x0和x1寄存器是64位的寄存器最大存储一个64位的数据。
8. ARM处理器的工作模式
(1. cortex-a的模式
ARM 有7种基本工作模式:
User : 非特权模式,大部分任务执行在这种模式
FIQ : 当一个高优先级(fast) 中断产生时将会进入这种模式
IRQ : 当一个低优先级(normal) 中断产生时将会进入这种模式
Supervisor :当复位或软中断指令执行时将会进入这种模式
Abort : 当存取异常时将会进入这种模式
Undef : 当执行未定义指令时会进入这种模式
System : 使用和User模式相同寄存器集的特权模式
Cortex-A特有模式:
Monitor : 是为了安全而扩展出的用于执行安全监控代码的模式;
也是一种特权模式
HYP:虚拟化支持模式
(2. cortex-M系列的工作模式
cortex-M系列只有两种工作模式:
线程模式 ----> 执行的主程序
异常模式 ----> 执行异常处理程序
按键中断,定时器的中断,硬件出错总结:特定的模式下执行特定的代码,完成特定的功能。
9. ARM的寄存器组织
(1. armv7架构寄存器组织
ARM 有37个32-Bits长的寄存器:
1 个用作PC( program counter)
1个用作CPSR(current program status register)
5个用作SPSR(saved program status registers)
30 个通用寄存器
Cortex体系结构下有
40个32-Bits长的寄存器:
Cortex-A多出3个寄存器,
Monitor 模式 r13_mon , r14_mon, spsr_mon
当前处理器的模式决定着哪组寄存器可操作.
任何模式都可以存取:
相应的r0-r12子集
相应的 r13 (the stack pointer, sp) and r14 (the link register, lr)
相应的 r15 ( the program counter, pc)
相应的CPSR(current program status register, cpsr)
特权模式 (除system模式) 还可以存取:
相应的 spsr (saved program status register)
(2. ARM v8架构的寄存器组织
10. ARM v7架构下的特殊功能寄存器
(1. R15(PC/ program counter)
1. R15又被称为程序计数器,PC寄存器,这个寄存器的作用是用来保存即将执行的指##令的地址。
2. 在程序正常向下执行时,一条指令执行结束后,PC寄存器的数值会自动向下+4
3. 如果有特殊清情况,可以手动修改PC寄存器的数值,实现程序的跳转
一条指令的执行步骤如下
(2. R14(LR)寄存器
R14寄存器又被称为LR(Link Register)寄存器,当我们实现程序跳转时,LR寄存器中会保存跳转之前执行的指令的下一条指令的地址,用于程序返回
(3. R13寄存器
r13又被称为SP(stack pointer)寄存器
R13寄存器始终保存栈顶元素所在位置的地址
在内存中我们一般会初始化一片内存,这片内存被称为栈区,栈区一般用于保存一些临时数据。而想要操作到栈区的内存,这里需要使用sp寄存器
(4. CPSR和SPSR寄存器
CPSR 寄存器:程序状态寄存器
这个寄存器的作用是用于保存当前程序的状态(工作模式,指令模式以及其他的程序特征)
SPSR 寄存器:
这个寄存器的作用是用于保存程序状态切换前的CPSR的数值,用于程序的状态返回
1. N[31] : 指令的运行结果为负数时,N位被自动置1,否则为0.
eg : 100 - 200
2. Z[30] : 指令的运行结果为零时,Z位被自动置1,否则为0.
3. C[29] :
加法:加法运算如果产生进位,C位被自动置1,否则为0.
32位指令:低32位向高32位进位
减法:减法运算如果产生借位,C位被自动清0,否则位1.
32位指令:低32位向高32位借位
4. V[28] : 符号位发送变化,V位被自动置1,否则清0.
5. I[7] : IRQ中断屏蔽位
I = 0 : 不屏蔽IRQ中断
I = 1 : 屏蔽IRQ中断
6. F[6] : FIQ中断屏蔽位
F = 0 : 不屏蔽FIQ中断
F = 1 : 屏蔽FIQ中断
7. T[5] : 状态位
T = 0 : 表示ARM状态,执行的是ARM指令集
T = 1 : 表示Thumb状态,执行的是Thumb指令集
ARM指令集 : 一条汇编指令编译生成32位的机器码
thumb指令集:一条汇编指令编译生成16位的机器码
ARM指令集的代码的密度低,而thumb指令记得代码密度高。
ARM指令集的功能性要高于Thumb指令集。
8. M[4:0] : 模式位
10000 User mode;
10001 FIQ mode;
10011 SVC mode;
10111 Abort mode;
11011 Undfined mode;
11111 System mode;
10110 Monitor mode;
10010 IRQ
其他没有使用到的值,保留。
11. ARM的流水线工作
对于ARM处理器一条指令执行需要三步:
1. 取址:向内存方式要执行的指令的地址,内存会将这个地址内的指令去处理放到IR寄存器中
2. 译码:对IR寄存器的指令进行译码操作,将译码后结果交给运算器
3. 执行:按照指令执行
ARM指令的执行采用流水线的方式,来提高指令的执行的效率。
重点掌握三级流水线。目前有3级,5级,7级,8级,13级流水线,
不管是多少级的流水线都在在三级的基础上扩展。
取指器:根据PC寄存器中的值从代码段取出对应的指令
译码器:翻译指令的功能,并将其给到对应的执行器
执行器:执行指令,并将结果写回到寄存器中
以上三个器件都是相互独立的器件,工作互不干扰,
每个器件都是单周期的器件。
时间周期\步骤 | 取址 | 译码 | 执行 |
---|---|---|---|
T1 | 指令1 | ||
T2 | 指令2 | 指令1 | |
T3 | 指令3 | 指令2 | 指令1 |
T4 | 指令4 | 指令3 | 指令2 |
T5 | 指令5 | 指令4 | 指令3 |
五、环境搭建
1. 搭建keil5汇编环境
如有需要可在本文顶部下载资源,含安装搭建教程
2. linux虚拟机安装交叉编译工具链
安装交叉编译工具链,需要安装兼容32位库,ubuntu一定需要联网
sudo apt-get install lib32z1
1.进入家目录
cd ~
2.创建toolchain文件夹
mkdir toolchain
3.拷贝交叉编译工具链,到toolchain目录下(STM32MP157-学生资料\开发工具\06.5_ubuntu版本交叉编译工具链)
交叉编译工具链,一定不要在windows下解压
tar -vxf gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf.tar.xz
4.将gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf文件进行重命名
mv gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf
gcc-7.5.0
5.对交叉编译工具链进行配置:
$:sudo vi /etc/bash.bashrc
添加一句话:
export PATH=$PATH:/home/ubuntu/toolchain/gcc-7.5.0/bin
6.重启终端
source /etc/bash.bashrc
7.测试交叉编译工具链是否安装成功
$: arm-linux-gnueabihf-gcc -v
注意:arm-l(Tab补全)
成功现象:
看到:gcc 版本 7.5.0 (Linaro GCC 7.5-2019.12)