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

相关文章
|
1天前
|
监控 Linux
深入了解Linux的pmap命令:进程内存映射的利器
`pmap`是Linux下分析进程内存映射的工具,显示内存区域、权限、大小等信息。通过`/proc/[pid]/maps`获取数据,特点包括详细、实时和灵活。参数如`-x`显示扩展信息,`-d`显示设备。示例:`pmap -x 1234`查看进程1234的映射。注意权限、实时性和准确性。结合其他工具定期监控,排查内存问题。
|
1天前
|
机器学习/深度学习 固态存储 Linux
一篇文章讲明白Linux下的ping命令用法与实现
一篇文章讲明白Linux下的ping命令用法与实现
|
2天前
|
存储 机器学习/深度学习 Linux
程序员必知:关于Linux内存寻址与页表处理的一些细节
程序员必知:关于Linux内存寻址与页表处理的一些细节
|
2天前
|
Unix Linux 调度
一篇文章讲明白linux僵死进程
一篇文章讲明白linux僵死进程
|
2天前
|
Linux
【linux】共享内存
【linux】共享内存
6 0
|
3天前
|
Linux 芯片
一篇文章讲明白Linux下控制GPIO的三种方法
一篇文章讲明白Linux下控制GPIO的三种方法
14 3
|
7天前
|
存储 缓存 Linux
【原创】(十)Linux内存管理 - zoned page frame allocator - 5(2)
【原创】(十)Linux内存管理 - zoned page frame allocator - 5
|
1月前
|
缓存 监控 Linux
linux 内存监控
linux 内存监控
26 1
|
存储 监控 Shell
Linux 性能监控之CPU&内存&I/O监控Shell脚本2
Linux 性能监控之CPU&内存&I/O监控Shell脚本2
454 0
|
监控 Shell Linux
Linux 性能监控之CPU&内存&I/O监控Shell脚本1
Linux 性能监控之CPU&内存&I/O监控Shell脚本1
159 0