Linux驱动中读写文件

最近做了一个TF卡烧写MAC地址,方法额外增加一个驱动,驱动中实现对TF卡和本地mac文件的读写功能,让以太网驱动加载时调用读写函数进行设置mac地址,代码比较简单,如下:

/*
 * setmac one chip USB 2.0 ethernet devices
 *
 * Author : yubo.wang 
 * Date : 2017-08-25
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2.  This program is licensed "as is" without any warranty of any
 * kind, whether express or implied.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "setmac.h"

#define SET_MAC_FILE 	"/system/etc/mac"
#define SET_MAC_MOUNT 	"/system/etc/tf_mac/mac"

int setmac_read_tf_mac(u8 *mac_addr)
{  
	u8 mac_buf[12] = {0,};
	int i = 0;
	struct file *fp;  
	mm_segment_t fs;  
	loff_t pos;  
	
	fp = filp_open(SET_MAC_MOUNT, O_RDONLY, 0);	
	if (IS_ERR(fp)) 
	{  
		printk(KERN_ERR "read tf mac addr file error,return!\n");	
		return -1;	
	}  
	
	fs = get_fs();	
	set_fs(KERNEL_DS);	
		
	pos = 0;  
	vfs_read(fp, mac_buf, sizeof(mac_buf), &pos);
	if(strlen(mac_buf) < 12)
	{
		printk(KERN_ERR "read tf mac addr len < 12,return!\n");  
		return -1;
	}
	mac_buf[12] = '\0';
	
	printk(KERN_INFO "read tf mac:%s",mac_buf);

	for (i=0; i<6; i++){ 
		u8 mac_tmp[3]= {0,};
		memcpy(mac_tmp, (char *)(mac_buf+i*2), 2);
		mac_addr[i] = simple_strtoul(mac_tmp, NULL, 16);
	}

	filp_close(fp, NULL);  
	set_fs(fs);  
	return 0;  
}
EXPORT_SYMBOL_GPL(setmac_read_tf_mac);

int setmac_write_tf_mac(u8 *mac_addr)
{  
	u8 mac_buf[12] = {0,};
	int i = 0;
	struct file *fp;  
	mm_segment_t fs;  
	loff_t pos;  
	
	fp = filp_open(SET_MAC_FILE, O_RDWR | O_CREAT, 0644);	
	if (IS_ERR(fp)) 
	{  
		printk(KERN_ERR "write tf mac addr file error,return!\n"); 
		return -1;	
	}  
	
	fs = get_fs();	
	set_fs(KERNEL_DS);	

	for (i=0; i<6; i++){ 
		u8 mac_tmp[3]= {0,};
		sprintf(mac_tmp, "%02x", mac_addr[i]);
		strncat(mac_buf, mac_tmp, 2);
	}
	mac_buf[12] = '\0';
	printk(KERN_INFO "write mac:%s",mac_buf);
	
	pos = 0;	
	vfs_write(fp, mac_buf, sizeof(mac_buf), &pos);
	vfs_fsync(fp, 0);
	filp_close(fp, NULL);
	set_fs(fs);
	return 0;
}
EXPORT_SYMBOL_GPL(setmac_write_tf_mac);

int setmac_read_mac_addr(u8 *mac_addr)
{  
	u8 mac_buf[12] = {0,};
	int i = 0;
	struct file *fp;  
	mm_segment_t fs;  
	loff_t pos;  
	
	fp = filp_open(SET_MAC_FILE, O_RDONLY, 0);	
	if (IS_ERR(fp)) 
	{  
		printk(KERN_ERR "read mac addr file error,return!\n");	
		return -1;	
	}  
	
	fs = get_fs();	
	set_fs(KERNEL_DS);	
		
	pos = 0;  
	vfs_read(fp, mac_buf, sizeof(mac_buf), &pos);
	if(strlen(mac_buf) < 12)
	{
		printk(KERN_ERR "read mac addr len < 12,return!\n");  
		return -1;
	}
	mac_buf[12] = '\0';
	
	printk(KERN_INFO "read mac:%s",mac_buf);

	for (i=0; i<6; i++){ 
		u8 mac_tmp[3]= {0,};
		memcpy(mac_tmp, (char *)(mac_buf+i*2), 2);
		mac_addr[i] = simple_strtoul(mac_tmp, NULL, 16);
	}

	filp_close(fp, NULL);  
	set_fs(fs);  
	return 0;  
}
EXPORT_SYMBOL_GPL(setmac_read_mac_addr);

int setmac_write_mac_addr(u8 *mac_addr) 
{  
	u8 mac_buf[12] = {0,};
	int i = 0;
	struct file *fp;  
	mm_segment_t fs;  
	loff_t pos;  
	
	fp = filp_open(SET_MAC_FILE, O_RDWR | O_CREAT, 0644);	
	if (IS_ERR(fp)) 
	{  
		printk(KERN_ERR "write mac addr file error,return!\n");	
		return -1;	
	}  
	
	fs = get_fs();	
	set_fs(KERNEL_DS);	

	for (i=0; i<6; i++){ 
		u8 mac_tmp[3]= {0,};
		sprintf(mac_tmp, "%02x", mac_addr[i]);
		strncat(mac_buf, mac_tmp, 2);
	}
	mac_buf[12] = '\0';
	printk(KERN_INFO "write mac:%s",mac_buf);
	
	pos = 0;	
	vfs_write(fp, mac_buf, sizeof(mac_buf), &pos);
	vfs_fsync(fp, 0);
	filp_close(fp, NULL);
	set_fs(fs);
	return 0;
}
EXPORT_SYMBOL_GPL(setmac_write_mac_addr);

MODULE_AUTHOR("yubo.wang ");
MODULE_DESCRIPTION("SETMAC one chip USB 2.0 ethernet devices");
MODULE_LICENSE("GPL");

预留问题:

1、量产多个mac地址递增还未实现,发现ops文件指针偏移不准导致读数据异常

2、没有对mac地址有效性检查,只检查了位数,且单播多播和OUI也没有检查

猜你喜欢

转载自blog.csdn.net/TSZ0000/article/details/77604189