admin管理员组

文章数量:1516870

一.u-boot目录介绍

主要在这三个文件夹做修改。

目 录

特 性

解 释 说 明

board

平台相关

存放开发板相关的目录文件,如 RPXlite(mpc8xx)、 smdk2410(arm920t)、sc520_cdp(x86) 等目录

arch

构架相关

存放了各种芯片构架相关的文件

api

通用

存放 U-Boot 提供的接口函数

common

通用

通用的代码,涵盖各个方面,以命令行处理为主

disk

通用

磁盘分区相关代码

lib

通用

存放 u-boot 源码中使用到的库函数

nand_spi

通用

NAND 存储器启动相关代码

include

平台相关

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

common

通用

通用的多功能函数实现

net

通用

存放网络相关程序

fs

通用

存放文件系统相关程序

post

通用

存放上电自检程序

drivers

通用

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

disk

通用

硬盘接口程序

examples

应用例程

一些独立运行的应用程序的例子,如 helloworld

tools

工具

存放制作 S-Record 或者 U-Boot 格式的镜像等工具,如 mkimage

doc

文档

开发使用文档

boards.cfg :存放着开发板的一些信息

config.mk 是一个 Makefile 文件,将来在某个 Makefile 中会去调用它

COPYING:版权申声明

CREDITS:记录对u-boot有贡献的人

MAINTAINERS:记录当前在参与维护u-boot源码的社区工作者

MAKEALL :一个脚本文件,帮助编译u-boot

Makefile :负责u-boot的编译

mkconfig :负责u-boot的配置,一个shell脚本

README:u-boot使用说明书

rules.mk:u-boot中Makefile使用的规则

二.u-boot启动流程分析

1.u-boot启动流程

1)汇编阶段:

设置CPU为SVC模式

关闭中断、MMU、看门狗、Cache

部分硬件初始化(时钟、串口、DRAM)

uboot自搬运到DDR(14K引导)

设置好栈区(准备运行C语言)

2)C语言阶段:

大部分硬件初始化

搬运Linux内核或者进入交互模式

运行LInux内核

2.uboot代码分析

u-boot 程序入口在 arch/arm/cpu/armv7/start.S 文件下 。并且读取的第一条指令在_start标号所指向的程序。

1)异常向量表定义

arch/arm/cpu/armv7/start.S

异常:当硬件发生故障的时候CPU会强制PC指针指向对应的异常入口执行代码(异常入口一般为异常处理函数)

ARM处理器有七种异常:分别是复位,未定义指令异常,软件中断异常,预取指异常,数据中止,普通中断异常,快速中断异常

异常向量表只与CPU架构有关

2)设置SVC模式并禁止中断

:arch/arm/cpu/armv7/start.S

CPSR是ARM内核的程序状态寄存器,操作该寄存器可以设置ARM内核的状态。

注:此代码属于架构级别,只要SOC芯片是ARM内核,代码不需要改变

3)关闭MMU和Cache

arch/arm/cpu/armv7/start.S

所有 CPU 初始化工作都在 cpu_init_crit 这里 完成,该函数在第282行:

注: 以上代码用于让L1的I/D cache失效(I-cache用来存指令 D-cache用来存数据)以及关闭MMU和Cache。这部分代码一般也不需要修改的,属于架构级的。只要使用ARM内核都不用修改。

4)部分硬件初始化

arch/arm/cpu/armv7/start.S

lowlevel_init函数用户基本硬件初始化,该函数在board/samsung/tiny4412/lowlevel_init.S文件中。

通过分析lowlevel_init代码,我们可以得知在lowlevel_init代码中完成了以下功能:

1.设置栈指针

2.设置电源管理

3.LED等初始化并且点亮LED灯

4.判断OM引脚状态,得到启动方式

5.时钟初始化:system_clock_init

6.DDR初始化:mem_ctrl_asm_init

7.串口初始化:uart_asm_init

8.u-boot自搬移:load_uboot

注:以上大部分代码属于芯片级的,如果所使用的芯片相同,则也不需要修改!

5)uboot自搬运

load_uboot代码在在board/samsung/tiny4412/lowlevel_init.S文件中

CPU会根据前面读取的启动方式,到指定的启动设备复制u-boot到DDR内存中

6)设置好栈

当复制完成后,便执行

在after_copy代码中,有如下代码:

上面代码表示跳转到board_init_f去执行。而board_init_f是有C语言来写的。至此u-boot的汇编阶段便结束了。

7)大部分硬件初始化

在board_init_f函数(arch/arm/lib/board.c),有如下代码:

这是一个for循环,通过函数指针init_fnc_ptr去循环调用init_sequence指针数组中的函数。

init_sequence[] 数组中存放的是用户需要进行初始化各的种设备函数,即实现了大部分硬件初始化。 如果函数执行失败,则u-boot会死循环。这部分代码就需要根据具体的硬件开发平台来进行相应的增删改。

8)引导内核

在board_init_f中最后执行的是relocate_code函数。relocate_code函数最终又会调用board_init_r函数,board_init_r函数在arch/arm/lib/board.c文件中。,这部分代码不仅实现了引导加载内核,而且还实现了命令交互的功能。

注:这部分代码都是通用的。


reset:
设置SVC模式,
屏蔽中断
cpu_init_crit:
Invalidate L1 I/D
disable MMU stuff and caches
lowlevel_init:基本硬件初始化
设置sp
read_om:
led (GPM4_0~3) on     LED1_ON
system_clock_init
mem_ctrl_asm_init
uart_asm_init
load_uboot:
mmcsd_boot
movi_uboot_copy:
after_copy:
LED1_ON  LED2_ON
board_init_f:(arch/arm/lib/board.c)
/* 大部分硬件初始化 */
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang();
}
}
relocate_code(start.S)
board_init_r:(arch/arm/lib/board.c)
//要不搬运内核,要不交互模式
main_loop();

三.注意

因为针对SOC芯片的电路设计比较复杂,所以为了节省项目开发周期,很多公司做嵌入式Linux项目直接采购现成的开发板进行项目开发。那么在这个时候开发板厂商一般会有移植好的u-boot供我们使用。我们直接拿来用即可,不要进行u-boot移植。

当然,也有很多公司做项目时会自己设计电路板,一般情况下,都会参考该芯片厂商发布的demo板进行硬件设计。核心板设计不会做太多的改动,比如demo板中使用哪种型号的内存芯片,哪种型号的FLASH芯片,那么公司设计的开发板也会采取这种方案。但是底板就需要根据项目进行特定的电路设计。这个时候,芯片厂商同样会提供demo板的u-boot,我们需要在这个u-boot的基础上进行修改,大部分是对硬件初始化进行修改,比如网卡驱动,串口驱动等。

最后,同学们面临最多的情况是,当你进入某家公司时,该公司的项目板对应的u-boot已经被移植好了,所以同学们直接u-boot即可。

总结:大部分工程师进行u-boot移植工作的概率很低,所以,对u-boot移植现在只需要掌握u-boot启动流程以及基本思想即可。其次,切忌不要在u-boot上浪费太多时间,因此即使u-boot有多完善,在整个Linux项目开发仅仅起到引导加载内核的作用,项目的功能的多样性还得靠系统编程及网络应用。

本文标签: 通用初始化编程