Red de conocimiento informático - Problemas con los teléfonos móviles - Cómo encontrar el último nodo de dispositivo agregado en Ubuntu

Cómo encontrar el último nodo de dispositivo agregado en Ubuntu

Agregar su propio código de kernel desarrollado al kernel de Linux implica 3 pasos:

1. Asegúrese de colocar el código que desarrolló en la ubicación correcta en el kernel

Copie el demo_chardev.c archivo al directorio ../drivers/char/.

demo_chardev.c

[cpp] Ver copia pura

#include

#include

#include

# include

/*Estructura de definición del archivo de encabezado file_ Operations*/

#include

/*Declarar el archivo de encabezado de la función copy_too_/from_user*/

/*Declarar el archivo de encabezado */

#include

/*Declarar información relacionada con class_create y device_create*/

#include

#define DEMO_DEBUG

#ifdef DEMO_DEBUG

#define dem_dbg(fmt, arg...) printk(KERN_WARNING fmt, ##arg )

#else

#define dem_dbg(fmt, arg...) printk(KERN_WARNING fmt, ##arg)

#else

#define dem_dbg(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)

#endif

#define DEVICE_COUNT 2

//* Registre el número de dispositivo principal actual ocupado por el controlador*/

static int major = 0

static int demo_open (struct inode *pnode, struct file *filp)

{

dem_dbg("[kern func]:%s mayor: %d menor: %d\n",

__FUNCTION__, imajor (pnodo), iminor(pnode) );

devuelve 0;

}

static ssize_t demo_read (archivo de estructura *filp, char __user *buf, size_t count, loff_t * offp)

{

unsigned char ary[100] = "¡Leíste correctamente! ";

unsigned long len = min(count, sizeof(ary)); //min es una macro utilizada para obtener el menor de dos números

int retval ;

dem_dbg("[kern func]: %s mayor: %d menor: %d\n",

__FUNCTION__, imajor(filp->f_dentry->d_inode),

iminor(filp->f_dentry->d_inode));

// f de la estructura del archivo

El miembro _flags se puede utilizar para determinar si la lectura está bloqueada y luego manejarla en consecuencia

if(copy_to_user(buf, ary, len) != 0){

retval = - EFAULT;

p>

ir a cp_err;

}

Devuelve len.

return len; // Devuelve con éxito el número de bytes realmente transferidos

cp_err:

Devuelve retval

}

estático ssize_to_user(buf, ary, len) ! p> static ssize_t demo_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)

{

unsigned char ary[100] = ""; p> unsigned long len = min(count, sizeof(ary)); //min es una macro utilizada para obtener el menor de dos números

int retval

dem_dbg(" [función kern]: %s mayor: %d menor: %d\n",

__FUNCTION__, imajor(filp->f_dentry->d_inode),

iminor(filp- >f_dentry->d_inode));

if(copy_from_user(ary, buf, len) != 0){

retval = -EFAULT; cp_err;

}

printk("[msg]: contexto de escritura: %s\n",ary);

return len; el número real de bytes transferidos

cp_err:

Return retval

}

static int demo_release (struct inode *pnode, struct archivo *filp)

{

dem_dbg("[[kern func]: %s mayor: %d menor: %d\n",

__FUNCTION__ , imajor(pnode), iminor(pnode));

return 0;

}

/*@Defina la variable de estructura de operaciones file_ */

estructura estática file_operaciones fops = {

.owner = ESTE_MODULE,

.read = demo_read,

.write = demo_write,

.open = demo_open ,

.release = demo_release,

};

clase de estructura estática *demo_class; static int __init drvdemo_ init(void)

{

struct dispositivo *demo_device

int

int retval

p>

dem_dbg("[msg]:esta es una demostración del controlador, en la función inicial del módulo\n");

> /*Registrar la función del controlador de caracteres, devolver con éxito el número de dispositivo principal asignado dinámicamente, falla

*Devolver código de error (negativo)*

major = Register_chrdev(0, "demo_chrdev", &fops

if(mayor < 0){

retval = mayor

goto chrdev_err; p> /*Crear clase de dispositivo*/

demo_class = class_create(THIS_MODULE , "demo_class");

if(IS_ERR(demo_class)){

retval = PTR_ERR(demo_class);

goto class_err;

}

/*Crea un archivo de dispositivo y notifica al usuario que cree un dispositivo en "/dev". /" archivo de directorio, cree un archivo de dispositivo llamado demoX*/

for(i=0; i

demo_device = device_create(demo_class,NULL, MKDEV(major, i), NULL, "demo%d",i);

If (IS_ERR(demo_device)) {

retval = PTR_ERR(demo_device);

get device_err

}

}

}

return 0;

device_err:

while(i--) //Operación de reversión para la creación del nodo del dispositivo device_destroy( demo_class,MKDEV(major, i));

class_destroy(demo_class); //eliminar la clase de dispositivo

class_err:

unregister_chrdev(major, "demo_chrdev) ");

unregister_chrdev(major, "demo_chrdev") "demo_chrdev");

chrdev_err:

Devolución de valor;

}

static void __exit drvdemo_exit(void)

{

int i;

dem_dbg("[msg]:en la función de salida del módulo \n");

/* Función para cancelar el registro del controlador de caracteres, sin valor de retorno, mayor es el número de dispositivo principal asignado*/

unregister_chrdev(major, "demo_chrdev");

/* Eliminar nodo de dispositivo y clases de dispositivo*/

for(i=0; i

device_destroy(demo_class,MKDEV(major, i)); /p>

class_destroy(clase_demo

}

module_destroy(demo_class,MKDEV(principal, i)).

module_init(drvdemo_init);

module_exit( drvdemo_exit);

MODULE_LICENSE("Dual BSD/GPL"); //Licencia dual BSD/GPL

MODULE_AUTHOR("hanbo"); //autor del módulo (opcional)

p>

MODULE_DESCRIPTION("usado para estudiar controladores de Linux"); //perfil secundario del módulo (opcional)

2. Agregar funciones de desarrollo propio a las opciones de configuración del kernel de Linux. Agregue funciones de desarrollo propio a las opciones de configuración del kernel de Linux para que los usuarios puedan seleccionar esta función

Al final del archivo vi drivers/char/Konfig, agregue una opción de configuración delante del menú final

[cpp ] ver copia simple

configuración DEMO_CHARDEV

bool "controlador demo_chardev para placas hanbo chardev"

valor predeterminado

ayuda

Este es el controlador CHARDEV para las placas hanbo chardev.

3. Compile o modifique el Makefile según la elección del usuario y compile el código apropiado en el kernel de Linux final generado

make menuconfig (agregue opciones de configuración) (si se le solicita). para encontrar la biblioteca " ncurses ", ejecute el siguiente comando: sudo apt-get install libncurses5-dev )

Controlador de dispositivo -->

Dispositivo de caracteres->

[ *] controlador demo_chardev para la placa Hanbao chardev

4.vi drivers/char/Makefile Agregue el siguiente contenido:

..........

obj-$(CONFIG_DEMO_CHARDEV) +=demo_chardev.o (agregar)

obj-$(CONFIG_JS_RTC) +=js-rtc.o (self)

js -rtc-y = rtc.o (self)

5. make (actualiza la imagen del kernel en la placa de desarrollo)

6. Compila de forma cruzada el programa de prueba en la placa de desarrollo ejecutar

arm-linux-gcc-gcc test.c -o demo

test.c

[cpp] Ver copia pura

#incluir

#incluir

#incluir

int main(int argc, char *argv[ ])

{

int fd1 = 0, fd2 = 0

unsigned char buf1[100] = "Soy un programa de prueba!";

unsigned char buf2[100] = {0};

int retval;

//Abre el archivo del dispositivo en lectura-escritura, sin bloqueo modo

fd1 = open("/dev/demo0", O_RDWR | O_NONBLOCK

if(fd1 < 0){

perror("open / dev/demo1");

salió;

}

//Abre el archivo del dispositivo en modo de solo lectura, bloqueando modo

fd2 = open ("/dev/demo1", O_RDONLY

if(fd2 < 0){

perror("open /dev/); demo2");

salir;

}

// Éxito del archivo del dispositivo en modo de bloqueo de solo lectura.

// El éxito devuelve la palabra escrita real Número de secciones, valor negativo devuelto en caso de error

retval = write(fd1, buf1, strlen(buf1)+1

retval); = escribir(fd1, buf1, strlen(buf1)+ 1) strlen(buf1)+1);

if(retval < 0){

perror("¡Error al escribir fd1! " ");

salir;

}

>

printf(".write bytes: %d escribir contenido: %s\n", retval, buf1

//Devuelve el número real de bytes leídos cuando se realiza correctamente, devuelve un valor negativo en caso de error

retval = read(fd2, buf2, sizeof(buf2));

if(retval < 0){

perror( "¡Error al leer fd2!");

salir

}

printf(": leer bytes: %d leer contenido: % s\n", retval, buf2);

devolver 0;

salir:

if(fd1 > 0)

cerrar (fd1);

if(fd2 > 0)

cerrar(fd2

devolver -1; /p>

2. Cargue manualmente el archivo .ko del controlador

1. Compile el archivo demo_chardev.c anterior en el kernel y genere el archivo .ko

2. El archivo demo_chardev.c anterior se compila en el kernel y genera un archivo .ko

Makefile

[cpp] ver copia simple

#Si se define KERNELRELEASE, luego Indica que la llamada al sistema es creada por el kernel

#Puedes usar declaraciones integradas

ifneq ($(KERNELRELEASE),)

obj- m +=demo_chrdev.o

# Luego la llamada al sistema es creada por el kernel

else

#Define y registra la ruta del código fuente del kernel

KERNELDIR = /home /hanbo/linux-2.6.35.7 (su propia ruta de código fuente, 2.6.35.7 se refiere a la versión actual del kernel)

#Registrar el directorio del proyecto actual

PWD := $(shell pwd)

Valor predeterminado:

$(MAKE) -C $(KERNELDIR) M=$(PWD) módulos

@ rm -rf *.o .t* .m* .*.cmd *.mod.c *.order *.symvers

endif

limpio:

rm -rf *.ko *.o .t* .m* .*.cmd *.mod.c *.order *.symvers

2. Luego usa el comando para cargar el controlador .ko

p>

lsmod enumera todos los módulos del sistema actual

lsmod enumera todos los módulos del sistema actual

rmmod xxx desinstala el especificado módulo (sin sufijo .ko)

3. Si no se usa en su propio código compilado

/*Crear clase de dispositivo*

demo_class = class_create( THIS_MODULE, "demo_class");

/*Crea un archivo de dispositivo y notifica al usuario que está ubicado en el directorio "/dev/"*/

demo_device = device_create(demo_class ,NULL,MKDEV(principal,

i),NULL, "demo%d",i);

Luego, debe agregar el nodo del dispositivo manualmente

mknod /dev/demo1 c master 0

mknod /dev/demo2 c master 1

Nota: Si rmmod: chdir (2.6.35.7): No aparece dicho archivo o directorio durante la desinstalación

Luego, bajo la raíz de la placa base sistema de archivos Cree un directorio: /lib/modules/2.6.35.7 (con el mismo nombre que la versión actual del kernel)

.