DM365 uboot启动分析

合集下载

u-boot启动分析

u-boot启动分析

背景:Board →ar7240(ap93)Cpu →mips1、首先弄清楚什么是u-bootUboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。

除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。

2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件):以下为为每个目录的说明:Board:和一些已有开发板有关的文件。

每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。

它的每个子文件夹里都有如下文件(以ar7240/ap93为例):MakefileConfig.mkAp93.c 和板子相关的代码Flash.c Flash操作代码u-boot.lds 对应的链接文件common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。

例如bootm命令对应就是cmd_bootm.ccpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录mips等。

它的每个子文件夹里都有入下文件:MakefileConfig.mkCpu.c 和处理器相关的代码sInterrupts.c 中断处理代码Serial.c 串口初始化代码Start.s 全局开始启动代码Disk:对磁盘的支持Doc:文档目录。

Uboot有非常完善的文档。

Drivers:Uboot支持的设备驱动程序都放在该目录,比如网卡,支持CFI的Flash,串口和USB等。

Fs:支持的文件系统,Uboot现在支持cramfs、fat、fdos、jffs2和registerfs。

Include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。

该目下configs目录有与开发板相关的配置文件,如ar7240_soc.h。

U-boot启动流程分析(三)

U-boot启动流程分析(三)

U-boot 启动流程(Linux 内核)的分析(三)U-boot 属于两阶段的Bootloader ,第一阶段的文件为cpu/arm920t/start.S 和board\samsung\smdk2410/lowlevel_init.S,前者是平台相关的,后者是开发板相关的。

1.U-Boot 第一阶段代码分析(1)硬件设备初始化依次完成如下设置:将CPU 的工作模式设为管理模式(SVC ),关闭WATCHDOG ,设置FCLK ,HCLK ,PCLK 的比例,关闭MMU ,CACHE 。

代码在cpu/arm920t/start.S 中,(2)为加载Bootloader 的第二阶段代码准备RAM 空间。

所谓准备RAM 空间,就是初始化内存芯片,使它可用,对于S3C24x0,通过在Start.S 中调用lowlevel_init 函数来设置存储控制器,使得外接 SDRAM 可用,lowlevel_init.S,文件是与开发板相关的,这表示如果外接的设备不一样,可以修改lowlevel_init.S 文件中的相关的宏。

(3)复制Bootloader 的第二阶段代码到RAM 空间中 这里将整个U-Boot 代码都复制到SDRAM 中,这在cpu/arm920t/start.s 中实现上面这段程序,在使用NANDFlash 启动时,需要修改。

(4)设置好栈 /*栈的设置灵活性很大,只要让sp 寄存器指向一段没有使用的内存即可*/.word TEXT_BASE //这里是获得代码段的起始地址,我的是0x33F80000(在board/xxx/config.mk中//可到找到“TEXT_BASE=0x33F80000”.globl lowlevel_init //这里相当于定义一个全局的lowlevel_init以方便调用lowlevel_init :/* memory control configuration *//* make r0 relative the current location so that it *//* reads SMRDATA out of FLASH rather than memory ! */ldr r0, =SMRDATA //SMDATA表示这 13个寄存器的值存放的开始地址,值为0x33F8xxxx,处于内//存中,这一句的作用是把其值加载到r0中ldr r1, _TEXT_BASE // 把代码的起始地址(0x33F80000)加载到r1中sub r0, r0, r1 //r0减去r1其结果存入r0,也即SMDATA中的起始地址0x33F8xxxx减去//0x33F80000,其结果就是13个寄存器的值在NOR Flash存放的开始地址ldr r1, =BWSCON /* Bus Width Status Controller */ //存储控制器的基地址add r2, r0, #13*4 //在计算出来的存放地址加上#13*4,然后其结果保存在r2中//13 个寄存器,每个寄存器占4个字节0:ldr r3, [r0], #4 //内存中r0的值加载到r3中,然后r0加4,即下一个寄存器的str r3, [r1], #4 //读出寄存器的值保存到r1中,然后r1也偏移4cmp r2, r0 //比较r0与r2的值,如果不等继续返回0:执行,也即13个寄存器的值// 是否读完bne 0b/* everything is fine now */mov pc , lr //程序跳转,返回到cpu_init_crit中.ltorg/* the literal pools origin */SMRDATA :...................relocate : /* 将U-Boot复制到RAM中 */adr r0, _start /* r0:当前代码的开始地址 */ldr r1, _TEXT_BASE /* r1:代码段的连接地址*/cmp r0, r1 /* 测试现在是在FLash中,还在是RAM中,如果要从NandFlash启动的话,这里要根据需要修改 */beq stack_setup /*如果已经在RAM中,则不需要复制*/ldr r2, _armboot_start /*_armboot_start在前面定义,是第一条指令的运行地址*/ldr r3, _bss_start /*在连接脚本U-Boot.lds中定义,是代码段的结束地址*/sub r2, r3, r2 /* r2 <- 代码段长度 */add r2, r0, r2 /* r2 <-代码段的结束地址 */copy_loop :ldmia {r3-r10} /* 从地址[r0]处获得数据 */stmia {r3-r10} /* 复制到地址[r1]处 */cmp r0, r2 /* 判断是否复制完毕 */ble copy_loop /*没有复制完,则继续*/#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ldr r0, _TEXT_BASE /* _TEXT_BASE 为代码段的开始地址,值为0x33F80000 */sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* 代码段下面,留出一段内存以实现malloc */sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* 再留出一段内存,存一些全局参数 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ +CONFIG_STACKSIZE_FIQ )#endifsub sp , r0, #12 /* 最后,留出12字节的内存给abort异常 */clear_bss :(5)跳转到第二阶段代码的C 入口点 在跳转之前,还要清除BSS 段(初始值0,无初始值的全局变量,静态变量放在BSS 段。

uboot 启动参数

uboot 启动参数

uboot 启动参数UBOOT是一种常用的启动程序,它能够运行在各种不同的硬件平台上,并且可以通过修改启动参数来适配不同的硬件环境。

下面将分步骤介绍UBOOT启动参数的相关内容。

第一步:获取UBOOT源码首先,需要在官方网站上下载UBOOT源码。

下载完成后,需要解压缩源码包,并通过命令行进入到UBOOT文件夹中。

第二步:配置启动参数配置启动参数需要修改UBOOT的配置文件。

在UBOOT源码目录下,有一个名为“config”的文件夹,其中包含了多个不同的配置文件。

每个配置文件对应着一个不同的硬件平台,可以选择对应的配置文件来进行修改。

打开对应的配置文件,找到“CONFIG_BOOTARGS”这个选项。

这个选项控制了UBOOT的启动参数,包括了启动时使用的内核命令参数、系统启动模式、显示分辨率、硬件时钟等等内容。

根据硬件的不同,需要根据实际情况来进行修改。

如果是嵌入式系统,需要将内核命令参数设置为启动时需要加载的模块和驱动程序;如果是开发板,需要指定启动模式为SD卡或者串口下载模式。

第三步:保存配置文件完成启动参数的修改后,需要保存配置文件。

保存后,可以通过编译UBOOT并将其烧录到目标硬件中。

第四步:运行UBOOT运行UBOOT的方式与平台有关。

在某些开发板上,可以通过在串口终端中运行“boot”命令来启动系统。

在嵌入式系统中,可以通过修改启动顺序来选择从NOR Flash或者SD卡中加载UBOOT。

总结通过上述步骤,可以修改UBOOT的启动参数,并实现对不同硬件平台的适配。

通过正确配置启动参数,可以使系统运行更加稳定,并且更加符合实际需求。

因此,UBOOT启动参数的修改是嵌入式开发中不可忽视的一部分。

uboot启动流程分析

uboot启动流程分析

uboot启动流程分析Uboot启动流程分析。

Uboot是一种常用的嵌入式系统启动加载程序,它的启动流程对于嵌入式系统的正常运行至关重要。

本文将对Uboot启动流程进行分析,以便更好地理解其工作原理。

首先,Uboot的启动流程可以分为以下几个步骤,Reset、初始化、设备初始化、加载内核。

接下来我们将逐一进行详细的分析。

Reset阶段是整个启动流程的起点,当系统上电或者复位时,CPU会跳转到Uboot的入口地址开始执行。

在这个阶段,Uboot会进行一些基本的硬件初始化工作,包括设置栈指针、初始化CPU寄存器等。

接着是初始化阶段,Uboot会进行一系列的初始化工作,包括初始化串口、初始化内存控制器、初始化时钟等。

这些初始化工作是为了确保系统能够正常地运行,并为后续的工作做好准备。

设备初始化阶段是Uboot启动流程中的一个重要环节,它包括对外设的初始化和检测。

在这个阶段,Uboot会初始化各种外设,如网卡、存储设备等,并对其进行检测,以确保它们能够正常工作。

最后一个阶段是加载内核,Uboot会从存储设备中加载操作系统的内核镜像到内存中,并跳转到内核的入口地址开始执行。

在这个过程中,Uboot会进行一些必要的设置,如传递启动参数给内核,并最终将控制权交给内核。

总的来说,Uboot的启动流程是一个非常重要的过程,它涉及到系统的硬件初始化、外设的初始化和内核的加载等工作。

只有当这些工作都顺利完成时,系统才能够正常地启动运行。

因此,对Uboot启动流程的深入理解对于嵌入式系统的开发和调试具有重要意义。

通过本文对Uboot启动流程的分析,相信读者对Uboot的工作原理有了更清晰的认识。

希望本文能够对大家有所帮助,谢谢阅读!。

U-Boot启动过程--详细版的完全分析

U-Boot启动过程--详细版的完全分析

(一)U-Boot启动过程--详细版的完全分析我们知道,bootloader是系统上电后最初加载运行的代码。

它提供了处理器上电复位后最开始需要执行的初始化代码。

在PC机上引导程序一般由BIOS开始执行,然后读取硬盘中位于MBR(Main Boot Record,主引导记录)中的Bootloader(例如LILO或GRUB),并进一步引导操作系统的启动。

然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动就完全由bootloader来完成。

它主要的功能是加载与引导内核映像一个嵌入式的存储设备通过通常包括四个分区:第一分区:存放的当然是u-boot第二个分区:存放着u-boot要传给系统内核的参数第三个分区:是系统内核(kernel)第四个分区:则是根文件系统如下图所示:u-boot是一种普遍用于嵌入式系统中的Bootloader。

Bootloader介绍Bootloader是进行嵌入式开发必然会接触的一个概念,它是嵌入式学院<嵌入式工程师职业培训班>二期课程中嵌入式linux系统开发方面的重要内容。

本篇文章主要讲解Bootloader 的基本概念以及内部原理,这部分内容的掌握将对嵌入式linux系统开发的学习非常有帮助!Bootloader的定义:Bootloader是在操作系统运行之前执行的一小段程序,通过这一小段程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。

意思就是说如果我们要想让一个操作系统在我们的板子上运转起来,我们就必须首先对我们的板子进行一些基本配置和初始化,然后才可以将操作系统引导进来运行。

具体在Bootloader中完成了哪些操作我们会在后面分析到,这里我们先来回忆一下PC的体系结构:PC机中的引导加载程序是由BIOS和位于硬盘MBR中的OS Boot Loader(比如LILO和GRUB等)一起组成的,BIOS在完成硬件检测和资源分配后,将硬盘MBR中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。

U-Boot启动内核分析

U-Boot启动内核分析

U-Boot启动内核分析先来引用一下这篇介绍“ARM Linux内核启动要求”的文章ARM Linux Kernel Boot Requirements,是ARM Linux内核的维护者Russell King写的。

∙CPU register settingso r0 = 0.o r1 = machine type number.o r2 = physical address of tagged list in system RAM.∙CPU modeo All forms of interrupts must be disabled (IRQs and FIQs.)o The CPU must be in SVC mode. (A special exception exists forAngel.)∙Caches, MMUso The MMU must be off.o Instruction cache may be on or off.o Data cache must be off and must not contain any stale data.∙Deviceso DMA to/from devices should be quiesced.∙The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image.大致就是以上条件了,请特别关注一下第一条,这个基本上就是U-Boot的go 命令和bootm命令之间的本质区别所在了。

先来看看bootm命令的实现,在是在这个文件内实现的(extern)。

可想而知,这个函数的实现应该是和体系结构相关的,具体到arm体系结构的实现就是在lib_arm/armlinux.c这个文件当中。

02-DM365 启动机制与Boot

02-DM365 启动机制与Boot

User Bootloader
继续在DEVICE_init函数中,下面是调用 DEVICE_DDR2Init函数来配置DDR控制器,这是 UBL中重要的一部分,如果硬件电路需要更换内存 芯片的话,需要在UBL中修改这个函数,即按照芯 片手册来配置DDR控制寄存器中的相关参数,比如 时序,BANK数,页大小等。 而后调用DEVICE_EMIFInit函数来配置EMIF模块, 调用DEVICE_UART0Init函数来配置串口0,调用 DEVICE_TIMER0Init函数来配置TIMER0,调用 DEVICE_I2C0Init函数来配置I2C控制器,都是操作 某一模块的控制寄存器实现。
Board ,cpu, lib_ppc, lib_arm, include
平台无关
Common, net, driver, fs
工具和文档
Tools, doc
U-boot启动过程的几个阶段
在Flash中运行汇编程序,将Flash中的启动代码复 制到RAM中,同时创造环境准备运行C程序; 在RAM中运行,对硬件进行初始化; 设置内核参数的标记列表,复制镜像文件,进入内 核的入口参数
Bootloader特点
Bootloader不属于操作系统内核,采用汇编语言编 写,因此针对不同的CPU体现结构,这一部分代码 不具有可移植性; 在移植操作系统时,这部分代码必须加以改写; Bootloader不但依赖于CPU的体现结构,而且依赖 于嵌入式系统板级设备的配置;
Bootloader的操作模式
TI DM36X 启动机制
BTSEL[2:0]=001时,系统加电/复位后ARM处理器 从AEMIF 执行引导启动代码,即从外部存储器 OneNand或Nor Flash启动。 AIROM支持以下启动模式 BTSEL[2:0]=000,ARM NAND Boot BTSEL[2:0]=010,ARM MMC/SD Boot BTSEL[2:0]=011,ARM UART Boot BTSEL[2:0]=100, ARM USB Boot

DM365系统烧写

DM365系统烧写

开发板DM365系统的烧写( DM365系统的烧写主要包括四方面的烧写:1.UBL的烧写 2.U-BOOT的烧写3.uImage的烧写 4.root文件系统的烧写。

UBL、U-BOOT的烧写是基于CCS3.3,而uImage 的烧写是基于TFTP,root文件系统的烧写是基于NFS )1. 基于CCS3.3烧写UBL、U-BOOT(1) CCS3.3启动完毕后,选择ARM端打开(2) 加载GEL,连接ARM(ctrl+c)(3)将Flash_Writer目录下的UBL_DM36x_NAND.bin与u-boot.bin两个文件拷贝到任意盘符根目录下,例如D:\(4) 在CCS中用File Load Program….命令,加载Flash_Writer目录下的NANDWriter_DM36x.out文件;然后点击运行,运行程序;(5) 程序会弹出下图所示对话框,输入UBL所在路径,如图输入D:\UBL_DM36x_NAND.bin,点击OK,进行UBL的烧写;(6)Ubl烧写完成后,将会弹出如下对话框,要求输入u-boot文件的路径,如图输入D:\u-boot.bin,点击OK,进行u-boot的烧写。

等待一会之后还会弹出两次下面的对话框,两次都点击OK,按默认的入口地址即可;在Stdout窗口将会显示“NAND boot preparation was successful!”字样,说明烧写完成;到此已烧写完成UBL、U-BOOT.2.基于TFTP烧写uImage(1)首先将DaVinci Linux Develop Software文件夹下SEED_DVS365-SDK.tar.gz复制到Linux下的/opt目录下,并进行解压缩安装:Host #tar -zxvf SEED_DVS365-SDK.tar.gz (过程大概需要10分钟)。

解压完成后得到dvsdk_2_10_00_17、mv_pro_5.0、nfs三个文件夹。

DM365 NAND启动模式解析

DM365 NAND启动模式解析

DM365 NAND启动模式解析首先,读取NAND的ID,可以从RBL的设备信息表中得到一些重要信息,然后,RBL在block1 page0处开始搜索UBL描述符。

若没有找到正确的UBL,会继续搜索下面的块,一直到block24结束。

这样做是为了跳过坏块,24个块几乎对所有的NAND设备都足够了。

当找到UBL标识之后,对应的块号(从1到24)被写到ARM内部RAM(指令RAM)的最后32位(0x7ffc-0x8000),假设通过JTAG通过读取这32位,你能够确定RBL是在哪个块中找到了一个正确的UBL标识。

如果搜索完24个块后没有找到正确的UBL标识,RBL会尝试从SD卡启动。

找到正确的UBL之后,读取并且处理UBL描述符,这个描述符提供了加载和控制跳转到UBL的必要信息。

然后UBL被读取并且处理。

RBL首先可能会使能一些更快的EMIF组合和基于UBL描述符中信息的指令cache操作。

通过UBL描述符可以知道在拷贝UBL期间是否使用了DMA。

一旦用户指定的启动状态被设置,RBL就复制UBL到ARM内部RAM,并且从地址0x0000 0020处启动。

NOTE:真正的拷贝实际上是从ARM内部数据RAM区0x10020-0x1781F的低30KB的空间。

将UBL读取到ARM IRAM的时候,NAND RBL使用4位的ECC来检测是否发生读错误。

若发生了错误,则通过ECC纠正算法来纠正错误。

通过冗余(24 blocks)和出错恢复来保证防止读错误。

NAND启动流程如下图所示:NAND UBL descriptor格式如下表:NOTE:ARM IRAM 的起始32个字节是ARM系统的中断向量表(IVT)(8个向量,每个4字节),复制的UBL从这32个字节的IVT之后开始启动。

在UBL descriptor中,不同的NAND启动模式可以设置不同的MAGIC IDs,下表列出了UBL标识:NAND启动详细流程:1、初始化RAM1的高2K栈空间(0x7800-0x7fff)。

u-boot启动分析

u-boot启动分析

u-boot启动分析背景:Board →ar7240(ap93)Cpu →mips1、首先弄清楚什么是u-bootUboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。

除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。

2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件):以下为为每个目录的说明:Board:和一些已有开发板有关的文件。

每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。

它的每个子文件夹里都有如下文件(以ar7240/ap93为例):MakefileConfig.mkAp93.c 和板子相关的代码Flash.c Flash操作代码u-boot.lds 对应的链接文件common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。

例如bootm命令对应就是cmd_bootm.ccpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU 在该目录下对应一个子目录,比如有子目录mips等。

它的每个子文件夹里都有入下文件:MakefileConfig.mkCpu.c 和处理器相关的代码sInterrupts.c 中断处理代码Serial.c 串口初始化代码Start.s 全局开始启动代码Disk:对磁盘的支持Doc:文档目录。

Uboot有非常完善的文档。

Drivers:Uboot支持的设备驱动程序都放在该目录,比如网卡,支持CFI的Flash,串口和USB等。

Fs:支持的文件系统,Uboot现在支持cramfs、fat、fdos、jffs2和registerfs。

Include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。

该目下configs目录有与开发板相关的配置文件,如ar7240_soc.h。

uboot源码分析2-启动第二阶段

uboot源码分析2-启动第二阶段

uboot源码分析2-启动第⼆阶段⼀、背景知识1、uboot第⼆阶段应该做什么?概括来讲uboot第⼀阶段主要就是初始化了SoC内部的⼀些部件(譬如看门狗、时钟),然后初始化DDR并且完成重定位。

由宏观分析来讲,uboot的第⼆阶段就是要初始化剩下的还没被初始化的硬件。

主要是SoC外部硬件(譬如iNand、⽹卡芯⽚····)、uboot本⾝的⼀些东西(uboot的命令、环境变量等····)。

然后最终初始化完必要的东西后进⼊uboot的命令⾏准备接受命令。

2、uboot中经常出现⼀种情况就是根据⼀个宏是否定义了来条件编译决定是否调⽤⼀个函数内部的代码。

uboot 中有2种解决⽅案来处理这种情况:⽅案⼀:在调⽤函数处使⽤条件编译,然后函数体实际完全提供代码。

⽅案⼆:在调⽤函数处直接调⽤,然后在函数体处提供2个函数体,⼀个是有实体的⼀个是空壳⼦,⽤宏定义条件编译来决定实际编译时编译哪个函数进去。

⼆、函数执⾏流程1、定义变量,gd,然后实例化2、给gd->bd赋值,内存间隔为了防⽌⾼版本的gcc的优化造成错误3、执⾏init_sequence函数,都是board级别的各种硬件初始化cpu_init():cpu内部的初始化,但在start.S初始化过,所以这⾥是空的。

board_init():⽹卡的GPIO和端⼝的配置、定义开发板的机器码、定义uboot给linux kernel启动时的传参的内存地址gd->bd->bi_boot_params=0x30000100注意:board_init中除了⽹卡的初始化之外,剩下的2⾏⽤来初始化DDR。

这⾥的初始化DDR和汇编阶段lowlevel_init中初始化DDR是不同的。

当时是硬件的初始化,⽬的是让DDR可以开始⼯作。

现在是软件结构中⼀些DDR相关的属性配置、地址设置的初始化,是纯软件层⾯的。

U-Boot启动分析

U-Boot启动分析

U-Boot启动流程(Linux内核)的分析(一)前面一段时间一直在移植U-Boot,Linux内核和构建根文件系统,其中有些地方还不是很明白,现在回过头来,理解一下U-boot的启动流程,以及u-Boot是如何加载引导内核启动的。

这里的分析也都是以U-Boot-2009.08版本为基础的,可能会和以前的版本有所不同。

在这里也不打算一句句分析U-Boot的源码,只是想把U-Boot一步一步怎么最终能够加载Linux内核的过程,分析一下。

首先,我们应该理解Bootloader是什么?它有什么作用?其实它就是系统上电后运行的和小段程序。

1 BootLoader的概念在系统上电后,需要一段程序来进行初始化:关闭WATCHDOG,改变系统时钟,初始化存储控制器,将更多的代码复制到内存中。

并将操作系统内核复制到内存中运行,这就段程序代码就叫做Bootloader。

没有一个Bootloader完全支持所有CPU,所以我们要想使用Bootloaser 一般情况下要自己进行修改,我们可以增强Bootloader的功能,让它具有网络功能,可以通过NFS远程下载Linux内核和根文件系统,可以烧写Linux内核和根文件系统到NandFlash中,而这些功能对于最终的用户来说是没有什么意义的,它们看到的只是Bootloader引导Linux内核启动这一个功能,而其余的功能只对开发人员很有用处。

也就是说在开发期间这些功能是必不可少的。

(1)启动加载模式:这种模式也称为“自主”模式。

也就是Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入,这种模式是在嵌入式产品发布里的通用模式。

(2)下载模式:在这种模式下,目标机上的Bootloader将通过串口连接或网络连接等通信手段从主机下载文件,例如:下载内核映像和根文件系统映像等。

从主机下载的文件通常首先被Bootloader保存到目标机的RAM中,然后再被Bootloader写到目标上的Flash类的固态存储设备中,Bootloader的这种模式是在在开发时使用的工作于这种模式的Bootloader通常都会向它的终端用户提供一个简单的命令行接口。

海思uboot启动流程详细分析(一)

海思uboot启动流程详细分析(一)

海思uboot启动流程详细分析(⼀)第⼀阶段 start.S⾸先我们可以在u-boot.lds中看到ENTRY(_start),即指定了⼊⼝_start,_start也就是整个start.S的最开始;1. reset在arch\arm\cpu\armv8\hi3559av100中的start.S注意x30在ARMV8中代表lr寄存器reset:/** Could be EL3/EL2/EL1, Initial State:* Little Endian, MMU Disabled, i/dCache Disabled*/adr x0, vectorsswitch_el x1, 3f, 2f, 1f3: msr vbar_el3, x0mrs x0, scr_el3orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */msr scr_el3, x0msr cptr_el3, xzr /* Enable FP/SIMD */#ifdef COUNTER_FREQUENCYldr x0, =COUNTER_FREQUENCYmsr cntfrq_el0, x0 /* Initialize CNTFRQ */#endifb 0f2: msr vbar_el2, x0mov x0, #0x33ffmsr cptr_el2, x0 /* Enable FP/SIMD */b 0f1: msr vbar_el1, x0mov x0, #3 << 20msr cpacr_el1, x0 /* Enable FP/SIMD */0:/** Cache/BPB/TLB Invalidate* i-cache is invalidated before enabled in icache_enable()* tlb is invalidated before mmu is enabled in dcache_enable()* d-cache is invalidated before enabled in dcache_enable()*//** read system register REG_SC_GEN2* check if ziju flag*/ldr x0, =SYS_CTRL_REG_BASEldr w1, [x0, #REG_SC_GEN2]ldr w2, =0x7a696a75 /* magic for "ziju" */cmp w1, w2bne normal_start_flowmov x1, sp /* save sp */str w1, [x0, #REG_SC_GEN2] /* clear ziju flag */adr x0, vectors,其中的vectors代表了异常向量表主要做了如下事情:1)reset SCTRL寄存器具体可参考reset_sctrl函数,由CONFIG_SYS_RESET_SCTRL控制,⼀般不需要打开。

U-boot的启动过程分析

U-boot的启动过程分析

U-boot的启动过程分析可执行文件及内存映射我们可以把可执行文件分为2种情况:存放态和运行态1.存放态:可执行文件经过烧到存储介质上(flash或磁盘)的分布,此时可执行文件通常有2部分组成,代码段和数据段,代码段又分为可执行代码段(.text)和只读数据段(.rodata),数据段可以分为初始化数据段(.data)和未初始化代码段(.bss),如下:+-------------+-----------|.bss|(ZI)+-------------+--数据段|.data|(RW)+-------------+-----------|.rodata||_____________|代码段(RO)|.text|+-------------+-----------2.运行态:可执行文件经过装载后就变成为运行态,当可执行文件装载后,在RAM中的分布如下:|...|+-------------+--ZI段结束地址|ZI段|+-------------+--ZI段起始地址|保留区2|+-------------+--RW段结束地址|RW段|+-------------+--RW段起始地址|保留区1|+-------------+--RO段结束地址|RO段|+-------------+--RO段起始地址所以装载过程必须完成把可执行文件的各个段搬移到RAM的指定位置,这个装载过程则是由启动程序来完成的。

而可执行代码在RAM中的地址则是由链接脚本来指定的。

一个可执行的image必须有一个入口点,并且只能有一个全局入口点,所以要通知编译器这个入口在哪里。

这个是有链接脚本来实现的,由此我们可以找到程序的入口点是在/board/lpc2210/u-boot.lds中指定的,其中ENTRY(_start)说明程序从_start开始运行,而他指向的是cpu/arm7tdmi/start.o文件。

因为我们用的是ARM7TDMI的cpu架构,在复位后从地址0x00000000取它的第一条指令,所以我们将Flash映射到这个地址上,这样在系统加电后,cpu将首先执行u-boot程序。

UBOOT 启动分析

UBOOT 启动分析
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
$(obj) 是什么?
# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
0x00FB FFAC Board Info Data and permanent copy of global data
0x00FC 0000 Malloc Arena
:
0x00FD FFFF
0x00FE 0000 RAM Copy of Monitor Code
lowlevel_init:
ldr sp, SRAM_STACK
str ip, [sp] /* stash old link register */
mov ip, lr /* save link reg across call */
- UBOOT的图片显示,新屏的移植
- gonganmin
20. UBOOT 文档
- UBOOT 的编译及Makefile 分析
- UBOOT 的启动流程分析
- UBOOT 的内存使用分析
- UBOOT 的移植
- 结合VC088x 分析AE的移植
- 启动logo 的屏幕显示
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f

TMS320DM365 NAND BOOT及源码分析

TMS320DM365 NAND BOOT及源码分析

D M3 6 5的启动方式可归为两种 , 通过 B 0 O r r S E 0 1 引脚决定。当 面只分析 U B L的启动代码。 其为 0 0 1 时, 直接从 A E MI F上启动, 如N O R和 O n e N A N D 。除此之外 入 口代码是汇编文件 s t a r t S , 主要是切换操作模式 , 建立堆栈等 , 然 都是从 R B L 启动 ,运行顺序为 R B L — U B L — U B O O T — K E R N E L , R B L 启 后跳转到 m a i n函数 ,进入到 b o a r d _ u t i l i t i e s / l f a s h u t i l s / C o m mo n / u b l / s r c 动方式如 N A N D, 串口, S D卡等等。 目录下 的 C文件 u b 1 . c 中。
1 N AN D启动流 程 U — b o o t 一 般存 在 于 D E V I C E — N A N D U B L _ S E AR C H — S T A R T _
D M3 6 5 启动模式设置根据外部硬件配置字 B T S E L [ 2 . . 0 ] , 当其值为 B L O C K 舌 的第0 页, u B L 南 D E V I C E _ N A N D _ U B L _ S E AR C H — 0 0 0 时, 为N A N D启动模式 。N A N D启动模式所用到的片选为片选 0 , S T A R T B L O C K块 向后搜索每块的第 0页, 找到 以后 , 前2 4 个字节分 其位宽及配置 由外部硬件配置字 A E C F G [ 2 . . 0 诀 定 。整个运行过程如 别记录着 u — b o o t 描述 , 如人 口函数等。 下: 首先 , 读取 N A N D F L A S H的设备 I D, 然后从 R B L的设备信息表 中 ma i n函数主要调用了 L O C A L _ b o o t 函数来进行各种引导功能 , 这 得到一些重要信息 , 如块大小 , 页大小等 , R B L的信息取决于设备所支 个 过程 完成后 ,便实现了 U B L启动 . 首先打开 N a n d F l a s h设备 , 将 持的 N A N D F AS L H的型号。紧接着 R B L在 b l o c k 1 p a g e O 处开始搜索 N a n d F l a s h的硬件信息放在 h N a n d l n f o 数据结构 内。移植 U B L时需要 U B L的描述符。如果没有找到正确的 U B L , R B L 会继续搜索下面的块 , 修改与 h N a n d l n f o 数据结构 相关 的参数 ,比如 E MI F地址( E MI F S t a r t 直到 b l o c k 2 4 为止。 这样做的 目的是为了跳过坏块 。 当找到 U B L描述 O x 0 2 0 0 0 0 O 0在 u b L c m d ; )D E V I C E — N A N D — C HI P _ i n f o T a b l e结 构 中 符后, 对应的块号( 从1 到2 4 )  ̄ j 到A R M 内部指令 RA M的最后 3 2 位 的页大小、 块数 、 块中的页数 、 … ( 0 x 7 f e 一 0 x 8 0 0 0 ) , 通过 J T A G读取这 3 2位 , 能够确定 R B L是在哪个块 先通过调用 D E V I C E — b o o t M o d e 甬数来判断启动方式 ( 通过读取 中找到了一个正确 的 U B L描述符。如果搜索完 2 4个块 唇没有找到正 S Y S寄存器实现) , 而后调用了 D E V I C E — i n i t 函数来进行平台的最底层 确的 U B L 描述符 , R B L 会尝试从其它的方式启动。 初始化 , 包括电源 , 时钟 , D D R , E M I F , U A R T , I 2 C , T I M E R等。而后通过 L s R B L找到正确 的 U B L描述符之后 , 读取并且处理 U B L描述符 , 这 UTI e t C u r r Me m P t r 函数对全局变量 c u r r M e mP t r 赋值。 接着通过判断 采取不同的处理办法 , 以 N A N D启动 为例 , 将调用 个描述符提供 了加载和控制跳转到 U B L人 口的必要信息 。然后 R B L 不 同的引导方式 , 读出 U B L 并且进行处理。 R B L 首先会使能一些更快的 E MI F 组合和基 NANDBOOT c o p y函数 。此函数将 N A N D中的某些 内容 ( 就是 U — O O T ) 搬移 到 R A M 中, 此时 U B L结束 , 控制权 正式 交 给 U B O O T 。 于U B L描述符中的信 息指令 c a c h e 操作。 通过 U B L描述符可以知道在 B 拷贝U B L 期 间是否使用 了 D M A。一旦用户设置 了指定 的启动状 态, U B L对 D M3 6 5的初 始 化 , 主要 是 调 用 D E V I C E — i n i t 函数 , 其 首 先 E V I C E _ P S C I n i t 函数实现对各模块 的电 R B L就复制 U B L到 A R M 内部 R AM,并且从地址 O x O 0 0 0 0 0 2 0处启 屏蔽和清除中断,然后调用 D 动。 源时钟使能, 然后调用 D E V I C E _ p i n mu x C o n t r o l 函数决定复用引脚的功 R B L将 U B L读取到 A R M的 I R A M 时, R B L使用 4位 的 E C C硬 能选择。接着调用 D M3 6 x / c o m mo n / s r c / d e v i c e . e 下的 D E V I C E — P L L l l n i t 件来检测是否发生读错误。若检测到发生了 4 位的E C C读错误 , U B L 函数实现了 P L L 1 的配置 ,预分频,倍频 ,后分频 ,分频到各个模块 , 则通过 E C C纠正算法来纠正错误。如果由于别的原因导致读失败 , 马 P L L 2的配 置类 似 。在 D E V I C E — i n i t 函数 中 ,接下 来 是调 用 D E — C E D D R 2 I n i t 函数来配置 D D R控制器,这是 U B L中最重要的一部 上停止考备 , R B L 会继续检测可 以使用的块 。 通过冗余和出错恢复来保 VI 证 防止 读错误 。 分, 如果硬件电路更换了内存芯片 , 需要在 U B L中修改这个 函数 , 按照 芯片手册来配置 D D R控制寄存器中的相关参数, 比如时序 , B A N K数 , 2 N A N D启 动详 细流 程 2 . 1 初始化 R A M1 的高 2 K栈空间( 0 x 7 8 0 0 — 0 】 【 7 邱。 不要使用 I R A M 页大小等。这个函数主要是操作 S Y S 模块和 D D R模块的相关寄存器 的最后 3 2个字节( 0 x T f c — O x 8 0 0 0 ) , 因为它要用来存写入 U B L的块号 。 来配置内存 ,函数中调用的 D E V I C E — L P S C T r a n s i t i o n函数用来实现模 E V I C E _ E MI F I n i t 函数来配置 2 _ 2 禁止所有中断, I R Q和 F I Q 。2 - 3 外部引脚 D E E P s L E E P Z / G 1 0 0 在芯 块 的电源时钟状态 的改变 ,而后调用 D 片为 N A N D模式启动复位时必须被置高 。2 . 4读 N A N D的设备 I D, 从 E MI F 模块, 这个模块用来接外部 F L A S H, 比如 N A N D , N O R等。 D M 3 6 5 R OM的表中获得 N A N D参数 。2 - 5 根据 N A N D l f a s h的参数初 始化 有两个 片选 空间 ,如果 某一 空 间配 置成 N A N D,则需要 在 寄存 器 中设 E V I C E — U A R T O I n i t 函数来 配置 串 口 0 ,调 用 D E — N A N D区域 。2 . 6搜索 U B L设定块号 ,通常在 C I S / I D I p a g e( 一般为 置 , 而 后 调 用 D CE T b l o c k o _ p a g e o ) 。2 . 7 U B L 描述符由以下参数组成( 所有 U B L参数位宽 VI I ME R O I n i t 函数 来 配置 T I ME R O , 调用 D E V I C E 一 1 2 C O I n i t 函数 都是 3 2 位) : 一人 口点地址 :加载 U B L之后 的绝对人 口点 ,必须在 来配置 I 2 C控制器, 都是操作某一模块的控制寄存器实现。 0 x 0 0 2 0 — 0 x 7 8 1 C之问。一 U B L占用 的 N A N D的页数 : 必须是相邻的页 , 4结论 【 _ 1 T 以跨越多个块 , 总字节觌 须小

uboot启动阶段修改启动参数方法及分析

uboot启动阶段修改启动参数方法及分析

uboot启动阶段修改启动参数⽅法及分析作者:围补本来启动⽅式这节不是什么复杂的事⼉,不过想简单的说清楚明⽩,还真是不知道怎么组织。

毕竟⽂字跟有声语⾔表达有别。

但愿简单的东西别让我讲的太复杂!Arm板系统⽂件⼀般有三个——bootloader(uboot)、kernel(uImage)及根⽂件系统(rootfs)。

在arm板上电后,按uboot->kernel->rootfs的顺序依次启动。

由于开发板上有多种存储介质,三个⽂件可以放在任何可以存储的介质上,因此也就导致⽂件的多种启动⽅式。

本⽂就来讨论,以上三个⽂件对应不通存放位置的不同启动配置。

⼀般开发板上会有flash(Nor or NAND),mmc,emmc,sd卡等。

系统⽂件可以烧写在其中的任意⼀种上,因此也就对应不通的启动。

在开发过程中,有时经常需要改动内核,或者修改应⽤程序,如果每次都修改后都重新烧写到板上的存储介质,会⽐较⿇烦。

因此,为⽅便调试,uImage和rootfs还可以从⽹络启动,即nfs启动。

但uboot只能从板上介质启动。

启动过程其实是先将要启动的⽂件从存储位置拷贝到内存空间,再在内存中运⾏。

因此所谓不同位置启动,也就是从不同位置拷贝⽽已。

下⾯我们以开发板启动为例,分别介绍三个⽂件从不同位置启动的过程⽅法。

我使⽤的开发板上有emmc和两个sd卡。

我们按照启动顺序,依次介绍。

⾸先是uboot启动。

Uboot是三个系统⽂件中第⼀个启动的,对它的拷贝⼯作由cpu中的固件决定。

固件中⽀持从⼏个位置拷贝uboot,它就能存放在⼏个位置上。

⾄于每次启动具体从其中的哪⾥开始,硬件拨码开关决定,对应拨码在开发板⼿册上能查到。

启动之前,先将uboot的⼆进制⽂件拷贝到对应介质。

有两种不同⽅法烧写,如下:1. uboot⼆进制⽂件拷贝到emmc,是通过芯⽚供应商的下载⼯具软件烧写完成;2. 拷贝到sd卡是在linux下,通过dd命令完成的。

Uboot启动过程详解

Uboot启动过程详解

Uboot启动过程详解u-boot系统启动流程大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。

依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。

1、Stage1 start.S代码结构u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下(1)定义入口。

:该工作通过修改连接器脚本来完成。

(2)设置异常向量(Exception Vector)。

(3)设置CPU的速度、时钟频率及终端控制寄存器。

(4)初始化内存控制器。

(5)将ROM中的程序复制到RAM中。

(6)初始化堆栈。

(7)转到RAM中执行,该工作可使用指令ldr pc来完成。

2、Stage2C语言代码部分 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的启动顺序主要顺序如下图所示函数顺序初始化顺序图为 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。

uboot启动流程

uboot启动流程

uboot启动流程U-Boot是一款开源的嵌入式引导加载程序(bootloader),主要用于嵌入式系统的引导启动。

它是一个跨平台的引导加载程序,可以在不同的处理器架构和操作系统上运行。

下面将介绍U-Boot的启动流程。

U-Boot启动流程主要包括三个阶段:启动ROM代码、启动SPL(Secondary Program Loader)和启动U-Boot。

首先,当嵌入式设备上电后,处理器会首先执行固定在芯片内部的启动ROM代码。

这些代码主要完成一些基本的硬件初始化工作,例如设置栈指针、初始化外设等。

然后,启动ROM 代码会从预定义的启动设备(例如闪存、SD卡等)中加载SPL。

接下来,SPL(Secondary Program Loader)被加载到内存中执行。

SPL是一个较小的引导加载程序,主要作用是完成一些必要的初始化和硬件配置。

SPL会初始化内存控制器、外设等,并加载U-Boot镜像到内存中。

最后,U-Boot被加载到内存中执行。

U-Boot是一个功能强大的引导加载程序,拥有丰富的命令和功能。

它可以根据不同的系统配置进行配置和扩展,并提供了丰富的调试和测试功能。

U-Boot的启动流程主要可以分为以下几个步骤:1. CPU初始化:U-Boot开始执行后,首先进行CPU的初始化工作,包括设置栈指针、cache的初始化等。

2. 设备初始化:接下来,U-Boot会初始化外设设备,例如串口、网络接口等。

这些设备的初始化是为了后续的调试和配置工作做准备。

3. 系统环境的初始化:U-Boot会读取存储在非易失性存储设备(例如NAND闪存、SD卡等)中的环境变量,根据这些变量进行系统的初始化配置。

4. 设备驱动的加载:U-Boot会加载并初始化必要的设备驱动程序,以便后续的硬件操作可以正常进行。

5. 启动命令的执行:U-Boot会根据配置文件中的设置,执行预定义的启动命令。

这些命令可以是启动操作系统、加载应用程序等。

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

至此启动完成。
第三阶段:启动完全,开始运行
1. main_loop()在common/main.c中
1.1 读命令readline()
由于getc最终会调用设备读接口[stdio_devices[file]->getc ()],因此此前将控制台适配为哪种设备,则现在就是和哪种设备通信;
dv_board_init:
mov pc, lr
第一个要链接的是cpu/arm920t/start.o,那么U-Boot的入口指令一定位于这个程序中。进入/u-boot/cpu/arm926ejs/。
查看start.s。流程为:
reset(复位)——cpu_init_crit(初始化CACHE,关闭MMU)——lowlevel_init(davinci/lowlevel_init.S下,设置pll,mux,memory)——relocate(把U-boot重新定位到RAM)——copy_loop(重新定位代码)——stack_setup(初始化堆栈)——clear_bss(清零bss)——clbss_l(bss段地址空间清零循环)——_start_armboot (start_armboot函数在lib_arm/board.c中实现)
第一阶段:汇编语言启动
先看u-boot/board/davinci/dm365_ipnc/下的文件。
u-boot.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
1.2 执行命令run_command()
各种命令通过U_BOOT_CMD宏被链接器搜集到.u_boot_cmd所在的__u_boot_cmd_start和 __u_boot_cmd_end区间中;具体参考include/comman.h和board/davinci/dm365/u-boot.lds;
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks 配置可用的RAM--board/davinci/dm365_ipnc/dm365_board.c */
Find_cmd中,从__u_boot_cmd_start开始查找对应命令结构体变量;如果是tftp等网络命令,则执行 do_tftpb()->netboot_common()->NetLoop();
2. netloop()
在for (;;)循环中使用eth_rx()不断接收数据,同时通过一状态机决定是否处理完毕;
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) Nhomakorabea} . = ALIGN(4);
.got : { *(.got) }
misc_init_r()
5、进行ether的MII和PHY进行初始化
使用net/eth.c中的eth_initialize()
6、main_loop /*总是试图自启动,循环不断执行*/
等待控制台命令,该命令可通过键盘输入或或者通过网络输入,不过对于main_loop命令解析层而言是透明的;
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
reloc_init, /* Set the relocation done flag, must do this AFTER cpu_init(), but as soon as possible--lib_arm/board.c */
.bss (NOLOAD) : { *(.bss) }
_end = .;
}
config.mk
TEXT_BASE = 0x81080000
board_init.s
#include <config.h>
.globl dv_board_init
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm926ejs/start.o (.text)
*(.text)
使用common/console.c中的console_init_r();这个函数中可将设备的读写接口挂在控制台的读写接口即标准输入/输出上,以实现对不同设备的适配;具体而言是由console_setfile()将dev挂入stdio_devices[file]数组;
4、各类杂项初始化,包括对eth的配置
#endif
board_init, /* basic board dependent setup 基本的板级相关配置--board/davinci/dm365_ipnc/dm365_board.c */
interrupt_init, /* set up exceptions 初始化中断处理--cpu/arm926ejs/interrupts.c */
env_init, /* initialize environment 初始化环境变量--common/cmd_flash.c(??) */
init_baudrate, /* initialze baudrate settings 初始化波特率设置--lib_arm/board.c */
4. nand
对于nand的write操作稍需注意,由于nand是按“与”操作才能写入,也就是擦除后,写入前nand中的bit值必须是1。这就意味着所写如果是 1,将不使nand的bit改变。在uboot nand的驱动中对于oob的fill也正是利用了这一点。看似将memory中的oob数据写到了nand oob中,但由于memory中的oob各bit是1,因此对nand oob值不产生影响。
serial_init, /* serial communications setup 串口通讯设置*/
console_init_f, /* stage 1 init of console 控制台初始化阶段1--/common/console.c*/
display_banner, /* say that we are here 打印u-boot信息--/lib_arm/board.c */
root@ss-desktop:/camera/u-boot/cpu/arm926ejs# ls davinci/
dp83848.c i2c.c lxt972.c nand.c timer.c
ether.c lowlevel_init.S Makefile reset.S
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
第四阶段:U-boot引导内核
1. go命令的实现
go命令调用 common/cmd_boot.c下do_go()函数,跳转到某个地址执行。如果在这个地址准备好了自引导的内核映像,就可以启动了。尽管go命令可以带变参,实际使用时一般不用来传递参数。
2. bootm命令的实现
bootm命令调用 common/cmd_bootm.c下的do_bootm函数,这个函数专门用来引导各种操作系统,可以支持引导Linux、vxworks等操作系统。引导Linux时,调用do_boom_linux()函数。
display_dram_config, /*显示RAM的配置大小--/lib_arm/board.c */
NULL,
};
2、进行nand初始化
使用driver/mtd/nand.c中的nand_init()
3、设备初始化及控制台初始化
使用common/devices.c中的devices_init();进行各设备的初始化,包括网络控制台设备的初始化drv_nc_init();在初始化过程中将dev注册到全局链表devlist中;
3. eth_rx()
这个函数实际上实现了数据由网络到上层协议栈再到应用层解析的整个过程,应用解析后会更改状态机状态;
对于tftp则是在tftp_start时由于利用NetSetHandler()指定了全局量packetHandler为TftpHandler;因此根据如下调用关系eth_rx()->net_receive()->packetHandler(),可知数据被tftphandler 处理并修改Netstate状态值;
3. do_bootm_linux函数的实现
do_bootm_linux函数在lib_arm/bootm.c下,是专门引导Linux映像的函数,它还可以处理ramdisk文件系统的映像。
在/u-boot/cpu/arm926ejs/下还有一些文件:
相关文档
最新文档