国嵌视频学习第九天——UBOOT基础

来源:互联网 发布:mac点击下载后没反应 编辑:程序博客网 时间:2024/05/16 12:59

参看BLOG:http://blog.csdn.net/linuxdianc/article/details/5026426#

BootLoader

软件层次

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

1.      引导加载程序

包括固化在固件(fireware)中的boot程序(可选)(比如CMOS中的BIOS),和BootLoader(比如grub)两大部分

2.Linux内核

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

3.文件系统

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

 

PC机的引导加载程序由BIOS(其本质是一段固件程序)和GRUB和 LILO一起组成。BIOS在完成硬件检测和资源分配后,将硬盘中的引导程序读到系统内存中然后将控制权交给引导程序。引导程序的主要任务是将内核从硬盘上读到内存中,然后跳转到内核的入口点去运行,即启动操作系统

 

定义

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

 

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

 

安装

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

 

流程

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

 

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

----硬件设备初始化

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

----拷贝BootLoader的stage2到RAM空间中

----设置好堆栈(目的是为stage2中的C程序的运行搭建环境)

----跳转到stage2的C入口点

该阶段的程序主要是由汇编代码写成

 

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

----初始化本阶段要使用的硬件设备(板载硬件,比如串口、网口)

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

----调用内核

 

该阶段的程序主要是由C代码写成

 

工作模式

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

 

启动模式:处理器一旦上电后,不需要干预便能自动地启动bootloader,并通过bootloader启动内核

下载模式:CPU上电后,目标机上的BootLoader将通过串口或网络等通信手段从主机(Host)下载文件,然后控制启动流程(常用于开发时)。

 

所以,用户常见的是启动模式

 

 

交叉工具链

工具链:gcc、gdb、ld等工具的集合便是工具链(sets)

交叉:软件产生于宿主机,运行于目标机的开发模式

 

安装

进行嵌入式开发前,首先需安装交叉工具链,步骤如下:
1.解压工具链到某一目录下,例:

tar xvzf arm-linux-gcc-4.5.1-v6-vfp.tgz –C/ (-C表示解压到后面指定的目录。如果没有-C则是默认解压到当前目录。解压后可以进入/4.5.1/bin/,可见很多工具)

2.修改/etc/profile,添加

export PATH=$PATH: /4.5.1/bin(如果不修改/etc/profile,那么每次运行工具如arm-linux-gcc则必须使用全路径:/4.5.1/bin/arm-linux-gcc)

3.让第二步对环境变量的修改生效

运行source /etc/profile

 

上述三步骤之后,可以在任何目录下运行arm-linux-gcc

http://blog.csdn.net/yinjiabin/article/details/7369071

http://blog.csdn.net/dreambegin/article/details/6794673

 

工具使用

----编译器:arm-linux-gcc

arm-linux-gcc hello.c –o hello

和gcc的用法完全一样,不过gcc编译的运行在X86上,而arm-linux-gcc编译的运行在arm上

----反汇编工具:arm-linux-objdump

arm-linux-objdum –D –S hello

将二进制文件编程汇编代码

arm-linux-objdum–D –S hello > log 导出到log文件中

 

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

arm-linux-readelf –a hello

查看的信息中,常用的是:Data项的大小端模式

                                          Machine项

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

 

UBoot

用于多种嵌入式CPU(MIPS、X86、ARM、XScale等)的bootloader程序,UBoot不仅支持嵌入式Linux系统的引导,还支持VxWorks,QNX等多种嵌入式操作系统。

 

U-BOOT启动流程

开发板上电后,执行U-BOOT的第一条指令,然后顺序执行U-BOOT启动函数。看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序,第一个哟链接的是cpu/arm920t/start.o,那么U-BOOT的入口指令一定位于这个程序中

 

 

下载

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

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

 

目录结构

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

|--board

|--common

|--cpu

|--disk

|--doc

|--drivers

|--dtt

|--examples

|--fs

|--include

 

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

----common:实现Uboot支持的命令

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

----disk:对磁盘的支持

----doc:文档目录,uboot有非常完善的文档,推荐阅读

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

.....

----tools:uboot的工具,如:mkimage、crc等等

 

编译

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

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

2.编译生成uboot.bin文件

 

uboot.bin的生成也分为两步,以mini2440开发板为例来说明,如下(申明:该演示所使用的u-boot为经过移植后的u-boot,未经移植的u-boot并不支持该6410开发板,移植过程将在嵌入式linux系统移植专题班讲解):

 

可以在/4.5.1/根目录下查看Makefile,来知道uboot支持哪些开发板(比如在这里可以查看smdk6410):

 

1.       选择要使用的board:

       $make mini2440_config

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

       #makeCROSS_COMPILE=arm-linux-

 

编译好后有个uboot.bin文件。之后将该文件烧写到开发板中去

 

UBoot命令

常用命令

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

不同的board支持的命令不一定一样(可配置)

 

环境变量相关

print(Printenv) 查看环境变量

——用法:

      printenv:

-print values of all environment variables

      printenv name ...

-print value of environment variable `name`

 

setenv:添加、修改、删除环境变量(存在于内存中,只在本次单板开机中有效)

——用法:

      setenv name value...

-set environment variable `name` to `value...`

      setenv name

-delete environment varible `name`

 

saveenv保存环境变量(存在于flash中)。将当前定义的所有变量及其值存入flash中

 

文件下载

tftp:通过网络下载文件(开发板必须有ip地址ipaddr和serverip)可以通过ping serverip看网络是否连通

 

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

如:

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

Uboot>setenv ipaddr 192.168.1.1

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

例:

Uboot>tftp c0800000 uImage

把serber(ip=环境变量中设置的serverip)中服务目录下的uImage通过TFTP读入到0xc0800000处

 

loadb:通过串口下载(速度慢,少用)

 

内存操作

md显示内存区的内容。

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

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

如:

md.w 100000

00100000:(显示的内容)

00100010:(显示的内容)

 

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

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

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

如:mm 100000

00100000:(显示的内容)

00100004:(显示的内容)

 

FLASH操作

flinfo:查看flash扇区信息

用法: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(默认是.l,即32位的拷贝)

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

例:

cp.b 31000000 50000 d0000

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

cp.b 32000000 120000 c0000

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

 

注意:必须先用erase命令擦除flash,才能用cp命令执行成功

 

执行程序

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

bootm要求所有可执行的二进制代码前部有固定格式的文件头,那么如何做这个文件头呢?——uboot下tools中有个mkimage工具可以

 

注意:bootm可以没有addr地址,这时它自动执行个默认的地址

   

开发板信息

bdinfo——显示开发板信息

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

 

自动启动

1.设置自动启动——通过设置环境变量:

比如:Mini2440=>setenv bootcmd tftp 31000000 uImage \; bootm 31000000

           Mini2440=>saveenv

           ——执行了两个操作并保存

 

 

原创粉丝点击