当前位置: 首页 > news >正文

系统移植相关概念总结

文章目录

    • (一)u-boot
      • 1. 启动流程
      • 2. u-boot如何传参
      • 3. 如果u-boot引导内核启动失败,分析原因
    • (二)内核移植
      • 1. 内核移植的步骤
      • 2. 内核启动流程
      • 3. 内核启动运行的第一个进程是什么,都做了什么
      • 4. 如果内核启动失败,分析下原因
    • (三)宏内核和微内核
    • (四)Linux系统启动级别
    • (五)设备树
      • 1、什么是设备树
      • 2、如何解析设备树

(一)u-boot

“the Universal Boot Loader”,通用引导加载程序
在系统启动时,初始化处理器、内存、存储设备、网络接口等硬件资源
加载操作系统内核并传递给处理器
通过环境变量存储启动参数和配置信息
提供命令行界面,允许用户执行内存读写、设备检测、文件传输等操作
U-Boot还可以提供安全启动功能,确保只有经过验证的操作系统内核和应用程序才能被加载和执行

1. 启动流程

U-Boot的启动流程可以分为两个阶段。
① 第一阶段(汇编语言实现)

CPU自身初始化
初始化CPU的相关寄存器,设置CPU的工作模式(如SVC模式)。
关闭内存管理单元(MMU)和高速缓存(Cache)。
初始化时钟系统、看门狗定时器、中断控制器等。

重定位
将U-Boot自身的代码从Flash中复制到RAM中,以便后续执行。

设置堆栈
分配堆栈空间,并设置堆栈指针。

清零BSS段
对未初始化的全局变量(BSS段)进行清零操作。

跳转到第二阶段入口
执行跳转指令,跳转到第二阶段代码的入口函数(如start_armboot())。

② 第二阶段(C语言实现)

为U-Boot内部私有数据分配存储空间
分配并清零U-Boot内部使用的数据结构。

依次调用初始化函数
通过一个函数指针数组(如init_sequence),依次调用各个初始化函数,对系统进行进一步的初始化。

Flash、LCD等设备的初始化
如果系统支持NOR Flash,调用相关函数进行初始化,并显示检测到的器件信息。
如果系统支持LCD或VFD,计算帧缓存(Framebuffer)大小,并在BSS数据段之后为其分配空间,初始化起始地址。

存储分配系统的初始化
初始化存储分配系统(类似于C语言中的堆),为后续的动态内存分配做准备。

环境变量的重定位
将环境变量从Flash中复制到RAM中,以便后续快速访问。

网络、IP地址等初始化
如果系统支持网络功能,进行网络接口的初始化。
从环境变量中读取IP地址和MAC地址,并进行相应的初始化。

控制台初始化
初始化控制台,以便输出调试信息和用户交互。

打开中断
配置中断控制器,打开中断功能。

进入主循环
最后,U-Boot进入一个主循环,等待用户的输入命令。用户可以通过命令行界面输入命令来加载内核、设置参数或执行其他操作。

在开机后,BIOS会进行硬件自检,并从硬盘的MBR中读取引导程序。然后,MBR会将控制权交给U-Boot,由U-Boot完成后续的硬件初始化和操作系统引导工作。

2. u-boot如何传参

  1. 可以通过环境变量来传递参数给内核。U-Boot提供了一个环境变量表,用户可以在其中设置一些参数(如bootargs),并在启动内核时将这些参数传递给内核。
  2. 参数链表方式中,U-Boot将每一个要传递给内核的参数封装成一个结构体(称为tag),并将这些结构体连续存储在内存的一片区域内。然后,U-Boot将这片区域的起始地址传递给内核。内核通过这个地址来解析U-Boot传递的参数。

3. 如果u-boot引导内核启动失败,分析原因

1、U-Boot配置问题
① 检查启动参数是否配置正确:
命令行参数中的console设置、bootargs、内存大小、根文件系统位置等关键参数。
② 环境变量设置:
bootcmd、bootfile等环境变量设置错误,导致U-Boot无法正确加载内核镜像。
③ 环境变量中的地址与实际内存布局不匹配。
④ U-Boot版本与内核版本不兼容
2、内核镜像问题
① 内核镜像格式不正确:
U-Boot可能不支持当前的内核镜像格式(如uImage、zImage等)。
② 内核镜像可能已损坏或未正确生成。
③ 内核镜像加载地址错误
④ 内核解压失败
3、硬件问题
内存问题:
内存初始化失败或内存存在故障。
内存大小与U-Boot或内核配置不匹配。
存储设备问题:
存储设备(如NAND、NOR Flash、SD卡等)存在故障或未正确连接。
存储设备上的内核镜像文件损坏或未正确写入。
处理器问题:
处理器配置不正确或存在故障。
处理器时钟频率与U-Boot或内核配置不匹配。

(二)内核移植

对Linux内核源码进行配置和编译,使linux内核源码支持自己的开发板并生成对应的镜像文件。

1. 内核移植的步骤

  1. 硬件平台选择
    根据项目需求选择合适的处理器类型,如ARM、MIPS、x86等。
    考虑处理器的性能,确保满足系统的运行效率需求。
    根据项目需求选择合适的外设资源,如内存大小、存储空间、网络接口等。
    选择与处理器类型相匹配的开发工具,如编译器、调试器等。
  2. 内核版本选择:
    选择一个稳定版本的内核,避免因为内核bug导致系统崩溃。
    确保所选内核版本支持当前硬件平台。
    根据项目需求选择具有相应功能的内核版本,如网络协议栈、文件系统等。
  3. 内核配置:
    安装相应的开发工具和依赖库。
    解压内核源码包,并进入内核源码目录。
    执行配置命令(如make menuconfig),进入内核配置界面,根据项目需求选择相应的内核选项。
    保存配置文件。
  4. 编译内核:
    执行编译命令(如make),开始编译内核。
    编译完成后,会生成内核镜像文件(如zImage)。
  5. 内核部署:
    将编译好的内核镜像文件部署到目标平台上

2. 内核启动流程

硬件设备初始化:
U-Boot在启动过程中会进行硬件设备的初始化,包括CPU、内存、外设等。

加载内核到内存:
U-Boot会将内核镜像文件从存储设备(如Flash)加载到内存中。

校验内核格式:
U-Boot会校验内核镜像文件的格式和CRC等校验码,确保内核文件的完整性和正确性。

准备启动参数:
U-Boot会根据配置的环境变量和启动参数,为内核准备启动所需的参数。

跳转执行内核:
U-Boot会将控制权交给内核,内核开始执行。
在执行过程中,内核会进行一系列的初始化操作,包括内存管理、设备驱动初始化、文件系统挂载等。

进入用户态:
当内核完成初始化并挂载了根文件系统后,会加载init进程(通常是/sbin/init或/bin/sh),进入用户态,此时用户可以开始使用系统。

3. 内核启动运行的第一个进程是什么,都做了什么

内核启动后运行的第一个进程通常是init进程,它是内核直接创建的第一个用户空间进程,其进程编号(PID)始终为1。

1、 进程管理
init进程负责启动、停止和管理系统中的其他进程。它会根据系统的配置和运行状态,启动必要的服务或进程,并在系统关闭时停止这些服务或进程。
2、系统初始化
init进程在启动时会读取系统的配置文件(如/etc/inittab或systemd的配置文件),以确定系统的运行级别和初始化脚本的执行。这些初始化脚本会负责设置系统的环境变量、挂载文件系统、启动必要的服务等。
3、运行级别管理
init进程还负责管理系统的运行级别,不同的运行级别会启动不同的服务和进程,以满足系统的不同需求。

读取配置文件:init进程首先会读取系统的配置文件,这些文件通常位于/etc目录下,如/etc/inittab(对于传统的SysV init系统)或systemd的配置文件(对于现代的systemd系统)。
确定运行级别:根据配置文件的设置,init进程会确定系统的运行级别。运行级别是一个数字,用于表示系统的运行状态。不同的运行级别会启动不同的服务和进程。
执行初始化脚本:init进程会根据运行级别的设置,执行相应的初始化脚本。这些脚本通常位于/etc/rc.d/或/etc/init.d/目录下,它们会负责设置系统的环境变量、挂载文件系统、启动网络服务、启动系统日志服务等。
启动必要的服务:除了初始化脚本外,init进程还会根据配置文件的设置,启动一些必要的服务或进程,如守护进程、登录进程等。
等待用户登录:最后,init进程会启动一个登录进程(通常是getty或mingetty),等待用户输入用户名和密码进行登录。

4. 如果内核启动失败,分析下原因

1、检查内存、存储设备、处理器和主板等硬件是否连接正确、无故障。
2、检查启动参数和配置文件,确保启动参数(如bootargs)和配置文件(如/etc/fstab)设置正确。
3、检查文件系统,使用文件系统检查工具(如fsck)检查并修复文件系统错误。
4、尝试不同的内核版本,检查是否是内核本身的问题。
5、确保boot loader版本与硬件和操作系统兼容
6、检查内核启动过程中的错误和异常。

(三)宏内核和微内核

宏内核,将操作系统的所有核心功能集中到一个内核空间。
将系统的所有基本服务(包括设备驱动程序、文件系统、内存管理、进程调度、系统调用等)都作为内核的一部分。
特点是操作系统的大部分功能都在内核态中运行,这样可以减少上下文切换的开销,但也使内核的复杂性增加。
宏内核的优点:
高性能,不需要频繁的用户态和内核态之间的上下文切换
硬件控制较高效,设备驱动和其他核心模块在内核中直接控制硬件,减少了延迟。
宏内核的缺点:不易维护和扩展、稳定性和安全性较低

微内核,将操作系统的核心功能进行分解,只保留一些最基本的服务,例如进程管理和内存管理等。而其他的服务则以独立的进程形式运行,这些进程可以在需要时动态加载和卸载。这种设计使得操作系统内核更加灵活,易于维护和扩展。
但是,由于在进程间通信时需要进行系统调用,因此微内核的性能通常较差。

(四)Linux系统启动级别

Linux系统通常有七个启动级别(0-6):

0级(系统停机状态):
系统默认运行级别不能设为0,否则无法正常启动。
一开机就自动关机,机器处于完全关闭状态。

1级(单用户模式):
类似于Windows的安全模式,具有root权限。
用于系统维护,禁止远程登录,没有网络功能。

2级(多用户模式,无NFS):
支持多用户登录,但没有NFS(网络文件系统)和网络支持。

3级(完整的多用户文本模式):
具有NFS和网络支持,登录后进入控制台命令行模式。
是标准的Linux运行级别之一,适用于服务器和需要命令行界面的场景。

4级(系统未使用,保留):
通常不使用此级别,但在一些特殊情况下可能会用到。
例如,在笔记本电脑电池即将用尽时,可以切换到这个模式来做一些设置。

5级(图形化模式):
登录后进入图形GUI模式,如GNOME、KDE等图形化界面。
适用于桌面环境和需要图形界面的场景。

6级(系统重启模式):
系统默认运行级别不能设为6,否则将无限重启,无法正常启动。
运行此级别时,系统会正常关闭并重启。

(五)设备树

1、什么是设备树

用于描述硬件设备的配置信息,使得操作系统(如Linux)能够正确地识别、配置和管理这些硬件设备

2、如何解析设备树

定义结构体:驱动要解析设备树,必须定义struct platform_driver类型结构体变量,并通过函数platform_driver_register()注册。同时,设备树节点会封装在struct device_node结构体变量中,各个属性信息会封装在struct property结构体变量中。
匹配设备树节点:内核在解析设备树的过程中,会根据设备节点的“compatible”属性来匹配相应的驱动程序。一旦找到匹配的驱动程序,内核就会将其加载并用于设备的初始化和管理。
解析设备树属性:在驱动程序的probe函数中,可以使用设备树提供的API(如of_property_read_u32、of_property_read_string等)来解析设备树节点的属性,并根据这些属性信息来配置和初始化硬件设备。


http://www.mrgr.cn/news/57992.html

相关文章:

  • docker run和docker start的区别
  • 掌握5个技巧,让你的答题测试小程序广告,收入提高3倍!
  • Angular 框架入门教程:从安装到路由、服务与状态管理详解
  • 【CSS in Depth 2 精译_054】8.2 CSS 层叠图层(cascade layer)的推荐组织方案
  • 软件开发术语(E开头)---持续更新
  • 桑黄辅助放、化疗比单独使用更有效
  • 力扣周赛第420场 中等 3325.字符至少出现k次的子字符串 I
  • C语言程序设计:现代设计方法习题笔记《chapter4》
  • java的maven打包插件来了,package一键打包exe、dmg、rpm等
  • JAVA应用测试,线上故障排查分析全套路!
  • C++,STL 045(24.10.24)
  • 【Linux】进程状态及其转换
  • Github_以太网开源项目verilog-ethernet代码阅读与移植(八)——移植工程分享
  • 头歌——人工智能(遗传算法)
  • 获取图像的风格矩阵
  • 现场总是发生急停,很可能是PLC和设置间网络中断
  • make_blobs函数
  • Django+Vue全栈开发旅游网项目首页
  • python实战(二)——房屋价格回归建模
  • 九、Linux实战案例:项目部署全流程深度解析
  • 【C++笔记】类和对象(下)
  • Java中的集合-Map和set(java数据结构)
  • 【SpringCloud】基础问题
  • 力扣每日一题3185. 构成整天的下标对数目 II
  • linux笔记(NFS服务)
  • WPF的UpdateSourceTrigger属性