u-boot启动代码start.S详解
Uboot中start.S源码的指令级的详尽解析+v1.6

Uboot中start.S源码的指令级的详尽解析
Version: 1.6 Author: green-waste (at)
目录
1. 正文乊前 .................................................................................................................................. 4 1.1. 本文内容........................................................................................................................4 1.2. 本文目标........................................................................................................................4 1.3. 代码来源..........................................4 1.4. 关亍本文内容的组织形式............................................................................................4 1.5. 阅读此文所要具有的前提知识....................................................................................5 1.6. 声明................................................................................................................................5
femto uboot 走读

Femtocell 项目uboot代码走读对于计算机系统来说,从开机上电到操作系统启动需要一个引导过程,这个引导程序就叫作Bootloader。
Bootloader是在操作系统运行之前执行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。
对于嵌入式系统,Bootloader是基于特定硬件平台来实现的。
因此,几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader。
Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。
对于2块不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般也都需要修改Bootloader的源程序。
反过来,大部分Bootloader仍然具有很多共性,某些Bootloader也能够支持多种体系结构的嵌入式系统。
例如,U-Boot就同时支持PowerPC、ARM、MIPS和X86等体系结构,支持的板子有上百种。
通常,它们都能够自动从存储介质上启动,都能够引导操作系统启动,并且大部分都可以支持串口和以太网接口。
一.汇编部分(cpu\arm926ejs\start.S),此部分为uboot能顺利运行C代码而准备其必须的环境。
1.当cpu上电后,CPU会_start:b reset首先跳转到标号reset处,将CPU设置为SVC模式。
(arm926ejs通用代码)2.cpu_init_crit: 设置I-CACHE , memory 时序等(arm926ejs通用代码)3.lowlevel_init:执行PC202独有的底层初始化工作(board\picochip\Pc7802\lowlevel_init.S)1)register_initialization : CPU需要使用仿真器的时候会定义CONFIG_PC20X_SIMULATION(咱们设备不使用仿真器。
u-boot源码分析之start.s分析

一、bootloader启动过程1、Stage1start.S代码结构(1)定义入口。
(2)设置异常向量(Exception Vector)。
(3)设置CPU的速度、时钟频率及终端控制寄存器。
(4)初始化内存控制器。
(5)将ROM中的程序复制到RAM中。
(6)初始化堆栈。
(7)转到RAM中执行,该工作可使用指令ldr pc来完成。
2、Stage2C语言代码部分(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
3、U-Boot的启动顺序二、具体代码分析1.Stage1start.S代码结构1.1定义入口(u-boot.lds)ENTRY(_start)1.2设置异常向量1.3设置全局向量表地址变量和字节对齐方式1.4定义重定位全局变量1.5设置全局搬移地址(falsh->dram)1.6设置中断向量地址1.7设置cpu模式设置cpu工作模式为SVC模式。
1.4中断向量表搬移,时钟设置1.5CPU设置(TBL,icache,MMU)1.6板级初始化1.7boot镜像搬移到SDRAM1.8清除bss段计算出偏移地址:__rel_dyn_start 、__rel_dyn_start 、__dynsym_start1.9跳转到Stage2C 语言部分1.10中断处理程序File :arch/arm/lib/Board.cvoid board_init_r (gd_t *id,ulong dest_addr)。
U-BOOT介绍以及常用U-bot命令介绍

U-BOOT介绍以及常用U-bot命令介绍一. BootLoader简介在专用的嵌入式板子运行GNU/Linux系统已经变得越来越流行。
一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:1、引导加载程序。
包括固化在固件(firmware)中的boot代码(可选),和BootLoader两大部分。
2、 Linux内核。
特定于嵌入式板子的定制内核以及内核的启动参数。
3、文件系统。
包括根文件系统和建立于Flash内存设备之上文件系统。
通常用ramdisk来作为rootfs。
4、用户应用程序。
特定于用户的应用程序。
有时在用户应用程序和内核层之间可能还会包括一个嵌入式图形用户界面。
常用的嵌入式GUI有:MicroWindows和MiniGUI懂。
引导加载程序是系统加电后运行的第一段软件代码。
PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OS BootLoader(比如,LILO和GRUB等)一起组成。
BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OS BootLoader。
BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
而在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。
比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
学习笔记-start.S解释1

学习笔记-start.S解释11、start.S 的⼊⼝:ENTRY(_start) 因此_start符号所在的⽂件就是整个程序的起始⽂件,_start所在处的代码就是整个程序的起始代码。
_start: b reset2、#include <config.h> 是配置过程中⾃动⽣成的⽂件(详见mkconfig脚本)这个⽂件包含x210_sd.h,主要是将x210_sd.h 与 start.S 联系起来了。
3、#include <version.h> 包含了include/version_autogenerated.h 这个⾥⾯的版本号和Makefile 中的配置值有关,在uboot启动打印的版本号就是这来的。
4、#include <asm/proc/domain.h> asm⽬录是配置时的符号连接,实指 asm-arm,实指⽂件:include/asm-arm/proc-armv/domain.h5、uboot这⾥start.S中在开头位置放了16字节的填充占位,这个占位的16字节只是保证正式的image的头部确实有16字节,但是这16字节的内容是不对的,还是需要后⾯去计算校验和然后重新填充的。
(mkv210image.c中就是为了计算这个校验头)。
#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED).word 0x2000.word 0x0.word 0x0.word 0x0#endif6、deadbeef .balignl 16,0xdeadbeef 这⼀句指令是让当前地址对齐排布,如果当前地址不对齐则⾃动向后⾛地址直到对齐,并且向后⾛的那些内存要⽤0xdeadbeef来填充。
7、 .word 汇编指令 格式如下: label: .word express这⾥的⽤法表⽰:在当前位置存放⼀个字,可能有些⼈会觉得就是放⼀个字word,这个要怎么看了,⼀般⼀个word是两个字节,跟CPU的型号有关,所以不要管word的限制,直 接理解成,在当前位置存放⼀个字,这个字是32位的即可。
U-boot启动详解

cpu/arm920t/start.S/****************************************************** ********************** Jump vector table as in table 3.1 in [1]****************************************************** *********************/;定义变量_start,然后跳转到处理器复位代码.globl _start_start: b reset;产生中断则利用pc来跳转到对应的中断处理程序中ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irqldr pc, _fiq;利用.word来在当前位置放置一个值,这个值实际上就用对应的中断处理函数的地址;.word的意义为在当前地址处放入一个16bits值_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/****************************************************** ********************** Startup Code (reset vector)** do important init only if we don't start from memory!* relocate armboot to ram* setup stack* jump to second stage****************************************************** *********************/;定义变量_TEXT_BASE:.word TEXT_BASE.globl _armboot_start_armboot_start:.word _start/** These are defined in the board-specific linker script.*/.globl _bss_start_bss_start:.word __bss_start.globl _bss_end_bss_end:.word _end#ifdef CONFIG_USE_IRQ/* IRQ stack memory (calculated at run-time) */.globl IRQ_STACK_STARTIRQ_STACK_START:.word 0x0badc0de/* IRQ stack memory (calculated at run-time) */.globl FIQ_STACK_STARTFIQ_STACK_START:.word 0x0badc0de#endif/** the actual reset code*/;实际处理代码reset:/** set the cpu to SVC32 mode*/mrs r0,cpsr;bic清除指定为1的位bic r0,r0,#0x1f;orr逻辑或操作orr r0,r0,#0xd3;经过以上两步r0值控制位位11010011,第0~4位标识处理器当前所处模式为10011(32位管理模式),第6、7位;为1标识禁止IRQ和FIQ中断,第5位为0标识程序运行为arm状态,若其为1则运行在thumb状态;设置处理器为32位管理模式,并运行与arm状态msr cpsr,r0/* turn off the watchdog */#if defined(CONFIG_S3C2400)# define pWTCON 0x15300000# define INTMSK 0x14400008 /* Interupt-Controller base addresses */# define CLKDIVN 0x14800014 /* clock divisor register */#elif defined(CONFIG_S3C2410);看门狗寄存器地址# define pWTCON 0x53000000;中断掩码寄存器,决定那个中断源被屏蔽,某位为1则屏蔽中断源,初始值为0xFFFFFFFF,屏蔽所有中断# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */;中断子掩码寄存器,该寄存器只能屏蔽11个中断源,因此其仅低11位有效,初始值为0x7FF# define INTSUBMSK 0x4A00001C;时钟分频控制寄存器# define CLKDIVN 0x4C000014 /* clock divisor register */#endif#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410);将看门狗寄存器清空,其各位含义为,第0位为1则当看门狗定时器溢出时重启,为0则不重启,初值为1;第2位为中断使能位,初值为0;第3、4位为时钟分频因子,初值为00,;第5位为看门狗的使能位初值为1;第8~15位为比例因子,初值为0x80ldr r0, =pWTCONmov r1, #0x0;将看门狗寄存器所有位置零,关闭看门狗,其实只要将第5位置0即可str r1, [r0];屏蔽所有中断,实际上中断屏蔽掩码寄存器初值即为0xFFFFFFFmov r1, #0xffffffffldr r0, =INTMSKstr r1, [r0]# if defined(CONFIG_S3C2410);设置子中断掩码寄存器ldr r1, =0x3ffldr r0, =INTSUBMSKstr r1, [r0]# endif;设置时钟寄存器,CLKDIVN第0位为PDIVN,为0则PCLK=HCLK,为1则PCLK=HCLK/2;第1位为HDIVN,为0则HCLK=FCLK,为1则HCLK=FCLK/2;这里两位均为1,则FCLK:HCLK:PCLK = 4:2:1/* default FCLK is 120 MHz ! */ldr r0, =CLKDIVNmov r1, #3str r1, [r0]#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 *//** we do sys-critical inits only at reboot,* not when booting from ram!*/;对临界寄存器的初始化,如果从ram中启动则不执行,如果重启则执行#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit#endif;重定向代码,也就是从flash中复制到ram中#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate: /* relocate U-Boot to RAM */;当前代码地址,adr获取当前代码的地址信息,若从ram运行则_start=TEXT_BASE,否则_start=0x00000000adr r0, _start /* r0 <- current position of code */;获取_TEXT_BASEldr r1, _TEXT_BASE /* test if we run from flash or RAM */cmp r0, r1 /* don't reloc during debug */ ;两者相等,表示从ram运行则跳转到堆栈设置beq stack_setup;不相等则表示从flash中运行,重定向代码ldr r2, _armboot_start;获取未初始化数据段地址ldr r3, _bss_start;计算代码段大小sub r2, r3, r2 /* r2 <- size of armboot */;计算代码段终止地址add r2, r0, r2 /* r2 <- source end address */;复制代码,r0为代码的起始地址,r1为ram中地址,r2为代码的终止地址 ;每次copy后将r0值递增同r2比较来判断是否复制完成copy_loop:ldmia r0!, {r3-r10} /* copy from source address [r0] */stmia r1!, {r3-r10} /* copy to target address [r1] */cmp r0, r2 /* until source end addreee [r2] */ble copy_loop#endif /* CONFIG_SKIP_RELOCATE_UBOOT *//* Set up the stack */stack_setup:;获取_TEXT_BASEldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */;获取分配区域起始指针,CFG_MALLOC_LEN=128*1024+CFG_ENV_SIZE=128*1024+0x1000 0=192Ksub r0, r0, #CFG_MALLOC_LEN /* malloc area */ ;另外分配128bytes来存储开发板信息sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif;再减去12bytes用于栈起点sub sp, r0, #12 /* leave 3 words for abort-stack */;清空未初始化数据段clear_bss:ldr r0, _bss_start /* find start of bss segment */ldr r1, _bss_end /* stop here */mov r2, #0x00000000 /* clear */clbss_l:str r2, [r0] /* clear loop... */add r0, r0, #4cmp r0, r1ble clbss_l#if 0;关闭看门狗/* try doing this stuff after the relocation */ldr r0, =pWTCONmov r1, #0x0str r1, [r0]/** mask all IRQs by setting all bits in the INTMR - default*/;禁止中断mov r1, #0xffffffffldr r0, =INTMRstr r1, [r0];设置时钟/* FCLK:HCLK:PCLK = 1:2:4 *//* default FCLK is 120 MHz ! */ldr r0, =CLKDIVNmov r1, #3str r1, [r0]/* END stuff after relocation */#endif;完成复制后跳转到start_armboot,到这里就进入函数lib_arm/board.c的start_armboot函数中ldr pc, _start_armboot_start_armboot: .word start_armboot;这里指的从flash中运行是指的从flash rom中运行,也就是常说的从nor flash中运行程序,现在有很多开发板;都是利用SDRAM和NAND-FLASH共同工作,所以需要添加从nand flash启动的代码。
am335xu-boot启动过程分析
am335xu-boot启动过程分析 u-boot属于两阶段的bootloader,第⼀阶段的⽂件为 arch/arm/cpu/armv7/start.S 和 arch/arm/cpu/armv7/lowlevel_init.S,前者是平台相关的,后者是开发板相关的。
1. u-boot第⼀阶段代码分析 (1)硬件设备初始化 将CPU的⼯作模式设为管理模式(SVC); 关闭中断; 禁⽤MMU,TLB ; 板级初始化; (2)为加载Bootloader的第⼆阶段代码准备RAM空间 加载u-boot.img,跳转到u-boot.img; 上述⼯作,也就是uboot-spl代码流程的核⼼。
代码如下:arch/arm/cpu/armv7/start.S1/*2 * the actual reset code3*/4reset:5 bl save_boot_params6/*7 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,8 * except if in HYP mode already9*/10 mrs r0, cpsr11 and r1, r0, #0x1f @ mask mode bits12 teq r1, #0x1a @ test for HYP mode13 bicne r0, r0, #0x1f @ clear all mode bits14 orrne r0, r0, #0x13 @ set SVC mode15 orr r0, r0, #0xc0 @ disable FIQ and IRQ16 msr cpsr,r017@@ 以上通过设置CPSR寄存器⾥设置CPU为SVC模式,禁⽌中断18@@ 具体操作可以参考《[kernel 启动流程] (第⼆章)第⼀阶段之——设置SVC、关闭中断》的分析1920/* the mask ROM code should have PLL and others stable */21#ifndef CONFIG_SKIP_LOWLEVEL_INIT22 bl cpu_init_cp1523@@ 调⽤cpu_init_cp15,初始化协处理器CP15,从⽽禁⽤MMU和TLB。
win7启动菜单引导startos(win7+startos双系统)
win7启动菜单引导startos(win7+startos双系统)⽬前安装startos5.1时在分区的界⾯中 “⾼级” 选项中有选择引导设备安装在哪个分区中,选项分别是“mbr”、“linux根⽬录”,如果只选 "linux根⽬录" 安装完后是没有linux 引导菜单的,在⼯具easybcd 添加新条⽬也不会出现linux菜单,所以要么选"mbr"要么都选,建议都选这样在win7的环境下可以⽤⼯具easybcd 配置启动菜单,⽇后重装win7也可以⽤下⾯的⽅法添加 linux 引导菜单。
不过需要注意的是 win7需要重新激活。
这种情况希望startos在以后的版本中能解决问题win7+startos 双系统,实现⽤win7启动菜单引导startos的:安装好startos5.1后,启动菜单是startos的,不动它。
重启到win7,下载 Easybcd2.2,绿⾊版也⾏。
打开Easybcd ,在Easybcd2.2 的“BCD部署”选项卡中下,只单击“编写MBR”按钮,重启后startos的启动菜单没了,只有win7的启动菜单,注意win7还需重新激活!再在 Easybcd2.2 的中选“添加新条⽬”项,选Linux/BSD卡,类型:GRUB2,名称⾃定为startos5.1,驱动器:分区7(Linux-8GB)即startos系统的根分区(按你⾃⼰安装startos的根分区选定),其它不动。
不要选“⾃动定位和加载”,否则还是会启动win7。
最后点“添加新条⽬”,就在win7的启动菜单中添加了startos5.1项。
但在win7启动菜单中选择启动startos后仍会有⼆级菜单出现,也即startos的启动菜单。
在startos的grub.cfg⽂件中把ylmf设为默认启动,等待时间为0。
这样在win7启动菜单中选择ylmf就直接进⼊startos了。
以后重装win7就可如法炮制,⽤ Easybcd2.2 增加⼀项startos就⾏了。
uboot 命令详解
u-boot 技术文档1.U boot 命令详解1.1查看帮助命令使用help 或者?1.2环境变量打印环境变量:printenv设置环境变量:setenv(不会保存)保存环境变量:saveenv这个时候就有了1.3nandflash命令使用nand查看nandflash 所有指令擦除nand erase1.4norflash命令查看Flash信息命令: flinfo加/解写保护命令: protect擦除命令: erase1.5内存命令nm1.5USB指令使用help usb 查看usb具体指令使用usb 启动使用usb tree查看信息f atls usb 0 罗列u盘信息1.5.1实例演练usb指令烧写1.6实例演练ftp指令烧写环境变量中体现了开发板上的IP地址为192.168.0.2,网关为192.168.0.1,要求电上的tftp 服务器的IP为192.168.0.1;运行电脑上tftp服务器,指定好根目录,将内核和根文件系统放在根目录下。
注:线接上后,电脑上的本地连接可能是显示网络电缆没插好,这很正常!在使用过程中它们会自动去连接!<2>分别下载内核和根文件系统到内存0x30008000开始的空间先检查坏块nand bad再擦除坏块清理某个区域0x560000 0x3b22c00将根文件系统加载到0x30008000然后再将根文件系统写到0x560000 0x3b22c00这个位置然后重启:重复上面的步骤:nand erase 0x60000 0x267000将内核文件保存到0x60000 0x267000这块区域运行1.8系统重启指令2.U boot 内核移植在cpu/arm920t/start.S中添加以下代码在修改并添加为以下代码在include/configs/mini2440.h修改为如下:将以下代码修改为:将以下代码修改为:将以下代码修改为:在drivers/mtd/nand/s3c2410_nand.h 在最后下面代码上添加如下带码:。
start.S详解 1
* armboot - Startup Code for ARM920 CPU-core** Copyright (c) 2001 Marius Gr鰃er <mag@sysgo.de>* Copyright (c) 2002 Alex Z黳ke <azu@sysgo.de>* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>** See file CREDITS for list of people who contributed to this* project.** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License as* published by the Free Software Foundation; either version 2 of* the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston,* MA 02111-1307 USA*/@文件包含处理#include <config.h>@由顶层的mkconfig生成,其中只包含了一个文件:configs/<顶层makefile中6个参数的第1个参数>.h#include <version.h>#include <status_led.h>/********************************************************************** ****** Jump vector table as in table 3.1 in [1]********************************************************************* *****/@向量跳转表,每条占一字节,地址范围为0x0000 0000~0x0000 0020@ARM体系结构规定在上电复位后的起始位置,必须有8条连续的跳转指令,通过硬件实现。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
U-BOOT一、U-BOOT的目录结构u-boot目录下有18个子目录,分别存放管理不通的源程序。
这些目录中所要存放的文件有其规则,可以分成三类。
■第一类目录与处理器体系结构或者开发板硬件直接相关;■第二类目录是一些通用的函数或者驱动程序;■第三类目录是u-boot的应用程序、工具或者文档。
Board:和一些已有开发板相关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
Common:与体系结构无关的文件,实现各种命令的C文件。
CPU:CPU相关文件,其中的子目录都是以u-boot所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c 和 interrupt.c和start.S。
其中cpu.c初始化cpu、设置指令cache和数据cache 等;interrupt.c设置系统的各种终端和异常,比如快速中断,开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是u-boot启动时执行的第一个文件,他主要是设置系统堆栈和工作发式,为进入C程序奠定基础。
Disk:disk驱动的分区处理代码、Doc:文档。
Drivers:通用设备驱动程序,比如各种网卡、支持CFI的flash、串口和USB 总线等。
Dtt:数字温度测量器或者传感器的驱动Examples:一些独立运行的应用程序的例子。
Fs:支持文件系统的文件,u-boot现在支持cramfs、fat、fdos、jffs2、yaffs 和 registerfs。
Include:头文件,还有对各种硬件平台支持的会变文件,系统的配置文件和对文件系统支持的文件。
Net:与网络有关的代码,BOOTP协议、TFTP协议RARP协议和NFS文件系统的实现。
Lib_ppc:存放对PowerPC体系结构通用的文件,主要用于实现PowerPC平台通用的函数,与PowerPC体系结构相关的代码。
Lib_i386:存放对X86体系结构通用的文件,主要用于实现X86平台通用的函数,与PowerPc体系结构相关的代码。
Lib_arm:存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数,与ARM体系结构相关的代码。
Lib_generic:通用的多功能函数实现。
Post:上电自检。
Rtc:实时时钟驱动。
Tools:创建S-Record格式文件和U-BOOT images的工具。
二、u-boot的编译u- boot的源码是通过GCC和Makefile组织编译的,顶层目录下的Makefile首先可以设置板子的定义,然后递归地调用各级目录下的 Makefile,最后把编译过的程序链接成u-boot的映像。
顶层目录下的Makefile,它是负责U-Boot整体配置编译。
每一种开发板在Makefile都需要有板子配置的定义,如smdk2442定义如下:smdk2442_config: unconfig@./mkconfig $(@:_config=) arm arm920t smdk2442执行配置U-Boot的命令make smdk2442_config,通过./mkconfig脚本生成include/config.mk的配置文件。
文件内容是根据Makefile对板子的配置生成的。
配置环境和编译过程如下所述,U-boot的编译环境配置需要:cross-2.95.3.tar.bz2和 s3c24x0_uboot_rel_0_0_1_061002.tar.bz2,将文件拷贝到/home/amoi/working/下,(chenpx@chenpx:/mnt/hgfs/share$ cp cross-2.95.3.tar.bz2 /home/amoi/working和chenpx@chenpx:/mnt/hgfs/share$ cp s3c-u-boot-1.1.6.tar.bz2/home/amoi/working),然后对对文件进行解压(chenpx@chenpx:/home/chenpx/working$ tar jxvf cross-2.95.3.tar.bz2和chenpx@chenpx:/home/chenpx/working$ tar jxvf s3c24x0_uboot_rel_0_0_1_061002.tar.bz2),在/usr/local/目录下建立一个arm文件夹(mkdir –p /usr/local/arm (-p 是需要时创建上层目录,如目录早已存在则不当作错误))将cross-2.95.3.tar.bz2解压出来的移动到/usr/local/arm/下(mv 2.95.3 /usr/local/arm/)移动后添加环境变量export PATH=$PATH:/usr/local/2.95.3/bin/修改s3c24x0_uboot_dev中的makefile, 修改CROSS_COMPILE =/usr/local/arm/2.95.3/bin/arm-linux-其他的用#注释掉。
接下来就是加载配置:最后进行编译:make,最终在s3c24x0_uboot-dev目录下生成u-boot、u- boot.bin、u-boot.map、2 u-boot.srec四个文件。
三、u-boot系统启动流程大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。
依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
1、Stage1 start.S代码结构u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口。
由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
(2)设置异常向量(Exception Vector)。
(3)设置CPU的速度、时钟频率及终端控制寄存器。
(4)初始化内存控制器。
(5)将 ROM中的程序复制到RAM中。
(6)初始化堆栈。
(7)转到RAM中执行,该工作可使用指令ldr pc来完成。
2、 Stage2 C语言代码部分lib_arm/board.c中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作:(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
3、U-Boot的启动顺序下面就根据代码进行解释:/*********************** 中断向量 ***********************/.globl _start //u-boot启动入口_start: b reset //复位向量并且跳转到resetldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irq //中断向量ldr pc, _fiq //中断向量b sleep_setting //跳转到sleep_setting并通过下段代码拷贝到内存里relocate: //把uboot重新定位到RAMadr r0, _start // r0 是代码的当前位置ldr r2, _armboot_start //r2 是armboot的开始地址ldr r3, _armboot_end //r3 是armboot的结束地址sub r2, r3, r2 // r2得到armboot的大小ldr r1, _TEXT_BASE // r1 得到目标地址add r2, r0, r2 // r2 得到源结束地址copy_loop: //重新定位代码ldmia r0!, {r3-r10} //从源地址[r0]中复制stmia r1!, {r3-r10} //复制到目标地址[r1]cmp r0, r2 //复制数据块直到源数据末尾地址[r2] ble copy_loop系统上电或reset后,cpu的PC一般都指向0x0地址,在0x0地址上的指令是reset: //复位启动子程序/******** 设置CPU为SVC32模式***********/mrs r0,cpsr //将CPSR状态寄存器读取,保存到R0中bic r0,r0,#0x1forr r0,r0,#0xd3msr cpsr,r0//将R0写入状态寄存器中/************** 关闭看门狗 ******************/ldr r0, =pWTCONmov r1, #0x0str r1, [r0]/************** 关闭所有中断 *****************/mov r1, #0xffffffffldr r0, =INTMSKstr r1, [r0]ldr r2, =0x7ffldr r0, =INTSUBMSKstr r2, [r0]/************** 初始化系统时钟 *****************/ldr r0, =LOCKTIMEldr r1, =0xffffffstr r1, [r0]clear_bss:ldr r0, _bss_start //找到bss的起始地址add r0, r0, #4 //从bss的第一个字开始ldr r1, _bss_end // bss末尾地址mov r2, #0x00000000 //清零clbss_l:str r2, [r0] // bss段空间地址清零循环add r0, r0, #4cmp r0, r1bne clbss_l/***************** 关键的初始化子程序 ************************// * cpu初始化关键寄存器* 设置重要寄存器* 设置内存时钟* /cpu_init_crit:/** flush v4 I/D caches*/mov r0, #0mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB *//************* disable MMU stuff and caches ****************/mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)orr r0, r0, #0x00000002 @ set bit 2 (A) Alignorr r0, r0, #0x00001000 @ set bit 12 (I) I-Cachemcr p15, 0, r0, c1, c0, 0/******* 在重新定位前,我们要设置RAM的时间,因为内存时钟依赖开发板硬件的,你将会找到board目录底下的 memsetup.S。