u-boot版本: v2009.08
前一片文章在分析env开机流程时默认为开机后env搬移到RAM中的情况,
此种情况会浪费一部分内存空间,在RAM吃紧时我们可以把env放到u-boot.bin
的text段中,至少flash要比RAM空间多一些。
首先需要使能如下宏:
#define CONFIG_ENV_IS_EMBEDDED 1uboot-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中。