Raspberry pi Raspberry PI版本1未检测到未对齐的访问
我正在执行一系列活动,以确保Redis在一系列嵌入式系统中运行良好,包括Raspberry PI。为了修复执行未对齐内存访问的Redis的某些代码路径(由于Redis 3.2中引入的更改),我试图强制PI记录未对齐内存访问的消息,或者在发生这种情况时向进程发送信号。通过这种方式,我既可以确保Redis在未对齐的访问发生冲突时运行良好,也可以确保它在可以执行此类访问但速度较慢的平台上运行更快。PI v1中使用的ARM v6显然能够处理未对齐的内存访问,因此如果我使用以下命令配置Linux,以便向执行未对齐访问的进程发送信号:Raspberry pi Raspberry PI版本1未检测到未对齐的访问,raspberry-pi,arm,memory-alignment,Raspberry Pi,Arm,Memory Alignment,我正在执行一系列活动,以确保Redis在一系列嵌入式系统中运行良好,包括Raspberry PI。为了修复执行未对齐内存访问的Redis的某些代码路径(由于Redis 3.2中引入的更改),我试图强制PI记录未对齐内存访问的消息,或者在发生这种情况时向进程发送信号。通过这种方式,我既可以确保Redis在未对齐的访问发生冲突时运行良好,也可以确保它在可以执行此类访问但速度较慢的平台上运行更快。PI v1中使用的ARM v6显然能够处理未对齐的内存访问,因此如果我使用以下命令配置Linux,以便向执
echo 4 > /proc/cpu/alignment
然后运行以下程序:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
char *buf = "foobareklsjdfklsjdfslkjfskdljfskdfjdslkjfdslkjfsd";
uint32_t *l = (uint32_t*) (buf+1);
printf("%p\n", l);
printf("%d\n", (int)*l);
return 0;
}
#包括
#包括
int main(int argc,字符**argv){
char*buf=“foobareklsjdfklsjdfslkjfskdljfskdfjdslkjfdslkjfsd”;
uint32_t*l=(uint32_t*)(buf+1);
printf(“%p\n”,l);
printf(“%d\n”,(int)*l);
返回0;
}
我看不到进程接收到的任何信号,也看不到/proc/cpu/alignment
处的计数器在递增
我的猜测是,这是因为如果设置了给定的CPU配置标志,ARMV6能够自动处理未对齐的地址。我的问题是,我的假设正确吗?如果是这样,如何强制PI版本1在未对齐的访问情况下实际引发异常,以便Linux内核可以根据/proc/cpu/alignment设置捕获它并发送信号、记录访问等等
编辑:值得注意的是,即使在ARMV6中,也不是所有指令都可以执行未对齐的访问。例如,STMDB、STMFD、LDMDB、LDMEA和类似的多字指令确实会引发异常并被Linux内核捕获。我想我最终找到了答案:
/proc/cpu/alignment
中的陷阱计数器if (cpu_is_v6_unaligned()) {
set_cr(__clear_cr(CR_A));
ai_usermode = safe_usermode(ai_usermode, false);
}
这意味着SCTLR.A位总是被清除,因此没有陷阱
将为ARM v6可以处理的未对齐访问生成/proc/cpu/alignment
设置为修复访问,也会生成SIGBUS如何在一个程序中可靠地找到所有未对齐的访问,对于AIK来说仍然是一个开放的问题,因为不幸的是,原本很好的valgrind程序从未实现过这个特性。在过去,我不得不使用QEMU模拟Sparc,但是这是一个非常缓慢的过程。Valgrind将是实现这一点的简单方法。ARMv4和v5还允许未对齐的访问,一些arm内核默认启用它,另一些则不启用,在这两种情况下,您都可以启用或禁用它。未对齐访问的旧内核行为与人们所期望的不同/奇怪,它将在字中旋转字节,而不是插入下一个地址。这非常有意义,因为这是在零字节通道上获取正确字节进行字节访问(或半字)的方式,但这不仅仅是剥猫皮的一种方式。请注意,如果您只想在软件中找到一般的未对齐访问,可以让x86在Linux下捕获未对齐的访问,如果是的,我发现,如果你指的是交流寄存器。然而,如果不是通过gdb set命令,我并没有找到一种可靠的方法在我的程序中启用它。@antrez:
pushf;orl$0x40000,(%rsp);popf
在x86上启用对齐检查,pushf;andl$0xFFFBFFFF,(%rsp);popf
来禁用它。显然,操作系统必须合作,因为pushf/popf
是可怕的不干净的特权分离破坏。未对齐支持中的检查页1129可以通过在CP15中设置一个位在CPU级别禁用。