程序流程:

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

uboot-----borad.c . .相关推荐

  1. 【整理】BIOS、BootLoader、uboot对比

    bios BIOS是英文"Basic Input Output System"的缩略语,直译过来后中文名称就是"基本输入输出系统".其实,它是一组固化到计算机内 ...

  2. 嵌入式系统UBOOT

    一个完整的嵌入式linux系统包含4部分内容:Bootloader.Parameters.Kernel.Root File System.3.4.5.6部分详细介绍了这4部分的内容,这是Linux底层 ...

  3. U-Boot源码目录分析(VScode工程创建及文件夹过滤)

    参考:U-Boot工程目录介绍 作者:一只青木呀 发布时间: 2020-10-21 14:47:30 网址:https://blog.csdn.net/weixin_45309916/article/ ...

  4. ARM Uboot经历——makefile与uboot目录

    makefile是个很复杂的东西,但是只要有耐心层层剥下,也能看到你想看到的东西.很遗憾的事,很多人都没有耐心去层层看,我也是. 对于makefile,我也仅仅从基础上了解了它在uboot中的原理和作 ...

  5. 【u-boot】uboot代码简要分析 (u-boot 移植)

    uboot代码简要分析 (u-boot 移植) 2012-12-19 22:46:04 [转] 先来看看源码目录结构,再按照代码的执行顺序简单地分析源码 1.U-boot源码整体框架 源码解压以后,我 ...

  6. Uboot代码结构详细分析

    1. Bootloader功能分析 Bootloader(如Uboot.Redboot.Blob.vivi等)直接和CPU.外围硬件设备(存储器.网卡.LCD等)打交道,负责初始化硬件设备,以及负责拉 ...

  7. Uboot 2017.01 启动流程分析

    前言 2017.01 UBoot包含两个阶段的启动,一个是SPL启动,一个是正常的启动我们称为第二阶段Uboot.当然,我们也可以选择使用SPL和不使用. 在编译的过程中,是先编译第二阶段Uboot, ...

  8. uboot start.S分析

    一.概述   1.本文综述及特色  阅读uboot,start.S是第一个源程序文件,主要完成初始化看门狗.定时器.重定位(拷贝代码段到内存中).初始化堆栈.跳转到第二阶段等工作. 网上关于这些内容的 ...

  9. uboot启动的第一阶段分析

    uboot启动的第一阶段分析 1.start.S引入,start.S在目录cpu/s5pc11x/下. (1)如何确认uboot的程序入口,那就是去分析u-boot.lds,从u-boot.lds找到 ...

  10. U-Boot启动第二阶段代码分析

    U-Boot第一阶段的启动流程.(nandflash启动,把nand的4k代码考到sram中,因为nand没址线,不能映射到内存,所以通过sram进行过度,sram中4k代码把整个uboot拷贝到sd ...

最新文章

  1. python数字类型及运算_Python基础之(基本数据类型及运算)
  2. Tomcat(四):tomcat图形管理和身份认证
  3. python如何进行双色球预测最准确_【原创】python基于大数据现实双色球预测
  4. 02 | 日志系统:一条 SQL 更新语句是如何执行的
  5. aspcms各版本漏洞0day集合
  6. Windows 7 下 Node.js 连接 Oracle
  7. python基本模块中的对象_Python 学习笔记 -- OS模块的常用对象方法
  8. 西安4年java多少时间_西安学习java一般要多久
  9. oracle 用户解锁和修改用户密码
  10. Rails测试《十》不能错过的杂七杂八
  11. Java学习资源、视频教程汇总
  12. 一年工作经验的java面试题
  13. word页码怎么从第三页开始设置为第一页_如何让页码从指定页开始,而不是第一页?...
  14. 【优化算法】缎面弓箭鸟优化(SBO)【含Matlab源码 1432期】
  15. 【从零开始学TVM】三,基于ONNX模型结构了解TVM的前端
  16. 软件测试用例设计 (一)等价类划分法
  17. 大数据学习第一章:初识大数据
  18. Paul Graham:未来的互联网创业[转]
  19. 微信公众号迁移流程 《openid转换》
  20. 云服务器转租赁协议,云服务器转租赁协议

热门文章

  1. 比scp更强大的复制命令rsync
  2. 2022年度规划和2021总结
  3. 写一个函数,实现n的阶乘。
  4. 基于Vue和Element-ui组件库搭建的后台管理系统
  5. CSS案例 • 【第7章 横幅广告滑块】
  6. Python之DataFrame基础知识点
  7. 快过年了,发亲手制作的新年贺卡。
  8. educoder Git进阶之冲突处理、忽略文件
  9. 【报告分享】 2020跨境出口电商行业白皮书-CBNDATA(附下载)
  10. Fritzing软件绘制Arduino面包板接线图传感器模块库文件249