準備工作:
1.搭建adbwireless 環境
參考:https://blog.csdn.net/Chhjnavy/article/details/97643584
https://blog.csdn.net/Chhjnavy/article/details/98845930
目標板:rk3288 android
編譯環境:android7.1.2
編譯路徑:源碼根目錄u-boot/ 以及 /u-boot/tools/env
2.產生fw_printenv 執行文件並下載到目標版中
1)u-boot/目錄下make env 可能會出錯如下:
解決辦法:添加交叉編譯工具: make CROSS_COMPILE=arm-linux-gnueabihf- env
編譯通過後,產生fw_printenv 以及fw_env.config 文件。
2)根據目標版屬性修改fw_env.config 文件
fw_env.config 文件如下:
# 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 not required 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/block/mmcblk0 0xc0000 0x20000
通過目標版終端查詢:使用的是 /dev/block/mmcblk0 ,因此在fw_env.config 文件中將開啓Block device
該文件對應的設備一定要修改對,否則會出現:Cannot access MTD device /dev/mtd1: No such file or directory
3)通過adbwireless 將文件 fw_printenv 下載到目標板目錄 /system/bin 中
adb push /system/bin fw_printenv
通過adbwireless 將文件 fw_env.config 下載到目標板目錄 /etc 中
adb push /etc fw_env.config
如果出現:無權限或者只讀類似的問題請使用以前命令修正
adb root
mount -o rw,remount -t auto /
chmod 777 system
chmod 777 etc
chmod 777 fw_printenv
chmod 777 fe_env.config
在目錄/system/bin/建立軟連接:ln -s /system/bin/fw_printenv /system/bin/fw_setenv
3.重啓開機會發現目標板根目錄創建的lib(存放在fw_printenv依賴庫) 目錄消失(以rk3288 爲例解決此問題)
爲什麼消失,這裏不做介紹,應該和根文件系統有關,請自查資料。
1)目標板可以在很多目錄下創建文件重啓開機都不會消失,除了根目錄下創建的。因此j將fw_printenv 依賴的庫放入system/lib 下,修改源碼包,在文件init.rc 中添加創建符號鏈接:
源碼根目錄:out/target/product/rk3288/root/init.rc
symlink /system/lib /lib
2)改寫保存,make snod 將修改的重新編譯到.img ,燒錄SD 卡,重啓目標板,發現根目錄下已存在lib 目錄,且每次開機都存在。
3)再次更改system/lib 下fw_printenv 依賴庫 ld-linux-armhf.so.3 和 libc.so.6 的權限:
chmod 777 ld-linux-armhf.so.3
chmod 777 libc.so.6
4)再次更改system/bin下fw_printenv 和 fw_setenv 的權限:
chmod 777 fw_printenv
chmod 777 fw_setenv
5)執行./fw_printenv 打印出環境變量參數
4.在根目錄下執行 ./fw_setenv 有可能出現以下問題
1)/system/bin/sh: ./fw_printenv: No such file or directory
解決方法:在編譯環境目錄 u-boot/tools/env 執行:readelf -l fw_printenv 發現需要依賴文件 ld-linux-armhf.so.3
在 ubuntu 根目錄下搜索:find / -name ld-linux* 發現 /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3
原來 ld-linux-armhf.so.3 是指向 ld-2.15.so ,將 ld-2.15.so 拷貝出來重命名爲 ld-linux-armhf.so.3 將其下載到目標目錄/lib 下
如果沒有lib 則:mkdir lib 創建一個。
adb push ld-linux-armhf.so.3 /lib
2)/system/bin/sh: ./fw_printenv: Permission denied
解決方法:目標板/lib 下:chomd 777 ld-linux-armhf.so.3
3)在1)2)的基礎上依然發現錯誤:./fw_printenv: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
解決方法:在 ubuntu 根目錄下搜索:find / -name libc.so.6 發現 /usr/arm-linux-gnueabihf/lib/libc.so.6
原來 libc.so.6 是指向 libc-2.15.so ,將 libc-2.15.so 拷貝出來重命名爲 libc.so.6 將其下載到目標目錄/lib 下
adb push libc.so.6 /lib
並在目標板/lib 下:chomd 777 libc.so.6
4)在1)2)3)的基礎上依然發現錯誤:Error opening lock file /var/lock/fw_printenv.lock
解決方法:在目錄u-boot/env/fw_env_main.c 下將lock 部分屏蔽掉,重新make CROSS_COMPILE=arm-linux-gnueabihf- env 產生新的fw_printenv ,code 如下:
/*
* (C) Copyright 2000-2008
* Wolfgang Denk, DENX Software Engineering, [email protected].
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* Command line user interface to firmware (=U-Boot) environment.
*
* Implements:
* fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
* - prints the value of a single environment variable
* "name", the ``name=value'' pairs of one or more
* environment variables "name", or the whole
* environment if no names are specified.
* fw_setenv [ -a key ] name [ value ... ]
* - If a name without any values is given, the variable
* with this name is deleted from the environment;
* otherwise, all "value" arguments are concatenated,
* separated by single blank characters, and the
* resulting string is assigned to the environment
* variable "name"
*
* If '-a key' is specified, the env block is encrypted with AES 128 CBC.
* The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
* of AES key), eg. '-a aabbccddeeff00112233445566778899'.
*/
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/file.h>
#include <unistd.h>
#include "fw_env.h"
#define CMD_PRINTENV "fw_printenv"
#define CMD_SETENV "fw_setenv"
static struct option long_options[] = {
{"script", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
void usage(void)
{
fprintf(stderr, "fw_printenv/fw_setenv, "
"a command line interface to U-Boot environment\n\n"
"usage:\tfw_printenv [-a key] [-n] [variable name]\n"
"\tfw_setenv [-a key] [variable name] [variable value]\n"
"\tfw_setenv -s [ file ]\n"
"\tfw_setenv -s - < [ file ]\n\n"
"The file passed as argument contains only pairs "
"name / value\n"
"Example:\n"
"# Any line starting with # is treated as comment\n"
"\n"
"\t netdev eth0\n"
"\t kernel_addr 400000\n"
"\t var1\n"
"\t var2 The quick brown fox jumps over the "
"lazy dog\n"
"\n"
"A variable without value will be dropped. It is possible\n"
"to put any number of spaces between the fields, but any\n"
"space inside the value is treated as part of the value "
"itself.\n\n"
);
}
int main(int argc, char *argv[])
{
char *p;
char *cmdname = *argv;
char *script_file = NULL;
int c;
// const char *lockname = "/var/lock/" CMD_PRINTENV ".lock";
// int lockfd = -1;
int retval = EXIT_SUCCESS;
/* lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (-1 == lockfd) {
fprintf(stderr, "Error opening lock file %s\n", lockname);
return EXIT_FAILURE;
}
if (-1 == flock(lockfd, LOCK_EX)) {
fprintf(stderr, "Error locking file %s\n", lockname);
close(lockfd);
return EXIT_FAILURE;
}
*/
if ((p = strrchr (cmdname, '/')) != NULL) {
cmdname = p + 1;
}
while ((c = getopt_long (argc, argv, "a:ns:h",
long_options, NULL)) != EOF) {
switch (c) {
case 'a':
/* AES key, handled later */
break;
case 'n':
/* handled in fw_printenv */
break;
case 's':
script_file = optarg;
break;
case 'h':
usage();
goto exit;
default: /* '?' */
fprintf(stderr, "Try `%s --help' for more information."
"\n", cmdname);
retval = EXIT_FAILURE;
goto exit;
}
}
if (strcmp(cmdname, CMD_PRINTENV) == 0) {
if (fw_printenv(argc, argv) != 0)
retval = EXIT_FAILURE;
} else if (strcmp(cmdname, CMD_SETENV) == 0) {
if (!script_file) {
if (fw_setenv(argc, argv) != 0)
retval = EXIT_FAILURE;
} else {
if (fw_parse_script(script_file) != 0)
retval = EXIT_FAILURE;
}
} else {
fprintf(stderr,
"Identity crisis - may be called as `" CMD_PRINTENV
"' or as `" CMD_SETENV "' but not as `%s'\n",
cmdname);
retval = EXIT_FAILURE;
}
exit:
//flock(lockfd, LOCK_UN);
//close(lockfd);
return retval;
}
再次執行:
./fw_printenv 即可打印環境變量信息
./fw_setenv bootdelay 9 即更改環境變量