【linux 系统下fw_printenv查看/fw_setenv设置env】

1. 概述

在uboot中我们可以很方便的在uboot shell中通过printenv/setenv/savenv来查看/设置/保存env环境变量或者在uboot源码中通过env_get/env_set/env_save 来获取/设置/保存env环境变量。有时候我们希望在进入linux系统后去查看或者修改env环境变量,那么在Linux系统下是否有工具去做这样的事情吗或者Linux kernel是否提供什么方式可以做这样的事情呢。幸运的是uboot仓库下提供了fw_printenv工具可以做上面提到的查看/修改/设置保存env环境的事情。

2. fw_printenv源码

fw_printenv源码位于uboot仓库,uboot源码可以从github中获取GitHub - u-boot/u-boot: "Das U-Boot" Source Tree 。

fw_printenv在uboot中的路径:uboot/tools/env

3. fw_printenv编译

arm:

1. make A10-OLinuXino-Lime_defconfig

2.   

        a. dynamically linked:

                make CROSS_COMPILE=arm-linux-gnueabihf- envtools 

        b.  statically linked

                make CROSS_COMPILE=arm-linux-gnueabihf- CC="arm-linux-gnueabihf-gcc -static" envtools

arm64:

1. make A10-OLinuXino-Lime_defconfig

2. 

        a. dynamically linked:

                make CROSS_COMPILE=aarch64-linux-gnu- envtools

         b.  statically linked

                make CROSS_COMPILE=aarch64-linux-gnu- CC="aarch64-linux-gnu-gcc -static" envtools

  4.  fw_printenv使用

          1.  在uboot/tools/env/fw_env.config中按照例子格式添加自己的设备描述,把其他不需要的屏蔽掉。

        2. 把修改好的fw_env.config放到系统的/etc/下

        3. 建立fw_setenv软链接ln -s /bin/fw_printenv /bin/fw_setenv 

4.1. show env

fw_printenv // show all env items

 fw_printenv XXX // show "XXX" the one env item     

4.2. set env

fw_setenv foo bar // set variable foo equal bar

fw_setenv foo  // clear variable foo

fw_setenv --script file run batch script

5. 代码分析

5.1. 入口

//tools/env/fw_env_main.c
207 int main(int argc, char *argv[])
208 {
209     char *lockname = "/run/" CMD_PRINTENV ".lock";
210     int lockfd = -1;
211     int retval = EXIT_SUCCESS;
212     char *_cmdname;
213
214     _cmdname = *argv;
215     if (strrchr(_cmdname, '/') != NULL)
216         _cmdname = strrchr(_cmdname, '/') + 1; // get the basename from path
217
218     // confirm the command is "fw_printenv" or "fw_setenv"
219     if (strcmp(_cmdname, CMD_PRINTENV) == 0) {
220         do_printenv = 1;
221     } else if (strcmp(_cmdname, CMD_SETENV) == 0) {
222         do_printenv = 0;
223     } else {
224         fprintf(stderr,
225             "Identity crisis - may be called as `%s' or as `%s' but not as `%s'\n",
226             CMD_PRINTENV, CMD_SETENV, _cmdname);
227         exit(EXIT_FAILURE);
228     }
229
230     /* the parameters is different between "fw_printenv" with "fw_setenv".
231      * parse_printenv_args() for "fw_printenv" nand parse_setenv_args for
232      * "fw_setenv". */
233     if (do_printenv) {
234         if (parse_printenv_args(argc, argv))
235             exit(EXIT_FAILURE);
236     } else {
237         if (parse_setenv_args(argc, argv))
238             exit(EXIT_FAILURE);
239     }
240
241     /* shift parsed flags, jump to non-option arguments */
242     argc -= optind;
243     argv += optind;

5.2. 参数

fw_printenv与fw_setenv参数的差异

parametercommentfw_printenvfw_setenv
h帮助信息
n相同的变量不重复展示
s批量变量
v打印U-boot版本号
c

指定配置信息的脚本,默认是

/etc/fw_env.config

l指定锁
// tools/env/fw_env_main.c
115 static void parse_common_args(int argc, char *argv[])
116 {
117     int c;
118
119     // "/etc/fw_env.config" is default CONFIG_FILE, if no specify
120 #ifdef CONFIG_FILE
121     env_opts.config_file = CONFIG_FILE;
122 #endif
123
124     while ((c = getopt_long(argc, argv, ":a:c:l:h:v", long_options, NULL)) !=
125            EOF) {
126         switch (c) {
127 #ifdef CONFIG_FILE
128         case 'c': // specify config file
129             env_opts.config_file = optarg;
130             break;
131 #endif
132         case 'l': // specify lock
133             env_opts.lockname = optarg;
134             break;
135         case 'h': // help
136             do_printenv ? usage_printenv() : usage_env_set();
137             exit(EXIT_SUCCESS);
138             break;
139         case 'v': // display U-boot version
140             fprintf(stderr, "Compiled with " U_BOOT_VERSION "\n");
141             exit(EXIT_SUCCESS);
142             break;
143         default:
144             /* ignore unknown options */
145             break;
146         }
147     }
148
149     /* Reset getopt for the next pass. */
150     opterr = 1;
151     optind = 1;
152 }
154 int parse_printenv_args(int argc, char *argv[])
155 {
156     int c;
157
158     parse_common_args(argc, argv);
159
160     while ((c = getopt_long(argc, argv, "a:c:ns:l:h:v", long_options, NULL))
161         != EOF) {
162         switch (c) {
163         case 'n': // do not repeat variable name in output
164             noheader = 1;
165             break;
166         case 'a':
167         case 'c':
168         case 'h':
169         case 'l':
170             /* ignore common options */
171             break;
172         default: /* '?' */
173             usage_printenv();
174             exit(EXIT_FAILURE);
175             break;
176         }
177     }
178     return 0;
179 }
181 int parse_setenv_args(int argc, char *argv[])
182 {
183     int c;
184
185     parse_common_args(argc, argv);
186
187     while ((c = getopt_long(argc, argv, "a:c:ns:l:h:v", long_options, NULL))
188         != EOF) {
189         switch (c) {
190         case 's': // specify the script_file for batch mode to minimize writes
191             script_file = optarg;
192             break;
193         case 'a':
194         case 'c':
195         case 'h':
196         case 'l':
197             /* ignore common options */
198             break;
199         default: /* '?' */
200             usage_env_set();
201             exit(EXIT_FAILURE);
202             break;
203         }
204     }
205     return 0;
206 }

5.3. 配置文件fw_env.config

格式:

dev_name  device_offset env_size  device_erase_size  env_sectors

注:如果env_secotrs不配置,那么默认它等于env_size / dev_erase_size.

对于字符设备支持NOR,SLCNAND,DATAFLASH,UBI类型的MTD设备。

对于块设备类型的设备,device_offset可以配置为负数,表示距设备结尾XX的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值