文档库 最新最全的文档下载
当前位置:文档库 › uboot讲义

uboot讲义

uboot讲义
uboot讲义

1嵌入式Linux软件结构与分布

一般情况下嵌入式Linux系统中的软件主要分为以下几部分:

1)引导加载程序:其中包括内部ROM中的固化启动代码和BootLoader两部分。内

部固化ROM是厂家在芯片生产时候固化的,作用基本上是引导BootLoader。

有的芯片比较复杂,比如Omap3在flash中没有代码的时候有许多启动方式:

USB、UART或以太网等等。而S3C24x0则很简单,只有Norboot和

Nandboot。

drive e rs。

2)Linux kernel和driv

3)文件系统。包括根文件系统和建立于Flash内存设备之上的文件系统(EXT4、UBI、

CRAMFS等等)。它是提供管理系统的各种配置文件以及系统执行用户应用程序

的良好运行环境及载体。

4)应用程序。用户自定义的应用程序,存放于文件系统之中。

在Flash存储器中,他们的分布一般如下:

BootLoader

(被挂载到根文件系统或者作为

2在嵌入式Linux中Boot

BootL L o a d er的必要性

Linux内核的启动除了内核映像必须在主存的适当位置,CPU还必须具备一定的条件:

1.CPU寄存器的设置:R0=0;

R1=Machine ID(即Machine Type Number,定义在linux/arch/arm/tools/mach-types);R2=内核启动参数在RAM中起始基地址;

2.CPU模式:必须禁止中断(IRQs和FIQs);

CPU必须SVC模式;

3.Cache和MMU的设置:MMU必须关闭;

指令Cache可以打开也可以关闭;数据Cache必须关闭;

但是在CPU刚上电启动的时候,一般连内存控制器都没有初始化过,根本

无法在主存中运行程序,更不可能处在Linux内核启动环境中。为了初始

化CPU及其他外设,使得Linux内核可以在系统主存中运行,并让系统

符合Linux内核启动的必备条件,必须要有一个先于内核运行的程序,

他就是所谓的引导加载程序(Boot Loader)。

3源码下载地址

U-boot官方主页

(注意其中的邮件列表链接)

http://www.denx.de/wiki/U-Boot/WebHome U-boot官方源码FTP下载ftp://ftp.denx.de/pub/u-boot/

4交叉编译链的介绍与安装

为什么要用交叉编译器?交叉编译通俗地讲就是在一种平台上编译出能运行在

体系结构不同的另一种平台上的程序,比如在PC平台(X86CPU)上编译出能

运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86CPU平台

上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。这种方法在异平台移植和嵌入式开发时非常有用。相对与交叉编译,平常做的编译叫本地编译,也就是在当前平台编译,编译得到的程序也是在本地执行。用来编译这种跨平台程序的编译器就叫交叉编译器,相对来说,用来做本地编译的工具就叫本地编译器。所以要生成在目标机上运行的程序,必须要用交叉编译工具链来完成。在裁减和定制Linux内核用于嵌入式系统之前,由于一般嵌入式开发系统存储大小有限,通常都要在性能优越的PC上建立一个用于目标机的交叉编译工具链,用该交叉编译工具链在PC上编译目标机上要运行的程序。交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc3个部分组成。

通常构建交叉工具链有3种方法。

方法一分步编译和安装交叉编译工具链所需要的库和源代码,最终生成交叉编译工具链。该方法相对比较困难,适合想深入学习构建交叉工具链的读者。如果只是想使用交叉工具链,建议使用方法二或方法三构建交叉工具链。

方法二通过Crosstool脚本工具来实现一次编译生成交叉编译工具链,该方法相对于方法一要简单许多,并且出错的机会也非常少,建议大多数情况下使用该方法构建交叉编译工具链。

方法三直接通过网上(https://www.wendangku.net/doc/7712790120.html,)下载已经制作好的交叉编译工具链。

5NAND flash

(1)NAND闪存工作原理

S3C2440开发板的NAND闪存由NAND闪存控制器(集成在S3C2440CPU中)和NAND闪存芯片(K9F1208U0A)两大部分组成。当要访问NAND闪存芯片中的数据时,必须通过NAND闪存控制器发送命令才能完成。所以,NAND闪存相当于S3C2410的一个外设,而不位于它的内存地址区。

NAND闪存(K9F1208U0A)的数据存储结构分层为:1设备(Device)=4096块(Block);1块=32页/行(Page/row);1页=528B=数据块(512B)+OOB块(16B)

在每一页中,最后16个字节(又称OOB)在NAND闪存命令执行完毕后设置状态,剩余512个字节又分为前半部分和后半部分。可以通过NAND闪存命令00h/01h/50h分别对前半部、后半部、OOB进行定位,通过NAND闪存内置的指针指向各自的首地址。

NAND闪存的操作特点为:擦除操作的最小单位是块;NAND闪存芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除;OOB部分的第6字节为坏快标志,即如果不是坏块该值为FF,否则为坏块;除OOB第6字节外,通常用OOB的前3个字节存放NAND闪存的硬件ECC(校验寄存器)码;

(2)从NAND闪存启动U-BOOT的设计思路

如果S3C2440被配置成从NAND闪存启动,上电后,S3C2440的NAND闪存控制器会

自动把NAND闪存中的前4K数据搬移到内部RAM中,并把0x00000000设置为内部

RAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。因此要把最核心的启动程序放在NAND闪存的前4K中。

由于NAND闪存控制器从NAND闪存中搬移到内部RAM的代码是有限的,所以,在启动代码的前4K里,必须完成S3C2440的核心配置,并把启动代码的剩余部分搬到RAM 中运行。在U-BOOT中,前4K完成的主要工作就是U-BOOT启动的第一个阶段(stage1)。根据U-BOOT的执行流程,可知要实现从NAND闪存中启动U-BOOT,首先需要初始化NAND闪存,并从NAND闪存中把U-BOOT搬移到RAM中,最后需要让U-BOOT支持NAND闪存的命令操作。

6u-boot具体分析

本文从以下几个方面粗浅地分析u-boot:

1、u-boot工程的总体结构

2、u-boot的流程

3、u-boot的重要细节,主要分析流程中各函数的功能。

一、u-boot工程的总体结构:

1、源代码组织

对于ARM而言,主要的目录如下:

board平台依赖存放电路板相关的目录文件,每一套板子对应一个目录。如smdk2410(arm920t)

cpu平台依赖存放CPU相关的目录文件,每一款CPU 对应一个目录,例如:arm920t、xscale、i386等目录

lib_arm平台依赖存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数,如软件浮点。

common通用通用的多功能函数实现,如环境,命令,控制台相关的函数实现。

include通用头文件和开发板配置文件,所有开发板的配置文件都在configs目录下

lib_generic通用通用库函数的实现

net通用存放网络协议的程序

drivers通用通用的设备驱动程序,主要有以太网接口的驱动,nand驱动。

.......

2.makefile简要分析

所有这些目录的编译连接都是由顶层目录的makefile来确定的。

在执行make之前,先要执行make$(board)_config对工程进行配置,以确定特定于目标板的各个子目录和头文件。

以smdk2410板为例,执行make smdk2410_config,

主要完成三个功能:

@在include文件夹下建立相应的文件(夹)软连接,

#如果是ARM体系将执行以下操作:

#ln-s asm-arm asm

#ln-s arch-s3c24x0asm-arm/arch

#ln-s proc-armv asm-arm/proc

@生成Makefile包含文件include/config.mk,内容很简单,定义了四个变量:

ARCH=arm

CPU=arm920t

BOARD=smdk2410

SOC=s3c24x0

@生成include/config.h头文件,只有一行:

/*Automatically generated-do not edit*/

#include"config/smdk2410.h"

顶层makefile先调用各子目录的makefile,生成目标文件或者目标文件库。

然后再连接所有目标文件(库)生成最终的u-boot.bin。

3、u-boot的通用目录是怎么做到与平台无关的?

include/config/smdk2410.h

这个头文件中主要定义了两类变量。

一类是选项,前缀是CONFIG_,用来选择处理器、设备接口、命令、属性等,主要用来决定是否编译某些文件或者函数。

另一类是参数,前缀是CFG_,用来定义总线频率、串口波特率、Flash地址等参数。这些常数参量主要用来支持通用目录中的代码,定义板子资源参数。

这两类宏定义对u-boot的移植性非常关键,比如drive/CS8900.c,对cs8900而言,很多操作都是通用的,但不是所有的板子上面都有这个芯片,即使有它在内存中映射的基地址也是平台相关的。所以对于smdk2410板,在smdk2410.h中定义了

#define CONFIG_DRIVER_CS89001/*we have a CS8900on-board*/

#define CS8900_BASE0x19000300/*IO mode base address*/ 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之类来实现的。

4、smkd2410其余重要的文件:

include/s3c24x0.h定义了s3x24x0芯片的各个特殊功能寄存器(SFR)的地址。

cpu/arm920t/start.s在flash中执行的引导代码,也就是bootloader中的

stage1,负责初始化硬件环境,把u-boot从flash加载到RAM中去,然后跳到

lib_arm/board.c中的start_armboot中去执行。

lib_arm/board.c u-boot的初始化流程,尤其是u-boot用到的全局数据结构gd,bd的初始化,以及设备和控制台的初始化。

board/smdk2410/flash.c在board目录下代码的都是严重依赖目标板,对于不同的CPU,SOC,ARCH,u-boot都有相对通用的代码,但是板子构成却是多样的,主要是内存地址,flash型号,外围芯片如网络。对fs2410来说,主要考虑从smdk2410板来移植,差别主要在nor flash上面。

二、u-boot的流程、主要的数据结构、内存分配

1、u-boot的启动流程:

从文件层面上看主要流程是在两个文件中:cpu/arm920t/start.s,lib_arm/board.c,

1)start.s

在flash中执行的引导代码,也就是bootloader中的stage1,负责初始化硬件环境,把u-boot从flash加载到RAM中去,然后跳到lib_arm/board.c中的start_armboot中去执行。

1.1.6版本的start.s流程:

硬件环境初始化:

进入svc模式;关闭watch dog;屏蔽所有IRQ掩码;设置时钟频率FCLK、HCLK、PCLK;清I/D cache;禁止MMU和CACHE;配置memory control;

重定位:

如果当前代码不在连接指定的地址上(对smdk2410是0x3f000000)则需要把u-boot 从当前位置拷贝到RAM指定位置中;

建立堆栈,堆栈是进入C函数前必须初始化的。

清.bss区。

跳到start_armboot函数中执行。(lib_arm/board.c)

2)lib_arm/board.c:

start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。这里只简要列出了主要执行的函数流程:

void start_armboot(void)

{

//全局数据变量指针gd占用r8。

DECLARE_GLOBAL_DATA_PTR;

/*给全局数据变量gd安排空间*/

gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-sizeof(gd_t));

memset((void*)gd,0,sizeof(gd_t));

/*给板子数据变量gd->bd安排空间*/

gd->bd=(bd_t*)((char*)gd-sizeof(bd_t));

memset(gd->bd,0,sizeof(bd_t));

monitor_flash_len=_bss_start-_armboot_start;//取u-boot的长度。

/*顺序执行init_sequence数组中的初始化函数*/

for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++init_fnc_ptr){ if((*init_fnc_ptr)()!=0){

hang();

}

}

/*配置可用的Flash*/

size=flash_init();

……

/*初始化堆空间*/

mem_malloc_init(_armboot_start-CFG_MALLOC_LEN);

/*重新定位环境变量,*/

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){

load_addr=simple_strtoul(s,NULL,16);

}

/*main_loop()循环不断执行*/

for(;;){

main_loop();/*主循环函数处理执行用户命令--

common/main.c*/

}

}

初始化函数序列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,/*初始化环境变量--common/env_flash.c*/

init_baudrate,/*初始化波特率设置--lib_arm/board.c*/

serial_init,/*串口通讯设置--cpu/arm920t/s3c24x0/serial.c */

console_init_f,/*控制台初始化阶段1--common/console.c*/

display_banner,/*打印u-boot信息--lib_arm/board.c*/

dram_init,/*配置可用的RAM--board/smdk2410/smdk2410.c*/

display_dram_config,/*显示RAM的配置大小--lib_arm/board.c*/

NULL,

};

整个u-boot的执行就进入等待用户输入命令,解析并执行命令的死循环中。

2、u-boot主要的数据结构

u-boot的主要功能是用于引导OS的,但是本身也提供许多强大的功能,可以通过输入命令行来完成许多操作。所以它本身也是一个很完备的系统。u-boot的大部分操作都是围绕它自身的数据结构,这些数据结构是通用的,但是不同的板子初始化这些数据就不一样了。所以u-boot的通用代码是依赖于这些重要的数据结构的。这里说的数据结构其实就是一些全局变量。

1)gd全局数据变量指针,它保存了u-boot运行需要的全局数据,类型定义:

typedef struct global_data{

bd_t*bd;//board data pointor板子数据指针

unsigned long flags;//指示标志,如设备已经初始化标志等。

unsigned long baudrate;//串口波特率

unsigned long have_console;/*串口初始化标志*/

unsigned long reloc_off;/*重定位偏移,就是实际定向的位置与编译连接时指定的位置之差,一般为0*/

unsigned long env_addr;/*环境参数地址*/

unsigned long env_valid;/*环境参数CRC检验有效标志*/

unsigned long fb_base;/*base address of frame buffer*/

#ifdef CONFIG_VFD

unsigned char vfd_type;/*display type*/

#endif

void**jt;/*跳转表,1.1.6中用来函数调用地址登记*/

}gd_t;

2)bd板子数据指针。板子很多重要的参数。类型定义如下:

typedef struct bd_info{

int bi_baudrate;/*串口波特率*/

unsigned long bi_ip_addr;/*IP地址*/

unsigned char bi_enetaddr[6];/*MAC地址*/

struct environment_s*bi_env;

ulong bi_arch_number;/*unique id for this board*/

ulong bi_boot_params;/*启动参数*/

struct/*RAM配置*/

{

ulong start;

ulong size;

}bi_dram[CONFIG_NR_DRAM_BANKS];

}bd_t;

移植前的环境准备:

(1)安装Red Hat9参照(第一步VMware安装)文档

(2)安装H-JTAG软件

H-JTAG软件的安装

在安装使用H-JTAG软件前,注意:

确保PC有并口,然后设置PC的BIOS的并口模式为“EPP”;

注意:您的PC如果没有并口,可忽略此小节。

PC机器已经安装好GIVEIO并口驱动;

JTAG板一端(25针)连接在您PC的并口上,另一条软排线头(10口)连接在开发板的JTAG口上开发板的电源打开。

开发板处于从Nor Flash启动状态,关于选择Nor/Nand Flash启动,请参考附录。

使用H-JTAG软件,有时候会出现“time out……“,或者找不到Nor Flash或Nand Flash情况,请手动多复位几次开发板。

H-JTAG软件在光盘“Windows平台开发工具包”目录下的“H-JTAG V0.9.2.rar”,解压后安装;或者到网站“https://www.wendangku.net/doc/7712790120.html,/download.html”下载最新版本安装。以下皆以光盘附带的H-JTAG V0.9.2.rar为例。

Step1、双击“H-JTAG V0.9.2.rar”解压,如果没有安装压缩软件的,请先到网上下载并安装压缩软件;

Step2、解压后出现H-JTAG V0.9.2.rar,双击它,进入安装向导。然后一直点击next(下一步)即可;

Step3、安装完毕后,会在电脑桌面上出现H-JTAG,H-Flasher2个快捷方式的图标。

H-JTAG的设置

H-Jtag的设置

Step1、双击打开H-JTAG图标,如图所示:

Step2、点击“close”选项,进入下图的界面,然后点击“Settings(设置)”菜单的“Jtag Settings”选项:

进入“Jtag Settings”界面,设置为如下图所示:

Step3、点击“OK”选项后,设置完毕。连接好目标板(电源,JTAG线),并启动目标板。点击“Detect target”()或者点击“Operations”菜单的“Detect target”选项:

Step4、如果侦测到CPU,会显示如下图所示,否则,提示错

H-Flasher的设置

Step1、启动H-Jtag软件,它会自动探测到CPU:

Step2、点击“”图标,启动H-Flasher软件:

Step3、点击”Load”导入我们已经做好的配置单,

目前v0.9.2版本的H-jtag已经支持烧写Nor Flash和Nand Flash,所以分别给出了烧写Nor Flash和Nand Flash的配置单:配置我们已经打包在H-JTAG V0.9.2.rar中,解压后使用。配置单说明:

TQ2440_nand_2KP.hfc用于烧写2K大页面Nand Flash的H-flash配置文件,烧写256MB Nand Flash请使用此配置文件

TQ2440_nand_64MB.hfc用于烧写512字节页面Nand Flash的H-flash配置文件,烧写64MB Nand Flash请使用此配置文件

TQ2440_nor_eon.hfc用于烧写Nor Flash的H-flash配置文件,烧写EON的flash请使用此配置文件

TQ2440_nor_sp.hfc用于烧写Nor Flash的H-flash配置文件,烧写Spansion的flash请使用此配置文件

烧写uboot到Nand Flash

以烧写256MB nanflash为例(64MBNand Flash类似):

1、请点击”Load”导入TQ2440_nand_2KP.hfc。

2、如下图:

点击“Programming”----点击“Check”------点击“Src File右边图标“”:

找到您要烧写uboot镜像,以烧写东华3.5寸屏uboot镜像为例,在光盘“\TQ2440_CD\出厂烧录镜像合集\东华3.5寸屏的镜像\U-boot\u-boot_W35.bin”

烧写u-boot,点击“Program”按钮,开始烧写:

点击“Close”按钮,至此,您就完成了把uboot烧写到Nand Flash的工作。

UBOOT移植步骤:

(1)解压源码tar xvfj/mnt/hgfs/share/u-boot-1.1.6.tar.bz2

(2)进入uboot目录:cd u-boot-1.1.6/

(3)gedit Makefile&在128行添加编译器路径,修改如下

(4)make sbc2410x_config

make

(5)我们把文件nand_flash.c文件添加进去,添加的位置在u-boot-1.1.6\cpu\arm920t\s3c24x0下,同时要改其目录下的Makefile文件,就是加上nand_flash.o

u-boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand flash的最初初始化函数。其调用与CFG_NAND_LEGACY宏有关,如果没定义CFG_NAND_LEGACY这个宏,就按照start_armboot()调用drivers/nand/nand.c中的nand_init函数(该函数在 1.1.6已经被实现),但还有个board_nand_init()函数没实现,需自己添加;如果定义了CFG_NAND_LEGACY,就不使用默认的nand_init,而调用自己写的nand_init函数了。

static void s3c24x0_nand_inithw(void)

{

S3C2410_NAND*const s3c2410nand=S3C2410_GetBase_NAND();

S3C2440_NAND*const s3c2440nand=S3C2440_GetBase_NAND();

#define TACLS0

#define TWRPH04

#define TWRPH12

if(gd->bd->bi_arch_number==MACH_TYPE_SMDK2410)

{

/*Enable NAND flash controller,Initialize ECC,enable chip select,Set flash memory timing*/

s3c2410nand->NFCONF=(1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

}

else

{

/*Set flash memory timing*/设置读写时序

s3c2440nand->NFCONF=(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

//NAND flash configuration register

/*Initialize ECC,enable chip select,NAND flash controller enable*/

s3c2440nand->NFCONT=(1<<4)|(0<<1)|(1<<0);

//NAND flash control register

}

}

/*

*Called by drivers/nand/nand.c,initialize the interface of nand flash

*/

void board_nand_init(struct nand_chip*chip)//drivers\nand\nand.c文件中的nand_init_chip()函数调用,最终被nand_init()调用

{

S3C2410_NAND*const s3c2410nand=S3C2410_GetBase_NAND();

S3C2440_NAND*const s3c2440nand=S3C2440_GetBase_NAND();

s3c24x0_nand_inithw();

if(gd->bd->bi_arch_number==MACH_TYPE_SMDK2410){

chip->IO_ADDR_R=(void*)&s3c2410nand->NFDATA;

chip->IO_ADDR_W=(void*)&s3c2410nand->NFDATA;

chip->hwcontrol=s3c2410_nand_hwcontrol;

chip->dev_ready=s3c2410_nand_devready;

chip->select_chip=s3c2410_nand_select_chip;

chip->options=0;

}else{

chip->IO_ADDR_R=(void*)&s3c2440nand->NFDATA;

chip->IO_ADDR_W=(void*)&s3c2440nand->NFDATA;

chip->hwcontrol=s3c2440_nand_hwcontrol;

chip->dev_ready=s3c2440_nand_devready;

chip->select_chip=s3c2440_nand_select_chip;

chip->options=0;

}

chip->eccmode=NAND_ECC_SOFT;

}

#endif

(6)我们要在sbc2410x.c文件中删除一些东西,文件位置在uboot1.1.6\board\sbc2410x。然后从#if(CONFIG_COMMANDS&CFG_CMD_NAND)开始处一直往后删除。如果不删除这里,编译的时候没法通过,我们刚才添加了nand_flash.c文件,目的就是完善这里。

(7)添加NAND_CMD支持。我们要打开sbc2410x.h文件,文件的位置在include/configs目录下。然后添加出位置(看红色部分)

#define CONFIG_COMMANDS\

(CONFIG_CMD_DFL|\

CFG_CMD_CACHE|\

CFG_CMD_NAND|\

/*CFG_CMD_EEPROM|*/\

/*CFG_CMD_I2C|*/\

/*CFG_CMD_USB|*/\

CFG_CMD_REGINFO|\

CFG_CMD_DATE|\

CFG_CMD_PING|\

CFG_CMD_DHCP|\

CFG_CMD_ELF)

(8)我们要在s3c24x0.h(位置在include)中增加S3C2440_NAND,如下:

typedef struct{

S3C24X0_REG32NFCONF;

S3C24X0_REG32NFCONT;

S3C24X0_REG32NFCMD;

S3C24X0_REG32NFADDR;

S3C24X0_REG32NFDATA;

S3C24X0_REG32NFMECCD0;

S3C24X0_REG32NFMECCD1;

S3C24X0_REG32NFSECCD;

S3C24X0_REG32NFSTAT;

S3C24X0_REG32NFESTAT0;

S3C24X0_REG32NFESTAT1;

S3C24X0_REG32NFMECC0;

S3C24X0_REG32NFMECC1;

S3C24X0_REG32NFSECC;

S3C24X0_REG32NFSBLK;

S3C24X0_REG32NFEBLK;

}/*__attribute__((__packed__))*/S3C2440_NAND;

这个是为了支持nand_flash.c中的

S3C2410_NAND*指针结构。

(9)我们要在s3c2410.h文件中加上如下内容:

static inline S3C2440_NAND*const S3C2440_GetBase_NAND(void)

{

return(S3C2440_NAND*const)S3C2410_NAND_BASE;

}

我们也是加在2410的对应函数的下面,这里也是为了支持nand_flash.c中的

S3C2440_GetBase_NAND()这个函数。

(10)先添加boot_init.c文件到u-boot-1.1.6\board\sbc2410x目录下,然后改下makefile该代码主要实现了CopyCode2Ram函数,该函数功能是拷贝flash代码到sdram 中。还实现了clock_init()时钟初始化函数。

(11)修改同目录下的u_boot.lds文件,我们添加红色部分

{

.=0x00000000;

.=ALIGN(4);

.text:

{

cpu/arm920t/start.o(.text)

board/sbc2410x/boot_init.o(.text)

*(.text)

}

(12)修改内存初始化函数。board/sbc2410x/config.mk:修改TEXT_BASE=0X33D80000,这个就是放置数据堆栈的起始位置。board/sbc2410x/lowinit.s:这里修改如下

#define B6_MT0x3/*SDRAM*/

#define B6_Trcd0x1

#define B6_SCAN0x1/*9bit*/

#define B7_MT0x3/*SDRAM*/

#define B7_Trcd0x1/*3clk*/

#define B7_SCAN0x1/*9bit*/

#define REFEN0x1/*Refresh enable*/

#define TREFMD0x0/*CBR(CAS before RAS)/Auto refresh*/

#define Trp0x0/*2clk*/

#define Trc0x3/*7clk*/

#define Tchr0x2/*3clk*/

#define REFCNT0x4f4

/**************************************/

_TEXT_BASE:

.word TEXT_BASE

.globl lowlevel_init

lowlevel_init:

/*memory control configuration*/

/*make r0relative the current location so that it*/

/*reads SMRDATA out of FLASH rather than memory!*/

ldr r0,=SMRDATA

ldr r1,_TEXT_BASE

sub r0,r0,r1

ldr r1,=BWSCON/*Bus Width Status Controller*/

add r2,r0,#13*4

0:

ldr r3,[r0],#4

str r3,[r1],#4

cmp r2,r0

bne0b

/*everything is fine now*/

mov pc,lr

.ltorg

/*the literal pools origin*/

SMRDATA:

.word

(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5

_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))

.word

((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2) +

(B0_PMC))

.word

((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2) +

(B1_PMC))

.word

((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2) +

(B2_PMC))

.word

((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2) +

(B3_PMC))

.word

((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2) +

(B4_PMC))

.word

((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2) +

(B5_PMC))

.word((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))

.word((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))

.word((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

.word0x32

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命令详解(z) 2010-09-30 15:05:52| 分类:学习心得体会|字号订阅 U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的 U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。 [u-boot@MINI2440]# version U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# v U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# base Base Address: 0x00000000 [u-boot@MINI2440]# ba Base Address: 0x00000000 由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧! (1)获取帮助 命令:help 或? 功能:查看当前U-boot版本中支持的所有命令。 [u-boot@MINI2440]#help ?- alias for'help' askenv - get environment variables from stdin base - print or set address offset bdinfo - print Board Info structure bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol

uboot2013.07lds分析

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);/*

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移植详解

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 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

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

xilinx uboot网卡驱动分析和一些概念扫盲

xilinx uboot网卡驱动分析和一些概念扫盲 1、MAC控制器、网卡、PHY、MDIO、mii、gmii、rgmii概念扫盲 网卡在功能上包含OSI模型的两个层,数据链路层和物理层。物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。网卡中负责数据链路的芯片叫做MAC控制器,负责物理层的芯片叫做PHY。所以,一个网卡由MAC控制器和PHY组成。 MAC控制器与PHY连接使用MII(Medium independent interface)媒体独立接口,这个接口是IEEE-802.3定义的以太网行业标准定义的接口,包括一个数据接口和一个MAC和PHY之间的管理接口即MDIO。MII标准接口用于连接MAC和PHY,媒体独立表示不对MAC硬件重新设计或替换的情况下,任何类型的PHY设备接到当前MAC控制器上都可以正常工作。 MII支持10M和100M的网络速率,由于网卡的速率不同,所以在其他速率下工作的与MII等效的接口有:AUI(10M以太网)、GMII(Gigabit以太网)和XAUI(10-Gigabit 以太网)。此外还有RMII、RGMII、SMII、SGMII等。所有这些接口都是由MII而来。MII支持10兆和100兆的操作,一个接口由14根线组成。RMII是简化的MII接口,在数据的收发上它比MII接口少了一倍的信号线。SMII是由思科提出的一种媒体接口,它有比RMII更少的信号线数目,S表示串行的意思。因为它只用一根信号线传送发送数据,一根信号线传输接受数据,所以在时钟上为了满足100的需求,它的时钟频率很高,达到了125兆,为什么用125兆,是因为数据线里面会传送一些控制信息。GMII采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100 Mbps工作方式。RGMII又是GMII接口的精简版。SGMII又是GMII的串行版。 MAC控制器和PHY除了数据传输的交流外,MAC和PHY控制信息的交流通过MDIO(管理数据输入输出)接口来完成。具体MAC控制器进行PHY检测、MAC控制器回去PHY 当前状态、MAC控制器控制PHY速率等操作就通过MDIO来完成。

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"

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 维护

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移植实验

一、移植环境 ?主机:UBUNTU ?开发板:飞凌2440 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.03.tar.bz2

3)修改u-boot根目录下的Makefile文件。查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立mini2440_config的编译选项,另外还要指定交叉编译器 4)测试编译新建的mini2440开发板项目

到此为止,u-boot对自己的mini2440开发板还没有任何用处,以上的移植只是搭建了一个mini2440开发板u-boot的框架,要使其功能实现,还要根据mini2440开发板的具体资源情况来对u-boot源码进行修改。 3. 根据u-boot启动流程图的步骤来分析或者修改添加u-boot源码,使之适合mini2440开发板(注:修改或添加的地方都用红色表示)。 1)mini2440开发板u-boot的stage1入口点分析。 一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。那么我们的my2440开发板u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下:

知道了程序的入口点是_start,那么我们就打开mini2440开发板u-boot第一个要运行的程序cpu/arm920t/start.S(即u-boot的stage1部分),查找到_start的位置如下: 从这个汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code 处的代码如下:

关于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、uboot使用实验

Uboot的使用 一、 实验目的 在实验平台上使用uboot常用命令及使用Tftp工具传输文件。 二、 实验资源 硬件资源 CPU Samsung S3C2440A Nand flash Samsung K9D1208V0M 64M RAM64M 软件资源 bootloader uboot Tftp server tftpd32.exe 三、 实验前的准备 1、一台PC机。 2、实验平台。 3、串口线、网络线。 4、tftpd32.exe软件。 四、 实验步骤 1、实验前的准备 a)将串口线、网络线连接到实验平台与PC机上。 b)在PC机上运行超级终端串口软件。

2、进入Uboot命令输出状态 实验平台上电,在超级终端串口软件中按空格键进入Uboot命令输出状态。 3、查看Uboot命令 运行help命令显示uboot提供的所有命令。

4、学习U-Boot的几个常用的命令 根据每一条命令的帮助信息,说明这些命令的功能、参数和用法。 z bootm => help bootm bootm [addr [arg ...]] - boot application image stored in memory passing arguments 'arg ...'; when booting a Linux kernel, 'arg' can be the address of an initrd image bootm 命令可以引导启动存储在内存中的程序映像。这些内存包括RAM 和可以永久保存的Flash。 第1 个参数addr 是程序映像的地址,这个程序映像必须转换成U-Boot 的格式。 第2 个参数对于引导Linux 内核有用,通常作为U-Boot 格式的RAMDISK 映像存储地址;也可以是传递给Linux内核的参数(缺省情况下传递bootargs环境变量给内核)。 例如: ——从内存地址0x300000启动 0x300000 bootm z cp => help cp cp [.b, .w, .l] source target count - copy memory cp命令可以在内存中复制数据块,包括对Flash的读写操作。 第1 个参数source是要复制的数据块起始地址。 第2 个参数target是数据块要复制到的地址。这个地址如果在Flash中,那么会直接调用写Flash的函数操作。所以U-Boot 写Flash就使用这个命令,当然需要先把对应Flash区域擦干净。 第3 个参数count是要复制的数目,根据cp.b cp.w cp.l分别以字节、字、长字为单位。 例如: cp.b 0x300000 0xFE040000 0x180000将1.5M数据从内存拷到flash 0xFE040000位

经典=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环境变量设置(大地小神之个人收藏)

u-boot的环境变量 u-boot的环境变量是使用u-boot的关键,它可以由你自己定义的,但是其中有一些也是大家经常使用,约定熟成的,有一些是u-boot 自己定义的,更改这些名字会出现错误,下面的表中我们列出了一些常用的环境变量: 上面只是一些最基本的环境变量,请注意,板子里原本是没有环境变量的,u-boot的缺省情况下会有一些基本的环境变量,在你执行了saveenv之后,环境变量会第一次保存到flash中,之后你对环境变量的修改,保存都是基于保存在flash中的环境变量的操作。

U-boot的环境变量值得注意的有两个:bootcmd 和bootargs ◆b o o t c m d 前面有说过bootcmd是自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置,然后设置bootcmd为你经常使用的那种参数。 ◆b o o t a r g s bootargs是环境变量中的重中之重,甚至可以说整个环境变量都是围绕着bootargs来设置的。bootargs的种类非常非常的多,我们平常只是使用了几种而已,感兴趣的可以看看这篇文章说的很全:https://www.wendangku.net/doc/7712790120.html,/u2/79570/showart_1675071.html。bootargs非常的灵活,内核和文件系统的不同搭配就会有不同的设置方法,甚至你也可以不设置bootargs,而直接将其写到内核中去(在配置内核的选项中可以进行这样的设置),正是这些原因导致了bootargs使用上的困难。 下面介绍一下bootargs常用参数,bootargs的种类非常的多,而且随着kernel的发展会出现一些新的参数,使得设置会更加灵活多样。 A.r o o t 用来指定r o o t f s的位置,常见的情况有: root=/dev/ram rw root=/dev/ram0 rw 请注意上面的这两种设置情况是通用的,我做过测试甚至

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调试指南

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所示:

Uboot启动代码解析

U-Boot启动过程 开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot 启动函数。看一下board/smdk2410/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 /* 关闭看门狗 */ ………… relocate: /* 把U-Boot重新定位到RAM */ adr r0, _start /* r0是代码的当前位置 */ ldr r1, _TEXT_BASE /*_TEXT_BASE是RAM中的地址 */ cmp r0, r1 /* 比较r0和r1,判断当前是从Flash启动,还是RAM */ beq stack_setup /* 如果r0等于r1,跳过重定位代码 */ /* 准备重新定位代码 */ ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 得到armboot的大小 */ add r2, r0, r2 /* r2 得到要复制代码的末尾地址 */ copy_loop: /* 重新定位代码 */ ldmia r0!, {r3-r10} /*从源地址[r0]复制 */

相关文档