一篇文章讲明白Linux内核态和用户态共享内存方式通信

简介: 一篇文章讲明白Linux内核态和用户态共享内存方式通信

1 //---用户态 芯片驱动层//

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10 #include

11 #include

12

13 #include

14 #include

15 #include

16 #include

17 #include

18 #include

19 #include

20

21 uint8 g_port_smi_addr_list【】 = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};

22 uint8 g_port_smi_serdes_addr_list【】 = {0, 0, 0, 0, 0xc, 0xd, 0xe};

23

24 typedef struct shm_info{

25 uint8 flag;

26

27 uint8 port【SCC_DIP_2_DPORT_NUM】;

28

29 }shm_info_t;

30

31 shm_info_t g_shm_mem_addr;

32

33

34 //在用户态初始化时定义Linux内核映射文件,

35 //将初始值传递到内核态,后续可动态更新

36 uint8 sccSysMemMapInit(void)

37 {

38 int fd;

39 uint8 i = 0;

40

41 if( (fd = open("/proc/shmfile", O_RDWR)) < 0){

42 printf("open /proc/shmfile error!\n");

43 return ERROR;

44 }

45

46 g_shm_mem_addr = (shm_info_t )mmap(NULL, SCC_MEM_MAP_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); // ignored, because we don't use "vm->pgoff" in driver.

47 if( MAP_FAILED == g_shm_mem_addr){

48 printf("mmap() error:【%d】\n", errno);

49 return ERROR;

50 }

51

52 memset(g_shm_mem_addr, 0, sizeof(shm_info_t));

53

54 for (i = 0; i < SCC_DIP_2_DPORT_NUM; i++){

55 g_shm_mem_addr->port【i】 = 0;

56 }

57

58 return OK;

59 }

60

61

62 uint8 sccSysMemMapFlagSet(uint8 enable)

63 {

64 if (TRUE != enable && FALSE != enable){

65 return ERROR;

66 }

67

68 g_shm_mem_addr->flag = enable;

69

70 return OK;

71 }

72

73

74 uint8 sccSysMemMapFlagGet(uint8 enable)

75 {

76 if (NULL == enable){

77 return ERROR;

78 }

79

80 enable = g_shm_mem_addr->flag;

81

82 return OK;

83 }

84

85

86 uint8 sccCtrlDevInit()

87 {

88 uint8 rc = OK;

89

90 rc = sccSysMemMapInit();

91

92 return rc;

93 }

94

95

96

97

98 //--Linux内核 gianfar.c//

99

100 #define PROC_SHM_FILE "shmfile"

101

102 struct proc_dir_entry //代码效果参考:http://www.zidongmutanji.com/zsjx/431599.html

g_proc_file = NULL;

103 unsigned long g_shm_addr = 0;

104

105 #define DIP_2_DPORT_NUM 3

106

107

108 typedef struct mem_shm_info{

109 unsigned char flag;

110

111 unsigned char port【DIP_2_DPORT_NUM】;

112

113 }mem_shm_info_t;

114

115

116

117 static int gfar_start_xmit(struct sk_buff skb, struct net_device dev)

118 {

119 int ret = 0;

120 unsigned char ptr_data = NULL;

121 unsigned char port = 0;

122 mem_shm_info_t info = NULL;

123 unsigned char port_num = 0;

124 unsigned char port_list【4】 = {0};

125

126 info = (mem_shm_info_t )g_shm_addr;

127 if ( 0 == info->flag ){

128 ret = gfar_start_xmit_real(skb, dev);

129 return ret;

130 }

131

132 ......

133 }

134

135

136 static int gfar_recv_port_check(unsigned char //代码效果参考:http://www.zidongmutanji.com/bxxx/141982.html

skbdata, unsigned char port)

137 {

138

139 mem_shm_info_t info = NULL;

140

141 info = (mem_shm_info_t )g_shm_addr;

142

143 / ipv4 packet , dest ip /

144

145 if (0 != info->port【port-1】){

146 ...

147 }

148

149 return 0;

150 }

151

152

153 / gfar_process_frame() -- handle one incoming packet if skb

154 isn't NULL. /

155 static int gfar_process_frame(struct net_device dev, struct sk_buff skb,

156 int amount_pull)

157 {

158 ...

159

160 gfar_recv_port_check();

161

162 ...

163 }

164

165

166

167 //Linux内核从用户态定义的文件名中,获取设置的值

168 int shm_mmap(struct file filp, struct vm_area_struct vma)

169 {

170 unsigned long page;

171

172 page = virt_to_phys((void *)g_shm_addr) ] PAGE_SHIFT;

173

174 if(remap_pfn_range(vma, vma->vm_start, page, (vma->vm_end - vma->vm_start), vma->vm_page_prot)) {

175 return -1;

176 }

177 vma->vm_flags |= VM_RESERVED;

178 printk("remap_pfn_rang page:【%lu】 ok.\n", page);

179

180 return 0;

181 }

182

183 static const struct file_operations g_shm_fops ={

184 .owner = THIS_MODULE,

185 .mmap = shm_mmap,

186 };

187

188

189 static int shm_init(void)

190 {

191 g_proc_file = proc_create(PROC_SHM_FILE, 0, NULL, &g_shm_fops);

192 if (NULL == g_proc_file) {

193 printk("proc create failed\n");

194 return -1;

195 }

196

197 g_shm_addr = get_free_page(GFP_KERNEL);

198 if(!g_shm_addr) {

199 printk("Allocate memory failure!/n");

200 return -1;

201 } else {

202 SetPageReserved(virt_to_page(g_shm_addr));

203 printk("Allocate memory success!. The phy mem addr=%lx\n", pa(g_shm_addr));

204 }

205

206 return 0;

207 }

208

209

210 static void shm_fini(void)

211 {

212 ClearPageReserved(virt_to_page(g_shm_addr));

213 free_page(g_shm_addr);

214 remove_proc_entry(PROC_SHM_FILE, NULL);

215

216 return;

217 }

218

219 static int init gfar_init(void)

220 {

221 #ifdef CONFIG_GFAR_SW_PKT_STEERING

222 gfar_cpu_dev_init();

223 #endif

224 gfar_1588_proc_init(gfar_match, sizeof(gfar_match));

225 shm_init();

226

227 return of_register_platform_driver(&gfar_driver);

228 }

229

230 static void exit gfar_exit(void)

231 {

232 shm_fini();

233 #ifdef CONFIG_GFAR_SW_PKT_STEERING

234 gfar_cpu_dev_exit();

235 #endif

236 gfar_1588_proc_exit();

237 of_unregister_platform_driver(&gfar_driver);

238 }

239

240 module_init(gfar_init);

241 module_exit(gfar_exit);

相关文章
|
5月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
477 0
Linux内存问题排查命令详解
|
4月前
|
安全 Go 开发者
“不要通过共享内存来通信”——深入理解Golang并发模型与CSP理论
Golang 采用 CSP 理念,主张“通过通信共享内存”,以消息传递替代共享内存,避免数据竞争。其核心为 Goroutine 与 Channel:轻量协程并发执行,通道安全传递数据,将并发复杂性转为通信编排,提升程序清晰度与可维护性。
332 0
|
缓存 Linux
linux 手动释放内存
在 Linux 系统中,内存管理通常自动处理,但业务繁忙时缓存占用过多可能导致内存不足,影响性能。此时可在业务闲时手动释放内存。
664 17
|
9月前
|
缓存 Linux 数据安全/隐私保护
Linux环境下如何通过手动调用drop_caches命令释放内存
总的来说,记录住“drop_caches” 命令并理解其含义,可以让你在日常使用Linux的过程中更加娴熟和自如。
1515 23
|
11月前
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
388 27
|
消息中间件 Linux
Linux中的System V通信标准--共享内存、消息队列以及信号量
希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。
477 48
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
328 16
|
12月前
|
缓存 NoSQL Linux
Linux系统内存使用优化技巧
交换空间(Swap)的优化 禁用 Swap sudo swapoff -a 作用:这个命令会禁用系统中所有的 Swap 空间。swapoff 命令用于关闭 Swap 空间,-a 参数表示关闭 /etc/fstab 文件中配置的所有 Swap 空间。 使用场景:在高性能应用场景下,比如数据库服务器或高性能计算服务器,禁用 Swap 可以减少磁盘 I/O,提高系统性能。
477 3
|
12月前
|
缓存 Linux
Linux查看内存命令
1. free free命令是最常用的查看内存使用情况的命令。它显示系统的总内存、已使用内存、空闲内存和交换内存的总量。 free -h • -h 选项:以易读的格式(如GB、MB)显示内存大小。 输出示例: total used free shared buff/cache available Mem: 15Gi 4.7Gi 4.1Gi 288Mi 6.6Gi 9.9Gi Swap: 2.0Gi 0B 2.0Gi • to
2070 2
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
901 20