一篇文章讲明白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);

相关文章
|
2月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
177 6
|
10天前
|
算法 Linux 开发者
深入探究Linux内核中的内存管理机制
本文旨在对Linux操作系统的内存管理机制进行深入分析,探讨其如何通过高效的内存分配和回收策略来优化系统性能。文章将详细介绍Linux内核中内存管理的关键技术点,包括物理内存与虚拟内存的映射、页面置换算法、以及内存碎片的处理方法等。通过对这些技术点的解析,本文旨在为读者提供一个清晰的Linux内存管理框架,帮助理解其在现代计算环境中的重要性和应用。
|
16天前
|
存储 缓存 监控
|
1月前
|
存储 缓存 监控
Linux中内存和性能问题
【10月更文挑战第5天】
38 4
|
1月前
|
算法 Linux
Linux中内存问题
【10月更文挑战第6天】
41 2
|
13天前
|
缓存 算法 Linux
Linux内核中的内存管理机制深度剖析####
【10月更文挑战第28天】 本文深入探讨了Linux操作系统的心脏——内核,聚焦其内存管理机制的奥秘。不同于传统摘要的概述方式,本文将以一次虚拟的内存分配请求为引子,逐步揭开Linux如何高效、安全地管理着从微小嵌入式设备到庞大数据中心数以千计程序的内存需求。通过这段旅程,读者将直观感受到Linux内存管理的精妙设计与强大能力,以及它是如何在复杂多变的环境中保持系统稳定与性能优化的。 ####
22 0
|
1月前
|
存储 缓存 固态存储
|
1月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
36 0
Linux C/C++之TCP / UDP通信
|
1月前
|
运维 网络协议 安全
Linux安全运维--一篇文章全部搞懂iptables
Linux安全运维--一篇文章全部搞懂iptables
41 1
|
1月前
|
网络协议 Linux
linux学习之套接字通信
Linux中的套接字通信是网络编程的核心,允许多个进程通过网络交换数据。套接字提供跨网络通信能力,涵盖本地进程间通信及远程通信。主要基于TCP和UDP两种模型:TCP面向连接且可靠,适用于文件传输等高可靠性需求;UDP无连接且速度快,适合实时音视频通信等低延迟场景。通过创建、绑定、监听及读写操作,可以在Linux环境下轻松实现这两种通信模型。
34 1