经典=Uboot-4-启动流程-代码注释


_not_used:
.word not_used
_irq:
.word irq
_fiq:
.word fiq
.balignl 16,0xdeadbeef (2)CPU进入SVC模式(cpu/arm920t/start.S)
start_code:
/*set the cpu to SVC32 mode*/
mrs r0, cpsr
{
*pdw = dwVal;
/* 恢复原来的数据 */
return 0;
}
}
下面来分析NOR Flash启动部分代码:
208
adr r0, _start
position of code */
/* r0 <- current
209
ldr r1, _TEXT_BASE
flash or RAM */
/* test if we run from
320 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
321 cpu_init_crit:
322
/*
323
* 使数据cache与指令cache无效 */
324
*/
325
mov r0, #0
326
mcr p15, 0, r0, c7, c7, 0
使ICache与DCache无效 */
146
bne 0b
147
148
/* 现在一切都很好 */
149
mov pc, lr
150
151
.ltorg
152
/* 文字池起源 */
153
154 SMRDATA:
/* 下面是13个寄存器的值 */
155
.word … …
156
.word … …
……
lowlevel_init初始化了13个寄存器来实现RAM时钟的初始化。 lowlevel_init函数对于U-Boot从NAND Flash或NOR Flash启动的情况都 是有效的。
*/
136
/* reads SMRDATA out of FLASH rather than memory ! */
137
ldr r0, =SMRDATA
138
ldr r1, _TEXT_BASE
139
sub r0, r0, r1
个寄存器的偏移地址 */
/* SMRDATA减_TEXT_BASE就是13
cmp r0, #0 返回值,若返回0表
/* r0存放bBootFrmNORFlash函数
在NOR Flash启动 */
示NAND Flash启动,否则表示
beq nand_boot
/* 跳转到NAND Flash启动代码 */
/* NOR Flash启动的代码 */
B stack_setup
/* 跳过NAND Flash启动的代码 */
/* 向c7写入0将
327
mcr p15, 0, r0, c8, c7, 0 /* 向c8写入0将使TLB失
效 */
328
329
/*
330
* 禁止MMU的功能和高速缓存
331
*/
332
mrc
到r0中 */
p15, 0, r0, c1, c0, 0
/* 读出控制寄存器
333
bic r0, r0, #0x00002300
140
ldr r1, =BWSCON
Controller */
/* Bus Width Status
141
add r2, r0, #13*4
142 0:
143
ldr r3, [r0], #4
值给对应的寄存器*/
/*将13个寄存器的值逐一赋
144
str r3, [r1], #4
145
cmp r2, r0
9:8 (--V- --RS)
@ clear bits 13,
334
bic
(B--- -CAM)
r0, r0, #0x00000087
@ clear bits 7, 2:0
335
orr r0, r0, #0x00000002
Align
@ set bit 2 (A)
336
orr r0, r0, #0x00001000
bic r0, r0, #0x1f
/*工作模式位清零*/
orr r0, r0, #0xd3
/*工作模式位设置为“10011”(管
理模式),并将中断禁止
位和快中断禁止位置1 */
msr cpsr, r0
(3)设置控制寄存器地址(cpu/arm920t/start.S)
# if defined(CONFIG_S3C2400)
/*软件中断向量*/
ldr 量*/
pc, _prefetch_abort
/*预取指令异常向
ldr 量*/
pc, _data_abort
/*数据操作异常向
ldr pc, _not_used
/*未使用*/
ldr pc, _irq
/*irq中断向量中断向量*/
/*中断向量表入口地址*/
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
CPU上电几毫秒后,晶振输出稳定,FCLK=Fin(晶振频率),CPU开始执行指令。但实际上, FCLK可以高于Fin,为了提高系统时钟,需要用软件来启用PLL。这就需要设置CLKDIVN, MPLLCON,UPLLCON这3个寄存器。
cpu/arm920t/start.S原来的代码是只支持从NOR Flash启动的,经 过修改现在U-Boot在NOR Flash和NAND Flash上都能启动了,实现的思 路是这样的:
bl bBootFrmNORFlash 还是NOR Flash启动 */
/* 判断U-Boot是在NAND Flash
str r1, [r0]
# endif
(6)设置MPLLCON、PLLCON、CLKDIVN(cpu/arm920t/start.S)
# if defined(CONFIG_S3C2440) 义?】
【这个变量在哪里定
#define MPLLCON 0x4C000004
#define UPLLCON 0x4C000008
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0] 不输出复位信号 */
/* 看门狗控制器的最低位为0时,看门狗
(5)屏蔽中断(cpu/arm920t/start.S)
/* mask all IRQs by setting all bits in the INTMR – default */
(7)关闭MMU,cache(cpu/arm920t/start.S)
#ifndef CONFIG_SKIP_LOWLEVEL_INIT 始化?】
【是不是跳过低水平初
bl cpu_init_crit 段,在start.S】
【它不是函数,它是个代码
#endif
cpu_init_crit这段代码在U-Boot正常启动时才需要执行,若将U-Boot 从RAM中启动则应该注释掉这段代码。下面分析一下cpu_init_crit到底 做了什么:
# define INTMSK */
0x4A000008
/* INTMSK寄存器地址
# define INTSUBMSK 址 */
0x4A00001C
/* INTSUBMSK寄存器地
# define CLKDIVN */
0x4C000014
/* CLKDIVN寄存器地址
# endif
(4)关闭看门狗(cpu/arm920t/start.S)
345
346
bl lowlevel_init
=/board/GT2440/lowlevel_init.S】
【位置
347
348
mov lr, ip
349
mov pc, lr
350 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
代码中的c0,c1,c7,c8都是ARM920T的协处理器CP15的寄存器。其中 c7是cache控制寄存器,c8是TLB控制寄存器。325~327行代码将0写入 c7、c8,使Cache,TLB内容无效。第332~337行代码关闭了MMU。这是通 过修改CP15的c1寄存器来实现的。 (8)初始化RAM控制寄存器 (board/samsung/mini2440/lowlevel_init.S) 由于内存初始化是依赖于开发板的,因此lowlevel_init的代码一般放 在board下面相应的目录中。
45 #define BWSCON 始地址 */
0x48000000
/* 13个存储控制器的开
……
129 _TEXT_BASE:
130
.word TEXT_BASE
132
.globl lowlevel_init
133 lowlevel_init:
134
/* 存储器控制设置 */
135
/* make r0 relative the current location so that it
mov 蔽 */
r1, #0xffffffff
/* 某位被置1则对应的中断被屏
ldr r0, =INTMSK
/* 中断源寄存器 */
str r1, [r0]
合集下载

uboot代码完全解析

uboot代码完全解析
1.相关文件 ....................................................................................................................................28 2.数据结构 ....................................................................................................................................28 3.ENV 的初始化...........................................................................................................................30
目录
u-boot-1.1.6 之 cpu/arm920t........................................................................2 u-boot 中.lds 连接脚本文件的分析 ...................................................................................................12 分享一篇我总结的 uboot 学习笔记(转) .....................................................................................15 U-BOOT 内存布局及启动过程浅析 ...................................................................................................22 u-boot 中的命令实现 ..........................................................................................................................25 U-BOOT 环境变量实现 ........................................................................................................................28

MIPS uboot代码注释

MIPS uboot代码注释

MIPS U-Boot——by M.CUboot启动流程关中断设置kseg0no cache初始化gp指针lowlevel_init mips_cache_reset 设置kseg0cache mips_cache_lockBoard_init_f relocate_code Board_init_r启动内核根据CPU rate初始化外部时钟、内存初始化cachecache未初始化前不能用cache已初始化设置临时cache栈把uboot程序从flash搬到ram执行start.Smtc0zero, CP0_WATCHLO mtc0zero, CP0_WATCHHI 清除硬件数据断点,防止产生调试断点,导致程序停止。

芯片在复位后,某些寄存器的内容也许是你想要的结果,但是谁知道呢,为了保证准确无误,最好还是重新进行手动初始化mfc0k0, CP0_STATUSli k1, ~ST0_IEand k0, k1mtc0k0, CP0_STATUS禁止全局中断mtc0zero, CP0_CAUSE初始化异常寄存器,清除异常原因指示mtc0zero, CP0_COUNTmtc0zero, CP0_COMPARE初始化时钟寄存器,防止产生计数器中断li t0, CONF_CM_UNCACHEDmtc0t0, CP0_CONFIG设置kseg0区不经过cache。

cache需要先初始化才能使用。

bal1fnop.word_gp1:lw gp, 0(ra)bal分支调用,ra返回地址指向下下一条指令,即.word _gp把.word_gp的存储位置载入gp寄存器,即设置GOT表的起始位置la t9, lowlevel_init jalr t9nop 根据CPU rate初始化外部时钟、内存。

lowlevel_init函数定义见lowlevel_init.Sla t9, mips_cache_reset jalr t9nop 初始化高速缓存cache。

u-boot整体结构、移植步骤以及启动代码分析

u-boot整体结构、移植步骤以及启动代码分析

u-boot整体结构、移植步骤以及启动代码分析本篇文章首先介绍u-boot的整体代码结构,移植的基本步骤,然后分析启动的代码(start.S)中其中代码结构和移植步骤是参考了下面两个连接的文章,这方面资源比较多,一搜一堆,就不自己发明车轮了阿,呵呵。

/blog/user1/9450/archives/2006/12887.html和老古开发网上面的一篇文章,作者是焦玉全黄乡生鲍玉军,题目是第7540篇:U-Boot在S3C2410上的移植(具体URL忘了,我文章是下载的,知道的朋友告诉一声)一、整体结构首先下载u-boot的源代码(www.denx.de),解压缩,你可以看到下面的目录:- board 目标板相关文件,主要包含SDRAM、FLASH驱动;- common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;- cpu 与处理器相关的文件。

如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;- driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)- doc U-Boot的说明文档;- examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;- include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;- lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;- net 与网络功能相关的文件目录,如bootp,nfs,tftp;- post 上电自检文件目录。

尚有待于进一步完善;- rtc RTC驱动程序;- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;二、移植步骤为了使U-Boot支持新的开发板,一种简便的做法是在U-Boot已经支持的开发板中选择一种和目标板接近的,并在其基础上进行修改。

u-boot移植4--支持DM9000

u-boot移植4--支持DM9000

U-boot移植5--支持DM9000开发板的原理图中得知:第二阶段从在lib_arm的board.c的start_armboot函数开始,其中有一个是跳到网卡初始化的eth_initialize函数(在net/eth.c中)(上面的宏CONFIG_NET_MULTI,等会要实现)。

1、在eth_initialize(文件中有两个,代码较长的那个)的#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)miiphy_init();#endif后面添加上下面的代码if (board_eth_init(bis) < 0)cpu_eth_init(bis);并在本文件前面增加如下代码:static int __def_eth_init(bd_t *bis){return -1;}int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));2、在mao2440.c中添加上面函数的实现#include <net.h>extern int dm9000_initialize(bd_t * bd);#ifdef CONFIG_DRIVER_DM9000int board_eth_init(bd_t *bis){return dm9000_initialize(bis);}#endif3、在include/configs/mao2440.h中注释CS8900的代码,如下:(62行)#if 0#define CONFIG_DRIVER_CS8900 1/* we have a CS8900 on-board */#define CS8900_BASE 0x19000300#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */#end if并添加DM9000的宏, 由上图知DM9000在BANK4上,所以定义为0x20000300如下:#define CONFIG_DRIVER_DM9000 1#define CONFIG_DM9000_BASE 0x20000300#define DM9000_IO CONFIG_DM9000_BASE#define DM9000_DATA (CONFIG_DM9000_BASE+4)#define CONFIG_DM9000_USE_16BIT 1#define CONFIG_NET_MULTI 14、网上说要修改dm9000x.c的eth_init(bd_t * bd)的内容,此步我的板不用eth_init(bd_t * bd){.............../* Set Node address *//*for (i = 0; i < 6; i++)((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);*/char *tmp = getenv ("ethaddr");char *end;for (i=0; i<6; i++) {bd->bi_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;if (tmp)tmp = (*end) ? end+1 : end;}……………….#if 0i = 0;…………#endifreturn 0;}红色的字符是要做的修改:功能是屏蔽原有获取MAC地址的语句,替换成从U-Boot的参数区读取数据并存到bd->bi_enetaddr[i]中功能是屏蔽无用的语句。

uboot启动流程

uboot启动流程

U-Boot工作过程U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能硬件设备初始化加载U-Boot第二阶段代码到RAM空间设置好栈跳转到第二阶段代码入口(2)第二阶段的功能初始化本阶段使用的硬件设备检测系统内存映射将内核从Flash读取到RAM中为内核设置启动参数调用内核1.1.1 U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/和board/samsung/mini2440/。

U-Boot启动第一阶段流程如下:图 U-Boot启动第一阶段流程根据cpu/arm920t/中指定的连接方式:ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/ (.text)board/samsung/mini2440/ (.text)board/samsung/mini2440/ (.text)*(.text)}… …}第一个链接的是cpu/arm920t/,因此的入口代码在cpu/arm920t/中,其源代码在cpu/arm920t/中。

下面我们来分析cpu/arm920t/的执行。

1. 硬件设备初始化(1)设置异常向量cpu/arm920t/开头有如下的代码:.globl _start_start: b start_code /* 复位*/ldr pc, _undefined_instruction /*未定义指令向量 */ldr pc, _software_interrupt /* 软件中断向量 */ldr pc, _prefetch_abort /* 预取指令异常向量 */ldr pc, _data_abort /* 数据操作异常向量 */ldr pc, _not_used /* 未使用 */ldr pc, _irq /* irq中断向量 */ldr pc, _fiq /* fiq中断向量 */ /* 中断向量表入口地址 */_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq.balignl 16,0xdeadbeef以上代码设置了ARM异常向量表,各个异常向量介绍如下:表 ARM异常向量表在cpu/arm920t/中还有这些异常对应的异常处理程序。

uboot 代码运行流程

uboot 代码运行流程

uboot 代码运行流程U-boot是一款ARM处理器启动管理程序,在ARM开发板研发中具有非常广泛的应用,它可以在开发板上提供各种服务和支持,使得用户能够轻松地启动系统和进行应用开发。

本文将从U-boot代码运行流程方面来介绍U-boot的一般执行过程。

U-boot代码运行流程主要可以分为两个方面,即bootloader代码执行流程和内核启动代码执行流程。

1. Bootloader代码执行流程Bootloader是指从CPU开始运行到操作系统启动、执行前的代码。

它的主要功能是加载操作系统内核、初始化硬件环境以及对操作系统进行配置等。

U-boot在启动过程中需要经历以下几个步骤:1)CPU复位在系统上电或者发生复位时,CPU内部控制块将根据复位信号重新启动,并从指定地址处读取第一条指令。

2)初始化硬件U-boot对内存、Flash、串口等硬件进行初始化,然后启动U-boot的“彩屏”启动画面。

3)读取启动设备U-boot通过Boot Device Driver从存储设备(SD卡、NAND Flash等)中读取启动文件,然后执行它。

默认情况下,U-boot会从SD卡中读取启动文件。

4)解析启动文件U-boot解析启动文件,提取内核映像、设备树和命令行参数等关键信息。

然后执行其它操作,如设备树重定位、加入命令行参数等。

5)启动内核U-boot将内核映像从Flash中加载到内存中,并将控制权转交给内核。

此时内核开始执行,U-boot自己退出。

2. 内核启动代码执行流程内核启动代码主要是内核启动过程中的初始化工作。

启动过程中,操作系统需要对内存进行初始化、加载一些关键模块、初始化驱动程序等工作,以实现操作系统本身的功能。

1)内核初始化内核初始化包括内存管理、进程管理、文件系统、驱动程序初始化等。

此时内核会创建init进程和kthreadd进程。

2)加载模块内核启动后加载模块,模块提供了丰富的功能,如网络支持、图形界面等。

uboot启动代码详细讲解

·1 引言在专用的嵌入式板子运行 GNU/Linux 系统已经变得越来越流行。

一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次:1. 引导加载程序。

固化在固件(firmware)中的 boot 代码,也就是 Boot Loader,它的启动通常分为两个阶段。

2. Linux 核。

特定于嵌入式板子的定制核以及核的启动参数。

3. 文件系统。

包括根文件系统和建立于 Flash 存设备之上文件系统,root fs。

4. 用户应用程序。

特定于用户的应用程序。

有时在用户应用程序和核层之间可能还会包括一个嵌入式图形用户界面。

常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 等。

引导加载程序是系统加电后运行的第一段软件代码。

回忆一下 PC 的体系结构我们可以知道,PC 机中的引导加载程序由 BIOS(其本质就是一段固件程序)和位于硬盘 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起组成。

BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的 Boot Loader 读到系统的 RAM 中,然后将控制权交给 OS Boot Loader。

Boot Loader 的主要运行任务就是将核映象从硬盘上读到 RAM 中,然后跳转到核的入口点去运行,也即开始启动操作系统。

而在嵌入式系统中,通常并没有像 BIOS 那样的固件程序(注,有的嵌入式 CPU 也会嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由 Boot Loader 来完成。

比如在一个基于 ARM7TDMI core 的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000 处开始执行,而在这个地址处安排的通常就是系统的 Boot Loader 程序。

·2 bootloader简介简单地说,Boot Loader (引导加载程序)就是在操作系统核运行之前运行的一段小程序,它的作用就是加载操作系统,它是系统加电后运行的第一段软件代码。

uboot学习之四-----uboot启动第二阶段--start_armboot函数

uboot学习之四-----uboot启动第⼆阶段--start_armboot函数uboot第⼆阶段应该做什么?uboot的第⼆阶段就是要初始化剩下的还没被初始化的硬件,主要是SOC外部硬件(譬如inand、⽹卡芯⽚)、uboot本⾝的⼀些东西(uboot 的命令、环境变量等),然后最终初始化完必要的东西后进⼊uboot的命令⾏准备接受命令。

uboot第⼆阶段完结于何处?uboot启动后⾃动运⾏打印出很多信息,这些信息就是uboot第⼀和第⼆阶段不断进⾏初始化时,打印出来的信息,然后uboot进⼊了bootdelay然后执⾏bootcmd对应的启动命令,如果这时候⽤户不⼲涉,会执⾏bootcmd进⼊⾃动启动内核的流程了。

(uboot的⽣命周期就结束了);所以uboot完结于命令⾏下,读取命令,解析命令,执⾏命令。

命令⾏死循环是uboot的最终归宿void start_armboot (void){init_fnc_t **init_fnc_ptr;char *s;int mmc_exist = 0;#if !defined(CFG_NO_FLASH) || defined (CONFIG_VFD) || defined(CONFIG_LCD)ulong size;#endif#if defined(CONFIG_VFD) || defined(CONFIG_LCD)unsigned long addr;#endif#if defined(CONFIG_BOOT_MOVINAND)uint *magic = (uint *) (PHYS_SDRAM_1);#endif/* 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_IRQgd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);#endifgd = (gd_t*)gd_base;#elsegd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));#endif/* compiler optimization barrier needed for GCC >= 3.4 */__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));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 ();}}#ifndef CFG_NO_FLASH/* configure available FLASH banks */size = flash_init ();display_flash_config (size);#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 */#ifdef CONFIG_LCD/* board init may have inited fb_base */if (!gd->fb_base) {# 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 *//* 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); #elsemem_malloc_init (_armboot_start - CFG_MALLOC_LEN);#endif//******************************//// Board Specific// #if defined(CONFIG_SMDKXXXX)//******************************//#if defined(CONFIG_SMDK6410)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");}#else#if defined(CONFIG_MMC)puts("SD/MMC: ");if (INF_REG3_REG == 0)movi_ch = 0;elsemovi_ch = 1;movi_set_capacity();movi_init();movi_set_ofs(MOVI_TOTAL_BLKCNT);#endif#endifif (INF_REG3_REG == BOOT_ONENAND) {#if defined(CONFIG_CMD_ONENAND)puts("OneNAND: ");onenand_init();#endif/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/} else {puts("NAND: ");nand_init();if (INF_REG3_REG == 0 || INF_REG3_REG == 7)setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000");elsesetenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");}#endif /* CONFIG_SMDK6410 */#if defined(CONFIG_SMDKC100)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");}#endif#if defined(CONFIG_CMD_ONENAND)puts("OneNAND: ");onenand_init();#endif#if defined(CONFIG_CMD_NAND)puts("NAND: ");nand_init();#endif#endif /* CONFIG_SMDKC100 */#if defined(CONFIG_X210)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");#ifdef CONFIG_CHECK_X210CV3check_flash_flag=0;//check inand error!#endif}#ifdef CONFIG_CHECK_X210CV3else{check_flash_flag=1;//check inand ok!}#endif#endif#if defined(CONFIG_MTD_ONENAND)puts("OneNAND: ");onenand_init();/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/ #else//puts("OneNAND: (FSR layer enabled)\n");#endif#if defined(CONFIG_CMD_NAND)puts("NAND: ");nand_init();#endif#endif /* CONFIG_X210 */#if defined(CONFIG_SMDK6440)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");}#else#if defined(CONFIG_MMC)if (INF_REG3_REG == 1) { /* eMMC_4.3 */puts("eMMC: ");movi_ch = 1;movi_emmc = 1;movi_init();movi_set_ofs(0);} else if (INF_REG3_REG == 7 || INF_REG3_REG == 0) { /* SD/MMC */ if (INF_REG3_REG & 0x1)movi_ch = 1;elsemovi_ch = 0;puts("SD/MMC: ");movi_set_capacity();movi_init();movi_set_ofs(MOVI_TOTAL_BLKCNT);} else {}#endif#endifif (INF_REG3_REG == 2) {/* N/A */} else {puts("NAND: ");nand_init();//setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");}#endif /* CONFIG_SMDK6440 */#if defined(CONFIG_SMDK6430)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");}#else#if defined(CONFIG_MMC)puts("SD/MMC: ");if (INF_REG3_REG == 0)movi_ch = 0;elsemovi_ch = 1;movi_set_capacity();movi_init();movi_set_ofs(MOVI_TOTAL_BLKCNT);#endif#endifif (INF_REG3_REG == BOOT_ONENAND) {#if defined(CONFIG_CMD_ONENAND)puts("OneNAND: ");onenand_init();#endif/*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/} else if (INF_REG3_REG == BOOT_NAND) {puts("NAND: ");nand_init();} else {}if (INF_REG3_REG == 0 || INF_REG3_REG == 7)setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000"); elsesetenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");#endif /* CONFIG_SMDK6430 */#if defined(CONFIG_SMDK6442)#if defined(CONFIG_GENERIC_MMC)puts ("SD/MMC: ");mmc_exist = mmc_initialize(gd->bd);if (mmc_exist != 0){puts ("0 MB\n");}#else#if defined(CONFIG_MMC)puts("SD/MMC: ");movi_set_capacity();movi_init();movi_set_ofs(MOVI_TOTAL_BLKCNT);#endif#endif#if defined(CONFIG_CMD_ONENAND)if (INF_REG3_REG == BOOT_ONENAND) {puts("OneNAND: ");onenand_init();}#endif#endif /* CONFIG_SMDK6442 */#if defined(CONFIG_SMDK2416) || defined(CONFIG_SMDK2450)#if defined(CONFIG_NAND)puts("NAND: ");nand_init();#endif#if defined(CONFIG_ONENAND)puts("OneNAND: ");onenand_init();#endif#if defined(CONFIG_BOOT_MOVINAND)puts("SD/MMC: ");if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {printf("Boot up for burning\n");} else {movi_init();movi_set_ofs(MOVI_TOTAL_BLKCNT);}#endif#endif /* CONFIG_SMDK2416 CONFIG_SMDK2450 */#ifdef CONFIG_HAS_DATAFLASHAT91F_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 */#ifdef CONFIG_SERIAL_MULTIserial_initialize();#endif/* 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_ETH1i = 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}devices_init (); /* get the devices list going. */#ifdef CONFIG_CMC_PU2load_sernum_ethaddr ();#endif /* CONFIG_CMC_PU2 */jumptable_init ();#if !defined(CONFIG_SMDK6442)console_init_r (); /* fully init console as a device */#endif#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_TI_EMACextern void dm644x_eth_set_mac_addr (const u_int8_t *addr);if (getenv ("ethaddr")) {dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);}#endif#ifdef CONFIG_DRIVER_CS8900cs8900_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 defined(CONFIG_CMD_NET)if ((s = getenv ("bootfile")) != NULL) {copy_filename (BootFile, s, sizeof (BootFile));}#endif#ifdef BOARD_LATE_INITboard_late_init ();#endif#if defined(CONFIG_CMD_NET)#if defined(CONFIG_NET_MULTI)puts ("Net: ");#endifeth_initialize(gd->bd);#if defined(CONFIG_RESET_PHY_R)debug ("Reset Ethernet PHY\n");reset_phy();#endif#endif#if defined(CONFIG_CMD_IDE)puts("IDE: ");ide_init();#endif/****************lxg added**************/#ifdef CONFIG_MPADextern int x210_preboot_init(void);x210_preboot_init();#endif/****************end**********************//* check menukey to update from sd */extern void update_all(void);if(check_menu_update_from_sd()==0)//update mode{puts ("[LEFT DOWN] update mode\n");run_command("fdisk -c 0",0);update_all();}elseputs ("[LEFT UP] boot mode\n");/* 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 */}start_armboot分析(uboot\uboot_jiuding\uboot\lib_arm 444⾏):① init_fnc_t **init_fnc_ptr;解析:typedef int (init_fnc_t) (void);这是⼀个函数类型,init_fnc_ptr就是⼀个⼆重函数指针,这⾥是⽤来指向⼀个函数指针数组。

Uboot启动流程分析和移植介绍

基于MPC83xx 的U-boot 启动流程分析和移植董 闯北京邮电大学信息与通信工程学院,北京(100876)E-mail :donix.dong@摘 要:本文首先引入Bootloader 的概念,接着介绍U-boot 这种引导程序,并以Freescale 32位微处理器MPC83xx 为例,结合代码详细分析了U-boot 的启动的各个阶段及最终引导Linux 内核的过程,最后,建立交叉编译环境,针对TC8313E 目标板,给出U-boot 移植与编译的基本步骤。

关键词:U-boot;MPC83xx;交叉编译;移植;嵌入式系统中图分类号:TP393.051.引言引导程序(Bootloader)是系统加电后运行的第一段软件代码,类似于PC 机中的引导加载程序BIOS 。

虽然引导程序仅在系统启动时运行非常短的时间,但对于嵌入式系统来说,这是一个非常重要的组成部分。

通过这段小程序,初始化必要的硬件设备,创建内核需要的一些信息并将这些信息传递给内核,从而将系统的软、硬件环境配置到一个合适的状态,最终调用操作系统内核,真正起到引导和加载内核的作用。

2. U-boot 介绍目前,嵌入式领域里出现了很多种类的Bootloader ,如Armboot 、Blob 、Redboot 、vivi 和U-boot 等,其中U-boot 是使用最广泛,功能最完善的。

U-boot (Universal Boot Loader)是从PPCBOOT 发展演化而来[1],其源码目录、编译形式与Linux 内核很相似,事实上,不少U-boot 源码就是相应的Linux 内核源程序的简化,尤其是一些设备的驱动程序,这从U-boot 源码的注释中就能体现。

U-boot 中Universal 有两层含义,一是U-boot 除了支持PowerPC 系列的处理器外,还能支持MIPS 、x86、ARM 、NIOS 、XScale 等诸多常用系列的处理器;另外一层含义则是U-boot 不仅仅支持嵌入式Linux 操作系统的引导,还支持OpenBSD, NetBSD, FreeBSD, SVR4, Solaris, VxWorks, LynxOS, pSOS, lrix, RTEMS, QNX, ARTOS 等操作系统的引导。

Uboot启动流程

Uboot启动流程(国嵌)开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数。

看一下board/smdk2410/u-boot.lds那个链接脚本,能够明白目标程序的各部分链接顺序。

第一个要链接的是cpu/arm920t/start.o,那么U-Boot 的入口指令一定位于那个程序中。

下面分两时期介绍启动流程:第一时期1.cpu/arm920t/start.S那个汇编程序是U-Boot的入口程序,开头确实是复位向量的代码。

_start: b reset //复位向量ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irq //中断向量ldr pc, _fiq //中断向量…/* the actual reset code */reset: //复位启动子程序/* 设置CPU为SVC32模式*/mrs r0,cpsrbic r0,r0,#0x1forr r0,r0,#0xd3msr cpsr,r0/* 关闭看门狗*/…………relocate: /* 把U-Boot重新定位到RAM */adr r0, _start /* r0是代码的当前位置*/ldr r1, _TEXT_BASE /*_TEXT_BASE是RAM中的地址*/ cmp r0, r1 /* 比较r0和r1,判定当前是从Flash启动,依旧RAM */beq stack_setup /* 如果r0等于r1,跃过重定位代码*//* 预备重新定位代码*/ldr r2, _armboot_startldr r3, _bss_startsub r2, r3, r2 /* r2 得到armboot的大小*/add r2, r0, r2 /* r2 得到要复制代码的末尾地址*/copy_loop: /* 重新定位代码*/ldmia r0!, {r3-r10} /*从源地址[r0]复制*/stmia r1!, {r3-r10} /* 复制到目的地址[r1] */cmp r0, r2 /* 复制数据块直到源数据末尾地址[r2] */ble copy_loop/* 初始化堆栈等*/stack_setup:ldr r0, _TEXT_BASE /* 上面是128 KiB重定位的u-boot */sub r0, r0, #CFG_MALLOC_LEN /* 向下是内存分配空间*/sub r0, r0, #CFG_GBL_DATA_SIZE /* 然后是bdinfo结构体地址空间*/#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endifsub sp, r0, #12 /* 为abort-stack预留3个字*/clear_bss:ldr r0, _bss_start /* 找到bss段起始地址*/ldr r1, _bss_end /* bss段末尾地址*/mov r2, #0x00000000 /* 清零*/clbss_l:str r2, [r0]/* bss段地址空间清零循环... */add r0, r0, #4cmp r0, r1bne clbss_l/* 跳转到start_armboot函数入口,_start_armboot字储存函数入口指针*/ldr pc, _start_armboot_start_armboot: .word start_armboot //start_armboot函数在lib_arm /board.c中实现第二时期2.lib_arm/board.cstart_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档