如何将结构分配/清除到指针指向的特定地址?

问题描述

我正在尝试将结构分配给特定的内存类型(回写)位置。我的最终目标是从该内存位置读取到 L1D 缓存中。

为了实现这一点,我做了以下工作,

  1. 使用 MTRR (Memory Type Range Register) control 中的示例代码将内存范围声明为回写类型。
  2. 然后使用 /dev/mem 映射该地址,使用来自 Accessing uncachable region using mmap and /proc/mtrr 的提示
  3. 创建一个指向我的结构的指针并将该 mmaped 指针分配给我的结构指针。

我的代码是:

#define MTRR_BASE 0xf80000
#define MTRR_SIZE 0x40000
#define MTRR_TYPE "write-back"
#define KEY_LEN 128
#define ERRSTRING strerror (errno)


static struct CACHE_ENV{
    unsigned char in[KEY_LEN];
    unsigned char out[KEY_LEN];
}cacheEnv;


static char *mtrr_strings[MTRR_NUM_TYPES] =
    {
            "uncachable",/* 0 */
            "write-combining",/* 1 */
            "?",/* 2 */
            "?",/* 3 */
            "write-through",/* 4 */
            "write-protect",/* 5 */
            "write-back",/* 6 */
    };


int mtrr_mmap(){

    int fd;
    fd = open("/dev/mem",O_RDWR|O_SYNC);
    if (fd == -1) {
        printf("\n Error opening /dev/mem");
        return 0;
    }

 
    unsigned char *addr = (unsigned char*)mmap((void *)MTRR_BASE,MTRR_SIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0x0);

    if (addr == MAP_FAILED) {
        printf("\n mmap() failed");
    }

    struct CACHE_ENV *enc_str =(struct CACHE_ENV *) addr;

    printf("size of enc_str is %ld\n",sizeof (*enc_str));

    // will read 64 bytes at a time from *enc_str to load struct CACHE_ENV into L1d cache 
    /**

    */


   // unmmap
   if (munmap(addr,MTRR_SIZE) == -1) {
       printf("\n Unmapping failed");
       return 0;
   }
   printf("\n Success......\n");
   return 0;
}


void mtrr_add(){
   int fd;
   struct mtrr_sentry sentry;
   sentry.base = MTRR_BASE;
   sentry.size = MTRR_SIZE;

   for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type){
       if (strcmp (MTRR_TYPE,mtrr_strings[sentry.type]) == 0) break;
   }

   if (sentry.type >= MTRR_NUM_TYPES){
       fprintf (stderr,"Illegal type: \"%s\"\n",MTRR_TYPE);
       exit (2);
   }

   if ( ( fd = open ("/proc/mtrr",O_WRONLY,0) ) == -1 ){
      if (errno == ENOENT){
          fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",stderr);
          exit (3);
      }
      fprintf (stderr,"Error opening /proc/mtrr\t%s\n",ERRSTRING);
      exit (4);
   }

   // adding MTRR entry
   if (ioctl (fd,MTRRIOC_ADD_ENTRY,&sentry) == -1){
      fprintf (stderr,"Error doing ioctl(2) on /dev/mtrr\t%s\n",ERRSTRING);
      exit (5);
   }

   // call memory map
   mtrr_mmap();

   fprintf (stderr,"Sleeping for 15 seconds so you can see the new entry\n");
   sleep (15);
   close (fd);
   fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",stderr);
}


int main (){
   mtrr_add();
} 

此代码编译并运行。运行代码后,cat /proc/mtrr 显示,

reg00: base=0x080000000 ( 2048MB),size= 2048MB,count=1: uncachable
reg01: base=0x070000000 ( 1792MB),size=  256MB,count=1: uncachable
. 
reg06: base=0x000f80000 (   15MB),size=  256KB,count=1: write-back

以上输出显示创建了所需类型的新 /proc/mtrr 条目。由于我的结构大小是 256B,所以它应该适合 L1d 缓存。

但是,我很困惑,如果此代码正在执行我想要实现的目标,因为我不知道如何验证我的结构是否在 L1d 缓存中。所以,我的问题是,

  • 我能否像在 mtrr_add() 中使用的那样使用 MTRR 来声明特定类型的内存范围,然后为该内存范围分配一个结构?
  • struct CACHE_ENV *enc_str =(struct CACHE_ENV *) addr; 指向特定地址的方式是否正确?我的意思是,如果我分配一个像 enc_str->out = "abcd" 这样的值,它最终会出现在 addr 中吗?

如果您对如何实现我的目标有任何建议,或者如果我做错了什么,请告诉我。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...