你能帮我用代码('C'或ARM程序集)将内存区域标记为“正常”,从而允许未对齐的内存访问吗?我知道我们需要在执行此操作之前启用 MMU。我是 ARM 架构的新手。
谢谢!
如果您只需要非对齐访问,请尝试将 cp15 sctlr[1](对齐位)设置为 0。
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #2
mcr p15, 0, r0, c1, c0, 0
我不知道是否需要为此启用 MMU。
#define L1PoniterTo2ndLevelPageTable(BASE_ADDRESS, P, DOMAIN) (BASE_ADDRESS<<10U | P<<9U | DOMAIN<<5U | 1U)
#define L1Section(BASE_ADDRESS, SBZ, NG, S, APX, TEX, AP, P, DOMAIN, XN, C, B) (BASE_ADDRESS<<20U | SBZ<<19 | 0U<<18U | NG<<17U | S<<16U | APX<<15U | TEX<<12U | AP<<10U | P<<9U | DOMAIN<<5U | XN<<4U | C<<3U | B<<2 |2U)
#define L1SuperSection(BASE_ADDRESS, SBZ, NG, S, APX, TEX, AP, P, DOMAIN, XN, C, B) (BASE_ADDRESS<<24U | SBZ<<19 | 1U<<18U | NG<<17U | S<<16U | APX<<15U | TEX<<12U | AP<<10U | P<<9U | DOMAIN<<5U | XN<<4U | C<<3U | B<<2 |2U)
unsigned long au32PageTableL1[4096U] __attribute__((aligned(0x4000)));
//extern unsigned long _endof_consts[4096U];
unsigned long u32EnableMMU()
{
unsigned long u32Index_l;
unsigned long dummy;
unsigned long sctlr;
//create L1 page table
for (u32Index_l=0;u32Index_l<sizeof(au32PageTableL1)/sizeof(au32PageTableL1[0]);u32Index_l++)
{
au32PageTableL1[u32Index_l] = L1Section
(
u32Index_l, //BASE_ADDRESS
0b0, //SBZ
0b0, //NG
0b0, //S
0b0, //APX
0b001, //TEX
0b11, //AP
0b0, //P
0,//DOMAIN
0b0, //XN
0b1, //C
0b1 //B
);
}
//set ttbr0
__asm("MCR p15, 0, %0, c2, c0, 0" : : "r" (au32PageTableL1));
//invalidate TLB
__asm("MCR p15, 0, %0, c8, c3, 0" : : "r" (dummy));
/* Ensure all TLB maintenance operations complete before returning. */
__asm("dsb");
//enable MMU
__asm("MRC p15, 0, %0, c1, c0, 0" : "=r" (sctlr));
sctlr |= 1U;
__asm("MCR p15, 0, %0, c1, c0, 0" : : "r" (sctlr));
return 0;
}