0nism

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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一份,然后可做任意修改。

posted on 2020-02-28 22:09  0nism  阅读(341)  评论(0编辑  收藏  举报