当前位置: 技术问答>linux和unix
linux 内存映射文件
来源: 互联网 发布时间:2016-09-22
本文导语: 即,mmap,请问该如何实现,最好能给个实例代码 | 参考网址:(希望对你有用) http://blog.csdn.net/shaoguangleo/archive/2010/08/20/5827387.aspx 最近再做PCI驱动程序,如果有兴趣,大家一起研究~~ 代码...
即,mmap,请问该如何实现,最好能给个实例代码
|
参考网址:(希望对你有用)
http://blog.csdn.net/shaoguangleo/archive/2010/08/20/5827387.aspx
最近再做PCI驱动程序,如果有兴趣,大家一起研究~~
代码如下:
例子中,用户态程序的KERNEL_VIRT_ADDR就是内核模块打印的地址p
这里是hard coding(先加载内核模块,再把打印的地址赋值给KERNEL_VIRT_ADDR),
可以采用其他的方式传递。
2.6内核验证。
内核模块-----------------------
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Wheelz");
MODULE_DESCRIPTION("mmap demo");
static unsigned long p = 0;
static int __init init(void)
{
//分配共享内存(一个页面)
p = __get_free_pages(GFP_KERNEL, 0);
SetPageReserved(virt_to_page(p));
printk(" p = 0x%08xn", p);
//在共享内存中写上一个字符串
strcpy(p, "Hello world!n");
return 0;
}
static void __exit fini(void)
{
ClearPageReserved(virt_to_page(p));
free_pages(p, 0);
}
module_init(init);
module_exit(fini);
用户态程序---------------------------------
#include
#include
#include
#include
#include
#define PAGE_SIZE (4*1024)
#define PAGE_OFFSET 0xc0000000
#define KERNEL_VIRT_ADDR 0xc5e3c000
int main()
{
char *buf;
int fd;
unsigned long phy_addr;
fd=open("/dev/mem",O_RDWR);
if(fd == -1)
perror("open");
phy_addr=KERNEL_VIRT_ADDR - PAGE_OFFSET;
buf=mmap(0, PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_SHARED,
fd, phy_addr);
if(buf == MAP_FAILED)
perror("mmap");
puts(buf);//打印共享内存的内容
munmap(buf,PAGE_SIZE);
close(fd);
return 0;
}
http://blog.csdn.net/shaoguangleo/archive/2010/08/20/5827387.aspx
最近再做PCI驱动程序,如果有兴趣,大家一起研究~~
代码如下:
例子中,用户态程序的KERNEL_VIRT_ADDR就是内核模块打印的地址p
这里是hard coding(先加载内核模块,再把打印的地址赋值给KERNEL_VIRT_ADDR),
可以采用其他的方式传递。
2.6内核验证。
内核模块-----------------------
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Wheelz");
MODULE_DESCRIPTION("mmap demo");
static unsigned long p = 0;
static int __init init(void)
{
//分配共享内存(一个页面)
p = __get_free_pages(GFP_KERNEL, 0);
SetPageReserved(virt_to_page(p));
printk(" p = 0x%08xn", p);
//在共享内存中写上一个字符串
strcpy(p, "Hello world!n");
return 0;
}
static void __exit fini(void)
{
ClearPageReserved(virt_to_page(p));
free_pages(p, 0);
}
module_init(init);
module_exit(fini);
用户态程序---------------------------------
#include
#include
#include
#include
#include
#define PAGE_SIZE (4*1024)
#define PAGE_OFFSET 0xc0000000
#define KERNEL_VIRT_ADDR 0xc5e3c000
int main()
{
char *buf;
int fd;
unsigned long phy_addr;
fd=open("/dev/mem",O_RDWR);
if(fd == -1)
perror("open");
phy_addr=KERNEL_VIRT_ADDR - PAGE_OFFSET;
buf=mmap(0, PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_SHARED,
fd, phy_addr);
if(buf == MAP_FAILED)
perror("mmap");
puts(buf);//打印共享内存的内容
munmap(buf,PAGE_SIZE);
close(fd);
return 0;
}
|
楼主到底是要mmap的实现代码还是示例代码??如果是实现的话,得在内核里面去找,示例代码的话就多了,Google一大把,man里面也有,APUE也有
下面是man的示例:
下面是man的示例:
EXAMPLE
The following program prints part of the file specified in its first command-line argu‐
ment to standard output. The range of bytes to be printed is specified via offset and
length values in the second and third command-line arguments. The program creates a mem‐
ory mapping of the required pages of the file and then uses write(2) to output the
desired bytes.
#include
#include
#include
#include
#include
#include
#define handle_error(msg)
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
char *addr;
int fd;
struct stat sb;
off_t offset, pa_offset;
size_t length;
ssize_t s;
if (argc 4) {
fprintf(stderr, "%s file offset [length]n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
handle_error("open");
if (fstat(fd, &sb) == -1) /* To obtain file size */
handle_error("fstat");
offset = atoi(argv[2]);
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
/* offset for mmap() must be page aligned */
if (offset >= sb.st_size) {
fprintf(stderr, "offset is past end of filen");
exit(EXIT_FAILURE);
}
if (argc == 4) {
length = atoi(argv[3]);
if (offset + length > sb.st_size)
length = sb.st_size - offset;
/* Can't display bytes past end of file */
} else { /* No length arg ==> display to end of file */
length = sb.st_size - offset;
}
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
if (s != length) {
if (s == -1)
handle_error("write");
fprintf(stderr, "partial write");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
} /* main */