1

我被问到这个:

使用您的 RPi,编写一个读取自由运行系统计时器的 C 函数。系统计时器每微秒计数一次。将此函数的源文件放在它自己的文件中。自由运行定时器是一个位于物理内存地址 0x20003004 的 64 位值,但是,RPi 一次只能访问该内存区域中的 32 位。要访问这些内存位置,将对文件 /dev/mem 调用 mmap()。请务必始终检查错误并采取适当措施。要访问系统计时器: (a) 通过测试静态变量来检查计数器是否被映射。

(b) 如果计数器未映射,则

一世。打开 /dev/men 只读。

ii. 获取系统页面大小

iii. 调用 mmap() 并将返回的地址(指向 32 位整数的指针)保存在静态变量中。通过允许 mmap() 设置地址映射来调用 mmap()。将长度设置为页面大小。将保护设置为只读。将标志设置为共享地图。接下来,传递 open() 返回的文件描述符,然后将偏移量设置为 0x20003000。请记住,对于这种情况,mmap() 只能对 __SC_PAGESIZE 字节的页面进行操作,因此不能直接映射地址 0x20003004 - 该地址必须与 __SC_PAGESIZE 对齐。

iv. 设置静态变量以指示已发生初始化。

v. 关闭打开的文件。

(c) 如果初始化成功,则将索引 1 处的 32 位值与索引 2 处的 32 位值组合返回一个 64 位数字。索引 1 处的 32 位值包含计数器的最低有效 32 位。索引 2 处的 32 位值包含计数器的最高有效 32 位。否则返回 0。

我能够获取第一个内存位置的计时器内容0x20003000

int main(int argc, char * argv[])
{
    int temp;
    int page_size;
    int *map;

    temp = open("/dev/mem", O_RDONLY);
    page_size = sysconf(_SC_PAGESIZE);


    map = mmap(0, page_size, PROT_READ, MAP_SHARED, temp, 0x20003000);
    printf("%X \n", map);

    close(temp);
    return 0;
}

我迷失在它要求我获取其他 32 位数字0x20003004并将其与原始数字结合的部分。欢迎任何帮助或指导。

4

1 回答 1

2

从您引用的描述中:

请记住,对于这种情况,mmap() 只能对 __SC_PAGESIZE 字节的页面进行操作,因此不能直接映射地址 0x20003004 - 该地址必须与 __SC_PAGESIZE 对齐。

这意味着mmap()只能映射到与 对齐的地址__SC_PAGESIZE。这也意味着返回的地址mmap()最多可以取消引用page_size。即,如果调用mmap()with0x20003000返回0x20003000,您可以取消引用[0x20003000, 0x20003000 + page_size).

我会把剩下的留给读者作为练习。

于 2013-01-31T02:18:33.277 回答