uboot-----borad.c .
http://blog.csdn.net/en_wang/article/details/7163193
程序流程:
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 ...
最新文章
- TextView显示插入的图片
- 【CF526F】Pudding Monsters
- 数据库范式1NF 2NF 3NF BCNF
- python获取IP位置信息
- 七、华为鸿蒙HarmonyOS应用开发之Java UI框架、常用Text组件和Button组件使用
- 【Elasticsearch】Elasticsearch bouncing result 问题
- linux常用命令(1)——文件管理
- python和c 的区别-对比平台--C和Python之间的区别
- intelliJ idea 激活和配置
- 每次开机都要选择Windwos10才能进系统的原因及解决方法--	【亲测有效】
- PostgreSQL 与 PostGIS
- 大米云主机首批优秀体验师新鲜出炉——软件服务篇
- 官宣!袋鼠云融资轮次和核心产品!欢迎来投
- 注释(单行注释、多行注释、文档注释)
- 黄东旭:开发者的“技术无感化”时代,从 Serverless HTAP 数据库开始 | PingCAP DevCon 2022
- nvidia dch 驱动 与windows 不兼容_Adobe 2020系统兼容性报告,不支持视频驱动程序!完美解决方案...
- Windows12[Beta1.2.6]公测
- 学术失信!2人被撤销硕士学位!导师均被撤销硕士研究生指导教师资格!
- 十进制转化为16进制
- Linux服务器操作习惯培养