ARMv7的非对齐地址访问
时间:11-10
来源:互联网
点击:
ARMv7默认支持非对齐地址访问,但有些条件:
CP15 的系统控制寄存器(SCTLR), bit.A = 0, (bit.U = 1, 对于ARMv7已经默认置1了,不可改).
访问的地址空间必须为Normal memory, 访问Device memory或Strongly memory都会引发alignment fault的Data Abort。而如果MMU disable的话,所有的memory都被当作Strongly memory处理(这句话没找到出处,来自ARM support回复的mail)。所以MMU必须enable,memory类型由页表项的C, B, TEX[2:0]决定,这部分可以查阅 的:
示例
关于编译器
CP15 的系统控制寄存器(SCTLR), bit.A = 0, (bit.U = 1, 对于ARMv7已经默认置1了,不可改).
访问的地址空间必须为Normal memory, 访问Device memory或Strongly memory都会引发alignment fault的Data Abort。而如果MMU disable的话,所有的memory都被当作Strongly memory处理(这句话没找到出处,来自ARM support回复的mail)。所以MMU必须enable,memory类型由页表项的C, B, TEX[2:0]决定,这部分可以查阅 的:
B3.7 Memory region attributes.
示例
MRS r0, CPSR ORR r0, r0, #(PSR_I_BIT|PSR_F_BIT) ; Disable IRQ & FIQ MSR CPSR_c, r0; Disable MMU stuff and caches MRC p15, 0, r0, c1, c0, 0 ; read control register to r0 BIC r0, r0, #0x000f ; clear W(Write buffer), C(Cache), A(Align), M(MMU) bits BIC r0, r0, #0x1100 ; clear I(ICache), S(System protection) bits MCR p15, 0, r0, c1, c0, 0 ; write control register. stack_setup LDR r0, =|Image$$ZI$$Limit| ADD r0, r0, #STACK_SIZE_SVC MSR CPSR_c, #(MODE_SVC :OR: PSR_F_BIT :OR: PSR_I_BIT) MOV sp, r0mmu_setup LDR r2, =MMU_TABLE_BASE ; mmu page base address MCR p15, 0, r2, c2, c0, 0 ; write mmu page base address BL _cpu_mmu_init LDR r0, =0x89 LDRH r1, [r0]
关于编译器
在Realview下,如果目标处理器选择了ARMv6、ARMv7-A(如Cortex-A8)、ARMv7-R,编译器的缺省选项是--unaligned_access, 而如果选择了ARMv6以前的版本,或ARMv7-M体系的处理器,缺省选项是--no_unaligned_access。
对于选项--no_unaligned_access,编译器会自动将C语言对非对齐地址的变量的访问,转化成若干个字节操作。 比如:
__packed struct usb_endpoint_descriptor { u8 bLength; u16 wMaxPacketSize; u8 bDescriptorType; u8 bEndpointAddress; u8 bmAttributes; u8 bInterval;} ;int main(void){ volatile struct usb_endpoint_descriptor ep; ep.wMaxPacketSize = 0x200; while(1); return 0;}如果--no_unaligned_access选项编译,它的反汇编代码如下: main 0xe100c5f0: e92d400c .@-. PUSH {r2,r3,lr} 0xe100c5f4: e3a00c02 .... MOV r0,#0x200 0xe100c5f8: e5cd0001 .... STRB r0,[sp,#1] 0xe100c5fc: e1a00420 ... LSR r0,r0,#8 0xe100c600: e5cd0002 .... STRB r0,[sp,#2] 0xe100c604: eafffffe .... B 0xe100c604 ; main + 20如果是--unaligned_access选项编译,它的反汇编代码如下: main 0xe100c5f0: e92d400c .@-. PUSH {r2,r3,lr} 0xe100c5f4: e3a00c02 .... MOV r0,#0x200 0xe100c5f8: e1cd00b1 .... STRH r0,[sp,#1] 0xe100c5fc: eafffffe .... B 0xe100c5fc ; main + 12
如果你的目标平台是ARMv6或ARMv7-AR,但是在你的代码中,MMU是disable的,那你应该手动添加编译选项--no_unaligned_access,让编译器来帮你处理非对齐访问。
ARMv7非对齐地址访 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)