如何在Linux 2.6.35的用户模式下清除和使ARM v7处理器缓存无效

9

我尝试清除和失效ARM v7处理器指令线的缓存,因为指令代码可能在执行过程中更改。

为了达到这个效果,我尝试了两种变体。它们如下:

  1. I used GCC __clear_cache() function but it didn't give a required result. Instruction codes in cache didn't change.

  2. I looked for a source codes for GCC and found the uclinux-eabi.h file where I found the next code for clearing cache:

    /* Clear the instruction cache from `beg' to `end'.  This makes an
       inline system call to SYS_cacheflush.  */
    #undef CLEAR_INSN_CACHE
    #define CLEAR_INSN_CACHE(BEG, END)                                    \
    {                                                                     \
        register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
        register unsigned long _end __asm ("a2") = (unsigned long) (END); \
        register unsigned long _flg __asm ("a3") = 0;                     \
        register unsigned long _scno __asm ("r7") = 0xf0002;              \
        __asm __volatile                                                  \
        (                                                                 \
            "swi 0x0    @ sys_cacheflush"                                 \
            : "=r" (_beg)                                                 \
            : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno));           \
    }
    

这个变量也没有给出结果。

也许有人知道我做错了什么?


1
我会检查编译器是否实际遵守您使用指定寄存器(a1、a2、a3、r7)的请求,并通过转储生成的目标文件作为汇编来进行检查。 您可能会发现错误的寄存器被用于内核调用(swi)。 - John Ripley
据我所知,这是获取特定寄存器中asm输入的推荐方法,因为没有针对单个寄存器的特定约束 :( https://dev59.com/5Jffa4cB1Zd3GeqP5kUJ - Peter Cordes
1个回答

9
我自己也遇到了类似的问题。__clear_cache()可以解决问题,但仅当使用mmap()并设置PROT_EXEC分配内存区域时才有效。即使处理器似乎可以从malloc()分配的内存中执行代码,Linux也不会刷新指令缓存,如果您提供来自常规malloc()内存的内存范围。请参见https://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code以获取如何执行此操作的示例代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接