文章目录
简单了解启动流程1. 上电与复位2. 第一阶段引导加载程序 (BOOT0/SPL)3. 第二阶段引导加载程序 (U-Boot)U-Boot小细节1. 内核镜像加载地址2. 内核启动地址3. 入口点地址4.总结以及理解5.具体场景示例未压缩内核压缩内核图解
4. Linux 内核启动5. 用户空间初始化6. 系统就绪
简单了解设备树简单介绍个人理解
简单修改设备树查看状态以及如何修改重新编译设备树检验修改是否生效
简单了解启动流程
大致流程:
1. 上电与复位 2. 第一阶段引导加载程序 (BOOT0/SPL) 3. 第二阶段引导加载程序 (U-Boot) 4. Linux 内核启动 5. 用户空间初始化 6. 系统就绪
1. 上电与复位
当电源接通时,CPU 处于复位状态,执行位于 ROM 或者专用启动区域中的初始引导代码。
2. 第一阶段引导加载程序 (BOOT0/SPL)
描述: BOOT0或者SPL通常存储在内部 Flash 或外部 SPI Flash 中的小型引导加载程序。主要用于:
加载第二阶段引导加载程序(U-Boot)到 RAM 并跳转执行。初始化必要的外设(如 UART 用于调试输出)。配置 SDRAM 控制器并初始化内存。
3. 第二阶段引导加载程序 (U-Boot)
U-Boot
描述:功能更强大的引导加载程序,负责进一步初始化硬件并准备操作系统内核的加载。主要用于:
初始化硬件:配置所有关键硬件组件,如 I2C、SPI、USB、网络接口等。
设置时钟频率:调整 CPU 和其他总线的速度以达到最佳性能。
初始化显示子系统:如果支持图形界面,则初始化显示器和相关驱动。
初始化 DRAM:确保外部内存可以正常工作,并可能进行简单的测试。
加载环境变量:从非易失性存储器中读取 U-Boot 的环境变量,这些变量控制着后续的操作,例如要加载的内核镜像位置。
加载内核和 DTB:从存储介质(如 SD 卡、eMMC、NAND Flash)中读取 Linux 内核和 DTB 文件到内存。
传递控制权给内核:将控制权交给 Linux 内核,并提供必要的准备启动参数(如启动地址,)、(如 root= 指定根文件系统的路径)、内核镜像在内存中的地址、Device Tree Blob (DTB) 的地址等。
简单来说,U-Boot 负责从 eMMC 等存储介质搬各种东西(如内核、DTB 等)到 DDR(动态随机存取存储器) 中,(也就是从存储内存搬到运行内存中),并且告诉内核这些东西搬过去放到DDR的哪个地址。此外,U-Boot 还承担了初始化关键的硬件和准备启动参数(从哪个地址开始启动内核镜像,从哪地址解析DTB,以及指定的跟文件系统的路径)的重要任务,以确保内核能够在正确环境中启动,交代完这些,就将控制权交给了内核。
一句话概括:就是初始化关键硬件,将eMMC内存里的部分东西搬到DDR里面,并交代搬过去的东西所放的地址,以及后面需要的各种启动参数(),解析DTB地址参数,等各种参数,交代完毕了,再将控制权给内核。
小细节
这里注意,理解内核镜像加载地址、内核启动地址、入口点地址之间的区别:
最好了解一下(有点多且绕):
1. 内核镜像加载地址
定义:这是 U-Boot 将内核镜像从存储介质(如 eMMC、SD 卡等)读取并加载到 DDR 中的地址。作用:U-Boot 负责将内核镜像复制到这个地址,以便后续执行。
2. 内核启动地址
定义:这是内核代码实际开始执行的地址。作用:当 U-Boot 完成所有准备工作后,它会跳转到这个地址,让内核开始执行。对于未压缩内核,这通常是加载地址;对于压缩内核,这是解压缩程序这条程序起始地址。
3. 入口点地址
定义:这是内核代码的第一个指令所在的地址,即内核真正开始执行的地方,并不是包含解压指令。作用:对于未压缩的内核,入口点地址就是加载地址;而对于压缩的内核,入口点可能是解压缩程序的起始地址,解压缩完成后,真正的内核代码会从解压后的地址开始执行。
4.总结以及理解
内核镜像加载地址:U-Boot 将内核镜像加载到 DDR 中的具体地址。内核启动地址:U-Boot 跳转以启动内核的地址,对于未压缩内核,这通常是加载地址;对于压缩内核,这是解压缩程序的起始地址。入口点地址:内核代码第一个指令所在的地址,对于未压缩内核,这是加载地址;对于压缩内核,这是解压缩后的内核代码地址。
内核镜像 = 解压指令+内核代码;
内核镜像加载地址(内核镜像所放地址):就是U-boot将内核镜像放在DDR的地址,不论压缩的还是未压缩的。
内核启动地址(包含解压指令):就是从U-boot跳转过来运行指令的地址(压缩指令也是指令啊,因此压缩的内核,启动地址就是解压指令的起始地址),又由于,从U-boot跳转过来就是为了启动内核镜像,因此未压缩镜像,启动地址就是加载地址(因为不需要在前面执行解压指令了)。
入口点地址(不包含解压指令):就是执行内核代码的地址,因此未压缩的内核,入口地址就是启动地址(因为不需要解压,直接执行内核代码),也是加载地址。压缩内核的入口地址,是解压内核后内核放在的起始地址。
5.具体场景示例
未压缩内核
加载地址:0x40008000启动地址:0x40008000 (与加载地址相同)入口点地址:0x40008000 (与加载地址相同)
压缩内核
加载地址:0x40008000 (内核镜像加载到这里)启动地址:0x40008000 (解压缩程序的起始地址)解压地址:0x40100000 (解压缩后的内核代码放置在这里)入口点地址:0x40100000 (解压缩后内核代码的起始地址)
图解
未压缩内核:
+-------------------+
| |
| 内核镜像 | <-- 加载地址 (0x40008000)
| |
+-------------------+
^
|
启动地址 (0x40008000) 和 入口点地址 (0x40008000)
压缩内核:
+-------------------+
| |
| 内核镜像 | <-- 加载地址 (0x40008000)
| |
+-------------------+
^
|
启动地址 (0x40008000) --> 解压缩程序
+-------------------+
| |
| 解压缩后的 | <-- 解压地址 (0x40100000)
| 内核代码 |
| |
+-------------------+
^
|
入口点地址 (0x40100000)
4. Linux 内核启动
描述:内核接管系统控制,继续初始化进程。任务:
解压缩内核(如果适用):对于压缩的内核映像,需要先解压缩。初始化硬件抽象层:包括设置页表、初始化中断控制器等。初始化子系统:如调度器、内存管理、文件系统等核心服务。探测和注册平台设备:根据 Device Tree 描述的信息,识别和初始化所有连接的硬件设备,这里主要是通过解析DTB文件与设备驱动进行匹配。挂载根文件系统:查找并挂载指定的根文件系统,这是系统启动后运行的第一个文件系统。启动 init 进程:执行 /sbin/init 或者由内核参数指定的其他初始化进程,这标志着用户空间程序开始启动。
5. 用户空间初始化
描述:init 进程负责启动所有用户空间的服务和应用程序。任务:
读取配置文件:如 inittab 或 systemd 的单元文件。启动基本服务:如网络服务、SSH 服务器等。运行启动脚本:执行系统启动所需的 shell 脚本或命令。提供登录提示:为用户提供一个交互式的登录界面,无论是通过串口、图形界面还是远程 SSH。
6. 系统就绪
描述:此时,所有的初始化工作已经完成,系统处于稳定运行状态。任务:等待用户输入或者按照预定义的任务计划自动执行各种操作。
简单了解设备树
简单介绍
Device Tree是一种描述硬件信息的数据结构,它表现为一棵由电路板上CPU、总线、设备组成的树。
Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可以包含子结点。所谓属性,就是名字对,也就是成对出现的name和value。 可以理解为结构体,节点是名字,属性是内容赋值。
Device Tree 提供了一种标准化的方式,通过 .dts 文件(Device Tree Source)来描述硬件配置。编译后生成 .dtb 文件(Device Tree Blob),然后由引导加载程序传递给内核。内核根据这些信息初始化硬件。
个人理解
1.设备树源文件:用于描述硬件设备信息的文本格式,如(.dts.dtsi 文件)
2. 设备树源文件通过编译生成DTB文件,在U-boot过程,将DTB传给内核,内核启动,解析DTB文件,并且匹配解析到的设备树与设备树驱动文件,对设备进行配置初始化。
3.流程:.dts.dtsi 文件通过编译生成了DTB文件,DTB文件是U-boot传给内核进行解析的,这个DTB被内核解析出来,生成设备树,然后内核通过配置设备树和设备驱动文件,对设备进行配置以及初始化。
通俗比喻:DTB文件被内核解析出来生成了一颗设备树,上面挂满了各种类型的设备(比如吹风机,电视,空调等),然后通过这写设备名称(吹风机,电视,空调)找到与之匹配的设备树驱动文件(也就是使用说明书),将它们配置好,初始化好(也就是通过说明书给他配置成自己需要的工作状态)。
简单修改设备树
查看状态以及如何修改
根据(七)Linux库的串口开发,可以知道串口4是使能状态的,也可以用指令查看:
ls /dev
可以看到dev目录下对应的ttyAS4设备节点。
下面直接修改源码
文件种类
因此需要改设备树源码文件。
查看创龙T113-i官方手册,可以看到。
我的板子是ARM32位架构的,因此是ARM32 CPU和板级设备树。
打开板级设备树路径:
cd /home/zhua/SDK/T113-i_v1.0/device/config/chips/t113_i/configs/tlt113-evm-emmc
如果是用vscode的ssh登陆的可按下ctrl+f,搜索uart4,这里以串口4为例子进行修改。将states = “okay”,有的是“enable”,将enable/okay改成disabled。
重新编译设备树
进入如下目录:
cd /home/zhua/SDK/T113-i_v1.0
编译SDK:
./build.sh j4
并包生成镜像:
./build.sh pack
然后借助Samba服务器进行文件传输,并烧录。可以参考(三)固化镜像开机。
检验修改是否生效
ls /dev
可以看见ttyAS4的设备节点以及不存在了。 或者直接看启动内核日志,发现串口3和5设备都被驱动起来了,而串口四并么有任何信息:
dmesg |grep ttyAS4