为了学习android系统,发现需要学习linux驱动,发现学习linux驱动,需要先知道处理器的各种架构,为了学习此种知识,发现网上有很多mini2440相关的知识,因此,将其作为蓝本,认真学习。直到linux驱动的学习完成。
这是linux驱动学习的第一部分,arm的汇编程序。
本文档的大部分资料翻译于《S3C2440A 32-BIT CMOS MICROCONTROLLER USER’S MANUAL》
处理器工作状态
从程序员的角度来看,ARM920T(s3c2440的内核)有如下两种状态:
ARM状态,执行32位,字对齐的指令THUMB状态,执行16位,半字对齐的THUMB指令。注意:这两种状态的切换,不会影响处理器的模式和寄存器状态
进入THUMB状态
将操作数寄存器的第0位,设为1,然后执行BX指令,就可以切换为THUMB状态。
例如:
BX Rm;如果Rm的第0位,是1,则跳转到Rm所在的地址,并且设置处理器在thumb模式下如果在THUMB状态下,进入了异常,从异常中退出,依然是THUMB状态
进入ARM状态
可以通过下面的方法,进入arm状态:
将操作数寄存器的第0位,清零,然后执行BX指令 BX Rm;如果Rm的第0位,是0,则跳转到Rm所在的地址,并且设置处理器为arm模式下 处理器发生异常时,PC被放置在异常模式下的连接寄存器中,然后从异常向量地址开始执行ARM920T 将内存视为一个线性的字节序列。字节地址从0开始。0到3字节保存第一个字。4到7字节保存第二个字,依次类推。这些字支持小端和大端格式。
指令长度为32位长(arm模式)和16位长(thumb模式)
ARM920T 支持字节(8位)、半字(16位)、字(32位)数据类型。字必须4字节对齐。半字必须两字节对齐。
ARM920T 支持7种运行模式:
User(usr):最普通的arm执行状态FIQ(fiq):被用来进行数据传输,和信道处理IRQ(irq):通用的中断处理Supervisor(svc):为操作系统设计的保护模式Abort mode(abt):数据和指令预取发生问题时,进入System(sys):为操作系统设计的特权用户模式Undefined(und):当一个未定义的指令执行时,进入此模式模式的改变可以通过软件控制,也可以通过外部的中断,或者异常。大多数的应用程序将运行在用户模式下。
特殊模式(非用户模式)仅仅在服务中断或者异常,或者访问受保护的资源时才会进入。
ARM920T 总共有37个寄存器。其中,31个通用的32位寄存器和6个状态寄存器。这37个寄存器,对于程序来说,不能同时可见。
处理器状态和运行模式,决定了那些寄存器对于程序员来说可见。
在arm状态下,程序员只能看到16个通用寄存器和1个或者2个状态寄存器。在特殊模式(非用户模式),相应的寄存器组被切换。图2-3展示了在每种模式下那些寄存器可见。这些寄存器组使用一个阴影三角形标记:
arm状态下的寄存器组包含16个可直接访问的寄存器:R0-R15.除了R15寄存器以外,其他的寄存器都是通用寄存器。可以用来存储数据或者地址。
除此之外,还有第十七个寄存器用来存储状态信息。
寄存器描述寄存器14该寄存器作为子程序的链接寄存器。当分支指令(Branch)和连接指令(BL)执行时,这个寄存器保存R15的值.其他时候,可以被作为通用寄存器来使用。对应的寄存器有:R14_svc,R14_irq,R14_fiq,R14_abt,R14_und,他们都在对应的模式下保存R15的值寄存器15这个寄存器为程序计数器(PC)。在arm模式下,bits[1:0]是0,bits[31-2]保存PC。在thumb模式下,bit[0]为0,bits[31:1]保存PC寄存器16这个寄存器是CPSR(当前程序状态寄存器)。它保存代码的各种flag和一些模式位FIQ模式有7个寄存器,被映射为R8-R14(R8_fiq-R14_fiq).在arm模式下有许多FIQ处理程序不需要保存的寄存器。
而USer,IRQ,SuperVisor,Abort和Undefined模式,都有R13和R14,并且允许他们有自己的堆栈指针和链接寄存器
ARM和THUMB之间的寄存器关系
如下:
THUMB模式下R0-R7 ,ARM模式下R0-R7 完全相同THUMB模式下CPSR和SPSRs,ARM模式下CPSR和SPSRs是完全相同的THUMB模式下SP映射为ARM的R13THUMB模式下LR映射为ARM下的R14THUMB模式下PC映射为ARM的R15在thumb模式下访问高寄存器组(Hi-registers)
在THUMB模式下,寄存器组R8-R15(被称为Hi-registers)不是标准寄存器组中的一部分。因此,汇编程序对他的访问是受限制的。但是他们可以用来作为临时的存放地。
可以使用mov指令,将R0-R7里面的值放置到高寄存器中。也可以将高寄存器中的值放到低寄存器中(R0-R7)
也可以使用CMP指令,将高寄存器和低寄存器进行比较
也可以使用ADD指令,将高寄存器中的值加到低寄存器中
ARM920T 包含一个当前程序状态寄存器(CPSR),以及5个已经保存了的程序状态寄存器(SPSR)。这些寄存器的功能有:
保存执行单元(ALU)最近的信息打开或者关闭中断处理器运行模式 313029282726252423222120191817161514131211109876543210NZCV--------------------IFTM4M3M2M1M0条件码标识
N,Z,C,V是条件码的标志位。这些将会被算术和逻辑运算改变,然后再根据这些位来决定指令是否执行。
在arm状态下,所有的指令可以被条件的执行。
在thumb状态下,只有分支指令才可以按照条件执行
控制位
最低下的8位被称为控制位。当一个异常发生时,他们会被改变。如果处理器在特权模式下,那么他们也可以被软件手动改变。
位描述T当为1时,处理器运行在THUMB模式下,否则运行在ARM模式下。他将影响TBIT外部信号中断禁止位I和F是中断禁止位。为1,则相应的禁止IRQ和FIQ模式位M4,M3,M2,M1,M0是模式位,如下表,只有下表出现的模式才是正确的模式,一旦程序设置了错误的模式,则会产生复位异常保留位剩下的位为保留位。 M[4:0]模式thumb模式下的寄存器arm模式下的寄存器10000UserR7…R0,LR,SP,PC,CPSRR14…R0,PC,CPSR10001FIQR7…R0,LR_fiq,SP_fiq,PC,CPSR,SPSR_fiqR7…R0,R14_fiq…R8_fiq,PC,CPSR,SPSR_fiq10010IRQR7…R0,LR_irq,SP_irq,PC,CPSR,SPSR_irqR12…R0,R14_irq,R13_irq,PC,CPSR,SPSR_iraq10011SupervisorR7…R0,LR_svc,SP_svc,PC,CPSR,SPSR_svcR12…R0,R14_svc,R13_svc,PC,CPSR,SPSR_svc10111AbortR7…R0,LR_abt,SP_abt,PC,CPSR,SPSR_abtR12…R0,R14_abt,R13_abt,PC,CPSR,SPSR_abt11011UndefinedR7…R0,LR_und,SP_und,PC,CPSR,SPSR_undP12…R0,R14_und,R13_und,PC,CPSR11111SystemR7…R0,LR,SP,PC,CPSRR14…R0,PC,CPSR例如响应外设电路的中断,此时反生异常。在异常处理前,当前处理器的状态必须保存下来,目的是,当异常处理完成之后,可以继续执行
在同一时间,可能同时出现多个异常,此时他们以固定的顺序进行处理,详见下面的异常优先级。
进入异常时的操作
当处理异常时,ARM920T会做如下的操作:
在链接寄存器中保存下一个指令的地址。如果异常从arm状态进入,则下一个指令的地址被复制到链接寄存器中(即PC+4,或者PC+8,具体依赖于不同的异常,后面有详细说明)如果异常从THUMB状态进入,链接寄存器则保存当前PC的偏移量。这就意味着,异常处理程序,不用管,到底是从哪个状态进入的异常。赋值CPSR到对应的SPSR修改CPSR对应的模式位修改PC为对应的异常向量地址还可以设置异常禁止位,防止异常嵌套的发生
如果处理器在THUMB状态下,此时发生了异常,当PC指向异常向量的地址时,自动切为ARM状态
离开异常时的操作
异常处理程序完成后:
将链接寄存器的值,复制到PC中复制SPSR到CPSR如果允许中断,则清除中断禁止位,异常入口/出口摘要
下表列出了异常发生时,保存在链接寄存器中的PC的值,以及退出异常处理程序的推荐的指令
返回的指令arm R14_xthumb R14_xBL;MOV PC,R14PC+4PC+2SWI;MOVS PC,R14_svcPC+4PC+2UDEF;MOVS PC,R14_undPC+4PC+2FIQ;SUBS PC,R14_fiq,#4PC+4PC+4IRQ;SUBS PC,R14_irq,#4PC+4PC+4PABT;SUBS PC,R14_abt,#4PC+4PC+4DABT;SUBS PC,R14_abt,#8PC+8PC+8RESET;NA--FIQ
FIQ(快速中断异常)被设计来处理数据传输和信道处理。在arm模式下,保证有最小,且足够的寄存器可用,以达到最优的上下文切换
外部的nFIQ输入为低时,产生FIQ异常。根据ISYNC输入信号的状态,nFIQ的输入可以被处理为同步或异步。当ISYNC为低时,nFIQ和nIRQ被当做异步。同步的周期延迟发生在中断影响处理器流之前。
无论异常是从ARM状态还是thumb状态进入的,FIQ异常可以通过下面的指令退出异常处理流程:
SUBS PC,R14_fiq,#4FIQ可以通过CPSR的F位来禁止(用户模式下无法操作)。如果F位为0,ARM920T在每条指令结束时检查FIQ同步器输出的低电平。
IRQ
IRQ就是常见的中断,它由nIRQ输入触发。IRQ的优先级比FIQ的优先级低并且当FIQ进入时,IRQ将被禁止。通过设置CPSR寄存器的I位,可以在任何时候在特殊模式下(非用户模式)禁止这个异常
可以执行下面的代码,返回异常:
SUBS PC,R14_irq,#4Abort
当前内存访问无法完成时,产生一个Abort异常。它也可以由外部的ABORT输入产生。ARM920T在内存访问周期中,检查abort异常
两种abort异常:
预取址Abort:在指令预取址的时候发生数据Abort:数据访问时发生如果预取址Abort发生,则取到的指令被标记为非法指令,并且直到指令到达管道的头部才发生异常。
如果指令没有被执行,abort也不会产生,比如分支指令
如果数据abort发生,接下来会发生什么,则依赖于指令的类型:
但数据传输指令(LDR,STR)写会被修改的寄存器。abort异常处理程序必须清楚这一点交换指令(swap)中止,就好像它没有被执行一样块数据传输指令继续完成(LDM,STM)。如果回写位被置位,则基址寄存器被更新。如果指令要覆盖基址寄存器,则覆盖会被中止,以保证不会覆盖。一旦发生abort异常,所有的寄存器覆盖都会被中止。因此R15就会被保留abort机制可以实现按需分页的虚拟内存系统。在这个系统中,处理器可以产生任意的地址。当数据地址无效时,内存管理单元(MMU)产生一个abort异常。然后abort异常处理程序找出abort的原因,让请求的数据可用,然后重新执行产生abort异常的指令。
应用程序不需要知道他可用的内存量,他的状态也不会受abort异常的任何影响
退出abort异常的指令为:
SUBS PC,R14_abt,#4;for a prefetch abort SUBS PC,R14_abt,#8;for a data abort然后恢复PC和CPSR,并且再次执行产生abort异常的指令
软件中断
软件中断(SWI)被用来进入Supervisor模式。软件中断通过下面的指令返回:
MOV PC,R14_svc他们恢复PC和CPSR,然后继续执行SWI后面的指令
未定义指令
当arm920T无法处理一个指令时,产生一个未定义指令异常。这种机制可以被用来扩展THUMB和ARM指令的软件仿真。
可以执行下面的指令,退出异常:
MOVS PC,R14_und恢复CPSR,然后执行产生未定义指令异常的下一条指令
异常向量表
下表展示了异常向量地址:
地址异常进入的模式0x00000000RestSupervisor0x00000004Undefined instructionUndefined0x00000008Software InterruptSupervisor0x0000000CAbort(prefetch)Abort0x00000010Abort(data)Abort0x00000014ReservedReserved0x00000018IRQIRQ0x0000001CFIQFIQ异常优先级
当同时产生异常时,系统以固定的顺序处理。
高优先级:
RestData abortFIQIRQPrefetch abort低优先级:
Undefined instruction,Software Interrupt注意:并不是所有的异常都能同时发生 未定义指令和软件中断异常他们是互斥的
如果数据abort异常和FIQ异常同时发生,并且FIQ异常被允许,ARM920T进入数据abort异常处理程序,然后立刻去处理FIQ的异常。FIQ异常退出之后,继续在abort异常处理程序中执行。
数据abort的优先级高于FIQ是有道理的,他能够保证第一时间捕获到传输错误。进入这个异常的时间,应该加上FIQ的延迟。
中断延迟
如果FIQ打开,则最长的延时包括:传递给同步器(Tsyncmax)的最长请求时间,加上,最长的指令时间(Tldm),加上,数据abort进入的时间(Texc),加上FIQ进入的时间(Tfiq)。然后才是ARM920T在0x1c处执行。
Tsyncmax三个处理器周期,Tldm20个处理器周期,Texc3个处理器周期,Tfiq2个处理器周期。总共需要28个处理器周期。在一个连续的20Mhz的处理器上大约消耗1.4微秒。
最大的IRQ延迟计算方式跟上面类似。但是必须考虑到FIQ有更高的优先级,可以延迟任意时间进入IRQ异常处理程序。
FIQ和IRQ的最小时间则由Tsyncmin加上Tfiq组成,为4个处理器周期。
复位异常
当nREST输入为低时,ARM920T放弃执行指令,然后继续从递增的字地址中取指令。
当nRest再次变高,ARM920T:
将当前的PC和CPSR,写入到R14_svc和SPSR_svc。将M[4:0]改为1011(supervisor模式),CPSR的I,F位置位,清楚CPSR的T位将PC为0x00在arm模式下,继续执行