Linux驱动--uboot启动流程

一.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启动流程

ARM寄存器及功能介绍

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项目开发仅仅起到引导加载内核的作用,项目的功能的多样性还得靠系统编程及网络应用。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Uboot启动Linux过程详解: 1. Uboot加载内核镜像:Uboot首先会从存储设备(如SD卡、NAND Flash等)中加载内核镜像到内存中。 2. 设置内核启动参数:Uboot会设置内核启动参数,包括内核镜像在内存中的位置、根文件系统的位置、启动参数等。 3. 启动内核:Uboot会将控制权交给内核,让内核开始执行。内核会进行一系列初始化操作,包括初始化CPU、内存、设备驱动等。 4. 挂载根文件系统:内核会挂载根文件系统,使得用户可以访问文件系统中的文件和目录。 5. 启动用户空间:内核会启动用户空间,即启动init进程。init进程会读取配置文件,启动各种系统服务和应用程序。 6. 用户空间运行:一旦用户空间启动成功,系统就进入了正常的运行状态,用户可以使用各种应用程序和系统服务。 总之,Uboot启动Linux的过程是一个复杂的过程,需要多个组件协同工作,才能让系统正常启动并运行。 ### 回答2: Uboot嵌入式系统中常用的一个开源启动加载程序,其主要功能是在嵌入式操作系统中启动Linux系统,并初始化系统硬件资源。Uboot在整个Linux系统启动过程中起到很关键的作用,下面就来详细介绍一下Uboot启动Linux过程. 一、Uboot的加载 第一个引导程序(Bootloader)需要存放在系统的闪存中,是Linux系统启动的重要组成部分。当开机后CPU默认开始执行闪存芯片0的地址,此时Uboot就被加载到RAM中,并执行。由于Uboot同样位于一块桥接器和一个NOR Flash的四接口ARM微控制器总线上,因此Uboot在存储器刚刚发挥了重要作用。 在Uboot的启动过程中,系统会根据用户的选择进行环境的设置,比如启动选项、串口设置等。同时,Uboot还会初始化内存,并将内核镜像加载到内存中,准备启动内核。 二、内核的启动 Linux内核启动主要分为五个过程,分别是: 1.内核加载 当Uboot初始化完成后,系统进入内核加载阶段。Uboot会将存放在NOR Flash中的内核镜像加载到系统主内存中。在加载内核时,会有一个fdt文件,该文件是系统在启动时加载设备树的重要文件,在设备树的启动阶段,大部分设备驱动程序都是通过fdt中的节点进行解析。 2.内核装载初始化 在内核镜像成功加载到内存中后,Linux内核开始进入装载初始化,该阶段主要进行一些内部的初始化工作,比如初始化调度程序、内存管理、文件系统等;此外还会启动ELF文件解析程序,解析各个驱动模块,以便后续的设备树解析和驱动程序的加载。 3.设备树解析 在内核镜像加载到内存中之后,Linux会对设备树进行解析。设备树是在启动时由Uboot加载、传递给内核的一种数据结构,主要用于描述系统的硬件资源分布情况,是操作系统启动过程中很关键的一环,因为设备树可以为操作系统提供有关系统硬件的信息,便于操作系统启动后初始化对应的硬件资源。 4.初始化进程 在设备树解析完成之后,Linux会进入初始化进程的阶段。在这个过程中,系统会完成一系列的启动脚本,完成基本系统的初始化,并启动基本服务。 5.用户空间启动 当初始化进程执行完毕后,系统进入用户空间启动阶段。此时可以执行用户的应用程序,系统也正式进入了可用状态了。 三、总结 以上就是Uboot启动Linux过程的详解了。在整个启动过程中,Uboot不仅完成了硬件资源初始化,还实现了内核和用户空间的启动,是整个系统的重要组成部分。对于嵌入式设备的开发者来说,深入了解Uboot的启动过程,对于准确定位问题和有序开发代码具有很大的帮助。 ### 回答3: uboot嵌入式系统中常用的一个启动引导程序,其作用是加载Linux内核文件到系统中,并启动该内核从而让系统正常运行。本文就uboot启动linux的过程进行详细的分析。 uboot启动linux的过程: 1. CPU从复位向量开始执行: 当CPU启动时,会首先寻找复位向量所在的地址,并执行该地址中存储的指令。在嵌入式系统中,这个复位向量通常被配置为uboot程序的起始地址。 2. 加载uboot程序: uboot启动后会先加载自身的程序代码。uboot的程序包括bootloader和一些工具函数,它们可以执行一些用户定制的任务,比如读写参数、显示系统信息等操作,然后才会加载Linux内核。 3. 加载Linux内核: 在uboot加载内核时,它首先要根据指定的地址和大小,从存储介质中读取内核文件,并将其存储到内存中。在读取内核文件期间,uboot会进行一些配置操作,比如初始化内存、配置内存映射等操作。 4. 启动Linux内核Linux内核启动时需要设置一些参数,这些参数通常由uboot传递给内核。例如,uboot会告诉内核内存的位置和大小、设备树等信息。接着,内核会根据这些参数进一步初始化系统,比如建立内存映射表、配置硬件设备等操作。这些操作完成后,Linux内核会开始执行用户空间程序,使得系统正常运行。 总结: 通过上述分析可知,uboot启动Linux的过程涉及到多个环节,其中包括uboot程序的加载、Linux内核的加载以及启动Linux内核时传递参数等操作。在实际系统中,这些过程需要针对具体的硬件平台进行适当的定制,才能保证系统正常启动和运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值