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
- 1 información del controlador de dispositivo sin formato de Linux
- 2 Controlador de dispositivo Linux modificado
- 3 Resumen de este número
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
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.