在BeagleBone Black裸机环境下禁用L2缓存遇到问题求助
我是ARM编程新手,希望在禁用L2缓存的前提下做相关分析。目前在BeagleBone Black的U-boot裸机环境中,正按照ARM官方文档的步骤尝试禁用缓存:
- 禁用C位;
- 清理并无效化L1和L2缓存;
- 将L2EN位清零以禁用L2缓存;
- 重新启用C位。
我只完成了第一步的代码编写:
asm volatile("MRC p15, 0, %0, c1, c0, 0\t\n": "=r"(controlRegister)); // 获取控制寄存器 controlRegister = controlRegister & ~(1u << 2); // 将C位设为0 asm volatile ("MCR p15, 0, %0, c1, c0, 0\t\n" :: "r"(controlRegister)); // 写入新值
但执行后发现,写入新值后再次读取控制寄存器,得到的结果是00000000,第一步操作根本没成功。
有人说必须处于Supervisor模式(超级用户模式)才能操作,但文档里提到这是给操作系统用的保护模式,我跑的是裸机环境,不确定这种"模式抽象"是否存在,求解决思路。
解决思路
确认当前CPU模式
裸机环境下依然存在ARM的特权模式,U-boot启动后通常会切换到Supervisor模式,但也可能因启动流程差异处于其他模式。你可以读取CPSR寄存器确认当前模式:mrs r0, cpsrCPSR的低5位是模式位,Supervisor模式对应的值是
0b10011。如果当前不是该模式,需要修改CPSR切换——切换前要先禁用IRQ/FIQ避免异常干扰:msr cpsr_c, #0xD3 ; 进入Supervisor模式,同时禁用IRQ/FIQ检查MMU状态
BeagleBone Black搭载的是ARM Cortex-A8,若MMU处于开启状态,直接修改CP15控制寄存器的C位(缓存使能位)会引发不可预测的行为,甚至导致寄存器被重置。你需要先读取控制寄存器的M位(第0位),如果值为1说明MMU开启,必须先关闭MMU再修改缓存位。添加指令同步屏障
修改CP15寄存器后,必须执行同步指令确保修改生效,否则后续读取可能得到旧值或错误值。在写入控制寄存器的代码后,要加上:isb ; 指令同步屏障 dsb ; 数据同步屏障你的代码缺少这一步,这很可能是写入后读取值异常的核心原因。
规避U-boot的初始化干扰
基于U-boot启动的裸机环境中,U-boot可能已经完成了缓存、MMU的初始化,甚至有硬件保护机制阻止直接修改CP15寄存器。可以尝试在U-boot更早的启动阶段(比如SPL阶段)执行代码,或者完全脱离U-boot,用自制的纯裸机镜像启动测试。
内容的提问来源于stack exchange,提问作者Lucas Barbosa

