Utilizando o driver de porta UART / Serial dentro de outro módulo / driver do Linux

1

Estou implementando um módulo / driver de rede no Linux que usa net_devices structure. E até agora consegui adicionar e remover meu módulo de e para o espaço do kernel usando o comando insmod . Via ifconfig eu configurei um ip para minha interface recém-criada e consegui enviar pacotes de ping. O que preciso fazer agora é capturar sk_buff pacotes dentro da minha função ndo_start_xmit e enviá-los / recebê-los por meio de conectores físicos UART. ou seja, assim como no caso de aplicativos userspace onde nós abrimos um dispositivo tty através de descritores de arquivos ( /dev/tty* ) e escrevemos para para transmissão (e lidos para receber), agora tenho que de alguma forma detectar ou encontrar meu dispositivo no kernel (dentro do meu módulo de rede) e enviar ou receber dados através das linhas Rx e Tx. Abaixo está o meu driver:

#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");

P.S. Eu pesquisei o seguinte método e preciso de uma alternativa para ele, por isso está fora de questão:

oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);

Como nota final, parece-me que preciso usar o driver UART no espaço do kernel em meu próprio módulo / unidade sem ir e voltar para o espaço do usuário.

    
por Ams 02.08.2018 / 13:58

0 respostas