uboot-----borad.c .

来源:互联网 发布:如何检测域名被墙 编辑:程序博客网 时间:2024/05/22 10:32

http://blog.csdn.net/en_wang/article/details/7163193

 

程序流程:

start_armboot,进入bord.c,

 

init_fnc_t **init_fnc_ptr;
char *s;

 

typedef int (init_fnc_t) (void);

 

#ifndef CFG_NO_FLASH
ulong size;
#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif

 

#define CFG_NO_FLASH  1  /* There is no FLASH memory */

#define CONFIG_VFD  1 /* VFD linear frame buffer driver */

#define CONFIG_LCD  1 /* use LCD controller ... */

 

#if defined(CONFIG_BOOT_MOVINAND)
uint *magic = (uint *) (PHYS_SDRAM_1);
#endif

 

CONFIG_BOOT_MOVINAND:

#define PHYS_SDRAM_1  0xc0000000 /* SDRAM Bank #1 */

 

/* Pointer is writable since we allocated a register for it */
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
ulong gd_base;

gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
#ifdef CONFIG_USE_IRQ
gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
#endif
gd = (gd_t*)gd_base;
#else
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
#endif

 

#define CONFIG_MEMORY_UPPER_CODE

#define CFG_UBOOT_BASE  0xc7e00000      //针对smdk6410,不同芯片对应不同地址

#define CFG_UBOOT_SIZE  (2*1024*1024)    ///* total memory required by uboot */
#define CFG_MALLOC_LEN  (CFG_ENV_SIZE + 128*1024)  //size of malloc() pool

#  ifndef  CFG_ENV_SIZE
#   define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
#  endif

#define CFG_STACK_SIZE  512*1024            //6410

typedef struct global_data {
bd_t  *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long cpu_clk; /* CPU clock in Hz!  */
unsigned long have_console; /* serial_init() was called */
unsigned long ram_size; /* RAM size */
unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address  of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid */
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
unsigned long post_log_word; /* Record POST activities */
unsigned long post_init_f_time; /* When post_init_f started */
#endif
void  **jt;  /* Standalone app jump table */
} gd_t;

 

/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");

 

1.内存屏障(memory barrier)
  #define set_mb(var, value) do { var = value; mb(); } while (0)
  #define mb() __asm__ __volatile__ ("" : : : "memory")

1)set_mb(),mb(),barrier()函数追踪到底,就是__asm__ __volatile__("":::"memory"),而这行代码就是内存屏障。
2)__asm__用于指示编译器在此插入汇编语句
3)__volatile__用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。即:原原本本按原来的样子处理这这里的汇编。
4) memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。
5)"":::表示这是个空指令。barrier()不用在此插入一条串行化汇编指令。在后文将讨论什么叫串行化指令。
6)__asm__,__volatile__,memory在前面已经解释

 

memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));

 

typedef struct bd_info {
int bi_baudrate;  /* serial console baudrate */
unsigned long bi_ip_addr; /* IP Address */
unsigned char bi_enetaddr[6]; /* Ethernet adress */
unsigned long bi_arch_number; /* unique id for this board */
unsigned long bi_boot_params; /* where this board expects params */
unsigned long bi_memstart; /* start of DRAM memory */
unsigned long bi_memsize; /* size  of DRAM memory in bytes */
unsigned long bi_flashstart; /* start of FLASH memory */
unsigned long bi_flashsize; /* size  of FLASH memory */
unsigned long bi_flashoffset; /* reserved area for startup monitor */
} bd_t;

 

monitor_flash_len = _bss_start - _armboot_start;

 

 

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
  if ((*init_fnc_ptr)() != 0) {
   hang ();
  }

 

init_fnc_t *init_sequence[] = {
cpu_init,  /* basic cpu dependent setup */
board_init,  /* basic board dependent setup */
interrupt_init,  /* set up exceptions */
env_init,  /* initialize environment */
init_baudrate,  /* initialze baudrate settings */
serial_init,  /* serial communications setup */
console_init_f,  /* stage 1 init of console */
display_banner,  /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo,  /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard,  /* display board info */
#endif
dram_init,  /* configure available RAM banks */
display_dram_config,
NULL,
};

 

#ifndef CFG_NO_FLASH
/* configure available FLASH banks */
size = flash_init ();
display_flash_config (size);
#endif /* CFG_NO_FLASH */

 

ulong flash_init (void)
{
int i, j;
ulong size = 0;

for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
  ulong flashbase = 0;

  flash_info[i].flash_id =
#if defined(CONFIG_AMD_LV400)
   (AMD_MANUFACT & FLASH_VENDMASK) |
   (AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
   (AMD_MANUFACT & FLASH_VENDMASK) |
   (AMD_ID_LV800B & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif
   flash_info[i].size = FLASH_BANK_SIZE;
  flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
  memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
  if (i == 0)
   flashbase = PHYS_FLASH_1;
  else
   panic ("configured too many flash banks!\n");
  for (j = 0; j < flash_info[i].sector_count; j++) {
   if (j <= 3) {
    /* 1st one is 16 KB */
    if (j == 0) {
     flash_info[i].start[j] =
      flashbase + 0;
    }

    /* 2nd and 3rd are both 8 KB */
    if ((j == 1) || (j == 2)) {
     flash_info[i].start[j] =
      flashbase + 0x4000 + (j -
              1) *
      0x2000;
    }

    /* 4th 32 KB */
    if (j == 3) {
     flash_info[i].start[j] =
      flashbase + 0x8000;
    }
   } else {
    flash_info[i].start[j] =
     flashbase + (j - 3) * MAIN_SECT_SIZE;
   }
  }
  size += flash_info[i].size;
}

flash_protect (FLAG_PROTECT_SET,
         CFG_FLASH_BASE,
         CFG_FLASH_BASE + monitor_flash_len - 1,
         &flash_info[0]);

flash_protect (FLAG_PROTECT_SET,
         CFG_ENV_ADDR,
         CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);

return size;
}                   /////2410

#ifndef CFG_NO_FLASH
static void display_flash_config (ulong size)
{
puts ("Flash:  ");
print_size (size, "\n");
}
#endif /* CFG_NO_FLASH */

 

#ifdef CONFIG_VFD
# ifndef PAGE_SIZE
#   define PAGE_SIZE 4096
# endif
/*
  * reserve memory for VFD display (always full pages)
  */
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
size = vfd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_VFD */

 

#define CONFIG_VFD  1 /* VFD linear frame buffer driver */

addr:    #if defined(CONFIG_VFD) || defined(CONFIG_LCD)
             unsigned long addr;
             #endif

 

#ifdef CONFIG_LCD
# ifndef PAGE_SIZE
#   define PAGE_SIZE 4096
# endif
/*
  * reserve memory for LCD display (always full pages)
  */
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
size = lcd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_LCD */

 为lcd或是vfd分配显存(显存:显卡内存,也叫frame buffer)

 

/* 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

 //初始化CFG_MALLOC_LEN大小空间

 

#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

#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

#else

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND:    ");
nand_init();  /* go init the NAND */
#endif

#endif

 初始化nandflash,

 

#ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif

 

 

/* initialize environment */
env_relocate ();

 初始化环境变量参数

 

#ifdef CONFIG_VFD
/* must do this after the framebuffer is allocated */
drv_vfd_init();
#endif /* CONFIG_VFD */

 初始化显存

 

/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

/* MAC Address */
{
  int i;
  ulong reg;
  char *s, *e;
  char tmp[64];

  i = getenv_r ("ethaddr", tmp, sizeof (tmp));
  s = (i > 0) ? tmp : NULL;

  for (reg = 0; reg < 6; ++reg) {
   gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
   if (s)
    s = (*e) ? e + 1 : e;
  }

#ifdef CONFIG_HAS_ETH1
  i = getenv_r ("eth1addr", tmp, sizeof (tmp));
  s = (i > 0) ? tmp : NULL;

  for (reg = 0; reg < 6; ++reg) {
   gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
   if (s)
    s = (*e) ? e + 1 : e;
  }
#endif
}

 通过命令行参数获取IP地址,MAC地址

 

devices_init (); /* get the devices list going. */

 调用相应驱动函数对相应硬件设备进行初始化

 

 

#ifdef CONFIG_CMC_PU2
load_sernum_ethaddr ();
#endif /* CONFIG_CMC_PU2 */

 

 

jumptable_init ();

console_init_r (); /* fully init console as a device */

 初始化串口

 

#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif

 

 

/* enable exceptions */
enable_interrupts ();

 启用中断

 

 /* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_CS8900
 //cs8900_get_enetaddr (gd->bd->bi_enetaddr);
#endif

#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
if (getenv ("ethaddr")) {
  smc_set_mac_addr(gd->bd->bi_enetaddr);
}
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */

 初始化网卡

 

 /* Initialize from environment */
 if ((s = getenv ("loadaddr")) != NULL) {
  load_addr = simple_strtoul (s, NULL, 16);
 }

 

 

#if (CONFIG_COMMANDS & CFG_CMD_NET)
 if ((s = getenv ("bootfile")) != NULL) {
  copy_filename (BootFile, s, sizeof (BootFile));
 }
#endif /* CFG_CMD_NET */

 

 

#ifdef BOARD_LATE_INIT
 board_late_init ();
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
 puts ("Net:     ");
#endif
 eth_initialize(gd->bd);
#endif
 /* main_loop() can return to retry autoboot, if so just run it again. */
 for (;;) {
  main_loop ();
 }

 /* NOTREACHED - no way out of command loop except booting */