http://hi.baidu.com/zengzhaonong/item/69bddc325170d4c01b969683
#include <stdio.h> // NULL
#include <fcntl.h> // O_RDWR
#include <sys/mman.h> // PROT_READ
/* 最大映射次数 */
#define MAP_MAX 32
/* addr_map()的调用次数 */
static ulong map_cnt = 0;
typedef struct
{
/* 用户需要映射的物理地址 */
ulong p_addr;
/* 用户需要映射的空间大小 */
ulong buf_size;
/* 实际映射出来的虚拟地址 */
void *v_addr;
/* 实际映射的空间大小 */
ulong size;
} map_struct;
map_struct map_array[MAP_MAX];
/*****************************************************
* 函数名: addr_map
* 作者: linglong
* 日期: 2010-12-01
* 功能: 将物理地址映射成虚拟地址
* 参数说明:
* p_addr 用户需要映射的物理地址
* buf_size 用户需要映射空间大小
* 返回值:
* 类型(ulong)
* 如果映射成功,则返回物理地址对应的虚拟地址
* 如果失败,则返回0
* 修改记录:
******************************************************/
ulong addr_map (ulong p_addr, ulong buf_size)
{
int map_fd = 0;
ulong low_addr = 0;
ulong size = 0;
ulong i = 0;
void *v_addr = NULL;
if (MAP_MAX == map_cnt)
{
printf ("map max = %d\n", MAP_MAX);
return 0;
}
for (i = 0; i < MAP_MAX; i++)
{
if (map_array[i].p_addr == p_addr
&& map_array[i].buf_size == buf_size)
{
printf ("Physical addr 0x%x has been mapped\n",
p_addr);
return 0;
}
}
/* 打开内存文件 */
map_fd = open ("/dev/mem", O_RDWR | O_SYNC);
if (-1 == map_fd)
{
perror ("open");
return 0;
}
/*
* 对p_addr地址进行4K对齐
* low_addr保存,非4K对齐的部分
*/
low_addr = p_addr & 0xfff;
/* 实际映射的空间大小 */
size = buf_size + low_addr;
/* 将输入的物理地址转换成虚拟空间 */
v_addr = mmap (NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, map_fd, p_addr & ~0x00000fff);
if (MAP_FAILED == v_addr)
{
perror ("mmap");
close (map_fd);
return 0;
}
map_array[map_cnt].p_addr = p_addr;
map_array[map_cnt].buf_size = buf_size;
map_array[map_cnt].v_addr = v_addr;
map_array[map_cnt].size = size;
map_cnt++;
#if 0
printf ("low_addr = 0x%x\n", low_addr);
printf ("v_addr = 0x%x\n", v_addr);
#endif
close (map_fd);
/* 将用户传入的物理地址p_addr所对应的虚拟地址返回给用户 */
return (ulong) (v_addr + low_addr);
}
void addr_unmap (ulong p_addr, ulong buf_size)
{
int i = 0;
ulong size = 0;
void *v_addr = NULL;
for (i = 0; i < MAP_MAX; i++)
{
if (map_array[i].p_addr == p_addr
&& map_array[i].buf_size == buf_size)
{
v_addr = map_array[i].v_addr;
size = map_array[i].size;
munmap ((void *) v_addr, size);
map_array[i].p_addr = 0;
map_array[i].buf_size = 0;
map_cnt--;
return;
}
}
printf ("Physical addr 0x%x does not map\n", p_addr);
return;
}
int main ()
{
ulong p_addr = 0;
ulong buf_size = 0;
ulong v_addr = -1;
ulong i = 10;
p_addr = 0x1234;
buf_size = 64;
//for (i = 0; i < MAP_MAX + 5; i++)
for (;;)
{
p_addr += i;
v_addr = addr_map (p_addr, buf_size);
if (-1 != v_addr)
{
//printf("v_addr = 0x%x\n", v_addr);
#if 0
printf ("*(ulong *)v_addr = 0x%x\n",
*(ulong *) v_addr);
#endif
}
addr_unmap (p_addr, buf_size);
}
}
---------------------------------------------------------------
#include <stdio.h> // NULL