Introdução ao Linux motoristas (a) personagem dispositivo fundação motorista

cópia de: https: //blog.csdn.net/weixin_42462202/article/details/99887783

entrada de driver Linux (a) dispositivo de caracteres base motorista do
artigo diretórios
entrada de driver Linux (a) caracteres dispositivo de base motorista
uma Introdução unidade
II conceito de driver de dispositivo de caracteres
terceiro lugar, o dispositivo de caracteres registrada
quatro ou compilar o módulo
cinco módulos de carga
sexto lugar, criar um nó de dispositivo
sete teste de
uma unidade Introdução
driver Linux para driver de dispositivo de caracteres, um drivers de dispositivo bloco, driver de dispositivo de rede

driver de dispositivo de caracteres

Um personagem dispositivos obrigação, a fim de série de acesso, como levou, um ecrã táctil, um mouse, etc.

Chamada acessível através de abrir, fechar, ler, escrever e outros sistemas

driver de dispositivo bloco

dispositivo de acesso bloco pode estar em qualquer ordem, em unidades de blocos para operar, como um disco rígido, e assim o EMMC

Há grandes diferenças conduzem os dispositivos de bloco projeto e caráter, mas também pode ser acessado via abrir, fechar, ler, escrever e outras chamadas de sistema, mas estes são geralmente usando o sistema de arquivos para gerenciar

driver de dispositivo de rede

dispositivo de rede é projetada para receber e enviar pacotes de dados, no sistema de arquivos, e não há nenhum nó de dispositivo correspondente, acessado através de interface de socket

Este trabalho, principalmente no dispositivo de caracteres

Em segundo lugar, o conceito de drivers de dispositivo de caracteres
no Linux tudo é um arquivo, como um desempenho do dispositivo conduzido no sistema de arquivos como / dev /, camada de aplicação levou nó de dispositivo através de abrir, ler, escrever e outras chamadas de sistema pode ser controlado levou

Por exemplo, quero levou luz, abrir a gravação de arquivos do dispositivo 1

int fd;
int val = 1;

Open = FD ( "/ dev / led", XXX);
Write (FD, e Val, o sizeof (Val));

de tal forma que ele pode ser conduzido iluminado

Agora pense sobre a questão, porque assim que você pode fazer o up luz led?

Para obter luzes LED, você deve operar o hardware, hardware operacional que faz parte da unidade de trabalho levou concluída

A maneira mais fácil é, para a camada de aplicação levou à operação de abertura, em seguida, a um correspondente condutor de levou led_open. Levou à camada de aplicação para as operações de escrita, a operação levou a um correspondente um dos led_write condutor, em seguida, a operação led_write para controlar o hardware, então o controlo levou

Em seguida, no dispositivo levou os nós aberta, chamada de sistema de gravação, como chamar a led_open do motorista, led_write isso?

Quando a camada de aplicativo chama aberta, ler, escrever e outras operações, fará com que uma exceção, fazendo com que o sistema se torne modo kernel, e, em seguida, para executar a chamada de sistema correspondente sys_open, sys_read, sys_write etc.

Irá encontrar o driver apropriado sys_open, sys_read, sys_write, e em seguida, chama ler, hardware aberto, gravação do motorista para operar

Como mostrado na FIG.

 

Sys_open em seguida, chamar um sistema de arquivos virtual, como você encontrou motorista levou em vez dos outros motoristas fazer?

Primeiro, conte-nos sobre o número do dispositivo

Cada dispositivo possui um número de dispositivo de 32 bits, em que 12 indica um elevado número de dispositivo mestre, 20 representa um número menor inferior

Use ls / dev / led dispositivo de visualização -l, as seguintes informações podem ser obtidas

a raiz-RW. 1 ---- CRW 0 10, 131. 1 12:00 Janeiro / dev / LED
. 1
em que 10, 131 designa um número de dispositivo, o número 10 indica o dispositivo mestre, menor número 131 denota

Para facilitar a compreensão, podemos considerar que existe um personagem do dispositivo do conjunto do kernel para o número de índice dispositivo mestre, o próprio dispositivo é um elemento array de caracteres, há um personagem conjunto de operações de arquivo de dispositivo, uma série de operações função definidos (por exemplo led_open, led_write, led_read)

chamadas de sistema sys_open para encontrar uma boa variedade de equipamentos pelo arquivo mestre, um conjunto de chamadas para o driver está led_open liderado por uma operação de arquivo de dispositivo de caractere e outras funções

 

driver de dispositivo de caracteres é melhorar as almofadinhas (arquivo de conjunto de operação), e em seguida, especifique o número do dispositivo, até o dispositivo de caracteres do kernel

Em terceiro lugar, o dispositivo de caracteres registrados
primeiro olhar para o objeto de dispositivo de caractere

file_operations struct {
ssize_t (* Leia) (struct arquivo *, char __user *, size_t, loff_t *);
int (* aberto) (struct inode *, struct arquivo *);
...
};

struct o cdev {
struct o kobject Kobj;
struct Module1 * proprietário; / * Ver Módulo * /
const struct os file_operations * OPS; operações / arquivo * definido * /
struct a Lista list_head;
o dev dev_t; / * número de dispositivo * /
unsigned int count;
};

em que os membros dev_t definir um número de dispositivo de 32 bits, de alta resolução dispositivo mestre 12, 20 para o número de sub-dispositivo inferior

Kernel dois seguintes maior e menor número de macro obter

MAJOR (dev_t dev) // maior número
menor (dev_t dev) // menor número

usando o seguinte número de dispositivo macro aquisição

Mkdev (int maior, menor int)

cada dispositivo tem seu próprio caráter dispositivo gama número correspondente, aqui está como aplicar o número do dispositivo

Nenhum equipamento de aplicação

alocação dinâmica

Esta função especifica o número de vezes que um número de dispositivo e o número de dispositivo pode ser atribuído dinamicamente número grande

* /
* Dev: aplicação para o número de dispositivo devolvido
baseminor *: começando número menor
* Contagem: o número do dispositivo de aplicação de número
* /
alloc_chrdev_region int (a dev_t * dev, sem sinal baseminor, sem sinal COUNT,
const char * nome)

atribuição estática

Esta função deve ser o número de número maior e menor e número do dispositivo

/ *
* De: Na verdade número do dispositivo
* Contagem: o número de número de dispositivo
* /
register_chrdev_region int (do dev_t, COUNT não assinado, const char * name)

após a conclusão do número dispositivo de aplicação, você pode usar este número de dispositivo para registrar um dispositivo de caractere

dispositivo de caracteres Register

Função e equipamentos relacionados com o personagem

vazio cdev_init (struct o cdev *, struct os file_operations *);
struct o cdev * cdev_alloc (void);
cdev_put vazio (struct o cdev * P);
cdev_add int (struct o cdev *, o dev_t, sem sinal);
cdev_del vazio (struct o cdev *);

cdev_init : FOPS e equipamento associado com o carácter utilizado, que é uma operação de arquivo file_operations definidos, é proporcionada uma série de funções de manipulação (por exemplo, aberto, lido, de gravação)

cdev_alloc: atribuir um objeto de dispositivo de caractere

cdev_add: dispositivo de caracteres Registro

cdev_del: cancelamento de um dispositivo de caractere

Um passo de registrar dispositivo de caractere

struct cdev * cdev_alloc (void); // dispositivo de caracteres atribuir

cdev_init void (struct cdev *, file_operations struct *); // vincular um fops

int cdev_add (struct cdev *, dev_t , não assinado); // caráter e para aplicar ao dispositivo o número dispositivo registrado no kernel

seguinte é um driver de dispositivo de caracteres simples

mydev.c

#include <linux / module.h>
#include <linux / init.h>
#include <linux / fs.h>
#include <linux / cdev.h>
#include <linux / slab.h>

dev_id dev_t estática;
struct cdev estática * mydev;

ssize_t mydev_read (struct arquivo * arquivo, char * __user dados, tamanho size_t, loff_t * loff)
{
printk ( "mydev_read \ n");

return 0;
}

ssize_t mydev_write (struct arquivo * arquivo, char const __user * dados, tamanho size_t, loff_t * loff)
{
printk ( "mydev_write \ n");

return 0;
}

int mydev_open (struct inode * inode, arquivo struct arquivo *)
{
printk ( "mydev_open \ n");

return 0;
}

/ *文件操作集合* /
static struct file_operations mydev_fops = {
.Owner = THIS_MODULE,
.read = mydev_read,
.open = mydev_open,
.write = mydev_write,
};

int mydev_init a estática __init (void)
{
/ * número de dispositivo de aplicação * /
alloc_chrdev_region (a dev_id & ,. 1 ,. 1 "que mydev");

/ * Atribuir dispositivo de caracteres * /
que mydev cdev_alloc = ();

/ * Dispositivo de caracteres Set * /
cdev_init (que mydev, & mydev_fops);

/ * Dispositivo de caracteres Registo * /
cdev_add (mydev, dev_id, 1);

/ * Pedido de impressão para a maior e menor número de * /
o printk ( "major: D%; Menor:% D \ n-", MAJOR (a dev_id), menor (a dev_id));

return 0;
}

__exit estática mydev_exit void (void)
{
cdev_del (mydev);
kfree (mydev);
unregister_chrdev_region (dev_id, 1);
}

module_init (mydev_init);
module_exit (mydev_exit);

MODULE_LICENSE ( "GPL");

quarto lugar, o módulo compilador
escrito em após o motorista, como é que vamos compilar o driver, existem duas maneiras, uma é compilado para o kernel e drivers juntos, um está escrito no driver sozinho módulo

A segunda apresentação aqui

Os drivers são compilados como módulos necessidade de escrever Makefile

Makefile como se segue

KERN_DIR = / trabalho / linux / kernel /

todos:
fazer -C $ (KERN_DIR) M = `pwd` módulos

limpo:
fazer -C $ (KERN_DIR) M = `pwd` módulos limpo
modules.order rm -rf

obj-m + = mydev.o
onde KERN_DIR = / trabalho / linux / kernel / semente árvore representa, de acordo com a necessidade de modificar o caminho onde o seu kernel

obj-m + = mydev.o arquivo de programa para ser compilado mydev.c

fazer $ -C (KERN_DIR) módulos pwd M = mostrar um salto para a árvore fonte do kernel, compilar módulo

O Makefile e mydev.c juntos, executar make, mydev.ko módulo da unidade podem ser obtidas

Em quinto lugar, o módulo de carregamento
utilizando o módulo de condução pode ser carregado xxx.ko insmod

Uso Ismod pode ver o módulo carregado no momento

Você pode desinstalar o driver usando módulos de xxx carregado rmmod

O mydev.ko acima copiados para gerar plataforma experimental, executar mydev.ko insmod

Uma vez módulo carregado, o kernel será executado module_init (mydev_init) entrada módulo especificado, a função mydev_init, aplicamos o número do dispositivo, registrou o dispositivo de caracteres, e imprimir o número de dispositivos maiores e menores

Você pode ver as informações de impressão

Major: 250; Menor: 1
1
representa o maior número 250, menor número 1 (o que você vê podem variar)

Neste ponto, o módulo foi carregado, podemos ver através das cat / proc / dispositivos que temos registrado o dispositivo de caractere

Mas não gerou nós de dispositivos, ainda não somos capazes de operar o equipamento no diretório / dev, aqui está como criar um nó de dispositivo

Seis, criar nós de dispositivo
criar um nó de dispositivo é criado automaticamente e manualmente criada é dividido nas seguintes foram introduzidos

criar manualmente

Nos melhores pilotos para imprimir maior: 250; menor: 1, podemos usar essa informação para criar nós de dispositivos

Até o seguinte comando para criar um nó de dispositivo

mknod nome do dispositivo tipo de dispositivo (personagem: C, bloco: b) número grande a partir do número do dispositivo

realizada

mknod / dev / mydev c 250 um

prazo após a geração do dispositivo de nó / dev / mydev

Criado automaticamente

Ele é criado automaticamente usando mecanismo udev mdev ou mecanismos, quando o controlador de dispositivo cria informações relacionadas / sys, MDEV udev ou dispositivo nodos são criados de acordo com as informações

O seguinte descreve como criar nós de dispositivos

classe struct estática * mydev_class;

mydev_class = class_create (THIS_MODULE, "mydev "); // Criar uma classe
device_create (mydev_class, NULL, dev_id, NULL, "mydev"); // criar um dispositivo de nó de acordo com o número do dispositivo

nó dispositivo destruição

device_destroy (mydev_class, dev_id); // nó dispositivo é destruído
class_destroy (mydev_class); // destruição classe

condução modificados

mydev.c

#include <linux / module.h>
#include <linux / init.h>
#include <linux / fs.h>
#include <linux / cdev.h>
#include <linux / slab.h>
#include <linux / device.h>

dev_id dev_t estática;
struct cdev estática * mydev;
classe struct estática * mydev_class;

ssize_t mydev_read (struct arquivo * arquivo, char * __user dados, tamanho size_t, loff_t * loff)
{
printk ( "mydev_read \ n");

return 0;
}

ssize_t mydev_write (struct arquivo * arquivo, char const __user * dados, tamanho size_t, loff_t * loff)
{
printk ( "mydev_write \ n");

return 0;
}

int mydev_open (struct inode * inode, arquivo struct arquivo *)
{
printk ( "mydev_open \ n");

return 0;
}

estática struct file_operations mydev_fops = {
.Owner = THIS_MODULE,
.read = mydev_read,
.open = mydev_open,
.write = mydev_write,
};

int mydev_init a estática __init (void)
{
/ * número de dispositivo de aplicação * /
alloc_chrdev_region (a dev_id & ,. 1 ,. 1 "que mydev");

/ * Atribuir dispositivo de caracteres * /
que mydev cdev_alloc = ();

/ * Dispositivo de caracteres Set * /
cdev_init (que mydev, & mydev_fops);

/ * Dispositivo de caracteres Registo * /
cdev_add (mydev, dev_id, 1);

/ * Pedido de impressão para a maior e menor número de * /
o printk ( "major: D%; Menor:% D \ n-", MAJOR (a dev_id), menor (a dev_id));

mydev_class = class_create (THIS_MODULE, "mydev");
device_create (mydev_class, NULL, dev_id, NULL, "mydev");

return 0;
}

__exit estática mydev_exit void (void)
{
device_destroy (mydev_class, dev_id);
class_destroy (mydev_class);

cdev_del (mydev);
kfree (mydev);
unregister_chrdev_region (dev_id, 1);
}

module_init (mydev_init);
module_exit (mydev_exit);

MODULE_LICENSE ( "GPL");

módulo recompilação carregado

Ver / sys / dev / char diretório, você vai encontrar mais algumas informações 250: 1

Neste ponto ver ls / dev / mydev, você vai encontrar o diretório / dev já tem um mydev

Sete teste
após cada motorista está terminado, você precisa testes de aplicativos de gravação

Aqui é o nosso programa de teste

mydev_test.c

#include <stdio.h>
#include <sys / types.h>
#include <sys / stat.h>
#include <fcntl.h>
#include <unistd.h>

int principal (int argc, char * argv [])
{
int val = 1;

int fd = open ( "/ dev / mydev", O_RDWR);

write (fd, & val, sizeof (val));

read (fd, & val, sizeof (val));

0 retorno;
}

compilado

mydev_test.c braço em Linux-gcc

módulo de carregamento

insmod mydev.ko

executar o programa de teste

./a.out

pode ver a impressão de console

[2639.832633] mydev_open
[2639.833528] mydev_write
[2639.836014] mydev_read

condutor normal, demonstrou

Este artigo para terminar aqui
----------------
Aviso: Este artigo é CSDN blogger ARTIGO ORIGINAL "estudantes JT", seguindo o CC 4.0 BY-SA acordo de direitos autorais, reimpressão Por favor, inclua links para a fonte original e esta declaração.
link original: https: //blog.csdn.net/weixin_42462202/article/details/99887783

Acho que você gosta

Origin www.cnblogs.com/Oude/p/12455626.html
Recomendado
Clasificación