Lendo e alterando as variáveis do U-Boot no Linux
- por Sergio Prado
O U-Boot possui uma ferramenta chamada fw_printenv que possibilita ler e alterar suas variáveis dentro do terminal de um sistema Linux.
Esta ferramenta pode ser compilada processando o target env no código-fonte do U-Boot:
$ make CROSS_COMPILE=arm-linux-gnueabi- -j8 env |
O binário será compilado no diretório tools/env/:
$ ls tools/env/fw_printenv tools/env/fw_printenv |
Então é só instalar o binário no target. É necessário criar também um link simbólico para este binário chamado fw_setenv, que será usado para criar ou alterar as variáveis do U-Boot.
Opcionalmente, também é possível compilar esta ferramenta através do Buildroot. Basta selecionar as opções abaixo:
Target packages ---> Hardware handling ---> [*] u-boot tools [*] fw_printenv (NEW) |
Depois de instalar a ferramenta, é necessário criar um arquivo de configuração com as informações sobre a localização das variáveis, incluindo o tipo do dispositivo de armazenamento (memória flash, cartão SD, etc), o endereço inicial das variáveis no dispositivo e o tamanho da região alocada para armazená-las.
Estas informações podem ser obtidas no código-fonte do U-Boot, através de algumas constantes definidas no arquivo de configuração da placa. Veja por exemplo a configuração da Wandboard:
$ cat include/configs/wandboard.h [...] #define CONFIG_ENV_IS_IN_MMC #define CONFIG_ENV_SIZE (8 * 1024) #define CONFIG_ENV_OFFSET (6 * 64 * 1024) [...] |
Então é só criar o arquivo de configuração em /etc/fw_env.config com estas informações:
# Configuration file for fw_(printenv/setenv) utility. # Up to two entries are valid, in this case the redundant # environment sector is assumed present. # Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash. # Futhermore, if the Flash sector size is ommitted, this value is assumed to # be the same as the Environment size, which is valid for NOR and SPI-dataflash # NOR example # MTD device name Device offset Env. size Flash sector size Number of sectors #/dev/mtd1 0x0000 0x4000 0x4000 #/dev/mtd2 0x0000 0x4000 0x4000 # MTD SPI-dataflash example # MTD device name Device offset Env. size Flash sector size Number of sectors #/dev/mtd5 0x4200 0x4200 #/dev/mtd6 0x4200 0x4200 # NAND example #/dev/mtd0 0x4000 0x4000 0x20000 2 # Block device example /dev/mmcblk0 0x60000 0x2000 |
Com o arquivo configurado, é só usar a ferramenta.
As variáveis existentes podem ser exibidas com o comando fw_printenv:
# fw_printenv baudrate=115200 boot_fdt=try bootargs=console=ttymxc0,115200n8 video=mxcfb0:dev=lcd,SEIKO-WVGA,if=RGB666,bpp=32 ip=192.168.0.2 root=/dev/nfs rw nfsroot=192.168.0.1:/opt/labs/ex/09/rootfs rootwait bootcmd=tftpboot ${loadaddr} uImage; bootm bootdelay=5 bootnfs=root=/dev/nfs rw nfsroot=192.168.0.1:/opt/labs/ex/09/rootfs rootwait bootscript=echo Running bootscript from mmc ...; source console=ttymxc0 consolecfg=console=ttymxc0,115200n8 [...] |
O comando fw_setenv permite criar ou alterar uma variável:
# fw_setenv bootdelay 2 |
Upgrade de firmware é um caso de uso interessante para estes comandos. Imagine um sistema com duas partições, uma para o sistema e outra para upgrade do firmware. Durante o funcionamento do sistema, você pode baixar e gravar uma nova versão do firmware na partição de upgrade, e usar esta ferramenta para mudar as variáveis do U-Boot que controlam o processo de boot, forçando o boot pela partição de upgrade quando o sistema for reiniciado.
Have fun!
Sergio Prado