Análisis de la carga anormal del controlador de dispositivo después de agregar un nuevo atributo de reinicio al nodo del árbol de dispositivos de Linux

Este problema ocurrió al depurar el controlador del dispositivo Linux. Este documento se compiló en función de la comprensión del problema en ese momento y el método de verificación correspondiente.

1 información del controlador de dispositivo sin formato de Linux

1.1 Información del nodo del árbol de dispositivos

/ {
    
    
        test_fw_load@0x100000000 {
    
    
                compatible = "test,test-x280-fw";
                reg = < 0x01 0x00000000 0x0 0x20000000 >, < 0x0 0x4000f000 0x0 0x200>;
        };
};

1.2 controlador de dispositivo Linux

Aquí solo damos un ejemplo del código del controlador test_fw.c, y las funciones específicas de la función de sonda no se publicarán.

// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>

#include <linux/io.h>
#include <linux/device.h>
#include <linux/firmware.h>

#define TEST_FW_LOAD_VERSION "1.0"


static int test_fw_probe(struct platform_device *pdev)
{
    
    
	printk("test fw probe\r\n");
	return 0;
}

/**
 * test_fw_remove - set driver_data of the device to NULL
 * @pdev: pointer to platform device handle
 *
 * Always returns 0
 */
static int test_fw_remove(struct platform_device *pdev)
{
    
    
	printk("test fw probe\r\n");

	return 0;
}

static const struct of_device_id test_fw_match[] = {
    
    
	{
    
     .compatible = "test,test-x280-fw", },
	{
    
    },
};
MODULE_DEVICE_TABLE(of, test_fw_match);

static struct platform_driver test_fw_load_driver = {
    
    
	.driver = {
    
    
		.name           = "test_fw_load",
		.of_match_table = test_fw_match,
	},
	.probe  = test_fw_probe,
	.remove = test_fw_remove,
};
module_platform_driver(test_fw_load_driver);

MODULE_AUTHOR("W Test <[email protected]>");
MODULE_VERSION(TEST_FW_LOAD_VERSION);
MODULE_LICENSE("GPL V2");

1.3 archivo MAKE

obj-$(CONFIG_TEST_FW_LOAD)      += test_fw.o

1.4 Kconfig

config TEST_FW_LOAD
        tristate "X280 Fw load on Test Platform"
        select FW_LOADER
        help
          This option enables support for the Test load X280 FW

          You may select when support test fw load. To compile this as a module
          choose M.

          If unsure, say N.

1.5 Archivo defconfig correspondiente

CONFIG_TEST_FW_LOAD=y

2 Controlador de dispositivo Linux modificado

2.1 Información modificada del nodo del árbol de dispositivos

Se agregó el atributo de reinicio al nodo test_fw_load.

/ {
    
    
	test_reset: test_reset {
    
    
		compatible = "test,scmi-reset";
		#reset-cells = <1>;
	};
};

/ {
    
    
        test_fw_load@0x100000000 {
    
    
                compatible = "test,test-x280-fw";
                reg = < 0x01 0x00000000 0x0 0x20000000 >, < 0x0 0x4000f000 0x0 0x200>;
                resets = <&test_reset 1>;
                reset-names = "test_reset";
        };
};

2.2 Análisis de problemas y causas del test_fw.c original

2.2.1 Problemas con el test_fw.c original

Después de agregar el atributo de reinicio al árbol de dispositivos correspondiente a test_fw.c, la función de sonda del controlador test_fw.c comenzó a no ejecutarse y parecía que no se llamaba a todo el controlador del dispositivo.
Se puede confirmar que el makefile, Kconfig y defconfig correspondientes a test_fw.c han agregado las opciones de configuración correspondientes normalmente y el controlador correspondiente a test_fw.c estaba funcionando bien.
Al mismo tiempo, si se comenta el atributo de reinicio, el controlador volverá a funcionar bien.

2.2.2 Análisis de las causas de los problemas en el test_fw.c original

Dado que agregar el controlador de dispositivo de atributo de reinicio causará una excepción de carga y comentar el controlador de atributo de reinicio se ejecutará correctamente, entonces podemos determinar que el problema se debe a agregar el atributo de reinicio.
La causa principal de este problema es que se utiliza la configuración del nodo de reinicio de test_reset, pero el controlador correspondiente al nodo test_reset no se procesa ni carga, lo que hace que el controlador correspondiente a test_fw.c se cargue de manera anormal.

2.3 Métodos para solucionar la carga anormal del controlador correspondiente a test_fw.c

La forma de solucionar la carga anormal del controlador correspondiente a test_fw.c es agregar el controlador de dispositivo del nodo correspondiente al nodo del árbol de dispositivos test_reset. El siguiente es un ejemplo del código esquemático correspondiente.

2.3.1 Agregue el archivo del controlador test_reset.c correspondiente

// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>

#include <linux/io.h>
#include <linux/device.h>

/**
 * test_reset_probe - probe routine of the driver
 * @pdev: pointer to Platform device handle
 *
 * Return zero for success and non-zero for failure
 */
static int test_reset_probe(struct platform_device *pdev)
{
    
    
        return 0;
}

/**
 * test_reset_remove - set driver_data of the device to NULL
 * @pdev: pointer to platform device handle
 *
 * Always returns 0
 */
static int test_reset_remove(struct platform_device *pdev)
{
    
    
        return 0;
}

static const struct of_device_id test_reset_match[] = {
    
    
        {
    
     .compatible = "test,scmi-reset", },
        {
    
    },
};
MODULE_DEVICE_TABLE(of, test_reset_match);

static struct platform_driver test_reset_driver = {
    
    
        .driver = {
    
    
                .name           = "test_reset",
                .of_match_table = test_reset_match,
        },
        .probe  = test_reset_probe,
        .remove = test_reset_remove,
};
module_platform_driver(test_reset_driver);

MODULE_AUTHOR("W Test <[email protected]>");
MODULE_DESCRIPTION("TEST RESET driver");
MODULE_LICENSE("GPL V2");

2.3.2 Makefile agrega soporte para test_reset.c

obj-$(CONFIG_TEST_RESET)    += test_reset.o

2.3.3 Kconfig agrega soporte para la función test_reset

config TEST_RESET
        tristate "test reset on Test Platform"
        help
          This option enables support for the TEST RESET

          You may select when support test reset. To compile this as a module
          choose M.

          If unsure, say N.

2.3.4 El archivo Defconfig agrega soporte para la función test_reset

CONFIG_TEST_RESET=y

3 Resumen de este número

3.1 Se deben considerar varios puntos al agregar un nuevo controlador de dispositivo Linux

Insertar descripción de la imagen aquí

3.2 Procesamiento de agregar nuevos atributos a los nodos del árbol de dispositivos

  • Si los atributos del dispositivo recién agregados necesitan realizar funciones específicas, debe agregar el controlador de dispositivo correspondiente de acuerdo con el Capítulo 3.1.
  • Si no es necesario, simplemente analice los atributos del dispositivo correspondientes directamente en el proceso de inicialización del controlador del dispositivo original.

Supongo que te gusta

Origin blog.csdn.net/u014100559/article/details/132865277
Recomendado
Clasificación