2-4 UBoot源码分析1解析

合集下载

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

U-Boot分析报告

U-Boot分析报告

cpu_init_f
其中cpu_init_f位于\cpu\mcf5227x\ 其中cpu_init_f位于\cpu\mcf5227x\cpu_init.c cpu_init_f位于 主要完成以下工作: 主要完成以下工作:
/* * Breath some life into the CPU * * Set up the memory map, * initialize a bunch of registers, * initialize the UPM's */
2.\lib_m68k\board.c系统初始化分析 2.\lib_m68k\board.c系统初始化分析
主要包括刚才涉及的两个函数: 主要包括刚才涉及的两个函数: 1. cpu_init_f 2. board_init_r 下面我们简要分析一下board.c 下面我们简要分析一下board.c
U-Boot的后续工作 Boot的后续工作
进入u boot主循环,并循环调用调用main_loop 进入u-boot主循环,并循环调用调用main_loop 主循环 Bootdelay到期后,会调用run_command函数, Bootdelay到期后,会调用run_command函数,自动执 到期后 run_command函数 bootcmd命令 行bootcmd命令 在run_command函数中调用函数指针cmdtp->cmd来启 run_command函数中调用函数指针cmdtp->cmd来启 函数中调用函数指针cmdtp do_bootm命令 动do_bootm命令 解析镜像的头部,需要解压的就调用解压缩函数解压, 解析镜像的头部,需要解压的就调用解压缩函数解压,就调 do_bootm_linux()去调用去加载linux系统镜像 去调用去加载linux 用do_bootm_linux()去调用去加载linux系统镜像 获取并设置Linux启动参数列表和机器号, 获取并设置Linux启动参数列表和机器号,最后调用函数指 Linux启动参数列表和机器号 针theKernel(0,machid,bd->bi_boot_params) theKernel(0,machid,bd-

uboot代码剖析

uboot代码剖析

Uboot 代码剖析黄雪莉代码重定位编译器在编译一段程序链接过程中,要对所有目标文件进行重定位,建立符号引用规则,同时为变量,函数等分配地址。

程序执行时,把代码加载到链接时指定的地址空间,以保证程序在执行过程中对变量,函数等符号的正确引用,是程序正常运行。

但是在操作系统中,一个进程通常从硬盘等二级存储设备拷贝到内存中去执行,这两者的地址是不同的,因此操作系统要对这个进程进行重定位,才能正确运行该进程。

位置不相关代码:在设计系统引导程序如bootloader时,一般为了提高速度,需要将bootloader 从ROM拷贝到RAM中去执行,这两者的地址也不同。

如果这些代码即使不在链接时指定的地址空间也能正确运行,这就是位置无关代码(position independent code)。

PIC的特点是,它被加载到任意地址空间都可以正确的执行。

其原理是PIC对常量和函数入口地址的操作都是基于PC+偏移量的寻址方式。

即使程序被移动,但是PC也变化了,而偏移量是不变的,所以程序仍然可以找到正确的入口地址或者常量。

位置代码无关在U-boot中的实现:U-Boot中用GOT表(Global Offset Table 全局偏移量表)实现PIC代码位置无关,总的来讲,U-Boot依靠维护GOT表来实现,在GOT表中存放一些全局label 的表项,这些表项记录重要的地址;运行在Flash时,GOT表中存放的是编译时全局label的值(地址);当U-Boot运行时检测RAM大小进行代码搬运之后,利用代码搬运前后产生的地址偏移对(相对偏移)GOT表中的各个表项值进行更新,使其记录RAM中的相应的地址。

这样代码运行时不会出现代码/变量地址出错的问题。

主要代码剖析1.关于GOT的主要宏定义(include/ppc_asm.tmpl)2. .got2段的声明3.上电复位,从flash的起始地址读取硬件复位配置字HRCW(Hard Reset Configuration Word),每次都8位,每四次组成一个32位配置字,分别组成低32位配置字和高32位配置字,分别存放在CFG_HRCW_LOW 和CFG_HRCW_HIGH寄存HRCW控制时钟及其他硬件的功能,如PCI host和Agent模式,启动位置和大小端。

U-boot代码解析

U-boot代码解析

u-boot源码解析u-boot介绍Uboot是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序, UBoot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS 嵌入式操作系统。

UBoot除了支持PowerPC系列的处理器外,还能支持MIPS、 x86、ARM、NIOS、XScale等诸多常用系列的处理器。

board:和一些已有开发板有关的文件。

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

它的每个子文件夹里都有如下文件:makefileconfig.mksmdk2410.c 和板子相关的代码(以smdk2410为例)flash.c Flash操作代码memsetup.s 初始化SDRAM代码u-boot.lds 对应的连接文件common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。

例如bootm命令对应就是cmd_bootm.c。

cpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录arm920t等。

cpu/ 它的每个子文件夹里都有如下文件:makefileconfig.mkcpu.c 和处理器相关的代码interrupts.c 中断处理代码serial.c 串口初始化代码start.s 全局开始启动代码disk:对磁盘的支持。

doc:文档目录。

Uboot有非常完善的文档,推荐大家参考阅读。

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

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

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

UBOOT源码分析

UBOOT源码分析

UBOOT源码分析UBOOT是一种开放源码的引导加载程序。

作为嵌入式系统启动的第一阶段,它负责初始化硬件设备、设置系统环境变量、加载内核镜像以及跳转到内核开始执行。

Uboot的源码是开放的,让我们可以深入了解其内部工作机制和自定义一些功能。

Uboot源码的文件组织结构非常清晰,主要分为三个大类:目录、文件和配置。

其中目录包含了一系列相关的文件,文件存放具体的源码实现代码,配置文件包含了针对特定硬件平台的配置选项。

Uboot源码的核心部分是启动代码,位于arch目录下的CPU架构相关目录中。

不同的CPU架构拥有不同的启动代码实现,如arm、x86等。

这些启动代码主要包括以下几个关键功能:1. 初始化硬件设备:Uboot首先需要初始化硬件设备,例如设置时钟、中断控制器、串口等设备。

这些初始化操作是在启动代码中完成的。

通过查看该部分代码,我们可以了解硬件的初始化过程,以及如何配置相关寄存器。

2. 设置启动参数:Uboot启动参数存储在一个称为"bd_info"的数据结构中,它包含了一些关键的设备和内存信息,例如DRAM大小、Flash 大小等。

这些参数是在启动代码中设置的,以便内核启动时能够正确识别硬件情况。

3. 加载内核镜像:Uboot负责加载内核镜像到内存中,以便内核可以正确执行。

在启动代码中,会通过读取Flash设备或者网络等方式,将内核镜像加载到指定的内存地址处。

加载过程中,可能会进行一些校验和修正操作,以确保内核数据的完整性。

4. 启动内核:在内核镜像加载完成后,Uboot会设置一些寄存器的值,并执行一个汇编指令,跳转到内核开始执行。

此时,Uboot的使命即结束,控制权交由内核处理。

除了启动代码,Uboot源码中还包含了许多其他功能模块,如命令行解析器、存储设备驱动、网络协议栈等。

这些功能模块可以根据需求进行配置和编译,以满足不同平台的需求。

例如,可以通过配置文件选择启用一些功能模块,或者自定义一些新的功能。

嵌入式linux开发uboot启动过程源码分析(一)

嵌入式linux开发uboot启动过程源码分析(一)

嵌⼊式linux开发uboot启动过程源码分析(⼀)⼀、uboot启动流程简介与⼤多数BootLoader⼀样,uboot的启动过程分为BL1和BL2两个阶段。

BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常⽤汇编语⾔来实现;BL2阶段主要是对外部设备如⽹卡、Flash等的初始化以及uboot命令集等的⾃⾝实现,通常⽤C语⾔来实现。

1、BL1阶段uboot的BL1阶段代码通常放在start.s⽂件中,⽤汇编语⾔实现,其主要代码功能如下: (1)指定uboot的⼊⼝。

在链接脚本uboot.lds中指定uboot的⼊⼝为start.S中的_start。

(2)设置异常向量(exception vector) (3)关闭IRQ、FIQ,设置SVC模式 (4)关闭L1 cache、设置L2 cache、关闭MMU (5)根据OM引脚确定启动⽅式 (6)在SoC内部SRAM中设置栈 (7)lowlevel_init(主要初始化系统时钟、SDRAM初始化、串⼝初始化等) (8)设置开发板供电锁存 (9)设置SDRAM中的栈 (10)将uboot从SD卡拷贝到SDRAM中 (11)设置并开启MMU (12)通过对SDRAM整体使⽤规划,在SDRAM中合适的地⽅设置栈 (13)清除bss段,远跳转到start_armboot执⾏,BL1阶段执⾏完2、BL2阶段start_armboot函数位于lib_arm/board.c中,是C语⾔开始的函数,也是BL2阶段代码中C语⾔的,同时还是整个u-boot(armboot)的主函数,BL2阶段的主要功能如下: (1)规划uboot的内存使⽤ (2)遍历调⽤函数指针数组init_sequence中的初始化函数 (3)初始化uboot的堆管理器mem_malloc_init (4)初始化SMDKV210开发板的SD/MMC控制器mmc_initialize (5)环境变量重定位env_relocate (6)将环境变量中⽹卡地址赋值给全局变量的开发板变量 (7)开发板硬件设备的初始化devices_init (8)跳转表jumptable_init (9)控制台初始化console_init_r (10)⽹卡芯⽚初始化eth_initialize (11)uboot进⼊主循环main_loop⼆、uboot程序⼊⼝分析1、link.lds链接脚本⽂件分析u-boot.lds⽂件是uboot⼯程的链接脚本⽂件,位于board\samsung\smdkc110⽬录下,对于⼯程项⽬编译后期的链接阶段⾮常重要,决定了uboot程序的组装。

uboot源码分析(2)uboot环境变量实现简析

uboot源码分析(2)uboot环境变量实现简析

uboot源码分析(2)uboot环境变量实现简析uboot 环境变量实现简析----------基于u-boot-2010.03u-boot的环境变量是使⽤u-boot的关键,它可以由你⾃⼰定义的,但是其中有⼀些也是⼤家经常使⽤,约定熟成的,有⼀些是u-boot⾃⼰定义的,更改这些名字会出现错误,下⾯的表中我们列出了⼀些常⽤的环境变量:bootdelay 执⾏⾃动启动的等候秒数baudrate 串⼝控制台的波特率netmask 以太⽹接⼝的掩码ethaddr 以太⽹卡的⽹卡物理地址bootfile 缺省的下载⽂件bootargs 传递给内核的启动参数bootcmd ⾃动启动时执⾏的命令serverip 服务器端的ip地址ipaddr 本地ip 地址stdin 标准输⼊设备stdout 标准输出设备stderr 标准出错设备上⾯只是⼀些最基本的环境变量,请注意,板⼦⾥原本是没有环境变量的,u-boot的缺省情况下会有⼀些基本的环境变量,在你执⾏了saveenv之后,环境变量会第⼀次保存到flash或者eeprom中,之后你对环境变量的修改,保存都是基于保存在flash中的环境变量的操作。

环境变量可以通过printenv命令查看环境变量的设置描述,通过setenv 命令进⾏重新设置,设置完成后可以通过saveenv将新的设置保存在⾮易失的存储设备中(nor flash 、nand flash 、eeprom)。

例如:setenv bootcmd "nand read 0x30008000 0x80000 0x500000;bootm 0x30008000"saveenv通过这两条命令就完成了环境变量bootcmd的重新设置,并讲其保存在固态存储器中。

下⾯简单分析下uboot中环境变量的实现流程。

uboot启动后,执⾏玩start.S中的汇编程序,将跳⼊board.c 中定义的start_arm_boot()函数中,在该函数中,uboot讲完成板⼦外设和相关系统环境的初始化,然后进⼊main_loop循环中进⾏系统启动或者等待与⽤户交互,这其中就包括环境变量的初始化和重定位。

uboot源码分析

uboot源码分析

U-Boot源码分析(u-boot-2009.03)hzb我们开始学习uboot,对于linux我还是个新手,在这只是对学习uboot做下笔记,文中错误之处请谅解。

一、cpu/arm920t/start.S分析#include<config.h>@该文件是第二步中mkconfig文件执行时创建的。

include/config.h#include<version.h>@global声明一个符号可被其他文档引用,相当于声明了一个全局变量。

@该部分为处理器的异常处理向量表。

地址范围为0x00000000~0x00000020,刚好8条指令。

.globl_start_start:b reset@uboot的主入口,跳到后面的标号reset处执行ldr pc,_undefined_instructionldr pc,_software_interruptldr pc,_prefetch_abortldr pc,_data_abortldr pc,_not_usedldr pc,_irqldr pc,_fiq@.word为定义一个4字节的空间_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.balignl16,0xdeadbeef_TEXT_BASE:.word TEXT_BASE@由链接器脚本决定,在/borad/samsung/smdk2410/config.mk.globl_armboot_start_armboot_start:.word_start@_start是在起始代码处定义的标号,当跳到_armboot_start后还是会跳转到_start .globl_bss_start_bss_start:.word__bss_start@在board/samsung/smdk2410/u-boot.lds中定义了__bss_start.globl_bss_end_bss_end:.word_end@在board/samsung/smdk2410/u-boot.lds中定义了__bss_start#ifdef CONFIG_USE_IRQ@这个宏在include/configs/smdk2410.h中定义,可以取消。

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

struct tag_பைடு நூலகம்eader { u32 size; u32 tag; };
//每个参数的大小 //每个参数的类型
do_bootm_linux流程
• 在do_bootm_linux函数(Uboot/lib_arm/bootm.c)中定义函 数指针theKernel函数指针,并通过读取Linux的内核镜像文 件uImage前面的40字节内容获取Linux内核的入口地址 – theKernel = (void (*)(int, int, uint))images->ep;
• UBoot如何给内核传递参数?
– UBoot和内核交互是单向的,两个程序不能同时运行,那么要实 现参数传递只能通过把参数存放到一个固定内存位置然后调用 theKernel函数给对R0,R1,R2寄存器赋值。Linux启动调用 start_kernel函数读取内容即可。
do_bootm_linux函数
• UBoot如何调用Linux内核?
– UBoot通过命令把Linux内核镜像文件从Flash中读取到内存的某一 位置,然后设置PC寄存器执向该位置UBoot调用Linux内核的
前提条件是?
– R0 =0 – R1=适当的机器码 机器码的位置存放在 linux/arch/arm/tools/mach-type文件中 – R2 =启动参数标记列表在内存中的位置 – CPU必须设置为SVC模式并关闭中断 – MMU必须关闭
theKernel (0, machid, bd->bi_boot_params); //启动Linux内核
theKernel函数
• 参数 zero:设置为0 R0寄存器为0 • 参数:arch 表示机器存储于R1寄存器中 • 参数:params用于传递给Linux的参数地址 (包括命令行参数信息)
• do_bootm_linux是UBoot真正启动Linux的 函数(位于UBoot所在目录/lib_arm/bootm.c)
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; void (*theKernel)(int zero, int arch, uint params); .................. theKernel = (void (*)(int, int, uint))images->ep; //传递Linux内核首地址
tag结构体
struct tag { struct tag_header hdr; union { struct tag_core struct tag_mem32 struct tag_videotext struct tag_ramdisk struct tag_initrd struct tag_serialnr struct tag_revision struct tag_videolfb struct tag_cmdline 。。。。。。。 struct tag_memclk } u; }; core; //列表的开始 mem; //描述内存信息 videotext; // ramdisk; initrd; serialnr; //串口信息 revision; //版本信息 videolfb; cmdline; //命令行 memclk; //内存时钟
tag_list参数列表
• UBoot如何组织这么多的参数信息呢?
– UBoot使用struct tag 和struct tag_head来描述这些参数信息。存放位置 (include/asm-arm/setup.h) – 相对应的在Linux内核源代码中也有完全相同的结构体定义存放位置 (linux/arch/arm/include/asm/setup.h) – – – – – – – – – #define ATAG_CORE 0x54410001 #define ATAG_MEM 0x54410002 #define ATAG_VIDEOTEXT 0x54410003 #define ATAG_RAMDISK 0x54410004 #define ATAG_INITRD 0x54410005 #define ATAG_SERIAL 0x54410006 #define ATAG_REVISION 0x54410007 #define ATAG_CMDLINE 0x54410009 #define ATAG_NONE 0x000000001
– 编译Linux内核时可以通过make menuconfig命 令进行命令行参数的配置 – Uboot引导的时候传递启动参数参数地址给内 核。
命令行参数
参数信息
• u-boot要传递给内核的参包含哪些内容?
– MACH_TYPE(即我们所说的机器码)、 – 命令行参数CommandLine – 系统根设备信息(标志,页面大小)、 – 内存信息(起始地址,大小)、 – RAMDISK信息(起始地址,大小)、压缩的 RAMDISK根文件系统信息(起始地址,大小)。 由此可见要传递的参数很多
• UBoot源码解析(一)
主要内容
• 分析UBoot是如何引导Linux内核 • UBoot Makefile分析 • UBoot源码的一阶段解析
UBoot存储空间分布
• UBoot是用来引导OS系统启动,那么它是如何引 导OS启动的呢?
启动参数
内核
根文件系统
bootloader
UBoot和内核的交互
(*theKernel)(int zero, int arch, uint params);
启动参数
• Linux内核启动的时候并不会自己去扫描硬 件的基本信息,因为它启动时都已经假设硬 件都已经准备好了,但是使用过程中不可 避免的要用到硬件信息,这些信息包括内 存大小,串口配置信息等等。那么这信息内 核是如何获的呢?
相关文档
最新文档