注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Java鸟

真才实料

 
 
 

日志

 
 

嵌入式Linux系统学习入门-UBOOT  

2012-07-18 16:09:03|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

交叉工具链

安装

进行嵌入式开发前,首先需安装交叉工具链,步骤如下:

1.  解压工具链到某一目录下

例:

tar xvzf arm-linux-gcc-4.3.2.tar.gz –C /

2.  修改/etc/profile ,添加

pathmunge /usr/local/arm/4.3.2/bin

3.      执行source /etc/profile

编译器:arm-linux-gcc

arm-linux-gcc hello.c –o hello

反汇编工具:arm-linux-objdump

arm-linux-objdump –D –S hello

ELF文件查看工具:arm-linux-readelf

arm-linux-readelf –a hello

arm-linux-readelf –d hello 查看hello使用的动态库

 

BootLoader介绍

软件层次

一个嵌入式系统从软件角度来看分为三个层次:

1. 引导加载程序

包括固化在固件(firmware)中的 boot 程序(可选),和 BootLoader 两大部分。

2. Linux 内核

特定于嵌入式平台的定制内核。

3. 文件系统

包括了系统命令和应用程序。

 

在嵌入式系统中,通常没有像BIOS那样的固件程序,因此整个系统的加载启动任务就完全由BootLoader来完成。比如在一个基于 ARM7TDMI core的嵌入式系统中,系统在上电或复位时都从地址 0x00000000开始执行。而在这个地址处安排的通常就是系统的BootLoader程序。

简单地说,BootLoader就是在操作系统运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统做好准备。

系统加电或复位后,所有的CPU通常都从CPU制造商预先安排地址开始执行。比如,S3C2410在复位后从地址0x00000000起开始执行。而嵌入式系统则将固态存储设备(比如:FLASH)安排在这个地址上,而bootloader程序又安排在固态存储器的最前端,这样就能保证在系统加电后,CPU首先执行BootLoader程序。

每种不同的CPU体系结构都有不同的

BootLoader。除了依赖于CPU的体系结构外,BootLoader 还依赖于具体的嵌入式板级设备的配置,比如板卡的硬件地址分配,外设芯片的类型等。这也就是说,对于两块不同的开发板而言,即使它们是基于同一种CPU而构建的,但如果他们的硬件资源或配置不一致的话,要想在一块开发板上运行的BootLoader程序也能在另一块板子上运行,还是需要作修改。

流程

BootLoader 的启动过程可分为单阶段(Single-Stage)和多阶段(Multi-Stage)两种,通常多阶段的 BootLoader 具有更复杂的功能,更好的可移植性。从固态存储设备上启动的BootLoader 大多采用两阶段,即启动过程可以分为 stage 1和 stage2:stage1完成初始化硬件,为stage2准备内存空间,并将stage2复制到内存中,设置堆栈,然后跳转到stage2。

BootLoader 的 stage1 通常包括以下步骤:

·硬件设备初始化

·为加载 BootLoader 的 stage2 准备 RAM 空间

·拷贝 BootLoader 的 stage2 到 RAM 空间中

·设置好堆栈(why??)

·跳转到 stage2 的 C 入口点

BootLoader 的 stage2 通常包括以下步骤:

·初始化本阶段要使用到的硬件设备

·将内核映像和根文件系统映像从 flash 上读到RAM 中

·调用内核

Uboot是德国DENX小组开发的用于多种嵌入式CPU( MIPS、x86、ARM、XScale等)的bootloader程序, UBoot不仅支持嵌入式Linux系统的引导,还支持VxWorks, QNX等多种嵌入式操作系统。

从下面地址可以下载到uboot的源代码:

ftp://ftp.denx.de/pub/u-boot/

 

目录结构

进入到UBOOT目录,可以得到如下的目录结构:

|-- board

|-- common

|-- cpu

|-- disk

|-- doc

|-- drivers

|-- dtt

|-- examples

|-- fs

|-- include

|-- lib_arm

|-- lib_generic

|-- lib_i386

|-- lib_m68k

|-- lib_microblaze

|-- lib_mips

|-- lib_nios

|-- lib_nios2

|-- lib_ppc

|-- net

|-- post

|-- rtc

|-- tools

 

Board

和开发板有关的文件。每一个开发板都以一个子目录出现在当前目录中,比如:SMDK2410,子目录中存放与开发板相关的文件。

v Common

实现Uboot支持的命令。

v Cpu

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

v Disk

对磁盘的支持。

v Doc

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

v Drivers

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

V Fs

文件系统的支持。

V Include

Uboot使用的头文件。该目录下configs目录有与开发板相关的配置头文件,如smdk2410.h。该目录下的asm目录有与CPU体系结构相关的头文件。

V Net

与网络协议栈相关的代码,例如:TFTP协议、RARP协议的实现。

V Tools

生成Uboot的工具,如:mkimage, crc等等。

 

编译

Uboot的Makefile从功能上可以分成两个部分:

1、执行每种board相关的配置

2、编译生成uboot.bin文件

 

Uboot.bin的生成也分为两步,以smdk2410为例来说明,如下:

1. 选择要使用的board:

$make smdk2410_config

2. 编译生成u-boot.bin:

$make CROSS_COMPILE=arm-linux-

 

常用命令

尽管UBOOT提供了丰富的命令集,但不同的单板所支持的命令并不一定一样(可配置,How?后面章节),help 命令可用于察看当前单板所支持的命令。

【2410】 # help

autoscr -run script from memory

base -print or set address offset

bdinfo -print Board Info structure

bootm -boot application image from memory

 

printenv 查看环境变量

usage:

printenv

- print values of all environment variablesprintenv name ...

- print value of environment variable 'name'

Uboot> printenv

ipaddr=192.168.1.1

ethaddr=12:34:56:78:9A:BC

serverip=192.168.1.5

 

setenv 添加、修改、删除环境变量

v setenv name value ...

- set environment variable 'name' to 'value ...‘

v setenv name

- delete environment variable 'name'

Uboot> setenv myboard AT91RM9200DK

Uboot> printenv

serverip=192.168.1.5

myboard=AT91RM9200DK

 

saveenv 保存环境变量

将当前定义的所有变量及其值存入flash中。

文件下载

tftp 通过网络下载文件

注意:使用tftp,需要先配置好网络

Uboot> setenv ethaddr 12:34:56:78:9A:BC

Uboot> setenv ipaddr 192.168.1.1

Uboot> setenv serverip 192.168.1.254 (tftp服务器的地址)

例:

Uboot> tftp 32000000 uImage

把server(IP=环境变量中设置的serverip)中服务目录下的

uImage通过TFTP读入到0x32000000处。

内存操作

md 显示内存区的内容。

md采用十六进制和ASCII码两种形式来显示存储单元的内容。这条命令还可以采用长度标识符 .l, .w和.b :

md [.b, .w, .l] address

md.w 100000

00100000: 2705 1956 5050 4342 6f6f 7420 312e 312e   

00100010: 3520 284d 6172 2032 3120 3230 3032 202d

mm 修改内存,地址自动递增。

mm [.b, .w, .l] address

mm 提供了一种互动修改存储器内容的方法。它会显示地址和当前值,然后提示用户输入。如果你输入了一个合法的十六进制数,这个新的值将会被写入该地址。然后提示下一个地址。如果你没有输入任何值,只是按了一下回车,那么该地址的内容保持不变。如果想结束输入,则输入空格,然后回车。

=> mm 100000

00100000: 27051956 ? 0

00100004: 50504342 ? AABBCCDD

 

flinfo 查看Flash扇区信息

Usage:Uboot> flinfo

protect Flash写保护

打开或关闭扇区写保护

用法:

protect off all

关闭所有扇区的写保护

protect on all

打开所有扇区的写保护

protect off start end

关闭从start 到 end 扇区的写保护(start为要关闭的第1个扇区的起始

地址,end为要关闭的最后一个扇区的结束地址)

protect on start end

打开从start 到 end 扇区的写保护

erase 擦除flash扇区

用法: erase start end

擦除从start 到 end 的扇区,start 为要擦除的第1个扇区的起始地址,end 为要擦除的最后一个扇区的结束地址(在使用cp命令向Nor型Flash写入数据之前必须先使用erase 命令擦除flash,因为nor flash 按字节写入时,无法写入1,所以必须通过擦除来写入1)。

例:erase 30000 1effff

 

cp 数据拷贝。

cp [.b, .w, .l] saddress daddress len

cp 提供了一种内存与内存,内存与Flash之间数据拷贝的方法。

例:

cp.b 31000000 50000 d0000

将内存地址0x31000000处的数据(长度为0xd0000)拷贝到地址0x50000处(Flash中)

cp.b 32000000  120000 c0000

将内存地址0x32000000处的数据(长度为0xc0000)拷贝到地址0x120000处(Flash中)

 

执行程序

go 执行内存中的二进制代码,一个简单的跳转到指定地址

go addr [arg ...]

- start application at address 'addr‘,

passing 'arg' as arguments

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

要求二进制代码有固定格式的文件头。

bdinfo – 显示开发板信息

bdinfo命令(简写为bdi)将在终端显示诸如内存地址和大小、时钟频率、MAC地址等信息。这些信息在传递给Linux内核一些参数时可能会用到。

 

自动启动

1. 设置自动启动

mini2440=>setenv bootcmd tftp 31000000 uImage /; bootm 31000000

mini2440 =>saveenv

 

工作模式

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

启动模式

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

 

下载模式

在这种模式下,目标机上的BootLoader 将通过串口或网络等通信手段从主机(Host)下载文件,然后控制启动流程。

 

 

Uboot移植

BootLoader 依赖于:

具体的CPU体系、具体的板级设备配置

(芯片级移植、板级移植)

板级设备的配置文件位于

include/configs/<board_name>.h

<board_name>用相应的BOARD定义代替(例:smdk2410.h)

Smdk2410.h

#define CONFIG_ARM920T 1

/* CPU 类型 */

#define CONFIG_S3C2410    1

/* MCU类型 */

#define CONFIG_SMDK2410 1

/* 开发板型号 */

#define USE_920T_MMU  1

/* 使用MMU */

#undef CONFIG_USE_IRQ

/* 不使用 IRQ/FIQ */

/* malloc  池大小*/

#define CFG_MALLOC_LEN   (CFG_ENV_SIZE +

128*1024)

/* 数据段大小 128字节 */

#define CFG_GBL_DATA_SIZE 128

/* 使用 CS8900 网卡 */

#define CONFIG_DRIVER_CS8900 1

/* CS8900A 基地址 */

#define CS8900_BASE 0x19000300

/* 使用串口1 */

#define CONFIG_SERIAL1  1

/* 波特率 */

#define CONFIG_BAUDRATE 115200

#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_ELF)

/*定义使用的命令,可添加额外命令,如PING*/

/* 自动启动等待时间 */

#define CONFIG_BOOTDELAY  3

/* 内核启动参数 */

#define CONFIG_BOOTARGS   

"root=ramfs devfs=mount console=ttySA0,9600“

#define CONFIG_ETHADDR 08:00:3e:26:0a:5b

#define CONFIG_NETMASK  255.255.255.0

#define CONFIG_IPADDR   10.0.0.110

#define CONFIG_SERVERIP 10.0.0.1

#define CONFIG_BOOTCOMMAND "tftp; bootm"

#define CFG_PROMPT "SMDK2410 # "

#define PHYS_SDRAM_1  0x30000000 /* SDRAM Bank #1 */

#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */

#define CFG_LOAD_ADDR  0x33000000

/* 默认的启动地址 */

#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }   /*可用的波特率*/

/* 有一片SDRAM */

#define CONFIG_NR_DRAM_BANKS1

/* FLASH No1的基地址 */

#define PHYS_FLASH_1 0x00000000 

/* FLASH 的基地址 */

#define CFG_FLASH_BASE PHYS_FLASH_1

 

移植方法

开始移植之前,首先要分析U-Boot已经支持的开发板,选择出硬件配置最接近的开发板。选择的原则是,首先选择MCU相同的开发板,如果没有,则选择MPU相同的开发板。

以mini2440开发板为例,该开发板采用s3c2440芯片。根据选择原则,首先选择MCU为s3c2440的开发板,但 UBoot 各版本均不支持采用s3c2440芯片的开发板。因此根据第二原则,选择MPU相同,即ARM核为arm920T的开发板,Uboot支持SMDK2410开发板,并且SMDK2410采用s3c2410芯片,s3c2410采用的正好是arm920T,因此选取SMDK2410开发板作为移植参考板。

移植U-Boot的基本步骤如下:

1. 在顶层Makefile中为开发板添加新的配置选项,使用已有的配置项目为例

smdk2410_config: unconfig

@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

参考上面2行,添加下面2行:

mini2440_config: unconfig

@./mkconfig $(@:_config=) arm arm920t mini2440 NULL s3c24x0

arm: CPU 架构

arm920t: CPU 类型,对应cpu/arm920t目录

mini2440: 开发板型号,对应board/mini2440目录

NULL:开发者

s3c24x0: 片上系统(SOC)

2. 在board目录中创建一个属于新开发板的目录,

并添加文件:

mkdir –p board/mini2440

cp –rf board/smdk2410/* board/mini2440

3. 为开发板添加新的配置文件

先复制参考开发板的配置文件,再修改。例如:

$cp include/configs/smdk2410.h include/configs/mini2440.h

4. 选择板级配置

$ make mini2440_config

5. 编译U-Boot

执行make CROSS_COMPILE=arm-linux- 命令,编译成功可以得到U-Boot映像。
  评论这张
 
阅读(892)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018