三星uboot1.1.6源码分析——start.s(12)--C语言部分(6)

来源:互联网 发布:xp添加网络win7打印机 编辑:程序博客网 时间:2024/04/30 11:58

上一篇博客我说完了那个很大的数组,然后回到了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是下面这个结构体的实例。

typedefstruct 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 structglobal_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
}

--------------------------------------------------