Linux内核态和用户态共享内存方式通信

  1 //-----------------------------------用户态 芯片驱动层----------------------------//
  2 #include <stdio.h>
  3 #include <unistd.h>
  4 #include <fcntl.h>
  5 #include <sys/stat.h>
  6 #include <sys/types.h>
  7 #include <sys/mman.h>
  8 #include <pthread.h>
  9 #include <sys/socket.h>
 10 #include <netinet/in.h>
 11 #include <arpa/inet.h>
 12 
 13 #include <stdlib.h>
 14 #include <sys/ioctl.h>
 15 #include <net/if.h>
 16 #include <errno.h>
 17 #include <sys/wait.h>
 18 #include <ctype.h>
 19 #include <net/if_arp.h>
 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 *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 *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);

 

posted on 2023-04-21 11:21  wallywl  阅读(620)  评论(0)    收藏  举报