ARM Linux y UBoot: ¿puedo hacer que un MTD de solo lectura sea grabable?

Tengo varios dispositivos Linux integrados instalados en los sitios de los clientes. Tenemos un kernel de Linux actualizado que estamos preparados para implementar en estos dispositivos. El problema es que en estos dispositivos, los argumentos de U-Boot se especifican de manera que:


bootargs = {....} mtdparts=atmel_nand:16M(kernel)ro,240M(rootfs)

Por lo tanto, no puedo flash_erase para escribir nand en el kernel o U-Boot sobre SSH porque MTD0 es de solo lectura. No puedo modificar los argumentos de U-Boot sin acceso en serie. Para muchos de los clientes, desarmar todos los dispositivos y conectarlos en serie e interrumpir el U-Boot para llegar a los bootargs sería extremadamente engorroso. ¿Hay alguna forma de cambiar MTD0 de ro a rw desde el kernel una vez que se carga?

Otra opción podría ser ver si su sistema admitiría el uso de kexec mientras se ejecuta para iniciar un nuevo kernel con una línea de comando o configuración diferente.
@ChrisStratton Esa fue una idea increíble, pero lamentablemente no está implementada en ese kernel. Sin embargo, definitivamente estoy buscando compilar kexec de forma cruzada y distribuirlo con la actualización, dependiendo de cuánto esté involucrado allí.
@ChrisStratton: no he podido hacer que kexec funcione; no está integrado en el kernel que estoy tratando de actualizar, logré crear herramientas de kexec, pero evidentemente eso es solo para trabajar con kexec si está instalado, pero supuestamente uno puede ejecutar kexec desde un binario frente a un módulo/incorporado. ¿Sabes algo de eso?

Respuestas (3)

¿Ha considerado crear un módulo kernel simple que pueda insertar para hacer que las particiones MTD se puedan escribir? Tuve este mismo problema y pude solucionarlo escribiendo un módulo del kernel. Para simplificar, seguí adelante e hice que todos los dispositivos MTD tuvieran capacidad de escritura. Básicamente, el módulo tiene que hacer algo como esto en su función de inicio:

struct mtd_info *mtd;
int x;
bool keep_going = true;

for (x = 0; keep_going; x++) {
    mtd = get_mtd_device(NULL, x);
    if (!IS_ERR(mtd)) {
        mtd->flags |= MTD_WRITEABLE;
        put_mtd_device(mtd);
    } else {
        keep_going = false;
    }
}

Después de insertar este módulo, pude usar flash_erase y nandwrite con éxito mientras arrancaba en el kernel, mientras que antes, flash_erase me decía: "error 13 (Permiso denegado)"

Aquí hay un módulo de kernel para hacer precisamente eso: github.com/mwarning/mtdRW
Otra opción, si puede modificar el kernel, es exponer el MTD_WRITEABLEindicador a través de sysfs en mtdcore.c. De esa manera, puede alternarlo según sea necesario para mantener el dispositivo MTD protegido contra escritura.

Otra opción es usar la fw_setenvutilidad (construida con u-boot) para modificar las variables de entorno guardadas de u-boot desde dentro de Linux. Eso requeriría un reinicio para ejecutar con el nuevo bootargs, a diferencia de cargar un módulo del kernel, pero eso es mucho menos trabajo que usar un cable serie. También es una herramienta útil para otras situaciones.

La documentación está aquí: https://elinux.org/U-boot_environment_variables_in_linux

Lo principal que debe saber es eso fw_setenvy fw_printenvusar un archivo de configuración para saber dónde u-boot almacena su entorno en un almacenamiento no volátil, y tiene que coincidir con lo que se compiló u-boot.

De hecho, esta podría ser una buena solución si U-Boot utiliza una configuración externa y si se puede escribir en el lugar donde se almacena. Sin embargo, no es raro que se use la configuración predeterminada compilada en la configuración, o que los proveedores de la plataforma pirateen el sistema de configuración configurando en lugar del código ... Pero si funciona, puede ser lo más simple. Idealmente, la configuración se volvería a configurar para que el volumen solo se lea después de que se realicen los cambios.
Eso es verdad. Las opciones disponibles son muy específicas para su dispositivo y configuración de hardware.

La solución habitual es

mount / -o remount,rw
No es el sistema de archivos el que es de solo lectura, sino la implementación de un dispositivo de bloque encima de la memoria flash.