[IMX6Q]u-boot环境变量存储到.text段

时间:2022-02-15 20:38:58

u-boot版本: v2009.08


前一片文章在分析env开机流程时默认为开机后env搬移到RAM中的情况,

此种情况会浪费一部分内存空间,在RAM吃紧时我们可以把env放到u-boot.bin

的text段中,至少flash要比RAM空间多一些。


首先需要使能如下宏:

#define CONFIG_ENV_IS_EMBEDDED 1
uboot-imx/include/environment.h

# ifdef CONFIG_ENV_IS_EMBEDDED
#  define ENV_IS_EMBEDDED	1
# endif
这样开机流程和上一篇文章不一样了
void env_relocate (void)
{
......

#ifdef ENV_IS_EMBEDDED
	/*
	 * The environment buffer is embedded with the text segment,
	 * just relocate the environment pointer
	 */
	/*定义了之后跑到了这里,取env_ptr后的reloc_off偏移*/
	env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
	DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#else
	/*
	 * We must allocate a buffer for the environment
	 */
	env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE);
	DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif
......
}
env_ptr:

uboot-imx/common/env_mmc.c

#ifdef ENV_IS_EMBEDDED
extern uchar environment[];
env_t *env_ptr = (env_t *)(&environment[0]);
#else /* ! ENV_IS_EMBEDDED */
env_t *env_ptr;
#endif /* ENV_IS_EMBEDDED */
environment:

uboot-imx/common/env_embedded.c

env_t environment __PPCENV__ = {
	ENV_CRC,	/* CRC Sum */
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
	1,		/* Flags: valid */
#endif
	{
#if defined(CONFIG_BOOTARGS)
	"bootargs="	CONFIG_BOOTARGS			"\0"
#endif
#if defined(CONFIG_BOOTCOMMAND)
	"bootcmd="	CONFIG_BOOTCOMMAND		"\0"
#endif
#if defined(CONFIG_RAMBOOTCOMMAND)
	"ramboot="	CONFIG_RAMBOOTCOMMAND		"\0"
#endif
#if defined(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_ETH4ADDR
	"eth4addr="	MK_STR(CONFIG_ETH4ADDR)		"\0"
#endif
#ifdef	CONFIG_ETH5ADDR
	"eth5addr="	MK_STR(CONFIG_ETH5ADDR)		"\0"
#endif
#ifdef	CONFIG_ETHPRIME
	"ethprime="	CONFIG_ETHPRIME			"\0"
#endif
#ifdef	CONFIG_IPADDR
	"ipaddr="	MK_STR(CONFIG_IPADDR)		"\0"
#endif
#ifdef	CONFIG_SERVERIP
	"serverip="	MK_STR(CONFIG_SERVERIP)		"\0"
#endif
#ifdef	CONFIG_SYS_AUTOLOAD
	"autoload="	CONFIG_SYS_AUTOLOAD			"\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_PREBOOT
	"preboot="	CONFIG_PREBOOT			"\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"		/* Term. env_t.data with 2 NULs */
	}
};
__PPCENV__是什么呢?

#  define __PPCENV__ __attribute__ ((section(".text")))
也就是说此environment是被放在了.text段了。

那么它是被放在了u-boot.bin的哪个位置呢?

env_embedded.c有一行:

GEN_ABS(env_offset, CONFIG_ENV_OFFSET);
GEN_ABS的宏定义:

#if defined(__bfin__)
# define GEN_SET_VALUE(name, value) asm (".set " GEN_SYMNAME(name) ", " GEN_VALUE(value))
#else
# define GEN_SET_VALUE(name, value) asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
#endif
#define GEN_SYMNAME(str) SYM_CHAR #str
#define GEN_VALUE(str) #str
#define GEN_ABS(name, value) \
		asm (".globl " GEN_SYMNAME(name)); \
		GEN_SET_VALUE(name, value)
相当于定义env_offset的值为CONFIG_ENV_OFFSET

那么编译链接的时候是如何被用到的呢?

uboot-imx/board/freescale/mx6q_sabresd/u-boot.lds

	  . = DEFINED(env_offset) ? env_offset : .;
	  common/env_embedded.o(.text)
如果env_offset有定义,就定义当前的位置为env_offset开始存放env_embedded.c的.text段。

也就是偏移CONFIG_ENV_OFFSET。

#define CONFIG_ENV_OFFSET       (768 * 1024)
看u-boot.map

 common/env_embedded.o(.text)
 .text          0x00000000278c0000     0x2004 common/env_embedded.o
                0x00000000278c0000                env_size
                0x00000000278c0004                environment
确实是被放到了768k的地方,当然你也可以修改offset的值。


这样env就被存放到了u-boot的.text段,并且开机加载的时候直接使用它,而不会搬移到RAM中。