uboot-----borad.c . .
程序流程:
start_armboot,进入bord.c,
init_fnc_t **init_fnc_ptr; |
typedef int (init_fnc_t) (void);
#ifndef CFG_NO_FLASH #if defined(CONFIG_VFD) || defined(CONFIG_LCD) |
#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 */ gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t); |
#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) #if defined(CONFIG_ONENAND) #if defined(CONFIG_BOOT_MOVINAND) if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) { #else #if (CONFIG_COMMANDS & CFG_CMD_NAND) #endif |
初始化nandflash,
#ifdef CONFIG_HAS_DATAFLASH |
/* initialize environment */ env_relocate (); |
初始化环境变量参数
#ifdef CONFIG_VFD /* must do this after the framebuffer is allocated */ drv_vfd_init(); #endif /* CONFIG_VFD */ |
初始化显存
/* IP Address */ /* MAC Address */ i = getenv_r ("ethaddr", tmp, sizeof (tmp)); for (reg = 0; reg < 6; ++reg) { #ifdef CONFIG_HAS_ETH1 for (reg = 0; reg < 6; ++reg) { |
通过命令行参数获取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 */ #if defined(CONFIG_DRIVER_SMC91111) || defined (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 /* NOTREACHED - no way out of command loop except booting */ |
uboot-----borad.c . .相关推荐
- 【整理】BIOS、BootLoader、uboot对比
bios BIOS是英文"Basic Input Output System"的缩略语,直译过来后中文名称就是"基本输入输出系统".其实,它是一组固化到计算机内 ...
- 嵌入式系统UBOOT
一个完整的嵌入式linux系统包含4部分内容:Bootloader.Parameters.Kernel.Root File System.3.4.5.6部分详细介绍了这4部分的内容,这是Linux底层 ...
- U-Boot源码目录分析(VScode工程创建及文件夹过滤)
参考:U-Boot工程目录介绍 作者:一只青木呀 发布时间: 2020-10-21 14:47:30 网址:https://blog.csdn.net/weixin_45309916/article/ ...
- ARM Uboot经历——makefile与uboot目录
makefile是个很复杂的东西,但是只要有耐心层层剥下,也能看到你想看到的东西.很遗憾的事,很多人都没有耐心去层层看,我也是. 对于makefile,我也仅仅从基础上了解了它在uboot中的原理和作 ...
- 【u-boot】uboot代码简要分析 (u-boot 移植)
uboot代码简要分析 (u-boot 移植) 2012-12-19 22:46:04 [转] 先来看看源码目录结构,再按照代码的执行顺序简单地分析源码 1.U-boot源码整体框架 源码解压以后,我 ...
- Uboot代码结构详细分析
1. Bootloader功能分析 Bootloader(如Uboot.Redboot.Blob.vivi等)直接和CPU.外围硬件设备(存储器.网卡.LCD等)打交道,负责初始化硬件设备,以及负责拉 ...
- Uboot 2017.01 启动流程分析
前言 2017.01 UBoot包含两个阶段的启动,一个是SPL启动,一个是正常的启动我们称为第二阶段Uboot.当然,我们也可以选择使用SPL和不使用. 在编译的过程中,是先编译第二阶段Uboot, ...
- uboot start.S分析
一.概述 1.本文综述及特色 阅读uboot,start.S是第一个源程序文件,主要完成初始化看门狗.定时器.重定位(拷贝代码段到内存中).初始化堆栈.跳转到第二阶段等工作. 网上关于这些内容的 ...
- uboot启动的第一阶段分析
uboot启动的第一阶段分析 1.start.S引入,start.S在目录cpu/s5pc11x/下. (1)如何确认uboot的程序入口,那就是去分析u-boot.lds,从u-boot.lds找到 ...
- U-Boot启动第二阶段代码分析
U-Boot第一阶段的启动流程.(nandflash启动,把nand的4k代码考到sram中,因为nand没址线,不能映射到内存,所以通过sram进行过度,sram中4k代码把整个uboot拷贝到sd ...
最新文章
- python数字类型及运算_Python基础之(基本数据类型及运算)
- Tomcat(四):tomcat图形管理和身份认证
- python如何进行双色球预测最准确_【原创】python基于大数据现实双色球预测
- 02 | 日志系统:一条 SQL 更新语句是如何执行的
- aspcms各版本漏洞0day集合
- Windows 7 下 Node.js 连接 Oracle
- python基本模块中的对象_Python 学习笔记 -- OS模块的常用对象方法
- 西安4年java多少时间_西安学习java一般要多久
- oracle 用户解锁和修改用户密码
- Rails测试《十》不能错过的杂七杂八
- Java学习资源、视频教程汇总
- 一年工作经验的java面试题
- word页码怎么从第三页开始设置为第一页_如何让页码从指定页开始,而不是第一页?...
- 【优化算法】缎面弓箭鸟优化(SBO)【含Matlab源码 1432期】
- 【从零开始学TVM】三,基于ONNX模型结构了解TVM的前端
- 软件测试用例设计 (一)等价类划分法
- 大数据学习第一章:初识大数据
- Paul Graham:未来的互联网创业[转]
- 微信公众号迁移流程 《openid转换》
- 云服务器转租赁协议,云服务器转租赁协议