问题描述
我正在尝试将结构分配给特定的内存类型(回写)位置。我的最终目标是从该内存位置读取到 L1D 缓存中。
为了实现这一点,我做了以下工作,
- 使用 MTRR (Memory Type Range Register) control 中的示例代码将内存范围声明为回写类型。
- 然后使用
/dev/mem
映射该地址,使用来自 Accessing uncachable region using mmap and /proc/mtrr 的提示 - 创建一个指向我的结构的指针并将该
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 (将#修改为@)