ARMv7-A 那些事 - 5.CP15协处理器协处理器概述ARM架构通过支持协处理器来扩展处理器的功能。ARM架构的处理器支持最多16个协处理器,通常称为CP0~CP15。下述的协处理器被ARM用于特殊用途:CP15:提供系统控制功能,主要用于配置MMU、TLB和Cache等功能。CP14:主要用于控制系统Debug功能。CP10、CP11:两个协处理器一起提供了对浮点运算和向量操作的支持,这两个协处理器主要用于控制和配置浮点功能和高级SIMD指令扩展。其他协处理器被ARM保留用于将来使用。本文主要说说CP15协处理器。CP15协处理器总览CP15是系统控制协处理器,主要用于对ARM处理器核心支持的许多特性功能进行配置。CP15协处理器支持16个32位主寄存器(primary register),命名为c0~c15。c0~c15主寄存器各自又有多个32位的物理寄存器(physical register)。CP15协处理器的大多数寄存器不能在USR模式下访问,只能在除USR模式外的其他模式下访问。下面列出c0~c15中比较常用的寄存器:primary registerphysical register描述c0MIDR主ID寄存器,用于记录版本信息c0MPIDR多核处理器情况下,提供一种方法来唯一标识集群中的各个核心c1SCTLR系统控制寄存器c1ACTLR辅助控制寄存器c1CPACR协处理器访问控制寄存器,控制访问除了CP14和CP15的协处理器c1SCR安全配置寄存器,被TrustZone使用c2、c3TTBR0一级转换页表基址寄存器0c2、c3TTBR1一级转换页表基址寄存器1c2、c3TTBCR页表转换控制寄存器c5、c6DFSR数据异常(Data Fault)状态寄存器c5、c6IFSR指令异常(Instruction Fault)状态寄存器c5、c6DFAR数据异常(Data Fault)地址寄存器c5、c6IFAR指令异常(Instruction Fault)地址寄存器c7branch predictorcache和分支预测管理功能c7barrier数据和指令屏障操作c8TLBTLB操作c9performance monitors性能监视器c12VBAR提供非监视模式处理异常的异常基地址c12MVBAR提供监视模式处理异常的异常基地址c13CONTEXTIDR上下文ID寄存器c15CBAR配置基址寄存器,为GIC和本地时钟类型外设提供基地址在CP15协处理器中,c0~c15每个主处理器下面有多个物理寄存器,上述表格只列出了部分常用的物理寄存器。协处理器操作指令ARMv7-A体系结构的处理器提供了MRC和MCR指令用于对协处理器进行读写操作。MRC指令用于将CP15协处理器中的寄存器数据读取到ARM通用寄存器中。MCR指令用于将ARM通用寄存器中的数据写入到CP15协处理器的寄存器中。MRCMRC指令的语法如下所示:MRC{cond} coproc, opc1, Rt, CRn, CRm{, opc2}cond为条件码。coproc为协处理器名称,CP0~CP15协处理器分别对应名称p0~p15。opc1为协处理器要执行的操作码,取指范围为0~7。Rt为ARM通用寄存器,用于存储读取到的协处理器寄存器数据。CRn为协处理器寄存器,对于CP15协处理器来说,CRn取值范围为c0~c15。CRm为协处理器寄存器,对于CP15协处理器来说,通过CRm和opc2一起来确定CRn对应的具体寄存器。opc2为可选的协处理器执行操作码,取指范围为0~7,当不需要的时候要设置为0。MRC指令使用示例如下:MCRMCR指令的语法如下所示:MCR{cond} coproc, opc1, Rt, CRn, CRm{, opc2}cond为条件码。coproc为协处理器名称,CP0~CP15协处理器分别对应名称p0~p15。opc1为协处理器要执行的操作码,取指范围为0~7。Rt为ARM通用寄存器,用于存储要写入到协处理器寄存器中的数据。CRn为协处理器寄存器,对于CP15协处理器来说,CRn取值范围为c0~c15。CRm为协处理器寄存器,对于CP15协处理器来说,通过CRm和opc2一起来确定CRn对应的具体寄存器。opc2为可选的协处理器执行操作码,取指范围为0~7,当不需要的时候要设置为0。MCR指令使用示例如下:CP15协处理器主寄存器组成CP15协处理器有c0~c15总共16个主寄存器,在每个主寄存器下面,又有多个物理寄存器。下图总结了CP15协处理器的寄存器组织形式:上图对于MRC和MCR指令所要使用到的一些参数都标明了,对于想要访问CP15协处理器相关寄存器,只需要看图填写好参数就行了。下面具体列一下c0~c15各个主寄存器的组成。CP15协处理器c0寄存器组成主寄存器c0主要提供ID相关的功能,c0寄存器的组成如下图所示:CP15协处理器c1寄存器组成主寄存器c1主要提供系统控制相关的功能,c1寄存器的组成如下图所示:在CP15协处理器的寄存器中,系统控制寄存器SCTLR是被访问的比较多的寄存器。对SCTLR寄存器的访问需要在PL1或者更高的特权等级。SCTLR寄存器的位关系如下图所示:位标志说明30TEThumb异常使能,控制在异常发生时(包括reset),将会进入哪种指令集,0:ARM指令集,1:Thumb指令集27NMFI不可屏蔽的FIQ支持,0:软件可以通过写CPSR.F位来屏蔽FIQ,1:软件不可以通过写CPSR.F位来屏蔽FIQ25EE在进入异常处理时的大小端模式配置,0:小端,1:大端22U表明是否使用对齐模式21FIFIQ配置使能13V选择异常向量表基址,0:0x00000000,1:0xffff000012I指令cache使能11Z分支预测使能2C数据cache使能1A对齐检查使能0MMMU使能CP15协处理器c2 c3寄存器组成主寄存器c2和c3主要提供内存保护和内存控制相关的功能,c2和c3寄存器的组成如下图所示:CP15协处理器c4寄存器组成在任何基于ARMv7实现的处理器中,协处理器CP15的c4寄存器没有被使用。CP15协处理器c5 c6寄存器组成主寄存器c5和c6主要提供内存系统错误上报功能,c5和c6寄存器的组成如下图所示:CP15协处理器c7寄存器组成主寄存器c7主要提供cache维护,地址转换和内存屏障操作相关的功能,c7寄存器的组成如下图所示:CP15协处理器c8寄存器组成主寄存器c8主要提供TLB维护相关的功能,c8寄存器的组成如下图所示:CP15协处理器c9寄存器组成主寄存器c9保留用于分支预测,cache和TCM操作,c9寄存器的组成如下图所示:CP15协处理器c10寄存器组成主寄存器c10主要提供内存重映射和TLB控制相关的功能,c10寄存器的组成如下图所示:CP15协处理器c11寄存器组成主寄存器c11保留用于TCM DMA操作,c11寄存器的组成如下图所示:CP15协处理器c12寄存器组成主寄存器c12提供安全扩展功能,c12寄存器的组成如下图所示:CP15协处理器c13寄存器组成主寄存器c13提供进程ID、上下文ID和线程ID处理功能,c13寄存器的组成如下图所示:CP15协处理器c14寄存器组成主寄存器c14保留用于通用定时器功能,c14寄存器的组成如下图所示:CP15协处理器c15寄存器组成主寄存器c15由处理器实现决定。这里只是简单的将CP15各个主寄存器的组成列出来了,方便在使用MRC和MCR指令配置CP15主寄存器时,查看指令各个参数的设置,以及对照配置的具体寄存器,至于寄存器的具体内容由于篇幅原因就不列出来了,CP15寄存器的细节可以参考ARMv7AR手册的B3.17章节内容。
ARMv7-A 那些事 - 4.处理器模式与特权等级对于现代操作系统,通常情况下用户的应用程序运行在用户态,操作系统内核运行在内核态。用户态的应用对于系统硬件资源的访问是受限的,内核态则能够访问所有的系统硬件资源。操作系统的用户态和内核态是根据处理器的特权等级和运行模式进行硬件隔离的,这也极大的提高了操作系统的安全性。安全扩展和虚拟化扩展ARMv7-A体系结构支持安全扩展和虚拟化扩展。当处理器实现了安全扩展之后,处理器就存在普通世界(Normal world)和安全世界(Secure world)这两个世界,这在硬件层面上就可以将敏感数据和要求在安全环境运行的应用和普通应用完全隔离,如下图所示:当处理器实现了虚拟化扩展之后,处理器就新增了一个hypervisor mode (Hyp),并且也新增了一个特权级模式PL2。支持虚拟化扩展的处理器示意图如下所示:虚拟化扩展允许在Normal world运行多个操作系统,Hypervisor只能运行在Normal world。Secure world可以运行Trusted OS和Trusted services。特权等级处理器的模式,特权等级和安全状态的关系如下图所示:本文仅讨论非安全状态。在非安全状态下,存在3种特权等级(Privilege level):PL0、PL1和PL2,描述如下:PL0:用户模式(User mode)运行的应用程序处于PL0特权等级。运行在用户模式的程序被称为非特权程序。非特权程序对于系统资源的访问是受限的,对应Linux的用户态。PL1:除了用户模式和Hyp模式外,其他模式下的程序执行都处于PL1特权等级。PL1模式是指除了用户模式和Hyp模式之外的其他模式。操作系统运行在PL1特权级。PL2:如果实现了虚拟化扩展,Hyp模式运行的系统管理程序处于PL2特权等级。系统管理程序将控制并启用多个操作系统在同一个处理器系统上共存和执行。处理器模式ARMv7-A体系结构提供了9种处理器模式,如下图所示:从上图可以知道ARMv7-A提供的处理器模式有User、FIQ、IRQ、Supervisor(SVC)、Monitor(MON)、Abort(ABT)、Hyp、Undefined(UND)、System(SYS)模式,各个处理器模式的描述如下:User:用户模式,用户程序运行在User模式下,拥有受限的系统资源访问权限。FIQ:快中断异常处理模式,发生FIQ中断时的处理器模式,相对于中断而言,快中断拥有更高的响应等级和更低的延迟。IRQ:中断异常处理模式,发生IRQ中断时的处理器模式。Supervisor(SVC):管理员模式,操作系统内核通常运行在该模式下,在处理器复位或者应用程序调用svc指令的时候将会进入到该模式,系统调用就是通过svc指令完成的。Abort(ABT):异常终止模式,当发生Data Abort exception或者Prefetch Abort exception异常的时候进入这个模式。Undefined(UND):未定义指令模式,当执行未定义指令时进入这个模式。System(SYS):系统模式,系统模式和用户模式共享寄存器视图,并且目前大多数系统未使用该模式,利用这个特性我们可以在处理器启动时通过设置系统模式的SP寄存器来达到设置用户模式堆栈的目的,要设置用户模式的其他寄存器也可以这样操作。Monitor(MON):监视模式,实现了安全扩展的处理器才有该模式,在该模式下执行Secure和Non-secure处理器状态的切换。Hyp:实现了虚拟化扩展的处理器才有该模式。User模式处于PL0特权等级。FIQ、IRQ、Supervisor(SVC)、Monitor(MON)、Abort(ABT)、Undefined(UND)、System(SYS)这些模式处于PL1特权等级。Hyp模式处于PL2特权等级。本文不讨论支持安全扩展和虚拟化扩展的场景,因此对于Monitor模式和Hyp模式也不做深入探讨。通常情况下,应用程序运行在User模式(PL0),运行在User模式下的应用程序对硬件没有直接访问权,所有的硬件操作都需要通过系统调用向内核进行申请。操作系统内核运行在管理员模式(PL1),对系统调用、中断、异常等系统事件进行响应、处理并返回,以这种硬件隔离的方式保证了操作系统内核的安全。以Linux操作系统为例,虽然ARMv7-A体系结构的处理器有9种模式,但是操作系统只工作在SVC和USR模式,SVC处于内核态,USR处于用户态。至于其他的异常模式,Linux只是简单的略过。比如中断模式irq,Linux只有很短的汇编代码在irq模式运行,主要是保存上下文,然后就立马切换到了SVC模式,由内核进行统一处理。寄存器集ARMv7-A体系结构的处理器在不同处理器模式下,对于通用寄存器的使用情况也有所不同,如下图所示:上图中蓝色背景的寄存器属于bank寄存器,也就是相同的寄存器名对应不同的寄存器实体。从上图可以看出:R0~R7,PC在所有模式下是共享的。系统模式和用户模式共享寄存器视图,系统模式没有bank寄存器。FIQ 模式下,R8~R12、SP、LR 都是该模式专门的寄存器,FIQ比IRQ响应和处理速度更快,也得益于FIQ模式具有比IRQ模式更多的bank寄存器。FIQ、IRQ、ABT、SVC和UND模式,都有他们自己模式下专用的SP和LR,也就是说,在模式切换的时候,不需要针对这两个寄存器进行现场保护和恢复;FIQ、IRQ、ABT、SVC和UND模式,都有他们自己模式下专用的SPSR。在处理器发生中断或者异常时,处理器会自动的从一个模式A进入到另一个模式B,模式A的CPSR/APSR将会自动保存到模式B的SPSR中,这样模式B中的处理程序能够通过访问SPSR寄存器得到模式A下CPSR寄存器的信息。处理器模式切换ARMv7-A体系结构的处理器,处理器模式是由状态寄存器CPSR的M域(BIT[4:0])来控制的。对于用户模式而言,是没有权限操作CPSR寄存器的M域的,只能通过svc指令进入到SVC模式。对于SYS、FIQ、IRQ、ABT、SVC和UND模式而言,可以通过给CPSR寄存器的M域赋值来达到切换处理器模式的目的。各个模式的编码如下图所示:下述代码简单的演示了处理器模式切换:在上述代码中,使用了cps #mode指令来完成处理器模式的切换,在切换到相应模式之后,设置了对应模式的堆栈。在上述代码中,为什么不直接切换到USR模式,再设置USR模式的堆栈,而要借助SYS模式来设置USR模式的堆栈呢?这个问题相信大家在学习了本节内容之后,应该还是比较简单的。
ARMv7-A 那些事 - 3.程序状态寄存器程序状态寄存器的作用就是反映处理器的状态信息。在程序运行期间我们可以通过查看程序状态寄存器的状态位来进行程序的分支跳转处理,或者我们可以设置程序状态寄存器的模式位来改变处理器的运行模式,或者我们可以设置程序状态寄存器的中断屏蔽位来屏蔽中断。在任何时刻,我们可以访问处理器的16个寄存器(R0~R15)和当前程序状态寄存器(Current Program Status Register,CPSR)。用户模式下的程序访问的程序状态寄存器叫做APSR(Application Program Status Register),APSR是CPSR在用户模式下的别名,因为在用户模式下CPSR的部分域是不能操作的,因此CPSR的部分域被屏蔽后就是APSR。CPSR寄存器组成在所有模式下均可以访问到CPSR,只是在用户模式下CPSR的部分域是不能操作的,当前程序状态寄存器(CPSR)的位组成如下图所示:各个位域的说明如下:位标志说明31N当运算结果为负且运算指令要求更新寄存器时,该位会被置位。30Z当运算结果为0且运算指令要求更新寄存器时,该位会被置位。29C当运算结果产生进位且指令要求更新寄存器时,该位会被置位。28V当运算结果产生符号位溢出且指令要求更新寄存器时,该位会被置位。27Qcumulative saturation。26:25IT[1:0]IT位,由IT[7:2]和IT[1:0]组成,Thumb指令集中IT指令的If-Then执行状态。24J指示ARM是否处于Jazelle状态。19:16GE[3:0]被一些SIMD(Single Instruction Multiple Data)指令使用。15:10IT[7:2]见IT[1:0]的描述。9E指示处理器的大小端模式,同时可以通过设置该位来修改处理器的大小端模式,1表示大端模式,0表示小端模式。8A是否屏蔽异步终止,该位为1时表示屏蔽异步终止,为0时表示打开异步终止。7I是否屏蔽IRQ,该位为1时表示屏蔽IRQ,为0时表示打开IRQ。6F是否屏蔽FIQ,该位为1时表示屏蔽FIQ,为0时表示打开FIQ。5T指示ARM是否处于Thumb状态。J和T标志共同决定处理器使用的指令集。J=0,T=0:ARM指令集;J=0,T=1:Thumb指令集;J=1,T=0:Jazelle指令集;J=1,T=1:ThumbEE指令集。4:0M[4:0]指示处理器的模式,同时可以通过设置该位域来修改处理器的模式。处理器各个模式的编码如下图所示:APSR寄存器组成在用户模式下,用户程序能够操作的CPSR寄存器位域是有限制的,对CPSR寄存器的部分位域屏蔽之后就是APSR了,应用程序状态寄存器(APSR)的位组成如下图所示:从上图可以看出,APSR只能访问N,Z,C,V,Q和GE[3:0]这些标志位,这些标志位的含义和CPSR中对应标志位的含义一样。SPSR备份程序状态寄存器(Saved Program Status Register,SPSR)主要用于存储前一个执行模式的CPSR。FIQ、IRQ、ABT、SVC和UND模式,都有他们自己模式下专用的SPSR。在处理器发生中断或者异常时,处理器会自动的从一个模式A进入到另一个模式B,模式A的CPSR/APSR将会自动保存到模式B的SPSR中,这样模式B中的处理程序能够通过访问SPSR寄存器得到模式A下CPSR寄存器的信息。程序状态寄存器操作指令CPS指令可以通过CPS(Change Processor State)指令来修改处理器模式。CPS指令也可以用来使能或者禁止异常。CPS指令的语法如下所示:mode是处理器的模式编码,比如在从其他模式下切换到SYS模式,使用下述代码即可:IE使能中断或者终止。ID禁止中断或者终止。iflags由下面的一种或者几种组成:a:表示异步终止(asynchronous abort);i:表示中断(IRQ);f:表示快中断(FIQ);下述代码是CPS指令的一些简单用法:MRS与MSR指令MRS和MSR指令可用于读写程序状态寄存器CPSR,APSR和SPSR。在ARM处理器中,只有MRS指令可以从程序状态寄存器CPSR,APSR和SPSR中读出数据到通用寄存器中。MRS指令操作程序状态寄存器的语法如下:MRS{cond} Rd, psrcond为条件码。Rd为目标寄存器,Rd不允许为R15。psr为程序状态寄存器CPSR,APSR或者SPSR。MRS指令的示例代码如下所示:MSR指令可以用来写程序状态寄存器CPSR,APSR和SPSR的全部或者部分域。MSR指令操作程序状态寄存器的语法如下:cond为条件码。psr为程序状态寄存器CPSR或者SPSR。constant是一个8位立即数。ARM文档对于constant的介绍如下:constant is an 8-bit pattern rotated by an even number of bits within a 32-bit word. (Not available in Thumb.)Rm是源寄存器。fields由下面的一个或者多个组合而成:c:xPSR[7:0],控制位域;x:xPSR[15:8],扩展位域;s:xPSR[23:16],状态位域;f:xPSR[31:24],标志位域;MSR指令的示例代码如下所示:只有在除用户模式外的其他模式下才能够修改状态寄存器。
ARMv7-A 那些事 - 2.通用寄存器与流水线世界上有很多种体系结构的处理器,比较知名的处理器体系结构有:ARM、x86、RISC-V、mips、LoongArch、PowerPC等。不论是哪一种架构的处理器,其处理器核心都会自带一定数量的寄存器,这些寄存器在处理器核心的运行过程中发挥着基础而又重要的作用。ARM体系结构是一种基于指令加载和存储的体系结构。在这种体系结构下,所有的数据处理都需要在通用寄存器中完成,而不能直接在内存中完成。因此,这种体系结构的处理器核心处理数据的过程为:首先把待处理数据从内存加载到通用寄存器,然后进行处理,最后把结果写入内存中。通用寄存器ARM架构提供了16个32位通用寄存器(R0-R15)用于软件使用。其中R0-R12是普通寄存器,R13、R14和R15在程序的运行过程中通常用作固定的用途。R13:又叫堆栈指针寄存器(Stack pointer)SP,SP通常用于保存堆栈地址,在使用入栈和出栈指令时,SP中的堆栈地址会自动的更新。堆栈主要用于保存局部变量,保存函数间调用的关键寄存器。对于根本不需要进行堆栈操作的程序,SP可以当做普通寄存器来存储数据。R14:又叫链接寄存器(Link register)LR,LR主要用于存放函数的返回地址,即当函数返回时,知道自己该回到哪儿去继续运行。通常链接寄存器是和BL/BLX/CALL指令搭配使用,这几个指令被调用后,默认会自动将当前调用指令的下一条指令地址保存到LR寄存器当中。R15:又叫程序计数器(Program Counter)PC,PC主要用于存放CPU取指的地址。ARMv7架构同时支持ARM指令集和Thumb指令集。在ARM指令集中,当CPU正在执行A指令时,PC的值为当前指令A地址+8;在Thumb指令集中,由于Thumb指令集为16位,当CPU正在执行A指令时,PC的值为当前指令A地址+4。但是当手动向PC赋值时,CPU就会跳转到赋值所代表的地址处去运行。记住PC存放的是取指地址,不是当前CPU运行地址。备注:在ARM状态下,PC指向的地址bit[1:0]总是为0,因此PC指向的地址都是4字节对齐。ARMv7架构的处理器支持混合编码即同时支持ARM指令集和Thumb指令集,因此为了区分Thumb指令集和ARM指令集,ARM将PC指向地址的bit[0]位作为标志位。如果PC指向的地址bit[0]位为1,表示当前是Thumb指令集;如果PC指向的地址bit[0]位为0,表示当前是ARM指令集。三级流水线为了增加处理器指令流的速度,ARM使用了多级流水线技术。多级流水线技术是一种将指令的执行分解成多个步骤,并让不同指令的各步骤重叠的一种准并行处理实现技术。经典的三级流水线结构将指令的执行分成取指,译码和执行这三个阶段。可以将指令的执行过程看成工厂加工产品的过程,当没有采用流水线时只有一个工人A,工人A先对指令取指,然后对指令译码,最后执行指令,然后再次对指令取指周而复始。工人A在同一个时间只能干一件事,指令的执行也就只有等工人A对指令完成取指和译码之后才能进行。工厂老板一看,这产品的生产效率太低,就又请了工人B和工人C,现在工人A只负责取指,工人B只负责译码,工人C只负责执行,这样三条流水线同时工作,每时每刻都有指令在被取指,译码和执行,产品的生产效率大大的提高了。三级流水线示意图如下图所示:上图是ARM指令集的三级流水线结构,每条指令的地址间隔为4字节,当CPU在t3时间段开始执行add r0,r1,#3指令时,PC的值为0x00000008,即PC此时指向cmp r0,#9指令处。记住PC存放的是取指地址,不是当前CPU运行地址。结合上图对于Thumb指令集的PC值分析也是比较简单的。采用多级流水线技术后,并没有加速单条指令的执行,每条指令的步骤并没有减少,只是多条指令的不同操作步骤同时执行,因而从总体上看加快了指令流速度,缩短了程序执行时间。
ARMv7-A 那些事 - 1.概述ARM公司与芯片ARM公司是一家知识产权(IP)供应商,它与一般的半导体公司最大的不同就是它不制造芯片并且不向终端用户出售芯片,而是通过转让设计方案,由合作伙伴生产出各具特色的芯片。ARM公司利用这种双赢的伙伴关系迅速成为了全球性RISC微处理器标准的缔造者。这种模式也给用户带来了巨大的好处,因为用户只需要掌握一种ARM内核结构及其开发手段,就能够使用多家公司相同ARM内核的芯片。ARM处理器在性能,成本与功耗之间的平衡,是ARM处理器的亮点。在智能家居、物联网、平板电脑、多媒体数字、汽车电子、医疗电子等领域ARM处理器具有统治地位。指令集、架构与处理器ARM体系结构是一种硬件规范,主要用来约定指令集、芯片内部体系结构(如MMU、Cache)等。指令集是处理器使用的指令编码方式,ARM指令集的命名方式为ARMv+version,目前是ARMv1~ARMv9,数字越大表示指令集越先进。下面列举一些指令集应用到具体处理器的例子。ARMv4和ARMv4T指令集主要在ARM7TDMI、ARM920T和StrongARM这些处理器中使用。ARMv5指令集主要在ARM926EJ-S、ARM946E-S和XScale这些处理器中使用。ARMv6指令集主要在ARM1136J-S、ARM1176JZ-S和ARM1156T2-S这些处理器中使用。ARMv6-M指令集主要在Cortex-M0和Cortex-M1这些处理器中使用。ARMv7-A指令集主要在Cortex-A5、Cortex-A7、Cortex-A8、Cortex-A9、Cortex-A12和Cortex-A15这些处理器中使用。ARMv7-R指令集主要在Cortex-R4、Cortex-R5和Cortex-R7这些处理器中使用。ARMv7-M指令集主要在Cortex-M3和Cortex-M4这些处理器中使用。架构主要是指某一个处理器所使用的具体指令集。在大部分场合,架构等于指令集。比如说i.MX 6ULL处理器是基于ARMv7-A架构的,也就是说i.MX 6ULL处理器使用的是ARMv7-A指令集。基于ARMv7-A的处理器内部结构ARMv7-A采用的是32位结构,因此其核心寄存器也是32位宽。基于ARMv7-A实现的处理器内部结构描述如下:处理器核心:有单核和多核之分,对称多核应用比较广泛,通常每个核心会包含L1 I-Cache、L1 D-Cache,可选的浮点单元,可选的NEON,MMU等。中断控制器:GIC。系统总线:处理器核心通过系统总线与外设控制器进行数据交互。时钟系统;电源管理系统;复位系统;调试系统。基于ARMv7-A指令集实现的Cortex-A5处理器的结构示意图如下所示:ARMv7-A的概述就先介绍这些吧,请关注ARMv7-A后续的内容。
Ubuntu释放VMware虚拟磁盘未使用空间在Windows 11中通过VMware安装Ubuntu 22.04做一些Linux相关的学习,刚安装的时候VMware虚拟磁盘空间也就6~7GB,但是没用几天,VMware虚拟磁盘空间就飙升到了20GB左右,着实吓人,下面讲讲如何释放VMware虚拟磁盘未使用空间,达到减小VMware虚拟磁盘占用空间的目的。下述内容有参考一些网友的文章,经过下述步骤VMware虚拟磁盘空间从20GB左右减少到10GB左右,释放了10GB空间,效果还是很明显的。清除apt缓存打开终端,并运行以下命令,可以查看到apt缓存有多少:sudo du -sh /var/cache/apt/archives如果你的Ubuntu系统已经使用很久的话,你将看到这个数字非常大。此时可以通过运行以下命令来清理apt缓存:xxxxxxxxxxsudo apt clean清空回收站将回收站中的文件清空,为后续释放VMware虚拟磁盘空间做准备。删除VMware drag_and_drop文件夹~/.cache/vmware/drag_and_drop文件夹是平时从Windows11拷贝文件到Ubuntu中的缓存,执行下述命令删除这些缓存内容。xxxxxxxxxxrm -rf ~/.cache/vmware/drag_and_drop查看磁盘占用情况在命令行执行命令baobab(baobab是Ubuntu自带的磁盘分析工具),可以知道磁盘的占用情况,我这里将/和/home是挂载到单独的分区的,因此分区工具也列出了/和/home各自的磁盘占用情况。/目录磁盘占用情况:/home目录磁盘占用情况:根据磁盘占用情况,可以删除一些无用的文件。释放未使用到的磁盘空间用0填充挂载点未使用的空间,然后删除填充文件,这样VMware就明确的知道这些空间是未被使用的,为后续的shrink操作能够有效的减小VMware虚拟磁盘空间提供基础。我的Ubuntu系统将/和/home是挂载到单独的分区的,如下图所示/dev/sda4挂载到/,/dev/sda5挂载到/home:从上图可以看出/和/home分配的空间都比较大,/分区大小为113GB,/home分区大小为133GB,因此释放空间也主要从/和/home入手,如果你有其他挂载点占用空间比较大,也可以按照下述步骤释放空间。释放/挂载点未使用到的空间用0填充/挂载点未使用到的空间,命令如下:xxxxxxxxxxsudo dd if=/dev/zero of=/wipefile bs=1M将缓存文件同步到磁盘,命令如下:xxxxxxxxxxsudo sync删除填充文件,命令如下:xxxxxxxxxxsudo rm -rf /wipefile执行下述命令,释放/挂载点未使用到的空间:xxxxxxxxxxsudo /usr/bin/vmware-toolbox-cmd disk shrink /释放/home挂载点未使用到的空间该步骤根据自己实际的分区情况进行选择使用。用0填充/home挂载点未使用到的空间,命令如下:xxxxxxxxxxsudo dd if=/dev/zero of=/home/wipefile bs=1M将缓存文件同步到磁盘,命令如下:xxxxxxxxxxsudo sync删除填充文件,命令如下:xxxxxxxxxxsudo rm -rf /home/wipefile执行下述命令,释放/home挂载点未使用到的空间:xxxxxxxxxxsudo /usr/bin/vmware-toolbox-cmd disk shrink /home使用VMware软件对磁盘进行一些操作执行完上述操作之后,关闭Ubuntu,然后在VMware界面中点击编辑虚拟机设置,在虚拟机设置界面中先点击压缩按钮对虚拟机磁盘进行压缩,之后点击碎片整理,最后关闭虚拟机设置界面。到这一步,看看Windows 11中Ubuntu的VMware虚拟磁盘空间是不是变的比以前小多了。
Ubuntu搭建ftp服务器本文将在Ubuntu 22.04上搭建ftp服务器,对于其他版本Ubuntu系统或者其他系列的Linux发行版,配置都差不多。下述内容配置好了匿名用户和Ubuntu本地用户登录ftp服务器,并能上传和删除文件。安装vsftpdsudo apt install vsftpdvsftpd服务在安装完成后会自动启动。通过下述命令可以查看vsftpd的状态:sudo systemctl status vsftpd配置vsftpd可以通过编辑/etc/vsftpd.conf文件来配置vsftpd服务器。大多数ftp配置在配置文件中都有描述。有关所有可用选项,可以官方vsftpd页面进行查询。执行下述命令打开/etc/vsftpd.conf文件:sudo vim /etc/vsftpd.conf配置FTP登录方式将/etc/vsftpd.conf文件中的anonymous_enable和local_enable设置成如下的配置:anonymous_enable:控制是否允许匿名登录。local_enable:控制是否允许Ubuntu的本地用户登录(ftp客户端可以使用Ubuntu的用户名和密码登录到ftp服务器中)。限制用户访问其他目录为防止FTP用户访问其主目录之外的其他目录,在/etc/vsftpd.conf文件中,取消chroot_local_user=YES的注释:chroot_local_user=YES并且在/etc/vsftpd.conf文件的末尾添加下述内容,设置ftp用户的主目录为/home:local_root=/home允许上传和删除操作在/etc/vsftpd.conf文件中,取消write_enable的注释,以允许对文件系统进行更改,例如上传和删除文件。在/etc/vsftpd.conf文件中,打开匿名用户的一些配置,如果下述配置在/etc/vsftpd.conf文件中没有,可以在配置文件中进行添加:设置匿名用户的默认目录在/etc/vsftpd.conf文件中,增加anon_root的配置,内容如下:anon_root=/home/ailsonjack/shareanon_root:设置匿名用户的默认路径。到这里已经完成了对/etc/vsftpd.conf文件的配置,保存退出/etc/vsftpd.conf文件的编辑。在/home/ailsonjack文件夹中创建share文件夹,命令如下:为了保证匿名用户能够顺利的上传和删除文件,需要在share文件夹中创建ftp文件夹,之后改变ftp文件夹的权限为777,匿名用户就只能在ftp文件夹中进行文件的上传或者删除。使配置生效设置完成/etc/vsftpd.conf文件之后,执行下述命令重启vsftpd来使设置生效:sudo systemctl restart vsftpd禁用防火墙为了确保ftp服务器能够正常工作,我这里简单的关闭防火墙,命令如下:sudo ufw disable关闭防火墙之后,可以执行下述命令查看防火墙的状态:sudo ufw status至此,Ubuntu搭建ftp服务器算是完成了,试试吧。
1、const char *ptrconst char *ptr 表示的是指向常量的指针,不能通过该指针去修改指针所指向地址中的内容,但是可以修改该指针的指向。 可以通过其他普通指针对同样地址中的数据进行修改,测试例子如下:编译测试程序:gcc test.c -o test.exegcc编译报错,提示对指向常量的指针的错误操作。屏蔽23行的代码 ptr[0] = 'A';,重新编译,运行结果如下:2、char const *ptrchar const *ptr 和 const char *ptr 等价。3、char * const ptrchar * const ptr 表示的是指针的指向不可以被修改,但是可以修改指针指向地址中的内容。测试例子如下:编译测试程序:gcc test.c -o test.exegcc编译报错,提示指针的指向不可以被修改。屏蔽27行的代码 ptr = name;,重新编译,运行结果如下:4、总结const char *ptr 表示的是指向常量的指针,不能通过该指针去修改指针所指向地址中的内容,但是可以修改该指针的指向。char const *ptr 和 const char *ptr 等价。char * const ptr 表示的是指针的指向不可以被修改,但是可以修改指针指向地址中的内容。const放在*号前表示修饰的是指针指向的对象,const放在*号后表示修饰的是指针本身。根据上面章节的内容,下面的写法是什么意思应该比较简单吧:const char * const ptr;表示的是ptr指针的指向不可以被修改,ptr指针所指向地址中的内容不可以被修改。
系统:Fedora-14-x86_64我这里的环境是在虚拟机中安装Fedora-14。由于Fedora-14比较老了,因此配置源以及其他一些操作就有些不一样,这里简单记录下我的配置,方便以后查找。使用在线源由于Fedora-14比较古老了,官方不再维护并且将其源路径更改了,因此源的配置也要进行变化。首先将 /etc/yum.repos.d/fedora.repo 进行备份(可以重命名为 fedora.repo.bak )。下面是可用的在线源配置,fedora.repo 文件内容如下:将 /etc/yum.repos.d/fedora.repo 中的文件内容更换为上述内容。验证在线源是否可用有可能之后的路径又会更改,在进行更新源操作之前,可以先确认下源的链接是否可用,分别用浏览器打开下面的3个链接,如果都能正常访问,那么说明在线源没有问题。如果在线源不能使用了,那么也可以考虑将Fedora-14的安装包 Fedora-14-x86_64-DVD.iso 作为本地源,这个配置在下面章节讲述。使用本地源在线源可用的情况下,可以跳过该小节。如果在线源不能使用了,那么我们可以将Fedora-14的安装包 Fedora-14-x86_64-DVD.iso 作为本地源,fedora.repo 文件内容如下:将 /etc/yum.repos.d/fedora.repo 中的文件内容更换为上述内容。备注:baseurl中的 %20 这里表示空格。在线源和本地源选择一种即可,建议当在线源不可用时,就使用本地源。更新源在更新了 fedora.repo 文件内容之后,依次执行下述命令完成更新源操作。上述命令执行的过程中没有报错,就表示源更新完成,之后可以使用下述命令查看源列表:yum repolist如果更新源过程中遇到了问题,可以看看下面的章节是否有提到。更新源遇到的问题Cannot retrieve repository metadata如果更新源的过程中,出现 Error: Cannot retrieve repository metadata (repomd.xml) for repository: updates. Please verify its path and try again 这样的信息,那么将 /etc/yum.repos.d/ 下面 updates 相关的文件进行重命名,我这里将 /etc/yum.repos.d/fedora-updates.repo 重命名为 /etc/yum.repos.d/fedora-updates.repo.bak 。如果更新源的过程中,出现 Error: Cannot retrieve repository metadata (repomd.xml) for repository: salt-latest. Please verify its path and try again 这样的信息,那么将 /etc/yum.repos.d/ 下面 salt-latest 相关的文件进行重命名 。经过上述的步骤之后,Fedora-14的源就配置好了,可以试试yum下载文件,应该OK了吧。
- 1
本站信息
目前本站共被浏览 145129 次
目前本站已经运行 3136 天
目前本站共有 157 篇文章
目前本站共有 6 条评论信息
目前本站共有 101 个标签
目前本站共有 0 条留言信息
网站创建时间: 2015年03月01日
最近更新时间: 2023年10月01日
目前本站已经运行 3136 天
目前本站共有 157 篇文章
目前本站共有 6 条评论信息
目前本站共有 101 个标签
目前本站共有 0 条留言信息
网站创建时间: 2015年03月01日
最近更新时间: 2023年10月01日
JLink V9掉固件修复(灯不亮) 3Zephyr笔记2 - 在STM32F429上运行HelloWorld 2计算NandFlash要传入的行地址和列地址 1ARMv7-A 那些事 - 5.CP15协处理器 0ARMv7-A 那些事 - 4.处理器模式与特权等级 0ARMv7-A 那些事 - 3.程序状态寄存器 0
最新评论
标签云
Linux嵌入式实用技巧ARM内核学习问题集合CC++编程语言阅读笔记汇编Linux内核完全注释Windows驱动开发计算机基础ARM11STM32IDESublimeUbuntu操作系统ARMv7-AOfficeVMWareAPUEgccRTOS中断漫游世界随笔感悟开发工具软件应用编程VsCodearmccarmclang编译器ZephyrSPIJLink网卡驱动安装各种芯片库函数NFSμCOS内核sambaFlashUnix命令与脚本输入法Linux内核设计与实现gitRIFFWAVJATGFTPar8161安装centos有线上网μCGUI字库工程建立右键菜单网络文件系统Firefox百度NTFS文件系统CodeBlocksCentOS数据结构算法PhotoShop51KeilQTUltraEditscanfglibc宏定义UIDGID优先级娱乐天地SourceInsight磁盘扇区总线I2CPDFBComparePythonI2SFPUMakefileSWDCPUARP软件推荐FileZilla