什么公司可以做网站,做音乐创作的网站,经营网站建设,南通通州区城乡建设局网站以下内容源于朱有鹏嵌入式课程的学习#xff0c;如有侵权#xff0c;请告知删除。
参考资料#xff1a;http://www.cnblogs.com/biaohc/p/6398515.html。 一、uboot的环境变量基础
1、环境变量的作用
在不改变源码、不用重新编译的情况下#xff0c;可以通过设置环境变量…以下内容源于朱有鹏嵌入式课程的学习如有侵权请告知删除。
参考资料http://www.cnblogs.com/biaohc/p/6398515.html。 一、uboot的环境变量基础
1、环境变量的作用
在不改变源码、不用重新编译的情况下可以通过设置环境变量的值来改变uboot的一些设置如bootdelay时间、机器码的值等等。
2、环境变量的优先级
1uboot代码当中有一个值SD卡中环境变量分区也有一个值。
uboot程序实际运行时规则是如果环境变量分区为空则使用uboot代码中的值如果环境变量分区不为空则优先使用环境变量分区对应的值。
2譬如machid机器码。
uboot中在x210_sd.h中定义了一个机器码2456写死在程序中的不能更改如果要修改则要重新编译烧录SD卡的环境变量分区中也有machid由于SD卡的环境变量分区中也有machid系统启动时会优先使用环境变量的machid这就是优先级问题。
3、环境变量在uboot中工作方式
1默认环境变量
在uboot/common/env_common.c的default_environment中本质是一个字符数组大小为CFG_ENV_SIZE16kb很多个环境变量连续分布组成的每个环境变量最末端以\0结束。
2SD卡中环境变量分区
在uboot的raw分区中SD卡中有专门的分区用来存储存储时把DDR中的环境变量整体写入SD卡的环境变量分区。因此saveenv时是所有的环境变量都被保存了一遍而不是只保存更改了的。
3DDR中环境变量
在default_environment中实质是字符数组。在uboot中其实是一个全局变量链接时在数据段重定位时default_environment就被重定位到DDR中一个内存地址处了。这个地址处的这个全局字符数组就是uboot运行时的DDR中的环境变量。
4总结
SD卡的环境变量分区一开始是空白的uboot第一次运行时加载的是uboot代码中的那份环境变量叫默认环境变量。在saveenv时DDR中的环境变量会被更新到SD卡的环境变量分区中。下次开机在环境变量relocate时会将SD卡中的环境变量加载到DDR中去。default_environment中的内容虽然被uboot源代码初始化为一定的值但是在env_relocate时代码会把环境变量从SD卡中拷贝到内存中然后去判断SD卡中的env分区的crc是否通过如果不通过则使用default_environment字符数组通过了使用SD卡内的环境变量。
4、环境变量的初始化
1没有初始化flash设备前进行环境变量初级初始化
函数env_init定义在commen/env_movi.c中把gd全局变量中的 env_valid 1 env_addr 全局变量default_enviroment数组的首地址。 2初始化flash设备之后 初始化flash后进行环境变量的重定位工作即把环境变量从flash中copy到内存中用一个全局变量env_ptr指向这段内存复制是通过movi_read_env这个函数实现的实际就是把sd卡中环境变量分区全部复制到env_ptr指向的这段内存中然后在对这段内存中的环境变量进行crc校验如果失败的话则把default_enviroment中的环境变量复制到这里。env_ptr (env_t *)malloc (CFG_ENV_SIZE); 这句代码作用是给uboot环境变量开辟一块16k大小的内存env_relocate_spec ();这句代码的作用是把sd卡中的uboot环境变量整个分区复制到开辟的这个内存地址处见博客http://blog.csdn.net/oqqhutu12345678/article/details/69365347的四2。
代码跟踪env_relocate_spec ()函数 输出*** Warning - bad CRC or moviNAND, using default environment:清0环境变量内存把default_environment中的值复制到环境变量内存计算crc写入内存中的crc位设置gd中的env_valid为1 二、环境变量相关命令源码解析举例
1、printenv实现函数为do_printfenv do_printenv函数首先区分是否argc1若argc1则循环打印所有的环境变量出来否则后面的参数就是要打印的环境变量给哪个就打印哪个。argc1时用双重for循环来依次处理所有的环境变量的打印。第一重for循环就是处理各个环境变量所以有多少个环境变量则第一重就执行循环多少圈。要明白整个环境变量在内存中如何存储的问题。 2、setenv命令实际调用的是_do_setenv函数
int _do_setenv (int flag, int argc, char *argv[])
{int i, len, oldval;int console -1;uchar *env, *nxt NULL;char *name;bd_t *bd gd-bd;uchar *env_data env_get_addr(0);if (!env_data) /* need copy in RAM */return 1;name argv[1];if (strchr(name, )) {printf (## Error: illegal character in variable name \%s\\n, name);return 1;}/** search if variable with this name already exists*/oldval -1;for (envenv_data; *env; envnxt1) {for (nxtenv; *nxt; nxt);if ((oldval envmatch((uchar *)name, env-env_data)) 0)break;}/** Delete any existing definition*/if (oldval 0) {/* Check for console redirection */if (strcmp(name,stdin) 0) {console stdin;} else if (strcmp(name,stdout) 0) {console stdout;} else if (strcmp(name,stderr) 0) {console stderr;}if (console ! -1) {if (argc 3) { /* Cannot delete it! */printf(Cant delete \%s\\n, name);return 1;}/* Try assigning specified device */if (console_assign (console, argv[2]) 0)return 1;#ifdef CONFIG_SERIAL_MULTIif (serial_assign (argv[2]) 0)return 1;
#endif}/** Switch to new baudrate if new baudrate is supported*/if (strcmp(argv[1],baudrate) 0) {int baudrate simple_strtoul(argv[2], NULL, 10);int i;for (i0; iN_BAUDRATES; i) {if (baudrate baudrate_table[i])break;}if (i N_BAUDRATES) {printf (## Baudrate %d bps not supported\n,baudrate);return 1;}printf (## Switch baudrate to %d bps and press ENTER ...\n,baudrate);udelay(50000);gd-baudrate baudrate;serial_setbrg ();udelay(50000);for (;;) {if (getc() \r)break;}}if (*nxt \0) {if (env env_data) {env--;} else {*env \0;}} else {for (;;) {*env *nxt;if ((*env \0) (*nxt \0))break;env;}}*env \0;}#ifdef CONFIG_NET_MULTIif (strncmp(name, eth, 3) 0) {char *end;int num simple_strtoul(name3, end, 10);if (strcmp(end, addr) 0) {eth_set_enetaddr(num, argv[2]);}}
#endif/* Delete only ? */if ((argc 3) || argv[2] NULL) {env_crc_update ();return 0;}/** Append new definition at the end*/for (envenv_data; *env || *(env1); env);if (env env_data)env;/** Overflow when:* name val \0\0 ENV_SIZE - (env-env_data)*/len strlen(name) 2;/* add for first arg, for all others */for (i2; iargc; i) {len strlen(argv[i]) 1;}if (len (env_data[ENV_SIZE]-env)) {printf (## Error: environment overflow, \%s\ deleted\n, name);return 1;}while ((*env *name) ! \0)env;for (i2; iargc; i) {char *val argv[i];*env (i2) ? : ;while ((*env *val) ! \0);}/* end is marked with double \0 */*env \0;/* Update CRC */env_crc_update ();/** Some variables should be updated when the corresponding* entry in the enviornment is changed*/if (strcmp(argv[1],ethaddr) 0) {char *s argv[2]; /* always use only one arg */char *e;for (i0; i6; i) {bd-bi_enetaddr[i] s ? simple_strtoul(s, e, 16) : 0;if (s) s (*e) ? e1 : e;}
#ifdef CONFIG_NET_MULTIeth_set_enetaddr(0, argv[2]);
#endifreturn 0;}if (strcmp(argv[1],ipaddr) 0) {char *s argv[2]; /* always use only one arg */char *e;unsigned long addr;bd-bi_ip_addr 0;for (addr0, i0; i4; i) {ulong val s ? simple_strtoul(s, e, 10) : 0;addr 8;addr | (val 0xFF);if (s) s (*e) ? e1 : e;}bd-bi_ip_addr htonl(addr);return 0;}if (strcmp(argv[1],loadaddr) 0) {load_addr simple_strtoul(argv[2], NULL, 16);return 0;}
#if defined(CONFIG_CMD_NET)if (strcmp(argv[1],bootfile) 0) {copy_filename (BootFile, argv[2], sizeof(BootFile));return 0;}
#endif#ifdef CONFIG_AMIGAONEG3SEif (strcmp(argv[1], vga_fg_color) 0 ||strcmp(argv[1], vga_bg_color) 0 ) {extern void video_set_color(unsigned char attr);extern unsigned char video_get_attr(void);video_set_color(video_get_attr());return 0;}
#endif /* CONFIG_AMIGAONEG3SE */return 0;
}