Linux内核空间共享的本质,Linux的内核空间和用户空间通过内存共享来进行通信的实现...

原文

一、内核空间的代码,经过编译后生成内核模块,利用insmod mmap_kernelspace.o进行该模块的加载

/*

* The program is used for testing communication between

* kernel-space and user-space in linux operating system.

*

* mmap_kernelspace.c

* Author: jiangyb (101381@gmail.com)

* Date: 11/23/2005

* gcc -c mmap_kernelspace.c -I/usr/src/linux-2.4/include -o mmap_kernelspace.o

*/

#define __KERNEL__

#define MODULE

#include

#include

#include

#include

#include

#include

#include

#ifndef KERNEL_VERSION

#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))

#endif

#define PAGES_ORDER 3

#define PAGES 8

#define MEM_WIDTH    1500

unsigned long mem_addr;

struct MEM_DATA {

unsigned short width;

unsigned short length;

unsigned short wptr;

unsigned short rptr;

} *mem_data;

struct MEM_PACKET {

unsigned int len;

unsigned char packetp[MEM_WIDTH - 4];/*sizeof(unsigned int) == 4*/

};

void init_mem()

{

char *addr;

char *buff;

int pages = 0;

int i;

struct MEM_PACKET *pdatapack;

mem_addr = __get_free_pages(GFP_KERNEL,PAGES_ORDER);

printk("inti_mem(), memory address that get from free pages is %x\n", mem_addr);

addr = (char *)mem_addr;

while(pages < PAGES) {

mem_map_reserve(virt_to_page(addr));

addr = addr + PAGE_SIZE;

pages++;

}

mem_data = (struct MEM_DATA *)mem_addr;

mem_data[0].length = PAGES*4*1024 / MEM_WIDTH;

mem_data[0].width = MEM_WIDTH;

mem_data[0].rptr = 1;

mem_data[0].wptr = 1;

for( i = 1; i <= mem_data[0].length; i++) {

buff = ( void * )( (char *)mem_addr + MEM_WIDTH * i );

pdatapack = (struct MEM_PACKET *)buff;

pdatapack->len = 0;

}

}

void del_mem()

{

int pages = 0;

char *addr;

addr = (char *)mem_addr;

while( pages < PAGES ) {

mem_map_unreserve(virt_to_page(addr));

addr = addr + PAGE_SIZE;

pages ++;

}

free_pages(mem_addr, PAGES_ORDER);

}

int put_mem(char *aBuf,unsigned int pack_size)

{

register int mem_ptr;

register int width,length;

register int s = 0;

register int i;

char *buf;

struct MEM_PACKET *pdatapack;

printk("put_mem(), content: %s, size: %d\n", aBuf, pack_size);

mem_data = (struct MEM_DATA *)mem_addr;

width = mem_data[0].width;

length = mem_data[0].length;

mem_ptr = mem_data[0].wptr;

buf = (void *)( (char *)mem_addr + width * mem_ptr);

for ( i=1; i < length; i++ ) {

pdatapack = (struct MEM_PACKET *)buf;

if ( pdatapack->len == 0) {

memcpy(pdatapack->packetp,aBuf,pack_size);

pdatapack->len = pack_size;

s = mem_ptr;

mem_ptr++;

if (mem_ptr >= length)

mem_ptr = 1;

mem_data[0].wptr = mem_ptr;

break;

}

mem_ptr++;

if (mem_ptr >= length) {

mem_ptr = 1;

buf = (void *)((char *)mem_addr + width);

}

else buf = (char *)mem_addr + width*mem_ptr;

}

if(i >= length)

s = 0;

return s;

}

int read_procaddr(char *buf,char **start,off_t offset,

int count,int *eof,void *data)

{

sprintf(buf,"%u\n",__pa(mem_addr));

printk("Memory address is : %u\n", __pa(mem_addr));

*eof = 1;

return 9;

}

int init_module(void)

{

printk("---------------------------\n");

printk("Corem module is installed\n");

init_mem();

put_mem("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26);

create_proc_read_entry("nf_addr",0,NULL,read_procaddr,NULL);

return 0;

}

void cleanup_module(void)

{

del_mem();

remove_proc_entry("nf_addr",NULL);

printk("Corem module is uninstalled\n");

}

MODULE_LICENSE("GPL");

二、用户空间的代码,编译成可执行文件

/*

* The program is used for testing communication between

* kernel-space and user-space in linux operating system.

*

* mmap_userspace.c

* Author: jiangyb (101381@gmail.com)

* Date: 11/23/2005

* gcc mmap_userspace.c -o mmap_userspace

*/

#include

#include

#include

#include

#include

#define PAGES 8

#define MEM_WIDTH 1500

char *mem_addr;

struct MEM_DATA {

unsigned short width;

unsigned short length;

unsigned short wptr;

unsigned short rptr;

} *mem_data;

struct MEM_PACKET {

unsigned int len;

unsigned char packetp[MEM_WIDTH - 4];/*sizeof(unsigned int) == 4*/

};

int get_mem(char *memaddr,char *inbuff,unsigned int *size)

{

register int mem_ptr;

register int width, length;

register int i;

register int s = 0;

char *buf;

struct MEM_PACKET *pdatapack;

mem_data = (void *)memaddr;

width = mem_data[0].width;

length = mem_data[0].length;

mem_ptr = mem_data[0].rptr;

buf = (void *)(memaddr + width * mem_ptr);

pdatapack = (struct MEM_PACKET *)buf;

if(pdatapack->len != 0) {

memcpy(inbuff,pdatapack->packetp,pdatapack->len);

*size = pdatapack->len;

pdatapack->len = 0;

s = mem_data[0].rptr;

mem_data[0].rptr++;

if(mem_data[0].rptr >= length)

mem_data[0].rptr = 1;

goto ret;

}

for (i=1;i

mem_ptr++;

if (mem_ptr >= length)

mem_ptr = 1;

buf = (void *)(memaddr + width*mem_ptr);

pdatapack = (struct MEM_PACKET *)buf;

if (pdatapack->len == 0)

continue;

memcpy(memaddr, pdatapack->packetp,pdatapack->len);

*size = pdatapack->len;

pdatapack->len = 0;

s = mem_data[0].rptr = mem_ptr;

mem_data[0].rptr++;

if(mem_data[0].rptr >= length)

mem_data[0].rptr = 1;

break;

}

ret:

return s;

}

int put_mem(char *mem_addr, char *aBuf, unsigned int pack_size)

{

register int mem_ptr;

register int width,length;

register int s = 0;

register int i;

char *buf;

struct MEM_PACKET *pdatapack;

mem_data = (struct MEM_DATA *)mem_addr;

width = mem_data[0].width;

length = mem_data[0].length;

mem_ptr = mem_data[0].wptr;

buf = (void *)( (char *)mem_addr + width * mem_ptr);

for(i=1; i < length; i++) {

pdatapack = (struct MEM_PACKET *)buf;

if(pdatapack->len == 0) {

memcpy(pdatapack->packetp,aBuf,pack_size);

pdatapack->len = pack_size;

s = mem_ptr;

mem_ptr++;

if (mem_ptr >= length)

mem_ptr = 1;

mem_data[0].wptr = mem_ptr;

break;

}

mem_ptr++;

if (mem_ptr >= length) {

mem_ptr = 1;

buf = (void *)((char *)mem_addr + width);

} else

buf = (char *)mem_addr + width*mem_ptr;

}

if(i >= length)

s = 0;

return s;

}

int main()

{

char *mem_addr;

char inbuff[1500];

int fd;

int fd_procaddr;

unsigned int size;

char addr[9];

unsigned long proc_addr;

fd = open("/dev/mem", O_RDWR);

/* read procaddr from nf_addr file in proc directory */

fd_procaddr = open("/proc/nf_addr", O_RDONLY);

read(fd_procaddr, addr, 9);

proc_addr = atol(addr);

close(fd_procaddr);

printf("read proc address is : %u[%8lx]\n", proc_addr, proc_addr);

/* Map the address in kernel to user space, use mmap function*/

mem_addr = mmap(0, PAGES*4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, proc_addr);

put_mem(mem_addr, "hello world", 12);

get_mem(mem_addr, inbuff, &size);

printf("Get data from core space, content: %s\n", inbuff);

munmap(mem_addr,PAGES*4*1024);

close(fd);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值