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 "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
#if 0 /* for fast booting */
"verify=" MK_STR(no) "\0"
#endif
#ifdef CONFIG_MTDPARTITION
"mtdpart=" CONFIG_MTDPARTITION "\0"
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
"ramboot=" CONFIG_RAMBOOTCOMMAND "\0"
#endif
#ifdef CONFIG_NFSBOOTCOMMAND
"nfsboot=" CONFIG_NFSBOOTCOMMAND "\0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(CONFIG_BOOTDELAY) "\0"
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" MK_STR(CONFIG_BAUDRATE) "\0"
#endif
#ifdef CONFIG_LOADS_ECHO
"loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "\0"
#endif
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
#endif
#ifdef CONFIG_ETH1ADDR
"eth1addr=" MK_STR(CONFIG_ETH1ADDR) "\0"
#endif
#ifdef CONFIG_ETH2ADDR
"eth2addr=" MK_STR(CONFIG_ETH2ADDR) "\0"
#endif
#ifdef CONFIG_ETH3ADDR
"eth3addr=" MK_STR(CONFIG_ETH3ADDR) "\0"
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "\0"
#endif
#ifdef CFG_AUTOLOAD
"autoload=" CFG_AUTOLOAD "\0"
#endif
#ifdef CONFIG_PREBOOT
"preboot=" CONFIG_PREBOOT "\0"
#endif
#ifdef CONFIG_ROOTPATH
"rootpath=" MK_STR(CONFIG_ROOTPATH) "\0"
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) "\0"
#endif
#ifdef CONFIG_HOSTNAME
"hostname=" MK_STR(CONFIG_HOSTNAME) "\0"
#endif
#ifdef CONFIG_BOOTFILE
"bootfile=" MK_STR(CONFIG_BOOTFILE) "\0"
#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" MK_STR(CONFIG_LOADADDR) "\0"
#endif
#ifdef CONFIG_CLOCKS_IN_MHZ
"clocks_in_mhz=1\0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
#endif
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
"\0"
};
这些环境变量以字符数组的形式存在。我一开始很奇怪为什么字符数组初始化可以这样写,后来写了一个小程序验证之后发现确实如此。类似于下面的初始化方法是可行的。而C编译器会在最后一个\0之后再附加一个'\0'字符。
unisgned chat string[] =
{
"asdzxc" "\0"
"zxcasd" "\0"
};
-
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) != '\0'; i=nxt+1) {
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
;
for (k=i; k<nxt; ++k)
putc(env_get_char(k));
putc ('\n');
if (ctrlc()) {
puts ("\n ** Abort\n");
return 1;
}
}
printf("\nEnvironment size: %d/%ld bytes\n",
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) != '\0'; j=nxt+1) {
for (nxt=j; env_get_char(nxt) != '\0'; ++nxt)
;
k = envmatch((uchar *)name, j);
if (k < 0) {
continue;
}
puts (name);
putc ('=');
while (k < nxt)
putc(env_get_char(k++));
putc ('\n');
break;
}
if (k < 0) {
printf ("## Error: \"%s\" not defined\n", 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一份,然后可做任意修改。