上一篇博客我说完了那个很大的数组,然后回到了start_armboot函数,分析了一段代码,现在接着分析。
------------------------------------------------------------------------------------
/* armboot_start is defined in the board-specific linker script */
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE);
#else
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
#endif
----------------------------------------------------------
看到下面这些,就应该明白了,还和那个UBOOT内存分配映射图有关。
/*
* Begin and End of memory area for malloc(), and current "brk"
*/
static ulong mem_malloc_start = 0;
static ulong mem_malloc_end = 0;
static ulong mem_malloc_brk = 0;
static
void mem_malloc_init (ulong dest_addr)
{
mem_malloc_start = dest_addr;
mem_malloc_end = dest_addr + CFG_MALLOC_LEN;
mem_malloc_brk = mem_malloc_start;
/* memset ((void *) mem_malloc_start, 0,
mem_malloc_end - mem_malloc_start); */
}
---------------------------------------------------------------------------
#if defined(CONFIG_SMDK6400) || defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_SMDK2450) || defined(CONFIG_SMDK2416)
----------------------------------------------------------------
#if defined(CONFIG_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
------------------------------
现在我们来看下nand_init函数,如下所示:
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY)
#include <linux/mtd/nand.h>
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
---------------------------------------------------------------
struct nand_chip {
int page_shift;
u_char *data_buf;
u_char *data_cache;
int cache_page;
u_char ecc_code_buf[6];
u_char reserved[2];
char ChipID; /* Type of DiskOnChip */
struct Nand *chips;
int chipshift;
char* chips_name;
unsigned long erasesize;
unsigned long mfr; /* Flash IDs - only one type of flash per device */
unsigned long id;
char* name;
int numchips;
char page256;
char pageadrlen;
unsigned long IO_ADDR; /* address to access the 8 I/O lines to the flash device */
unsigned long totlen;
uint oobblock; /* Size of OOB blocks (e.g. 512) */
uint oobsize; /* Amount of OOB data per block (e.g. 16) */
uint eccsize;
int bus16;
};
struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
/* NAND configuration */
#define CFG_MAX_NAND_DEVICE 1
#define CFG_NAND_BASE (0x70200010)
#define NAND_MAX_CHIPS 1
---------------------------------------------------------------
void nand_init(void)
{
nand_probe(CFG_NAND_BASE); -------- 对nand芯片进行查询,得出相应信息。
if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) {
print_size(nand_dev_desc[0].totlen, "\n");
}
}
#endif
-----------------------------------------------------------------
#if defined(CONFIG_ONENAND)
puts ("OneNAND: ");
onenand_init(); /* go init the One-NAND */
#endif
----------------------------------------------------------------
#if defined(CONFIG_BOOT_MOVINAND)
puts ("SD/MMC: ");
if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {
printf("Boot up for burning\n");
} else {
movi_set_capacity();
movi_set_ofs(MOVI_TOTAL_BLKCNT);
movi_init();
}
#endif
-------------------------------------------------------------------
上面这三个的关系大家一看就明白了,我们采用的是NAND。
-------------------------------------------------------------------
#else
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
#endif
-------------------------------------------------------------------------------
#ifdef CONFIG_HAS_DATAFLASH -----这个没定义
AT91F_DataflashInit();
dataflash_print_info();
#endif
------------------------------------------------------------------------------
下面这些都有环境变量有关:
/* initialize environment */ ------初始化环境参数
env_relocate ();
--------------------------------------------------
void env_relocate (void)
{
DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
gd->reloc_off);
#ifdef CONFIG_AMIGAONEG3SE -----没定义
enable_nvram();
#endif
--------------------------------------------------------
#ifdef ENV_IS_EMBEDDED
/*
* The environment buffer is embedded with the text segment,
* just relocate the environment pointer
*/
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 (CFG_ENV_SIZE);
DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif
存储环境变量的两种方式,做不同的处理。
------------------------------------------------------------
/*
* After relocation to RAM, we can always use the "memory" functions
*/
env_get_char = env_get_char_memory;
----------------------------------------------------------
uchar (*env_get_char)(int) = env_get_char_init;
static uchar env_get_char_init (int index)
{
uchar c;
/* if crc was bad, use the default environment */
if (gd->env_valid)
{
c = env_get_char_spec(index);
} else {
c = default_environment[index];
}
return (c);
}
uchar env_get_char_memory (int index)
{
if (gd->env_valid) { -----还记得这个变量吗?我在以前的一篇博客中有说,那篇博客是确定
gd->env_valid的值,现在就用到了。
return ( *((uchar *)(gd->env_addr + index)) );
} else {
return ( default_environment[index] );
}
}
-----不太明白这种用法,有待以后查看。
----------------------------------------------------------
if (gd->env_valid == 0) { ---------还是那个变量
#if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */
puts ("Using default environment\n\n");
#else
puts ("*** Warning - bad CRC, using default environment\n\n");
SHOW_BOOT_PROGRESS (-1);
#endif
if (sizeof(default_environment) > ENV_SIZE)
{
puts ("*** Error - default environment is too large\n\n");
return;
}
memset (env_ptr, 0, sizeof(env_t));
memcpy (env_ptr->data,
default_environment,
sizeof(default_environment)); -----复制环境变量
---------------------------------------------
其中env_ptr是下面这个结构体的实例。
typedef struct environment_s {
unsigned long crc; /* CRC32 over data bytes */
#ifdef CFG_REDUNDAND_ENVIRONMENT
unsigned char flags; /* active/obsolete flags */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;
---------------------------------------------
#ifdef CFG_REDUNDAND_ENVIRONMENT ----不明白这个变量的含义
env_ptr->flags = 0xFF;
#endif
env_crc_update ();
gd->env_valid = 1;
}
else {
env_relocate_spec ();
}
gd->env_addr = (ulong)&(env_ptr->data); 上面这些很多都涉及到了gd这个变量,其实它是个结构体,用来保存信息。如下所示:
----------------------------------------
/*
* The following data structure is placed in some memory wich is
* available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
* some locked parts of the data cache) to allow for a minimum set of
* global variables during system initialization (until we have set
* up the memory controller so that we can use RAM).
*
* Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
*/
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* display type */
#endif
#if 0
unsigned long cpu_clk; /* CPU clock in Hz! */
unsigned long bus_clk;
unsigned long ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
#endif
void **jt; /* jump table */
} gd_t;
----------------------------------------
#ifdef CONFIG_AMIGAONEG3SE
disable_nvram();
#endif
}
--------------------------------------------------