u-boot环境变量
u-boot环境变量
一、环境变量
优先级
环境变量的优先级高于代码中的值。
环境变量存在形式
环境变量有三种存在形式。
- default环境变量
#if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) || defined(CONFIG_S5P6440) || defined(CONFIG_S5PC100) || defined(CONFIG_S5PC110) || defined(CONFIG_S5P6442)
uchar default_environment[CFG_ENV_SIZE] = {
#else
uchar default_environment[] = {
#endif
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS " "
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND " "
#endif
#if 0 /* for fast booting */
"verify=" MK_STR(no) " "
#endif
#ifdef CONFIG_MTDPARTITION
"mtdpart=" CONFIG_MTDPARTITION " "
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
"ramboot=" CONFIG_RAMBOOTCOMMAND " "
#endif
#ifdef CONFIG_NFSBOOTCOMMAND
"nfsboot=" CONFIG_NFSBOOTCOMMAND " "
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(CONFIG_BOOTDELAY) " "
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" MK_STR(CONFIG_BAUDRATE) " "
#endif
#ifdef CONFIG_LOADS_ECHO
"loads_echo=" MK_STR(CONFIG_LOADS_ECHO) " "
#endif
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) " "
#endif
#ifdef CONFIG_ETH1ADDR
"eth1addr=" MK_STR(CONFIG_ETH1ADDR) " "
#endif
#ifdef CONFIG_ETH2ADDR
"eth2addr=" MK_STR(CONFIG_ETH2ADDR) " "
#endif
#ifdef CONFIG_ETH3ADDR
"eth3addr=" MK_STR(CONFIG_ETH3ADDR) " "
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) " "
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) " "
#endif
#ifdef CFG_AUTOLOAD
"autoload=" CFG_AUTOLOAD " "
#endif
#ifdef CONFIG_PREBOOT
"preboot=" CONFIG_PREBOOT " "
#endif
#ifdef CONFIG_ROOTPATH
"rootpath=" MK_STR(CONFIG_ROOTPATH) " "
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) " "
#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) " "
#endif
#ifdef CONFIG_HOSTNAME
"hostname=" MK_STR(CONFIG_HOSTNAME) " "
#endif
#ifdef CONFIG_BOOTFILE
"bootfile=" MK_STR(CONFIG_BOOTFILE) " "
#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" MK_STR(CONFIG_LOADADDR) " "
#endif
#ifdef CONFIG_CLOCKS_IN_MHZ
"clocks_in_mhz=1 "
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) " "
#endif
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
" "
};
这些环境变量以字符数组的形式存在。我一开始很奇怪为什么字符数组初始化可以这样写,后来写了一个小程序验证之后发现确实如此。类似于下面的初始化方法是可行的。而C编译器会在最后一个 之后再附加一个' '字符。
unisgned chat string[] =
{
"asdzxc" " "
"zxcasd" " "
};
-
SD卡上的环境变量
存储在uboot的raw分区中。在SD卡中就是专门给了个分区。存储的时候,把DDR的数据整体写入SD卡分区中。 -
DDR上的环境变量
当uboot被copy到DDR中时,默认的环境变量就被copy进DDR的某一区域了。
利用fastboot烧录完系统后,iNand的环境变量分区仍然处于空白状态。
当第一次启动uboot时,默认的环境变量被加载进DDR中。saveenv之后DDR中的环境变量就会被保存进iNand的env分区中。第二次启动时,就可以直接读取iNand中的env。
do_printenv
printenv命令,不加参数,输出所有环境变量的值和环境变量的大小。加参数,可以输出指定环境变量的值。
/************************************************************************
* Command interface: print one or all environment variables
*/
int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i, j, k, nxt;
int rcode = 0;
/* Print all env variables */
if (argc == 1) {
for (i=0; env_get_char(i) != ' '; i=nxt+1) {
for (nxt=i; env_get_char(nxt) != ' '; ++nxt)
;
for (k=i; k<nxt; ++k)
putc(env_get_char(k));
putc ('
');
if (ctrlc()) {
puts ("
** Abort
");
return 1;
}
}
printf("
Environment size: %d/%ld bytes
",
i, (ulong)ENV_SIZE);
return 0;
}
/* print single env variables */
for (i=1; i<argc; ++i) {
char *name = argv[i];
k = -1;
for (j=0; env_get_char(j) != ' '; j=nxt+1) {
for (nxt=j; env_get_char(nxt) != ' '; ++nxt)
;
k = envmatch((uchar *)name, j);
if (k < 0) {
continue;
}
puts (name);
putc ('=');
while (k < nxt)
putc(env_get_char(k++));
putc ('
');
break;
}
if (k < 0) {
printf ("## Error: "%s" not defined
", name);
rcode ++;
}
}
return rcode;
}
do_setenv
有些环境变量比较特殊,需要特殊处理。
比如网卡地址和串口信息一次启动只能设置一次;version是只读的;波特率的变化需要确认该波特率可用,然后更新global_data
;env分区溢出处理等。
do_svaeenv
实际使用的save命令与x210_sd.h
中的配置相同,为CFG_ENV_IS_IN_AUTO
,可以判断使用的为env_auto.c
中的该函数。
该文件中的函数利用OMpin引脚了解到启动介质,自动进行save操作。
真正执行保存环境变量操作的是cpu/s5pc11x/movi.c
中的movi_write_env
函数。再向下就是uboot驱动层了。
do_getenv
该函数有两个版本。一个是可重入的,另一个是不可重入的。
不可重入版本只需要将环境变量从DDR中遍历找出相应字符串即可。
可重入版本将该字符串copy一份,然后可做任意修改。