-----

一:我们先来了解下实际内存:

nand、nor、ram。

所以从CPU是从那部分启动的呢?

答:要看主控芯片的boot如何设置(正如分的启动方式和下载方式一样)。

uboot:sd卡→iRAM(DDR3)

作用简述:

他的作用就是硬件→OS;相当于OS和硬件的一个桥梁

Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader。
我们以Grub为例来讲解吧,毕竟用lilo和spfdisk的人并不多。
系统读取内存中的grub配置信息(一般为menu.lst或grub.lst),并依照此配置信息来启动不同的操作系统。

移植方略:

1.1 uboot的介绍

Uboot是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序, UBoot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。UBoot除了支持PowerPC系列的处理器外,还能支持MIPS、 x86、ARM、NIOS、XScale等诸多常用系列的处理器。

1.2 uboot的体系结构

目录树

|--board

|--common

|--cpu

|--disk

|--doc

|--drivers

|--dtt

|--examples

|--fs

|--include

|--lib_arm

|--lib_generic

|--net

|--post

|--rtc

|--tools

2. board:和一些已有开发板有关的文件. 每一个开发板都以一个子目录出现在当前目录中,比如说: leopard2a子目录中存放与我们开发板相关的配置文件.

3. common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。例如bootm命令对应就是cmd_bootm.c。

4. cpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录arm926ejs就是我们开发板上使用的cpu架构目录。

5. disk:对磁盘的支持。

5. doc:文档目录。Uboot有非常完善的文档,推荐大家参考阅读。

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

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

8. include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。该目录耤onfigs目录有与开发 板相关的配置头文件,如leopard2a.h。该目录下的asm目录有与CPU体系结构相关的头文件,asm对应的是asmarm.

9. lib_xxxx: 与体系结构相关的库文件。如与ARM相关的库放在lib_arm中。

10. net:与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。

11. tools:生成Uboot

的工具,如:mkimage, crc等等。

2. uboot的运行过程分析

2.1 启动模式介绍

大多数 Boot Loader 都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,Boot Loader 的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。

启动加载(Boot loading)模式:这种模式也称为"自主"(Autonomous)模式。也即 Boot Loader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。这种模式是 BootLoader 的正常工作模式,因此在嵌入式产品发布的时侯,Boot Loader 显然必须工作在这种模式下。

下载(Downloading)模式:在这种模式下,目标机上的 Boot Loader 将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被 BootLoader 保存到目标机的 RAM 中,然后再被 BootLoader 写到目标机上的FLASH 类固态存储设备中。BootLoader 的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用 BootLoader 的这种工作模式。工作于这种模式下的 Boot Loader 通常都会向它的终端用户提供一个简单的命令行接口。

UBoot这样功能强大的 Boot Loader 同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。

2.2 运行过程

大多数bootloader都分为阶段1(stage1)和阶段2(stage2)两大部分,uboot也不例外。依赖于CPU体系结构的代码(如CPU 初始化代码等)通常都放在阶段1中且通常用汇编语言实现,而阶段2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。

U - Boot 编译后的代码定义一般不超过100kB ,并且这100 kB 又分成两个阶段来执行. 第一阶段的代码在start . s 中定义,大小不超过10 kB ,它包括从系统上电后在0x00000000 地址开始执行的部分. 这部分代码运行在Flash 中,它包括对arm926ejs的一些寄存器的初始化和将U - Boot 的第二阶段代码从Flash 拷贝到SDRAM 中. 除去第一阶段的代码,剩下的部分都是第二阶段的代码. 第二阶段的起始地址是在第一阶段代码中指定的,被复制到SDRAM后,就从第一阶段跳到这个入口地址开始执行剩余部分代码. 第二阶段主要是进行一些BSS 段设置,堆栈的初始化等工作,最后会跳转到main -loop 函数中,接受命令并进行命令处理. 图1 给出了U - Boot 的详细的运行过程包括对内核的设置、装载及调用过程.

系统复位进入u-boot stage l的入口点

硬件设备的初始化

为加载uboot stage 2准备ram空间

设置好堆栈

跳转到stage 2的C入口点

初始化本阶段要用到的设备

检查内存映射

将kernel映像和文件映像从flash中读到ram中

为内核设定启动参数

调用内核

2.3 本开发板的地址分布(leopard2a

可以根据变换后的分区结构,设置

uboot_addr,uboot_addr_end,kernel_addr,kernel_addr_end,rootfs_addr,rootfs_addr_end,

config_addr, config_addr_end等环境变量,调整bootloader。

SDRAM的调整修改linux-2.4.20_mvl31/drivers/mtd/maps/physmap.c

2.4 运行代码分析

2.4.1 stage 1

uboot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码包括定义入口,设置异常向量,设置cpu的模式和频率,配置内存区控制寄存器,安装uboot的栈空间,关闭看门狗等。由于本人对ram的汇编不太熟悉,所以这一部分不作具体分析。

2.4.2 stage 2

lib_arm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个uboot(armboot)的主函数,该函数主要完成如下操作:

2.4.2.1 调用一系列初始化函数

1. 指定初始函数表:

init_fnc_t *init_sequence[] = {

cpu_init, /* cpu的基本设置 */

board_init, /* 开发板的基本初始化 */

interrupt_init, /* 初始化中断 */

env_init, /* 初始化环境变量 */

init_baudrate, /* 初始化波特率 */

serial_init, /* 串口通讯初始化 */

console_init_f, /* 控制台初始化第一阶段 */

display_banner, /* 通知代码已经运行到该处 */

dram_init, /* 配制可用的内存区 */

display_dram_config,

#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)

checkboard,

#endif

NULL,

};

执行初始化函数的代码如下:

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

if ((*init_fnc_ptr)() != 0) {

hang ();

}

}

2. 配置可用的Flash区

flash_init ()

3. 初始化内存分配函数

mem_malloc_init()

4. nand flash初始化

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

puts ("NAND:");

nand_init();        /* go init the NAND */

#endif

5. 初始化环境变量

env_relocate ();

6. 外围设备初始化

devices_init()

7. I2C总线初始化

i2c_init();

8. LCD初始化

drv_lcd_init();

9. VIDEO初始化

drv_video_init();

10. 键盘初始化

drv_keyboard_init();

11. 系统初始化

drv_system_init();

2.4.2.2初始化网络设备

初始化相关网络设备,填写IP、MAC地址等。

1. 设置IP地址

gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

2. 设置mac地址

{

int i;

ulong reg;

char *s, *e;

uchar tmp[64];

i = getenv_r ((uchar*)("ethaddr"), tmp, sizeof (tmp));

s = (i > 0) ? (char*)tmp : NULL;

for (reg = 0; reg < 6; ++reg) {

gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;

if (s)

s = (*e) ? e + 1 : e;

}

}

2.4.2.3进入主UBOOT 命令行

进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

for (;;) {

main_loop ();

}}

3. uboot的移植和测试

3.1 移植的过程

① 在宿主机上建立交叉编译开发环境

② 修改cpu/arm926ejst目录中的文件内容,

主要包含cpu.C,start.S,interrupts.C以及seria1.C,speed.C等文件

③ 在board目录下创建自己的目标板(开发板)目录leopard2a

在目录下创建leopard2a.C,flash.C,memsetup.S

以及Makefile,u-bot.1ds,config.mk文件

④在include/configs目录下创建leopard2a.h

 

⑤ 打开u-bot目录下Makefile文件,加入如下两行:

leopard2a_config :      unconfig

@./mkconfig $(@:_config=) arm arm926ejs leopard2a

⑨ 编译。运行命令:

1. make leopard2a_config

2. make

编译成功.生成基本的u—b00t.

⑦ 烧写.把编译成的u-bot.bin

至此移植u-bot过程结束.

3.2 移植主要修改的文件

移植u—boot到开发板上只需要修改和硬件相关的代码即可。这首先就联想到cpu目录下的启动代码,另外参考u—boot/readme文件可知其他还需要修改的主要文件有:

Makefile文件,和include目录下的目标板.h头文件(leopard2a.h),board目录下的目标板.C文件(leopard2a.c),flash.C文件,u-boot.1ds链接文件,以及cpu目录下的串口驱动文件。

具体修改如下:

①      cpu/arm926ejst目录下

◆ start.S启动代码。

②    board/leopard2a

◆  leopard2a.C文件。这个文件主要是SDRAM 的驱动程

序,主要完成SDRAM 的UPM 表设置,上电初始化。暂时不

改。

◆  flash.C文件。Flash的驱动程序就在此文件中。

◆      memsetup.S文件。

◆  config.mk文件.此文件用于设置程序链接的起始地

址.

◆u-boot.Ids文件。

③ include/configs目录下leopard2a.h文件.此文件是

leopard2a目标板头文件,大多数寄存器参数是在这一文件中

设置完成的.

3.3 uboot网络下载功能的添加和RAM调试

在commom/main.c 中的main_loop函数中添加tftp下载的函数,可以通过按钮触发下载rimage,kimage。

在烧录u-boot.bin之前,需要进行ram调试,保证uboot可以在EVB上正常运行。

先下載U-boot 到SDRAM上, 然後執行SDRAM 上的U-boot 程序, 以確認U-boot可以正常執行,

Command 如下:

1.       “tftp a00000 u-boot.bin” <= 下載程序到SDRAM

2.       “go a00000” <= 從SDRAM 執行程序

如果U-boot 可以相容於目前的硬件, 5VT EVB 會重新正常啟動

要是不能正常啟動,表示U-boot 不相容於目前的硬件, 請更換新的u-boot.

再重新測試, 直到被測試的U-boot可以正常啟動。

① 获得发布的最新版本U-Boot源码,与Linux内核源码类似,也是 bzip2的压缩格式。可从U-Boot的官方网站http://sourceforge.net/projects/U-Boot上获得;
② 阅读相关文档,主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULG(The DENX U-Boot and Linux Guide)文档http://www.denx.de/twiki/bin/view/DULG/Manual。尤其是DULG文档,从如何安装建立交叉开发环境和解决U-Boot移植中常见问题都一一给出详尽的说明;
③ 订阅U-Boot用户邮件列表http://lists.sourceforge.net/lists/listinfo/u-boot-users。在移植U-Boot过程中遇有问题,在参考相关文档和搜索U-Boot-User邮件档案库http://sourceforge.net/mailarchive/forum.php?forum_id=12898仍不能解决的情况下,第一时间提交所遇到的这些问题,众多热心的U-Boot开发人员会乐于迅速排查问题,而且很有可能,W.D本人会直接参与指导;
④ 在建立的开发环境下进行移植工作。绝大多数的开发环境是交叉开发环境。在这方面,DENX 和MontaVista均提供了完整的开发工具集;

 

参考资料:

linux启动过程

http://www.cnblogs.com/Ph-one/p/4282124.html

Exynos 4412的启动过程分析[2]

http://www.cnblogs.com/Ph-one/p/4547395.html

---------

1uboot移植要点[原创☆☆]的更多相关文章

  1. 嵌入式web server——Goahead移植要点

    前言 在嵌入式设备中,在没有液晶显示的情况下,可以使用web来访问设备,查看设备的运行状态以及进行参数设置,类似于路由器设置.网上有很多关于各种web server的优劣的评论,在此不讨论,只是介绍其 ...

  2. 基于sys文件系统的LED驱动的移植【原创】

    基于RK3188平台LED驱动程序的移植的移植.如有不正确之处,欢迎大家指点. 本文的LED驱动程序不是通过打开设备节点来访问和控制LED的,是通过sys文件系统来控制LED. 板子上有四盏灯以及对应 ...

  3. uboot 移植 要点

    1.第一 首先要  学会 shell 语法   比如 变量的 概念 变量的使用 ,if 语法  ,以及简单 IF 语法(与 或预算),以及  while for 循环 等等语法,才能看得懂 uboot ...

  4. alsa-lib、alsa-utils移植

    /************************************************************************** * alsa-lib.alsa-utils移植 ...

  5. 标题:u-boot 移植步骤详解

    1 U-Boot简介U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目.从FADSROM.8xxROM.PPCBOOT逐步发展演化而来.其源码目录.编译形式与 ...

  6. 【MCU】国民N32固件库移植

    目录 前言 移植N32Gxxx系列要点 前言 链接: 李柱明博客 移植AT32库&FreeRTOS教程 由于大部分国产MCU移植固件库.RTOS源码都是差不多的,所以本文不讲细节,如想熟悉移植 ...

  7. wifi详解(五)

    1        Android平台的Wifi模块移植要点 1.1      Wifi结构 user interface Android WiFiService WPA_Supplicant DHD ...

  8. FreeModbus for stm32(Keil工程)——精简Modbus slave协议【worlsing笔记】

    FreeModbus For stm32:点击下载源码 1.测试环境Keil MDK 4.7a  stm32f103c8, PB12为输出线圈,    可以通过Modbus Poll来控制线圈的输出状 ...

  9. 嵌入式web server——Goahead启用SSL

    前言 之前已经介绍过如何把goahead移植到linux平台,现在再介绍goahead应用SSL的一些关键要点.因为此博文是继承于上一篇关于移植的博文,有不明白的请先回看.移植篇点这里. 移植环境 g ...

随机推荐

  1. SpringInAction读书笔记--第4章面向切面

    1.什么是面向切面编程 在软件开发中,散布于应用中多处的功能被称为横切关注点,这些横切关注点从概念上是与应用的业务逻辑相分离的,但往往分直接嵌入到应用的业务逻辑之中,把这些横切关注点与业务逻辑相分离正 ...

  2. java多线程 join方法以及优先级方法

    /*join:当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果 ...

  3. Java语言----三种循环语句的区别

    ------- android培训.java培训.期待与您交流! ---------- 第一种:for循环 循环结构for语句的格式:       for(初始化表达式;条件表达式;循环后的操作表达式 ...

  4. [PR & ML 3] [Introduction] Probability Theory

    虽然学过Machine Learning和Probability今天看着一part的时候还是感觉挺有趣,听惊呆的,尤其是Bayesian Approach.奇怪发中文的笔记就很多人看,英文就没有了,其 ...

  5. 堆排序 C++

    1 堆排序拥有插入排序的优点 (是一种原地排序算法只需要存储常数个元素在输入数组以外 即省空间), 同时拥有合并排序算法的复杂度 nlgn,逼格有点高 2 堆数据结构 是一个数组对象,可以被视为一颗完 ...

  6. Poj 2159 / OpenJudge 2159 Ancient Cipher

    1.链接地址: http://poj.org/problem?id=2159 http://bailian.openjudge.cn/practice/2159 2.题目: Ancient Ciphe ...

  7. OpenJudge 2766 最大子矩阵

    1.链接: http://bailian.openjudge.cn/practice/2766 2.题目: 总Time Limit: 1000ms Memory Limit: 65536kB Desc ...

  8. OpenJudge 2795 金银岛

    1.链接地址: http://bailian.openjudge.cn/practice/2795/ 2.题目: 总Time Limit: 3000ms Memory Limit: 65536kB D ...

  9. CentOS7 firewall的使用

    # 查看区域 firewall-cmd --get-zones # 查看默认区域 firewall-cmd --get-default-zone # 给区域添加永久性服务 firewall-cmd - ...

  10. Linux EMACS的简单使用

    1 File 菜单项 open file 打开文件 close 关闭当前操作的文件 save 保存当前操作的文件 save buffer as 另存为 split window 拆分窗口 ,同时操作不 ...