我正在 Linux 中实现一个使用结构的网络模块/驱动程序net_devices
。到目前为止,我已经能够使用insmod
命令在内核空间中添加和删除模块。通过ifconfig
我为新创建的接口设置了一个 ip,并且能够发送 ping 数据包。我现在需要做的是捕获函数sk_buff
内的数据包ndo_start_xmit
并通过 UART 物理连接器发送/接收它们。即,就像在用户空间应用程序中,我们通过文件描述符 ( /dev/tty*
) 打开 tty 设备并写入以进行传输(并读取以进行接收)一样,我现在必须以某种方式在内核空间中检测或找到我的设备(在我的内部)网络模块)并通过 Rx 和 Tx 线发送或接收数据。以下是我的司机:
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/etherdevice.h>
struct net_device *mynet;
int mynet_open(struct net_device *dev) {
printk(KERN_ALERT "open called\n");
return 0;
}
int mynet_release(struct net_device *dev) {
printk(KERN_ALERT "release called\n");
netif_stop_queue(dev);
return 0;
}
int mynet_xmit(struct sk_buff *skb, struct net_device *dev) {
printk(KERN_ALERT "dummy xmit function called...\n");
///////// UART SEND HERE /////////
dev_kfree_skb(skb);
return 0;
}
int mynet_init(struct net_device *dev) {
printk(KERN_ALERT "gohmnet0 device initialized\n");
return 0;
}
const struct net_device_ops my_netdev_ops = {
.ndo_init = mynet_init,
.ndo_open = mynet_open,
.ndo_stop = mynet_release,
.ndo_start_xmit = mynet_xmit,
};
static void virtual_setup(struct net_device *dev){
dev->netdev_ops = &my_netdev_ops;
}
int mynet_init_module(void) {
int result;
mynet = alloc_netdev(0, "mynet",NET_NAME_UNKNOWN, virtual_setup);
if((result = register_netdev(mynet)))
{
printk(KERN_ALERT "mynet: Error %d initalizing card ...", result);
return result;
}
return 0;
}
void mynet_cleanup (void)
{
printk (KERN_ALERT "<0> Cleaning Up the Module\n");
unregister_netdev (mynet);
}
module_init(mynet_init_module);
module_exit(mynet_cleanup);
MODULE_LICENSE("GPL");
PS我已经研究了以下方法,我需要替代它,所以这是不可能的:
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);
最后一点,在我看来,我需要在我自己的模块/驱动器的内核空间中使用 UART 驱动程序,而不需要来回跳转到用户空间。