当前位置:文档之家› UBoot实验3、u-boot源码分析

UBoot实验3、u-boot源码分析

UBoot实验3、u-boot源码分析
UBoot实验3、u-boot源码分析

U-Boot的源码分析
概述: 文档详细介绍PC2440a实训包中所使用的BootLoader-U-Boot。对 其源码的目录结构、MakeFile文件、源码的主要数据结构、U-Boot 的启动过程、U-Boot与内核的关系等进行详细的分析。 名称: U-Boot的源码分析 版本: version 1.0 修改:
版本 V1.0
修改时间 2009/4/1
修正作者 侯德振
修正说明 文件创建
Note:任何修改操作请在上述表格备注说明



U-Boot的源码分析 ....................................................................................1 1.1 U-Boot源码分析 ..............................................................................3 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.2 1.3 1.4 U-Boot工程简介 .................................................................3 U-Boot源码结构 .................................................................3 makefile简要分析 .............................................................5 平台相关的文件分析 .........................................................7 U-Boot主要的数据结构 .....................................................8 U-Boot重定位后的内存分布...........................................12
U-Boot启动过程 ............................................................................12 U-Boot与内核的关系 ....................................................................18 U-Boot的重要细节 ........................................................................27

1.1 U-Boot源码分析
U-Boot作为通用的Bootloader,U-Boot可以方便地移植到其他硬件平台上, 其源代码也值得开发者们研究学习。
1.1.1
U-Boot工程简介
最早,DENX软件工程中心的Wolfgang Denk基于8xxrom的源码创建了PPCBOOT 工程, 并且不断添加处理器的支持。 后来, Sysgo Gmbh 把ppcboot 移植到ARM 平 台上,创建了ARMboot工程。然后以ppcboot工程和armboot工程为基础,创建了 U-Boot工程。 现在U-Boot已经能够支持PowerPC、ARM、X86、MIPS体系结构的上百种开发 板,已经成为功能最多、灵活性最强并且开发最积极的开放源码Bootloader。目 前仍然由DENX 的Wolfgang Denk维护。 U-Boot 的源码包可以从sourceforge 网站下载,还可以订阅该网站活跃的 U-Boot Users邮件论坛,这个邮件论坛对于U-Boot的开发和使用都很有帮助。 U-Boot软件包下载网站:https://www.doczj.com/doc/e413136554.html,/project/u-boot。 U-Boot 邮件列表网站: https://www.doczj.com/doc/e413136554.html,/lists/listinfo/u-boot-users/。 DENX 相关的网站:http://www.denx.de/re/DPLG.html。
1.1.2
U-Boot源码结构
从网站上下载得到U-Boot源码包,例如:U-Boot-1.2.0.tar.bz2 解压就可以得到全部U-Boot源程序。在顶层目录下有18 个子目录,分别存 放和管理不同的源程序。这些目录中所要存放的文件有其规则,可以分为3类。 第1 类目录与处理器体系结构或者开发板硬件直接相关;
第2 类目录是一些通用的函数或者驱动程序; 第3 类目录是U-Boot的应用程序、工具或者文档。 表4.1 列出了U-Boot顶层目录下各级目录存放原则。





解 释 说 明 存 放 电 路 板 相 关 的 目 录 文 件 , 例 如 :
board
平台依赖
RPXlite(mpc8xx)

smdk2410(arm920t)

sc520_cdp(x86) 等目录 cpu 平台依赖 存放 CPU 相关的目录文件,例如:mpc8xx、ppc4xx、 arm720t、arm920t、 xscale、i386 等目录 存放对 PowerPC 体系结构通用的文件, 主要用于实现 PowerPC 平台通用的函数 存放对 ARM 体系结构通用的文件,主要用于实现 ARM 平台通用的函数 存放对 X86 体系结构通用的文件,主要用于实现 X86 平台通用的函数 头文件和开发板配置文件, 所有开发板的配置文件都 在 configs 目录下 通用的多功能函数实现 通用库函数的实现 存放网络的程序 存放文件系统的程序 存放上电自检程序 通用的设备驱动程序,主要有以太网接口的驱动 硬盘接口程序 RTC 的驱动程序 数字温度测量器或者传感器的驱动 一些独立运行的应用程序的例子,例如 helloworld
lib_ppc
平台依赖
lib_arm
平台依赖
lib_i386
平台依赖
include
通用
common
通用
lib_generic 通用 Net Fs Post drivers Disk Rtc Dtt examples 通用 通用 通用 通用 通用 通用 通用 应用例程

tools
工具
存放制作 S-Record 或者 U-Boot 格式的映像等工 具,例如 mkimage 开发使用文档
Doc
文档
U-Boot的源代码包含对几十种处理器、数百种开发板的支持。可是对于特定 的开发板,配置编译过程只需要其中部分程序。这里具体以S3C2440 arm920t 处 理器为例,具体分析S3C2440处理器和开发板所依赖的程序,以及U-Boot的通用 函数和工具。
1.1.3
makefile简要分析
所有这些目录的编译连接都是由顶层目录的makefile来确定的。 在执行make之前,先要执行make $(board)_config 对工程进行配置,以确 定特定于目标板的各个子目录和头文件。 $(board)_config:是makefile 中的一个伪目标, 它传入指定的CPU, ARCH, BOARD, SOC参数去执行mkconfig脚本。 这个脚本的主要功能在于连接目标板平台相关的头文件夹,生成config.h 文件包含板子的配置头文件。 使得makefile能根据目标板的这些参数去编译正确的平台相关的子目录。 以smdk2410板为例,执行 主要完成三个功能: @在include文件夹下建立相应的文件(夹)软连接, #如果是ARM体系将执行以下操作: #ln -s #ln -s #ln -s asm-arm arch-s3c24x0 proc-armv asm asm-arm/arch asm-arm/proc make smdk2410_config,
@生成Makefile包含文件include/config.mk, 内容很简单, 定义了四个变量: ARCH CPU = arm = arm920t

BOARD SOC
= smdk2410 = s3c24x0
@生成include/config.h头文件,只有一行: /* Automatically generated - do not edit */ #include “config/smdk2410.h” 顶层makefile先调用各子目录的makefile,生成目标文件或者目标文件库。 然后再连接所有目标文件(库)生成最终的u-boot.bin。 连接的主要目标(库)如下: OBJS LIBS = cpu/$(CPU)/start.o = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a LIBS += cpu/$(CPU)/lib$(CPU).a ifdef SOC LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a endif LIBS += lib_$(ARCH)/lib$(ARCH).a LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \ fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a LIBS += net/libnet.a LIBS += disk/libdisk.a LIBS += rtc/librtc.a LIBS += dtt/libdtt.a LIBS += drivers/libdrivers.a LIBS += drivers/nand/libnand.a LIBS += drivers/nand_legacy/libnand_legacy.a LIBS += drivers/sk98lin/libsk98lin.a LIBS += post/libpost.a post/cpu/libcpu.a LIBS += common/libcommon.a

LIBS += $(BOARDLIBS) 显然跟平台相关的主要是: cpu/$(CPU)/start.o board/$(BOARDDIR)/lib$(BOARD).a cpu/$(CPU)/lib$(CPU).a cpu/$(CPU)/$(SOC)/lib$(SOC).a lib_$(ARCH)/lib$(ARCH).a 这里面的四个变量定义在include/config.mk(见上述)。 其余的均与平台无关。 所以考虑移植的时候也主要考虑这几个目标文件(库)对应的目录。
1.1.4
平台相关的文件分析
1、include/config/smdk2440.h 这个头文件中主要定义了两类变量。 一类是选项,前缀是 CONFIG_,用来选择处理器、设备接口、命令、属性等, 主要用来 决定是否编译某些文件或者函数。 另一类是参数,前缀是 CFG_,用来定义总线频率、串口波特率、Flash 地址 等参数。这些常数参量主要用来支持通用目录中的代码,定义板子资源参数。 这两类宏定义对 u-boot 的移植性非常关键, 比如 drive/CS8900.c, cs8900 对 而言,很多操作都是通用的,但不是所有的板子上面都有这个芯片,即使有它在 内存中映射的基地址也是平台相关的。所以对于 smdk2440 板,在 smdk2440.h 中定义了 #define CONFIG_DRIVER_CS8900 1 on-board */ #define CS8900_BASE 0x19000300 /*IO mode base address*/ /* we have a CS8900
CONFIG_DRIVER_CS8900 的定义使得 cs8900.c 可以被编译(当然还得定义 CFG_CMD_NET 才行),因为 cs8900.c 中在函数定义的前面就有编译条件判断: #ifdef CONFIG_DRIVER_CS8900

如果这个选项没有定义,整个 cs8900.c 就不会被编译了。 而常数参量 CS8900_BASE 则用在 cs8900.h 头文件中定义各个功能寄存器的 地址。u-boot 的 CS8900 工作在 IO 模式下,只要给定 IO 寄存器在内存中映 射的基地址,其余代码就与平台无关了。 u-boot 的命令也是通过目标板的配置头文件来配置的,比如要添加 ping 命 令, 就必须添加 CFG_CMD_NET 和 CFG_CMD_PING 才行。 不然 common/cmd_net.c 就不会被编译了。 从这里我可以这么认为,u-boot 工程可配置性和移植性可以分为两层: 一是由 makefile 来实现,配置工程要包含的文件和文件夹上,用什么编译 器。 二是由目标板的配置头文件来实现源码级的可配置性,通用性。主要使用 的是#ifdef #else #endif 之类来实现的。 2、smdk2440 其余重要的文件: include/s3c24x0.h (SFR)的地址。 cpu/arm920t/start.s 在 flash 中执行的引导代码,也就是 bootloader 定义了 s3x24x0 芯片的各个特殊功能寄存器
中的 stage1,负责初始化硬件环境,把 u-boot 从 flash 加载到 RAM 中去, 然后跳到 lib_arm/board.c 中的 start_armboot 中去执行。 lib_arm/board.c u-boot 的初始化流程,尤其是 u-boot 用到的
全局数据结构 gd,bd 的初始化,以及设备和控制台的初始化。 board/smdk2440/flash.c 在 board 目录下代码的都是严重依赖目标板,
对于不同的 CPU,SOC,ARCH,u-boot 都有相对通用的代码,但是板子构成 却是多样的,主要是内存地址,flash 型号,外围芯片如网络。
1.1.5
U-Boot主要的数据结构
u-boot 的主要功能是用于引导 OS 的,但是本身也提供许多强大的功能,可 以通过输入命令行来完成许多操作。所以它本身也是一个很完备的系统。u-boot 的大部分操作都是围绕它自身的数据结构,这些数据结构是通用的,但是不同的

板子初始化这些数据就不一样了。所以 u-boot 的通用代码是依赖于这些重要的 数据结构的。这里说的数据结构其实就是一些全局变量。 1)gd 全局数据变量指针,它保存了 u-boot 运行需要的全局数据,类型定义:
typedef struct global_data { bd_t 据指针 unsigned long flags; 标志等。 unsigned long baudrate; unsigned long have_console; unsigned long reloc_off; 的位置与编译连接 */ unsigned long env_addr; unsigned long env_valid; */ unsigned long fb_base; buffer */ #ifdef CONFIG_VFD unsigned char vfd_type; #endif void 用地址登记 */ } gd_t; 2)bd 板子数据指针。板子很多重要的参数。 类型定义如下: typedef struct bd_info { int bi_baudrate; /* 串口波特率 */ /* IP 地址 */ /* MAC 地址*/ **jt; /* 跳转表,1.1.6 中用来函数调 /* display type */ /* base address of frame /* 环境参数地址*/ /* 环境参数 CRC 检验有效标志 //串口波特率 /* 串口初始化标志*/ /* 重定位偏移,就是实际定向 时指定的位置之差,一般为 0 //指示标志,如设备已经初始化 *bd; //board data pointor 板子数
unsigned long bi_ip_addr; unsigned char bi_enetaddr[6];

struct environment_s ulong board */ ulong struct { ulong start; ulong size;
*bi_env; /* unique id for this
bi_arch_number;
bi_boot_params;
/* 启动参数 */ /* RAM 配置 */
}bi_dram[CONFIG_NR_DRAM_BANKS]; } bd_t; 3)环境变量指针 env_t *env_ptr = (env_t *)(&environment[0]); (common/env_flash.c) env_ptr 指向环境参数区,系统启动时默认的环境参数 environment[],定 义在 common/environment.c 中。 参数解释: bootdelay 定义执行自动启动的等候秒数 baudrate 定义串口控制台的波特率 netmask 定义以太网接口的掩码 ethaddr 定义以太网接口的 MAC 地址 bootfile 定义缺省的下载文件 bootargs 定义传递给 Linux 内核的命令行参数 bootcmd 定义自动启动时执行的几条命令 serverip 定义 tftp 服务器端的 IP 地址 ipaddr 定义本地的 IP 地址 stdin 定义标准输入设备,一般是串口 stdout 定义标准输出设备,一般是串口 stderr 定义标准出错信息输出设备,一般是串口 4)设备相关: 标准 IO 设备数组 evice_t *stdio_devices[] = { NULL, NULL, NULL };

设备列表
list_t
devlist = 0;
device_t 的定义:include\devices.h 中: typedef struct { int flags; input/output/system */ int ext; char name[16]; /* GENERAL functions */ int (*start) (void); int (*stop) (void); /* 输出函数 */ void (*putc) (const char c); /* To put a char */ /* To start the device /* To stop the device */ */ /* Supported extensions /* Device name */ */ /* Device flags:
void (*puts) (const char *s); /* To put a string (accelerator) */ /* 输入函数 */ int (*tstc) (void); int (*getc) (void); /* Other functions */ void *priv; } device_t; u-boot 把可以用为控制台输入输出的设备添加到设备列表 devlist,并把当 前用作标准 IO 的设备指针加入 stdio_devices 数组中。 在调用标准 IO 函数如 printf()时将调用 stdio_devices 数组对应设备的 IO 函数如 putc()。 5)命令相关的数据结构,后面介绍。 6)与具体设备有关的数据结构, 如 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];记录 nor flash 的 信息。 nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; 息 nand flash 块设备信 /* Private extensions */ /* To test if a char is ready... */ /* To get that char */

1.1.6
U-Boot重定位后的内存分布
对于 smdk2440,RAM 范围从 0x30000000~0x34000000. u-boot 占用高端内存 区。从高地址到低地址内存分配如下:
Ramdisk空间,大约 40M U-boot 区 域
大小 32k (0x8000)
0x40 header ZImage 0x300000
0x30800000(ramdisk加载地址 0x33f80000 Download Area 临时区域 0x30008000(kernel 加载地址 0x33000000 (需要自己计算) u-boot自己定 义的
Kernel 区域 , 将近 8M 空间足够 了 Download临时区域
1.2
U-Boot启动过程
如果能够充分理解代码的启动流程,那么对准确地解决和分析问题很有帮
助。开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数。 函数调用顺序如图6.3所示。 看一下board/smsk2410/u-boot.lds这个链接脚本,可以知道目标程序的各 部分链接顺序,第一个要链接的是cpu/arm920t/start.o,那么U-Boot 的入口指 令一定位于这个程序中。 下面详细分析一下程序跳转和函数的调用关系以及函数 实现。 1、cpu/arm920t/start.S 这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。

_start: b reset //复位向量 ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq //中断向量 ldr pc, _fiq //中断向量 … /* the actual reset code */ reset: //复位启动子程序 /* 设置CPU为SVC32模式 */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3

msr cpsr,r0 /* 关闭看门狗 */ /* 这些初始化代码在系统重起的时候执行,运行时热复位从RAM中启动不执行 */ #ifdef CONFIG_INIT_CRITICAL bl cpu_init_crit #endif relocate: /* 把U-Boot重新定位到RAM */ adr r0, _start ldr r1, _TEXT_BASE cmp r0, r1 定位 */ beq stack_setup /* 准备重新定位代码 */ ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 add r2, r0, r2 copy_loop: /* 重新定位代码 */ ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r0, r2 */ ble copy_loop /* 初始化堆栈等 */ stack_setup: ldr r0, _TEXT_BASE sub r0, r0, #CFG_MALLOC_LEN sub r0, r0, #CFG_GBL_DATA_SIZE /* 上面是128 KiB重定位的u-boot */ /* 向下是内存分配空间 */ /* 然后是bdinfo结构体地址空间 */ /*从源地址[r0]复制 */ /* 复制到目的地址[r1] */ /* 复制数据块直到源数据末尾地址[r2] /* r2 得到armboot的大小 */ /* r2 得到要复制代码的末尾地址 */ /* 如果r0等于r1,跳过重定位代码 */ /* r0是代码的当前位置 */ /* 测试判断是从Flash启动,还是RAM */ /* 比较r0和r1,调试的时候不要执行重

#ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 clear_bss: ldr r0, _bss_start ldr r1, _bss_end mov r2, #0x00000000 clbss_l:str r2, [r0] add r0, r0, #4 cmp r0, r1 bne clbss_l /* 跳转到start_armboot函数入口,_start_armboot字保存函数入口指 针 */ ldr pc, _start_armboot _start_armboot: lib_arm/board.c 中实现 /* 关键的初始化子程序 */ cpu_init_crit: …… //初始化CACHE,关闭MMU等操作指令 /* 初始化RAM时钟。 * 因为内存时钟是依赖开发板硬件的,所以在board的相应目录下可以找到 memsetup.S文件。 */ mov ip, lr bl memsetup //memsetup子程序在board/smdk2410/memsetup.S中实现 mov lr, ip mov pc, lr .word start_armboot //start_armboot 函 数 在 /* 找到bss段起始地址 */ /* bss段末尾地址 */ /* 清零 */ /* bss段地址空间清零循环... */ /* 为abort-stack预留3个字 */

2、lib_arm/board.c start_armboot 是U-Boot 执行的第一个C语言函数,完成系统初始化工作, 进入主循环,处理用户输入的命令。 void start_armboot (void) { DECLARE_GLOBAL_DATA_PTR; ulong size; init_fnc_t **init_fnc_ptr; char *s; /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); /* 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; /* 顺序执行init_sequence数组中的初始化函数 */ for ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) } /*配置可用的Flash */ size = flash_init (); display_flash_config (size); /* _armboot_start 在u-boot.lds链接脚本中定义 */ mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); hang (); (init_fnc_ptr = init_sequence; *init_fnc_ptr;

/* 配置环境变量,重新定位 */ env_relocate (); /* 从环境变量中获取IP地址 */ gd->bd->bi_ip_addr = getenv_IPaddr (“ipaddr”); /* 以太网接口MAC 地址 */ …… devices_init (); /* 获取列表中的设备 */ jumptable_init (); console_init_r (); /* 完整地初始化控制台设备 */ enable_interrupts (); /* 使能例外处理 */ /* 通过环境变量初始化 */ if ((s = getenv ( “ loadaddr ” )) != NULL) simple_strtoul (s, NULL, 16); /* main_loop()总是试图自动启动,循环不断执行 */ for (;;) { main_loop (); /* 主 循 环 函 数 处 理 执 行 用 户 命 令 common/main.c */ } /* NOTREACHED - no way out of command loop except booting */ } -load_addr =
3、init_sequence[] init_sequence[]数组保存着基本的初始化函数指针。这些函数名称和实现 的程序文件在下列注释中。 init_fnc_t *init_sequence[] = { cpu_init, cpu/arm920t/cpu.c */ /* 基 本 的 处 理 器 相 关 配 置 --

board_init, board/smdk2410/smdk2410.c */ interrupt_init, cpu/arm920t/s3c24x0/interrupt.c */ env_init, */ init_baudrate, */ serial_init, cpu/arm920t/s3c24x0/serial.c */ console_init_f, */ display_banner, dram_init, board/smdk2410/smdk2410.c */
/* 基 本 的 板 级 相 关 配 置
--
/*
初 始 化 例 外 处 理
--
/* 初始化环境变量 -- common/cmd_flash.c
/* 初始化波特率设置 -- lib_arm/board.c
/*
串 口 通 讯 设 置
--
/* 控制台初始化阶段1 -- common/console.c
/* 打印u-boot信息 -- lib_arm/board.c */ /* 配 置 可 用 的 RAM --
display_dram_config, /* 显示RAM的配置大小 -- lib_arm/board.c */ NULL, };
1.3
U-Boot与内核的关系
U-Boot 作为Bootloader,具备多种引导内核启动的方式。常用的go和bootm
命令可以直接引导内核映像启动。U-Boot 与内核的关系主要是内核启动过程中 参数的传递。 1、go命令的实现 /* common/cmd_boot.c */ int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, rc;

int rcode = 0; if (argc < 2) { printf (“Usage:\n%s\n”, cmdtp->usage); return 1; } addr = simple_strtoul(argv[1], NULL, 16); printf (“## Starting application at 0x%08lX ...\n”, addr); /* * pass address parameter as argv[0] (aka command name), * and all remaining args */ rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]); if (rc != 0) rcode = 1; printf (“## Application terminated, rc = 0x%lX\n”, rc); return rcode; } go 命令调用do_go()函数,跳转到某个地址执行的。如果在这个地址准备好 了自引导的内核映像,就可以启动了。尽管go命令可以带变参,实际使用时一般 不用来传递参数。
2、bootm 命令的实现 /* common/cmd_bootm.c */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong addr; ulong data, len, checksum; ulong *len_ptr;

uint unc_len = 0x400000; int i, verify; char *name, *s; int (*appl)(int, char *[]); image_header_t *hdr = &header; s = getenv (“verify”); verify = (s && (*s == 'n')) ? 0 : 1; if (argc < 2) { addr = load_addr; } else { addr = simple_strtoul(argv[1], NULL, 16); } SHOW_BOOT_PROGRESS (1); printf (“## Booting image at %08lx ...\n”, addr); /* Copy header so we can blank CRC field for re-calculation */ memmove (&header, (char *)addr, sizeof(image_header_t)); if (ntohl(hdr->ih_magic) != IH_MAGIC) { puts (“Bad Magic Number\n”); SHOW_BOOT_PROGRESS (-1); return 1; } SHOW_BOOT_PROGRESS (2); data = (ulong)&header; len = sizeof(image_header_t); checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0;

u-boot启动分析

背景: Board →ar7240(ap93) Cpu →mips 1、首先弄清楚什么是u-boot Uboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。 除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。 2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件): 以下为为每个目录的说明: Board:和一些已有开发板有关的文件。每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。它的每个子文件夹里都有如下文件(以ar7240/ap93为例): Makefile Config.mk Ap93.c 和板子相关的代码 Flash.c Flash操作代码 u-boot.lds 对应的链接文件 common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。例如bootm命令对应就是cmd_bootm.c cpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录mips等。它的每个子文件夹里都有入下文件: Makefile Config.mk Cpu.c 和处理器相关的代码s Interrupts.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。该目录下的asm目录有与CPU体系结构相关的头文件,比如说mips 对应的有asm-mips。 Lib_xxx:与体系结构相关的库文件。如与ARM相关的库放在lib_arm中。 Net:与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。 Tools:生成Uboot的工具,如:mkimage等等。 3、mips架构u-boot启动流程 u-boot的启动过程大致做如下工作: 1、cpu初始化 2、时钟、串口、内存(ddr ram)初始化 3、内存划分、分配栈、数据、配置参数、以及u-boot代码在内存中的位置。 4、对u-boot代码作relocate 5、初始化malloc、flash、pci以及外设(比如,网口) 6、进入命令行或者直接启动Linux kernel 刚一开始由于参考网上代码,我一个劲的对基于smdk2410的板子,arm926ejs的cpu看了N 久,启动过程和这个大致相同。 整个启动中要涉及到四个文件: Start.S →cpu/mips/start.S Cache.S →cpu/mips/cache.S Lowlevel_init.S →board/ar7240/common/lowlevel_init.S Board.c →lib_mips/board.c 整个启动过程分为两个阶段来看: Stage1:系统上电后通过汇编执行代码 Stage2:通过一些列设置搭建了C环境,通过汇编指令跳转到C语言执行. Stage1: 程序从Start.S的_start开始执行.(至于为什么,参考u-boot.lds分析.doc) 先查看start.S文件吧!~ 从_start标记开始会看到一长串莫名奇妙的代码:

UBoot移植详解

u-boot 移植步骤详解 1 U-Boot简介 U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux 系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。 选择U-Boot的理由: ①开放源码; ②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS; ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale; ④较高的可靠性和稳定性; ④较高的可靠性和稳定性; ⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等; ⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等; ⑦较为丰富的开发调试文档与强大的网络技术支持; 2 U-Boot主要目录结构 - board 目标板相关文件,主要包含SDRAM、FLASH驱动; - common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

AM335x uboot spl分析

AM335x uboot spl分析 芯片到uboot启动流程 ROM → SPL→ uboot.img 简介 在335x 中ROM code是第一级的bootlader。mpu上电后将会自动执行这里的代码,完成部分初始化和引导第二级的bootlader,第二级的bootlader引导第三级bootader,在 ti官方上对于第二级和第三级的bootlader由uboot提供。 SPL To unify all existing implementations for a secondary program loader (SPL) and to allow simply adding of new implementations this generic SPL framework has been created. With this framework almost all source files for a board can be reused. No code duplication or symlinking is necessary anymore. 1> Basic ARM initialization 2> UART console initialization 3> Clocks and DPLL locking (minimal) 4> SDRAM initialization 5> Mux (minimal) 6> BootDevice initialization(based on where we are booting from.MMC1/MMC2/Nand/Onenand) 7> Bootloading real u-boot from the BootDevice and passing control to it. uboot spl源代码分析 一、makefile分析 打开spl文件夹只有一个makefile 可见spl都是复用uboot原先的代码。 主要涉及的代码文件为u-boot-2011.09-psp04.06.00.03/arch/arm/cpu/armv7 u-boot-2011.09-psp04.06.00.03/arch/arm/lib u-boot-2011.09-psp04.06.00.03/drivers LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds 这个为链接脚本 __image_copy_end _end 三、代码解析 __start 为程序开始(arch/arm/cpu/armv7/start.S) .globl _start 这是在定义u-boot的启动定义入口点,汇编程序的缺省入口是 start 标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点。

UBoot源码分析1

?UBoot源码解析(一)

主要内容 ?分析UBoot是如何引导Linux内核 ?UBoot源码的一阶段解析

BootLoader概念?Boot Loader 就是在操作系统内核运行之前运行 的一段小程序。通过这段小程序,我们可以初始 化硬件设备、建立内存空间的映射图,从而将系 统的软硬件环境带到一个合适的状态,以便为最 终调用操作系统内核准备好正确的环境 ?通常,Boot Loader 是严重地依赖于硬件而实现 的,特别是在嵌入式世界。因此,在嵌入式世界 里建立一个通用的Boot Loader 几乎是不可能的。 尽管如此,我们仍然可以对Boot Loader 归纳出 一些通用的概念来,以指导用户特定的Boot Loader 设计与实现。

UBoot来源?U-Boot 是 Das U-Boot 的简称,其含义是 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。最早德国 DENX 软件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSROM 的源码创建了 PPCBoot 工程项目,此后不断 添加处理器的支持。而后,Sysgo Gmbh 把 PPCBoot 移 植到 ARM 平台上,创建了 ARMBoot 工程项目。最终, 以 PPCBoot 工程和 ARMBoot 工程为基础,创建了 U- Boot 工程。 ?而今,U-Boot 作为一个主流、通用的 BootLoader,成功地被移植到包括 PowerPC、ARM、X86 、MIPS、NIOS、XScale 等主流体系结构上的百种开发板,成为功能最多、 灵活性最强,并且开发最积极的开源 BootLoader。目前。 U-Boot 仍然由 DENX 的 Wolfgang Denk 维护

uboot版本文件结构

uboot版本文件结构的更新改变 分类:ARM2011-09-22 12:57 339人阅读评论(0) 收藏举报本来是开始分析uboot代码的,但是无论是教材还是网上资料都对于我最新下的uboot原码结构不同,对于还是小白的我不容易找到相应的文件,下面是uboot版本中文件组织结构的改变,,,,, u-boot版本情况 网站:http://ftp.denx.de/pub/u-boot/ 1、版本号变化: 2008年8月及以前 按版本号命名:u-boot-1.3.4.tar.bz2(2008年8月更新) 2008年8月以后均按日期命名。 目前最新版本:u-boot-2011.06.tar.bz2(2011年6月更新) 2、目录结构变化: u-boot目录结构主要经历过2次变化,u-boot版本第一次从u-boot-1.3.2开始发生变化,主要增加了api的内容;变化最大的是第二次,从2010.6版本开始。 u-boot-2010.03及以前版本 ├── api存放uboot提供的接口函数 ├── board根据不同开发板定制的代码,代码也不少 ├── common通用的代码,涵盖各个方面,已命令行处理为主 ├── cpu与体系结构相关的代码,uboot的重头戏 ├── disk磁盘分区相关代码 ├── doc文档,一堆README开头的文件 ├── drivers驱动,很丰富,每种类型的设备驱动占用一个子目录 ├── examples示例程序 ├── fs文件系统,支持嵌入式开发板常见的文件系统 ├── include头文件,已通用的头文件为主 ├── lib_【arch】与体系结构相关的通用库文件 ├── nand_spl NAND存储器相关代码 ├── net网络相关代码,小型的协议栈 ├── onenand_ipl

iTop4412的uboot第一阶段

2 uboo t 源码分析 2.5.1.star t.S 2.5.1.star t.S 引入引入 2.5.1.1、u-boot.lds中找到start.S入口 (1)在C语言中整个项目的入口就是 main函数(这是 个.c文件的项目,第一个要分析的文件就是包含了C语言规定的),所以譬如说一 个有 main函数的那个文件。 10000 ( 2 方。ENTRY(_start)因此 _start 符号所在的文件就是整个程序的起始文 件, _sta rt 所在处的 代码就是整个程序的起始代码。 2.5.1.2、SourceInsight中如何找到 文件 (1)当前状况:我们知道在uboot中的1000多个文件中有一个符号 叫 _start,但是我们不知道 这个符号在哪个文件中。这种情况下要查找一个符号在所有项目中文件中的引用,要使用SourceInsight的搜索功能。 (2)start.s 在cpu/arm_cortexa9/start.s (3)然后进入start.S文件中,发现 个uboot的入口代码,就是第57 57行中就 是行。_sta rt 标号的定义处,于是乎我们就找到了整 2.5.1.3、SI中找文件技巧 (1)以上,找到了start.S文件,下面我们就从start.S文件开始分析uboot第一阶段。 (2)在SI中,如果我们知道我们要找的文件的名字,但是我们又不知道他在哪个目录下,我 们要怎样找到并打开这个文件?方法是在 SI中先打开右边的工程项目管理栏目,然后点击 最左边那个(这个是以文件为单位来浏览的),然后在上面输入栏中输入要找的文件的名 字。我们在输入的时候,SI在不断帮我们进行匹配,即使你不记得文件的全名只是大概记 得名字,也能帮助你找到你要找的文件。 2.5.2.start.S解析1 2.5.2.1、不简单的头文件包含

uboot环境变量总结

Common目录下面与环境变量有关的文件有以下几个:env_common.c,env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c,env_nowhere.c,env_nvram.c,environment.c。 env_common.c中包含的是default_environment[]的定义; env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c, env_nvram.c 中包含的是相应存储器与环境变量有关的函数:env_init(void),saveenv(void),env_relocate_spec (void),env_relocate_spec (void),use_default()。至于env_nowhere.c,因为我们没有定义CFG_ENV_IS_NOWHERE,所以这个文件实际上没有用。 environment.c这个文件时是我真正理解环境变量的一个关键。在这个文件里定义了一个完整的环境变量的结构体,即包含了这两个ENV_CRC(用于CRC校验),Flags(标志有没有环境变量的备份,根据CFG_REDUNDAND_ENVIRONMENT这个宏定义判断)。定义这个环境变量结构体的时候还有一个非常重要的关键字: __PPCENV__,而__PPCENV__在该.c文件中好像说是gnu c编译器的属性,如下: # define __PPCENV__ __attribute__ ((section(".text"))) 意思是把这个环境变量表作为代码段,所以在编译完UBOOT后,UBOOT的代码段就会有环境变量表。当然,这要在我们定义了ENV_IS_EMBEDDED之后才行,具体而言,环境变量表会在以下几个地方出现(以nand flash为例): 1、UBOOT中的代码段(定义了ENV_IS_EMBEDDED), 2、UBOOT中的默认环 境变量, 3、紧接UBOOT(0x0 ~ 0x1ffff)后面:0x20000 ~ 0x3ffff 之间,包括备份的环境变量,我们读取,保存也是对这个区域(即参数区)进行的。3、SDRAM中的UBOOT中,包括代码段部分和默认部分,4、SDRAM中的melloc分配的内存空间中。 Environment.c代码如下: env_t environment __PPCENV__ = { ENV_CRC, /* CRC Sum */ #ifdef CFG_REDUNDAND_ENVIRONMENT 1, /* Flags: valid */ #endif { #if defined(CONFIG_BOOTARGS) "bootargs=" CONFIG_BOOTARGS "\0" #endif #if defined(CONFIG_BOOTCOMMAND) "bootcmd=" CONFIG_BOOTCOMMAND "\0" #endif #if defined(CONFIG_RAMBOOTCOMMAND) "ramboot=" CONFIG_RAMBOOTCOMMAND "\0"

嵌入式Linux之我行 史上最牛最详细的uboot移植,不看别后悔

嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一) 嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux 的朋友提供方便。如有错误之处,谢请指正。 ?共享资源,欢迎转载:https://www.doczj.com/doc/e413136554.html, 一、移植环境 ?主机:VMWare--Fedora 9 ?开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 本次移植的功能特点包括: ?支持Nand Flash读写 ?支持从Nor/Nand Flash启动 ?支持CS8900或者DM9000网卡 ?支持Yaffs文件系统 ?支持USB下载(还未实现) 1.了解u-boot主要的目录结构和启动流程,如下图。

u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。各个部分的流程图如下:

2. 建立自己的开发板项目并测试编译。 目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM 处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。 1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440 2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改

U_Boot第一启动阶段Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解)

Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解) Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解) 1 u-boot.lds 首先了解uboot的链接脚本board/my2410/u-boot.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) board/my2440/lowlevel_init.o (.text) *(.text) } . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } . = ALIGN(4); .data : { *(.data) } /* 只读数据段,所有的只读数据段都放在这个位置*/ . = ALIGN(4); .got : { *(.got) } /*指定got段, got段式是uboot自定义的一个段, 非标准段*/ . = .; __u_boot_cmd_start = .; /*把__u_boot_cmd_start赋值为当前位置, 即起始位置*/ .u_boot_cmd : { *(.u_boot_cmd) } /* u_boot_cmd段,所有的u-boot命令相关的定义都放在这个位置,因为每个命令定义等长,所以只要以__u_boot_cmd_start为起始地址进行查找就可以很快查找到某一个命令的定义,并依据定义的命令指针调用相应的函数进行处理用户的任务*/ __u_boot_cmd_end = .; /* u_boot_cmd段结束位置,由此可以看出,这段空间的长度并没有严格限制,用户可以添加一些u-boot的命令,最终都会在连接是存放在这个位置。*/

关于uboot移植 CAMDIVN与时钟

关于uboot移植 CAMDIVN与时钟 2010-03-09 19:57 在该文件的122行附近有这样一个结构体 typedef struct { S3C24X0_REG32 LOCKTIME; S3C24X0_REG32 MPLLCON; S3C24X0_REG32 UPLLCON; S3C24X0_REG32 CLKCON; S3C24X0_REG32 CLKSLOW; S3C24X0_REG32 CLKDIVN; } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER; 是用来封装时钟寄存器的,我们要在其中增加一项S3C24X0_REG32 CAMDIVN,为什么加这么一个呢?因为这个寄存器是2410所没有的,而2440在配置时钟的时候又必须用到,看名字我们就知道是用来配置CAMERA时钟的,也就是配置摄像头的时钟的。 貌似和配置uboot启动的时钟没有关系?其实不然,我们在修改下一个文件的时候就可以看到其用途了, 此结构体修改后的结果为 typedef struct { S3C24X0_REG32 LOCKTIME; S3C24X0_REG32 MPLLCON; S3C24X0_REG32 UPLLCON; S3C24X0_REG32 CLKCON; S3C24X0_REG32 CLKSLOW; S3C24X0_REG32 CLKDIVN; S3C24X0_REG32 CAMDIVN; } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER; 第二个文件..\cpu\arm920t\s3c24x0\speed.c 在这个文件中需要修改两个函数 第一个函数在54行附近:static ulong get_PLLCLK(int pllreg) 由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以get_PLLCLK 函数也需要修改:

经典=Uboot-2-命令详解(bootm)

bootm命令中地址参数,内核加载地址以及内核入口地址 分类:u-boot2010-11-04 10:472962人阅读评论(0)收藏举报downloadlinuxbytecmdheaderimage bootm命令只能用来引导经过mkimage构建了镜像头的内核镜像文件以及根文件镜像,对于没有用mkimage对内核进行处理的话,那直接把内核下载到连接脚本中指定的加载地址0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。 通过mkimage可以给内核镜像或根文件系统镜像加入一个用来记录镜像的各种信息的头。同样通过mkimage也可以将内核镜像进行一次压缩(指定-C none/gzip/bzip2),所以这里也就引申出了两个阶段的解压缩过程:第一个阶段是u-boot里面的解压缩,也就是将由mkimage压缩的镜像解压缩得到原始的没加镜像头的内核镜像。第二个阶段是内核镜像的自解压,u-boot 里面的解压实际上是bootm 实现的,把mkimage -C bzip2或者gzip 生成的uImage进行解压;而kernel的自解压是对zImage进行解压,发生在bootm解压之后。 下面通过cmd_bootm.c文件中对bootm命令进行解析以及执行的过程来分析,这三种不同地址的区别: ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ...... if (argc < 2) { addr = load_addr;//当bootm命令后面不带地址参数时,将默认的加载地址赋值给addr } else { addr = simple_strtoul(argv[1], NULL, 16); //如果bootm命令后面带了加载地址,则将该地址赋值给addr,所以最终有用的地址还是bootm命令后附带的地址 } ...... //

uboot调试指南

Uboot调试参考指南 一、调试目的 Uboot的调试旨在通过观察uboot运行时状态来测试硬件问题。 二、调试步骤 1.修改代码 在uboot代码路径下,编辑uboot代码,需要做以下修改; a.修改config.mk文件,添加以下两行内容: AFLAGS += -Wa,-gdwarf2 CFLAGS += -g2 -gdwarf-2 b.修改. /arch/powerpc/lib/board.c文件 debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); printf("Now running in RAM - U-Boot at: %08lx\n", dest_addr); 将debug改为printf,如上所示。 2.编译uboot 执行make BSC9131RDB_SYSCLK100_NAND,编译uboot 3.将编译好的u-boot-nand.bin(uboot image格式)及u-boot(elf格式文件)文件拷 贝出来 4.烧录uboot 将步骤3中保存的u-boot-nand.bin烧录到目标板中,烧录过程略。 5.建立工程 a.在cw界面,点击file->import, 选择code warrior -> Power architecture ELF executable,如图1所示: 图1 建立elf工程 b.选择步骤3中保存的u-boot(elf格式文件),toolchain选择bareboard application, target OS选择none,工程名字请根据需要设置,比如我的机器上设置为example, 点击next,如图2所示:

Ubuntu下配置并使用LXR查看Uboot代码(原创)

Ubuntu下配置并使用LXR查看Uboot代码(原创) 之前买了个mini6410觉得查看uboot的源代码太麻烦,上网查到,利用lxr查看源代码比较方便,使用到的有:apache2,glimpse-4.18.6,lxr,u-boot-mini6410(查看的目标文件夹),我使用的Ubuntu9.10,在ylmf3下面也验证成功。 下面就正式开始搭建我们自己的lxr. 建议下面的所有的操作都使用root权限操作: sudo su 输入当前用户的使用密码即可就变成“root@XXXXXXX:” 一、安装apach2: sudo apt-get install apache2 二、安装glimpse: 先去网站下载最新的源代码glimpse-4.18.6.tar.gz,然后解压到当前目录下 tar -xvgf glimpse-4.18.6.tar.gz 再接着进入解压后的目录下,比如我的是: cd glimpse-4.18.6/ 在编译之前,首先看看你的机器上是否已经安装了flex,因为编译glimpse的时候需要这个软件。如果没有的话,那么进行安装: sudo apt-get install flex 接着进行编译: ./configure make sudo make install 执行完上面的步骤后,将生成的glimpse glimpseindex 拷贝到/bin目录下: cd /bin sudo cp glimpse glimpseindex /bin 三、安装lxr sudo apt-get install lxr 新建/usr/share/lxr/http/.htaccess文件 在里面增加如下内容: SetHandler cgi-script 四、复制U-boot源代码

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 (引导加载程序)就是在操作系统内核运行之前运行的一段小程序,它的作用就是加载操作系统, 实现硬件的初始化,建立内存空间的映射图,为操作系统内核准备好硬件环境并引导内核的启动。如上图所示的那样在设备的启动过程中bootloader位于最底层,首先被运行来引导操作系统运行,很容易可以看出bootloader是底层程序所以它的实现严重地依赖于硬件,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。尽管如此,一些功能强大、支持硬件环境较多的BootLoader也被广大的使用者和爱好者所支持,从而形成了一些被广泛认可的、较为通用的的bootloader实现。 2.1 Boot Loader 所支持的CPU 和嵌入式板 每种不同的CPU 体系结构都有不同的Boot Loader。有些Boot Loader 也支持多种体系结构的CPU,比如U-Boot 就同时支持ARM 体系结构和MIPS 体系结构。除了依赖于CPU 的体系结构外,Boot Loader 实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU 而构建的,要想让运行在一块板子上的Boot Loader 程序也能运行在另一块板子上,通常也都需要修改Boot Loader 的源程序。 2.2 Boot Loader 的安装媒介(Installation Medium)

uboot移植心得

最近跑完裸机之后,便开始跑系统,但想着裸机与系统之间隔着个Bootloader,反正以前也没怎么深入研究,便说花一到两周时间来搞搞U-BOOT。 参考了fzb和赵春江两位大牛的,也研究了2010.06版本的和2011.06版本两个经典版本,也对比了TQ(我买的板是天嵌的)自己写的U-BOOT,学到了不少,也发现了很多东西,以下便记录以下自己的心得吧,以便以后可以自己参考下。 U-BOOT的两个阶段启动过程:(2010.06经典版来说) 第一阶段:start.S的路径位于arch\arm\cpu\arm920t\这段汇编代码一般被称作第一阶段初始化代码。主要作用是初始化运行环境;初始化内存;重新放置UBOOT代码到内存中;跳入到内存中执行第二段初始化代码 1、关闭开门狗,屏蔽所有中断 2、设置分频比 3、bl cpu_init_crit() 关MMU,初始化内存 bl lowlevel_init() 配置内存,修改内存刷新率参数等 4、relocate判断当前代码是在NORFLASH还是RAM copy_loop循环将FLASH代码复制至RAM中 5、stack_setup栈设置 clear_bss_bss_start到_bss_end之间的数据清0 6、ldr pc , start_armboot 跳转到第二阶段 //===================================================================== 第二阶段:board.c的路径位于arch/arm/lib/board.c,这段代码为U-BOOT的第二阶段初始化代码。主要作用是初始化两个重要数据结构,对SDRAM的内存分配设置,对各种需要用到的外设进行初始化,最后循环跳入main_loop()函数 二阶段start_armboot分为board_init_f 和 board_init_r两部分 先执行的board_init_f部分: 1、为gd数据结构分配地址,并清零 2、执行init_fnc_ptr函数指针数组中的各个初始化函数,如下 board_early_init_f ,timer_init ,env_init init_baudrate serial_init console_init_f display_banner dram_init 3、A、分配SDRAM高64KB为TLB,用于U-BOOT B、分配SDRAM下一单元为U-BOOT代码段,数据段,BSS段 (这里插一句,原来BSS段是用来存放未初始化的全局变量与静态变量) C、接着开辟malloc空间,存bd , gd , 3个字大小的异常堆空间 4、将relorate的地址值赋给gd结构体相应变量(2011.06版本的,用于返回start.S) 后执行的board_init_r部分: 1、对gd , bd 数据结构赋值初始化 2、各种外设初始化: 初始化NORFLASH, NANDFLASH,初始化ONENAND FLASH

2440超详细U-BOOT(UBoot介绍+H-jtag使用+Uboot使用)

凌FL2440超详细U-BOOT作业(UBoot介绍+H-jtag使用+Uboot 使用) Bootloader是高端嵌入式系统开发不可或缺的部分。它是在操作系统内核启动之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。现在主流的bootloader有U-BOOT、vivi、Eboot等。 本次作业先做Uboot的烧写吧。希望通过这个帖子,能让更多的初学者朋友了解一些UBoot的知识,也希望高手朋友对我的不足予以斧正。 首先说一下什么是Uboot: U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FAD SROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linu x系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Li nux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot 的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOAD ER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。 选择U-Boot的理由: ①开放源码; ②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, AR TOS, LynxOS; ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;

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()函数传递的参数,接下来我们来看看他们是如何定义的。 哈哈,终于到了让人头疼的地方了。先来看看struct nand_chip和struct mtd_info两个结构体,这两个结构体的成员有很多很多,很多初学者一看到就晕头转向了,为了让大家不被吓到,我对这两个结构体的成员做了精简,只保留我们关心的成员,其它的都去掉了。 (1)struct nand_chip

相关主题
文本预览
相关文档 最新文档