讨论,用户空间和内核空间如何通信,有什么方式,如何实现的?
来源: 互联网 发布时间:2015-10-30
本文导语: 我现在知道两种: 1. ioctl ifconfig用的这种方式 2. sendmsg keepalived中见到过,设置端口ip地址 还有没有其他方式,并且现在我只能是去抄袭别人实现的代码,但是自己不清楚应该如何去用,如何查资料? 大家...
我现在知道两种:
1. ioctl ifconfig用的这种方式
2. sendmsg keepalived中见到过,设置端口ip地址
还有没有其他方式,并且现在我只能是去抄袭别人实现的代码,但是自己不清楚应该如何去用,如何查资料?
大家有没有这种感受啊?
1. ioctl ifconfig用的这种方式
2. sendmsg keepalived中见到过,设置端口ip地址
还有没有其他方式,并且现在我只能是去抄袭别人实现的代码,但是自己不清楚应该如何去用,如何查资料?
大家有没有这种感受啊?
|
通过共享内存(文件)的方式可行
/*user.c*/
#include
#include
#include
#include
#include
#define PAGES 512
#define MEM_WIDTH 1500
struct MEM_DATA
{
//int key;
unsigned short width;/*缓冲区宽度*/
unsigned short length;/*缓冲区长度*/
//unsigned short wtimes;/*写进程记数,预留,为以后可以多个进程写*/
//unsigned short rtimes;/*读进程记数,预留,为以后可以多个进程读*/
unsigned short wi;/*写指针*/
unsigned short ri;/*读指针*/
} * mem_data;
struct MEM_PACKET
{
unsigned int len;
unsigned char packetp[MEM_WIDTH - 4];/*sizeof(unsigned int) == 4*/
};
int get_mem(char *aMem,char *aBuf,unsigned int *size)
{
register int i,s,width,length,mem_i;
char *buf;
struct MEM_PACKET * curr_pack;
s = 0;
mem_data = (void *)aMem;
width = mem_data[0].width;
length = mem_data[0].length;
mem_i = mem_data[0].ri;
buf = (void *)(aMem + width * mem_i);
curr_pack = (struct MEM_PACKET *)buf;
if (curr_pack->len != 0){/*第一个字节为0说明该部分为空*/
memcpy(aBuf,curr_pack->packetp,curr_pack->len);
*size = curr_pack->len;
curr_pack->len = 0;
s = mem_data[0].ri;
mem_data[0].ri++;
if(mem_data[0].ri >= length)
mem_data[0].ri = 1;
goto ret;
}
for (i=1;i= length)
mem_i = 1;
buf = (void *)(aMem + width*mem_i);
curr_pack = (struct MEM_PACKET *)buf;
if (curr_pack->len == 0)
continue;
memcpy(aBuf,curr_pack->packetp,curr_pack->len);
*size = curr_pack->len;
curr_pack->len = 0;
s = mem_data[0].ri = mem_i;
mem_data[0].ri++;
if(mem_data[0].ri >= length)
mem_data[0].ri = 1;
break;
}
ret:
return s;
}
int main()
{
char *su1_2;
char receive[1500];
int i,j;
int fd;
int fd_procaddr;
unsigned int size;
char addr[9];
unsigned long ADDR;
j = 0;
/*open device 'mem' as a media to access the RAM*/
fd=open("/dev/mem",O_RDWR);
fd_procaddr = open("/proc/nf_addr",O_RDONLY);
read(fd_procaddr,addr,9);
ADDR = atol(addr);
close(fd_procaddr);
printf("%u[%8lx]n",ADDR,ADDR);
/*Map the address in kernel to user space, use mmap function*/
su1_2 = mmap(0,PAGES*4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ADDR);
perror("mmap");
while(1)
{
bzero(receive,1500);
i = get_mem(su1_2,receive,&size);
if (i != 0)
{
j++;
printf("%d:%s[size = %d]n",j,receive,size);
}
else
{
printf("there have no datan");
munmap(su1_2,PAGES*4*1024);
close(fd);
break;
}
}
while(1);
}
/*user.c*/
#include
#include
#include
#include
#include
#define PAGES 512
#define MEM_WIDTH 1500
struct MEM_DATA
{
//int key;
unsigned short width;/*缓冲区宽度*/
unsigned short length;/*缓冲区长度*/
//unsigned short wtimes;/*写进程记数,预留,为以后可以多个进程写*/
//unsigned short rtimes;/*读进程记数,预留,为以后可以多个进程读*/
unsigned short wi;/*写指针*/
unsigned short ri;/*读指针*/
} * mem_data;
struct MEM_PACKET
{
unsigned int len;
unsigned char packetp[MEM_WIDTH - 4];/*sizeof(unsigned int) == 4*/
};
int get_mem(char *aMem,char *aBuf,unsigned int *size)
{
register int i,s,width,length,mem_i;
char *buf;
struct MEM_PACKET * curr_pack;
s = 0;
mem_data = (void *)aMem;
width = mem_data[0].width;
length = mem_data[0].length;
mem_i = mem_data[0].ri;
buf = (void *)(aMem + width * mem_i);
curr_pack = (struct MEM_PACKET *)buf;
if (curr_pack->len != 0){/*第一个字节为0说明该部分为空*/
memcpy(aBuf,curr_pack->packetp,curr_pack->len);
*size = curr_pack->len;
curr_pack->len = 0;
s = mem_data[0].ri;
mem_data[0].ri++;
if(mem_data[0].ri >= length)
mem_data[0].ri = 1;
goto ret;
}
for (i=1;i= length)
mem_i = 1;
buf = (void *)(aMem + width*mem_i);
curr_pack = (struct MEM_PACKET *)buf;
if (curr_pack->len == 0)
continue;
memcpy(aBuf,curr_pack->packetp,curr_pack->len);
*size = curr_pack->len;
curr_pack->len = 0;
s = mem_data[0].ri = mem_i;
mem_data[0].ri++;
if(mem_data[0].ri >= length)
mem_data[0].ri = 1;
break;
}
ret:
return s;
}
int main()
{
char *su1_2;
char receive[1500];
int i,j;
int fd;
int fd_procaddr;
unsigned int size;
char addr[9];
unsigned long ADDR;
j = 0;
/*open device 'mem' as a media to access the RAM*/
fd=open("/dev/mem",O_RDWR);
fd_procaddr = open("/proc/nf_addr",O_RDONLY);
read(fd_procaddr,addr,9);
ADDR = atol(addr);
close(fd_procaddr);
printf("%u[%8lx]n",ADDR,ADDR);
/*Map the address in kernel to user space, use mmap function*/
su1_2 = mmap(0,PAGES*4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ADDR);
perror("mmap");
while(1)
{
bzero(receive,1500);
i = get_mem(su1_2,receive,&size);
if (i != 0)
{
j++;
printf("%d:%s[size = %d]n",j,receive,size);
}
else
{
printf("there have no datan");
munmap(su1_2,PAGES*4*1024);
close(fd);
break;
}
}
while(1);
}
|
仅就bekars(涡轮增压)贴出的文章中的“内存共享 需要信号量辅助,而信号量又无法使用。 ”得出用户空间和内核空间无法通过内存共享是错误的, 当然使用通常意义上的信号量的确是不行的,但我们可以自己构造自己的信号量来保持两个空间的同步。 上面我的帖出的代码实际上很多是我自己写的,并且经过了测试和运用在以前的一个产品中了,我只是选取了其中的一部分贴出来而已。
|
copy_from_user, copy_to_user 不是吗?
|
驱动
系统调用
系统调用
|
TO 楼上的:
这个问题说起来可以说半天的,总之,LINUX提供了统一的驱动接口,但具体功能和编程要自己实现,关于驱动方面,你可以看一下,不过在网上能下载的都是英文版的
关于系统调用相关资料,你看一下一书
这个问题说起来可以说半天的,总之,LINUX提供了统一的驱动接口,但具体功能和编程要自己实现,关于驱动方面,你可以看一下,不过在网上能下载的都是英文版的
关于系统调用相关资料,你看一下一书
|
中断
系统调用
信号
系统调用
信号
|
操,直接操作/dev/kmem吧
QQ:28286880
QQ:28286880
|
共享内存的方式太龌龊了