uboot2013.07lds分析

合集下载

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使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。

gcc编程环境基础4--ld命令和u-boot中的lds文件实例和简单实例分析

gcc编程环境基础4--ld命令和u-boot中的lds文件实例和简单实例分析
3.脚本格式
4.简单例子
5.简单脚本命令
6.对符号的赋值
7. SECTIONS命令
8. MEMORY命令
9. PHDRS命令
10. VERSION命令
11.脚本内的表达式
12.暗含的连接脚本
1.概论
--------------------------------------------------------------------------------
符号(symbol):每个目标文件都有符号表(SYMBOL TABLE),包含已定义的符号(对应全局变量和static变量和定义的函数的名字)和未定义符号(未定义的函数的名字和引用但没定义的符号)信息.
符号值:每个符号对应一个地址,即符号值(这与c程序内变量的值不一样,某种情况下可以把它看成变量的地址).可用nm命令查看它们. (nm的使用方法可参考本blog的GNU binutils笔记)
如果.data section的LMA为0x08050000,显然结果是j=2
如果.data section的LMA为0x08050004,显然结果是j=1
还可这样理解LMA:
.text section内容的开始处包含如下两条指令(intel i386指令是10字节,每行对应5字节):
jmp 0x08048285
-T选项用以指定自己的链接脚本,它将代替默认的连接脚本.你也可以使用<暗含的连接脚本>以增加自定义的链接命令.
以下没有特殊说明,连接器指的是静态连接器.
2.基本概念
--------------------------------------------------------------------------------

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源码中还包含了许多其他功能模块,如命令行解析器、存储设备驱动、网络协议栈等。

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

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

uboot笔记uboot命令分析+实现

uboot笔记uboot命令分析+实现

uboot笔记uboot命令分析+实现uboot笔记:uboot命令分析+实现Ubootuboot命令分析+实现先贴⼀个重要结构,位于uboot/include/command.h,这个结构代表每个uboot命令struct cmd_tbl_s {char *name; /* Command Name */int maxargs; /* maximum number of arguments*/int repeatable;/* autorepeat allowed? *//* Implementation function */int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);char *usage; /* Usage message (short)简短⽤法信息*/#ifdef CFG_LONGHELPchar *help; /* Help message (long) 长的帮助信息*/#endif#ifdef CONFIG_AUTO_COMPLETE/* do auto completion on the arguments */ int (*complete)(intargc, char *argv[], charlast_char, intmaxv, char *cmdv[]); #endif};typedefstruct cmd_tbl_s cmd_tbl_t;============================================================uboot的第⼀阶段:硬件相关初始化0.reset执⾏arm920t/start.s 过程如下1.设置cpu svc管理模式2.关看门狗中断,mmu等3.设置时钟,sdram,外部总线4.代码重定位,搬运代码,从flash到sdram5.设置栈,bss段清零, bss⽤于未初始化的全局变量和静态变量6.ldr pc, _start_armboot即进⼊uboot启动的第⼆阶段,调⽤c函数start_armboot()从start_armboot开始经过⼀系列外设初始化⽐如falsh_initnand_init...最后循环调⽤mian_loop()main_loop主要流程{1. ⽣成环境变量mtdparts, 调⽤mtdparts_init2. 在启动过程中若⽆空格键按下则boot_zImage,即run_command(getenv("bootcmd"),0)有空格键按下则run_command("menu",0)3. shell过程,读取⽤户的输⼊并执⾏相应的命令{从控制台获得命令,保存在全局变量comsole_buffer中解析命令⾏字符串,分割命令与参数,最后执⾏run_command(...); }}也就是说在mian_loop中,是处理环境变量和控制台⼈机交互,mian_loop调⽤readline ()读取命令⾏到console_buffer,再把console_buffer复制到lastcommand中去,还要设置flag,最后调⽤run_command (lastcommand, flag)函数,run_command (lastcommand, flag)函数中,⾸先定义cmd_tbl_t *cmdtp,再解析命令⾏。

u_boot移植(五)之分析uboot源码中nand flash操作

u_boot移植(五)之分析uboot源码中nand flash操作

u_boot移植(五)之分析uboot源码中nand flash操作一、OneNand 和Nand Flash我们已经能从Nand Flash启动了,启动之后,大家会看到如下效果:可以看出,我们的uboot默认使用的是OneNand。

需要注意的是我们的FSC100上面是没有OneNand的,有的是K9F2G08U0B型号的NAND FLASH。

前面我们了解过Nor Flash 和Nand Flash,那OneNand Flash又是什么呢?二、uboot 源码中Nand Flash部分代码分析我们从Nand Flash初始化看起,打开lib_arm/board.c文件,为了紧抓主线,以下代码只列举出了主线代码。

可以看出,我们可以通过CONFIG_CMD_NAND和CONFIG_CMD_ONENAND两个宏来选择NAND FLASH初始化还是 ONENAND FLASH初始化。

uboot 中默认定义了宏CONFIG_CMD_ONENAND,所以选择的是ONENAND FLASH初始化。

我们的FSC100上面使用的是NAND FLASH,所以我们要定义CONFIG_CMD_NAND宏,取消CONFIG_CMD_ONENAND宏的定义。

嗯!先做个记录:修改include/configs/fsc100.h,定义宏CONFIG_CMD_NAND,取消宏CONFIG_CMD_ONENAND。

好了,接下我们看看nand_init()函数时如何实现的。

看以看出,这段代码调用根据CONFIG_SYS_MAX_NAND_DEVICE宏[默认没有定义]的值来决定系统中Nand Flash设备的个数。

接着调用nand_init_chip()函数完成Nand Flash初始化,然后计算出每块Nand Flash的大小。

最终会输出Nand Flash总的容量。

嗯!做个记录:修改include/configs/fsc100.h,定义宏CONFIG_SYS_MAX_NAND_DEVICE,值为1没有看明白的地方是给nand_init_chip()函数传递的参数,接下来我们来看看他们是如何定义的。

uboot启动流程分析

uboot启动流程分析

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UBOOT的lds文件

UBOOT的lds文件

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")/*指定输出可执行文件是elf格式,32位ARM指令,小端*/OUTPUT_ARCH(arm)/*指定输出可执行文件的平台为ARM*/ENTRY(_start)/*指定输出可执行文件的起始代码段为_start*/SECTIONS{/*指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。

必须使编译器知道这个地址,通常都是修改此处来完成*/. = 0x00000000;/*;从0x0位置开始*/. = ALIGN(4);/*代码以4字节对齐*/.text :{cpu/arm920t/start.o (.text)/*代码的第一个代码部分*/*(.text)/*下面依次为各个text段函数*/}. = ALIGN(4);/*代码以4字节对齐*/.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }/*指定只读数据段*/. = ALIGN(4);/*代码以4字节对齐*/.data : { *(.data) }. = ALIGN(4);/*代码以4字节对齐*/.got : { *(.got) }/*指定got段, got段是uboot自定义的一个段, 非标准段*/. = .;__u_boot_cmd_start = .;/*把__u_boot_cmd_start赋值为当前位置, 即起始位置*/.u_boot_cmd : { *(.u_boot_cmd) }/*指定u_boot_cmd段, uboot把所有的uboot命令放在该段.*/__u_boot_cmd_end = .;/*把__u_boot_cmd_end赋值为当前位置,即结束位置*/. = ALIGN(4);/*代码以4字节对齐*/__bss_start = .;/*把__bss_start赋值为当前位置,即bss段的开始位置*/.bss (NOLOAD) : { *(.bss) . = ALIGN(4); }/*指定bss段,告诉加载器不要加载这个段*/__bss_end = .;/*把_end赋值为当前位置,即bss段的结束位置*/}看完上面的解析思路本来应该是很清晰的,于是乎编译u-boot,查看一下System.map,30100000 T _start30100020 t _undefined_instruction30100024 t _software_interrupt30100028 t _prefetch_abort3010002c t _data_abort30100030 t _not_used30100034 t _irq30100038 t _fiq发现_start 的链接地址不是u-boot.lds中.text 的当前地址0x00000000,而是0x30100000,这就产生很多疑问了:(1) 为什么u-boot.lds指定的 .text 的首地址不起作用?(2) 0x30100000是什么地址,由谁指定.text的首地址是0x30100000的呢?(3) 假如有其他动作改变了 .text 的首地址,那么该动作跟u-boot.lds的优先级又是怎么决定的呢?其实这三个问题都在Makefile的LDFLAGS 变量和u-boot.lds 中找到答案。

lds分析

lds分析
OUTPUT_FORMAT("elf32&shy;littlearm","elf32&shy;littlearm", "elf32&shy;littlearm")
;指定输出可执行文件是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm)
;指定输出可执行文件的平台为ARM
ENTRY(_start)
_start = 0;当此段在RAM中执行时_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值为0x33F80000,
即u-boot在把代码拷贝到RAM中去执行的代码段的开始) */
ldr r1, _TEXT_BASE /* 测试判断是从Flash启动,还是RAM */
现在,我们首先开看一看 xloader.lds 的代码:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(XLOADER_ENTRY) SECTIONS {
. = 0x00000000; . = ALIGN(4); .text : {
;指定输出可执行文件的起始代码段为_start.
SECTIONS
{
. = 0x00000000 . = ALIGN(4) .text :
; 从0x0位置开始 ; 代码以4字节对齐 ;指定代码段
{
cpu/arm920t/start.o (.text) ; 代码的第一个码部分 *(.text) ;其它代码部分
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

uboot 2013.07 lds 分析
转载自: uboot 2013.07 lds 分
析 .OUTPUT_FORMAT("elf32-littlearm", "elf32-
littlearm",
//指定输出可执行文件是 elf 格式 ,32 位
ARM 指令 ,小端 OUTPUT_ARCH(arm) //指定输出可执行
文件的平台为 ARMENTRY(_start) // 指定函数入口点为 _start 。

cpu/arm920t/start.S
0x00000000; // 指定可执行 image 文件的全局入口点,通常
这个地址都放在 ROM(flash)0x0 位置。

必须使编译器知道这
以4 字节对齐 .text : //代码段
00000000 T __image_copy_start 见 __image_copy_start 等同于 _start
CPUDIR/start.o (.text*) // 代码段的第一个代码部分 ALIGN(4); .rodata :
"elf32-littlearm") 中定义 SECTIONS{
个地址,通常都是修改此处来完成 . = ALIGN(4); // 代码
*(.__image_copy_start) // 在 System.map
匚=f
00000000 T _start, *(.text*)
//其它代码部分
{ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } 对应原来的 U_BOOT_CMD 对于那个的段 .
KEEP(*(SORT(.u_boot_list*))); * 在 System.map 中
0006f52c D _u_boot_list_2_env_clbk_2_flags
0006f534 D _u_boot_list_2_env_clbk_2_loadaddr
0006f53c B __bss_base
0006f53c B __bss_start
0006f53c B monitor_flash_len
0006f53c D __image_copy_end
0006f53c D __rel_dyn_start
//指定只读数据段 . = ALIGN(4); .data : { // 指定读 / 写数据段
*(.data*) ALIGN(4); . = ALIGN(4); .u_boot_list : {
// } . = ALIGN(4);/*
*/ .image_copy_end :
*(.__image_copy_end) } .rel_dyn_start : //0006f53c D __rel_dyn_start
*(.rel*) //.rel 段落保存了相对跳转的地址
和相对 } .rel_dyn_end : //00078874 R
this MMU section is used by pxa at present but should not be used by new boards/CPUs. bss_start and __bss_end, see arch/arm/lib/bss.c *
bss_base and __bss_limit are for linker only
(overlay
容 .bss_start __rel_dyn_start (OVERLAY) :
0006f53c D __image_copy_end
.bss_end __bss_limit (OVERLAY) :
KEEP(*(.__bss_end)); //000bd6a0 B
bss_end } /DISCARD/ : { *(.dynsym) }
*(.__rel_dyn_start) } .rel.dyn :
跳转的类型
rel_dyn_end *(.__rel_dyn_end)
end = .; //00078874 A _end /*
* Deprecated: */
ALIGN(4096); .mmutable :
*(.mmutable) }/* * Compiler-generated
ordering) */ //保存了未初始化的全局变量的内
{ //0006f53c B __bss_start
0006f53c D __rel_dyn_start
KEEP(*(.__bss_start));
bss_base } .bss
bss_base (OVERLAY) : { //0006f53c B __bss_base *(.bss*) . = ALIGN(4);
bss_limit = .; //000bd6a0 B
bss_limi }
/DISCARD/ : { *(.dynstr*) } /DISCARD/ : { *(.dynamic*) } /DISCARD/ : { *(.plt*) } /DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }}。

相关文档
最新文档