Linux内核学习(三):Bootloader的特种兵-Uboot(一)

简介: Linux内核学习(三):Bootloader的特种兵-Uboot(一)

Linux内核学习(三):Bootloader的特种兵-Uboot(一)

内容全部来自–>《嵌入式应用开发完全手册》

1、什么是U-Boot

U-Boot,全称为Universal Boot Loader,即通用Bootloader,是遵循GPL条款的开放源代码项目。

其前身是由德国DENX软件工程中心的Wolfgang Denk基于8xxROM的源码创建的 PPCBOOT 工程。后来整理代码结构使得非常容易增加其他类型的开发板、其他架构的CPU(原来只支持PowerPC);增加更多的功能,比如启动Linux、下载S-Record格式的文件、通过网络启动、通过PCMCIA/CompactFLash/ATA disk/SCSI等方式启动。增加ARM架构CPU 及其他更多CPU的支持后,改名为U-Boot。

它的名字“通用”有两层含义:可以引导多种操作系统、支持多种架构的CPU。

  • 支持如下操作系统:Linux、NetBSD、VxWorks、QNX、RTEMS、ARTOS、LynxOS等
  • 支持如下架构的CPU:PowerPC、MIPS、 x86、ARM、NIOS、xScale等。

U-Boot有如下特性。

  • 开放源码。
  • ·支持多种嵌入式操作系统内核,如Linux.NetBSD. VxWorks.QNX.RTEMS、ARTOS.LynxOs.
  • 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、xScale。·较高的可靠性和稳定性。
  • 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等。丰富的设备驱动源码,如串口、以太网、SDRAM、Flash、LCD、NVRAM、EEPROM、RTC、键盘等。
  • 较为丰富的开发调试文档与强大的网络技术支持。
  • 支持NFS挂戟、RAMDISK(压缩或非压缩)形式的根文件系统。·支持NFS挂载、从Flash中引导压缩或非压缩系统内核。
  • 可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤对Linux支持最为强劲。
  • 支持目标板环境变量多种存储方式,如Flash、NVRAM、EEPROM… CRC32校验,可校验Flash 中内核、RAMDISK镜像文件是否完好。
  • 上电自检功能: SDRAM、Flash 大小自动检测,SDRAM故障检测,CPU型号.·特殊功能:XIP内核引导。

可以从http://sourceforge.net/projects/U-Boot 获得U-Boot的最新版本,如果使用过程中碰到问题或是发现Bug,可以通过邮件列表网站 http://lists.sourcef orge.net/ lists/ listinfo/U-Boot-users/获得帮助。

2、U-Boot源码结构

从sourceforge网站下载U-Boot-1.1.6.tar.bz2后解压即得到全部源码,U-Boot 源码目录结构比较简单。

U-Boot-1.1.6根目录下共有26个子目录,可以分为4类。

  • (1) 平台相关的或开发板相关的。
  • (2)通用的函数。
  • ( 3)通用的设备驱动程序。
  • (4)U-Boot工具、示例程序、文档。

U-Boot 中各目录间也是有层次结构的,虽然这种分法不是绝对的,但是在移植过程中可以提供一些指导意义,如图所示。

比如common/cmd_nand.c文件提供了操作NAND Flash 的各种命令,这些命令通过调用drivers/nand/nand_base.c中的擦除、读写函数来实现。

这些函数针对NAND Flash 的共性作了一些封装,将平台/开发板相关的代码用宏或外部函数来代替。

而这些宏与外部函数,如果与平台相关,就要在下一层次的cpu/xxx(xxx 表示某型号的CPU)中实现;如果与开发板相关,就要在下一层次的 board/xxx目录(xxx表示某款开发板)中实现。

以增加烧写yaffs 文件系统映象的功能为例,即在 common目录下的cmd_nand.c中增加命令。比如nand write.yaffs,这个命令要调用drivers/nand/nand_util.c中的相应函数,针对yaffs文件系统的特点依次调用擦除、烧写函数。而这些函数依赖于drivers/nand/nand_base.c、cpu/arm920t/s3c24x0/nand_flash.c 文件中的相关函数。

目前U-Boot-1.1.6支持10种架构,根目录下有10个类似lib_i386的目录; 31个型号(类型)的CPU,cpu目录下有31个子目录;214种开发板,board目录下有214个子目录,很容易从中找到与自己的板子相似的配置,在上面稍作修改即可使用。

3、U-Boot 的配置、编译、连接过程

3.1 、U-Boot初体验

U-Boot-1.1.6中有几千个文件,要想了解对于某款开发板,使用哪些文件、哪个文件首先执行、可执行文件占用内存的情况,最好的方法就是阅读它的 Makefile。

根据顶层Readme文件的说明,可以知道如果要使用开发板board/<board_name>,就先执行“make board_name>_config”命令进行配置,然后执行“make all",就可以生成如下3个文件。

  • U-Boot.bin:二进制可执行文件,它就是可以直接烧入ROM、NOR Flash的文件。
  • U-Boot: ELF格式的可执行文件。
  • U-Boot.srec: Motorola S-Record格式的可执行文件。

对于S3C2410的开发板,执行“make smdk2410_config "、"make all”后生成的U-Boot.bin可以烧入NOR Flash中运行。启动后可以看到串口输出些信息后进入控制界面,等待用户的输入。

对于S3C2440的开发板,烧入上面生成的U-Boot.bin,串口无输出,需要修改代码。在修改代码之前,先看看上面两个命令“make smdk2410_config”、“make all”做了什么事情,以了解程序的流程,知道要修改哪些文件。

**另外,编译U-Boot成功后,还会在它的 tools子目录下生成一些工具,比如 mkimage等。**将它们复制到/usr/local/bin目录下,以后就可以直接使用它们了,比如编译内核时,会使用mkimage 来生成U-Boot格式的内核映象文件uImage。(内核镜像生成的过程中也有用到这个工具,认真看那个图)

3.2、U-Boot 的配置过程

假定在U-Boot-1.1.6的根目录下编译,则其中的MKCONFIG就是根目录下的mkconfig文件.$(@:_config)的结果就是将“smdk2410_config"中的”_config”去掉,结果为“ smdk2410"。所以“make smdk2410_config”实际上就是执行如下命令:

到这里我们来看看这个mkconfig

(1)确定开发板名称BOARD_NAME,相关代码如下:

(2)创建到平台/开发板相关的头文件的链接。

略过mkconfig 文件中的一些没有起作用的行,如下所示:

(3)创建顶层Makefile 包含的文件includelconfig.mk,如下所示:

对于“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令,上面几行代码创建的config.mk 文件内容如下:

( 4)创建开发板相关的头文件include/config.h,如下所示:

现在总结一下,配置命令“make smdk2410_config”,实际的作用就是执行“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令。假设执行“./mkconfig $1 $2 $3 $4 $5$6”命令,则将产生如下结果。

配置文件中有以下两类宏。

从下面的编译、连接过程可知,U-Boot中儿乎每个文件都被编译和连接,但是这些文件是否包含有效的代码,则由宏开关来设置。比如对于网卡驱动drivers/cs8900.c,它的格式为:

可以这样认为,“CONFIG_”除了设置一些参数外,主要用来设置U-Boot的功能、选择使用文件中的哪一部分;而“CFG_”用来设置更细节的参数。

(到这里我不知道你是什么样的感受,但是对于我来说,我其实第一次是有点开始懵懵,就是那种感觉学到了,懂点了,但是又把整个脉络整个不清楚的感觉,但是这是因为到这里的时候又把前面的东西搞忘了,所以多多重复,在看这个部分能联想起之前的部分,就会好很多。)

3. U-Boot的编译、连接过程

配置完后,执行“make all”即可编译,从Makefile中可以了解U-Boot使用了哪些文件、哪个文件首先执行、可执行文件占用内存的情况。

先确定用到哪些文件,下面所示为Makefile 中与ARM相关的部分。

第117、164行用于包含其他的config.mk文件,第117行所要包含文件的就是在上面的配置过程中制作出来的include/config.mk 文件,其中定义了ARCH、CPU、BOARD、SOC等4个变量的值为arm、arm920t、smdk2410、s3c24x0。

第164行包含顶层目录的config.mk 文件,它根据上面4个变量的值确定了编译器、编译选项等。其中对我们理解编译过程有帮助的是BOARDDIR、LDFLAGS 的值,如下所示:

继续看看makefile

对于整个分析这还是沧海一粟,大家拉着源码自己在VScode上看,然后边学习韦神的书,效果会更好点。

现在总结一些U-Boot的编译流程:

内容太干了,喝点水哦!!!

下一篇接着跟着韦神看看这个Uboot启动的源码是什么样。

目录
相关文章
|
10天前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
51 15
|
1月前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
1月前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
1月前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
1月前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
1月前
|
负载均衡 算法 Linux
深入探索Linux内核调度机制:公平与效率的平衡####
本文旨在剖析Linux操作系统内核中的进程调度机制,特别是其如何通过CFS(完全公平调度器)算法实现多任务环境下资源分配的公平性与系统响应速度之间的微妙平衡。不同于传统摘要的概览性质,本文摘要将直接聚焦于CFS的核心原理、设计目标及面临的挑战,为读者揭开Linux高效调度的秘密。 ####
40 3
|
1月前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
2月前
|
算法 Linux 调度
深入理解Linux内核调度器:从基础到优化####
本文旨在通过剖析Linux操作系统的心脏——内核调度器,为读者揭开其高效管理CPU资源的神秘面纱。不同于传统的摘要概述,本文将直接以一段精简代码片段作为引子,展示一个简化版的任务调度逻辑,随后逐步深入,详细探讨Linux内核调度器的工作原理、关键数据结构、调度算法演变以及性能调优策略,旨在为开发者与系统管理员提供一份实用的技术指南。 ####
89 4
|
2月前
|
缓存 并行计算 Linux
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
42 2
|
2月前
|
缓存 网络协议 Linux
深入探索Linux操作系统的内核优化策略####
本文旨在探讨Linux操作系统内核的优化方法,通过分析当前主流的几种内核优化技术,结合具体案例,阐述如何有效提升系统性能与稳定性。文章首先概述了Linux内核的基本结构,随后详细解析了内核优化的必要性及常用手段,包括编译优化、内核参数调整、内存管理优化等,最后通过实例展示了这些优化技巧在实际场景中的应用效果,为读者提供了一套实用的Linux内核优化指南。 ####
55 1