【嵌入式】揭秘嵌入式产品启动奥秘:从硬件上电到应用全速运行的精彩旅程

1. 概述

嵌入式产品的启动过程是一个复杂而有序的过程,涉及硬件初始化、引导加载程序(bootloader)的执行、操作系统的加载和初始化以及用户应用程序的启动等多个阶段。下面,我们将以常见的ARM芯片、U-Boot作为bootloader、Linux作为操作系统以及systemd作为init进程为例,详细解析这一过程。

文章目录

  • 1. 概述
  • 2. 硬件上电与初始化
  • 3. U-Boot引导加载程序的执行
  • 4. Linux操作系统加载与初始化
  • 5. init进程初始化与管理
  • 6. 应用程序的启动
  • 7. 用户交互与系统运行
  • 8. 总结

2. 硬件上电与初始化

当嵌入式产品上电后,ARM芯片首先会从Boot ROM(引导只读存储器)中读取并执行启动代码。Boot ROM是芯片内部预置的一段程序,通常是用汇编语言编写的,负责在芯片上电后进行最基本的初始化操作。

这些初始化操作可能包括设置时钟源、初始化内存控制器、配置中断向量表等。由于Boot ROM中的代码是汇编语言编写的,它直接操作硬件寄存器,确保在C语言环境初始化之前,硬件能够工作在正确的状态。

以下是一个简化的Boot ROM中启动代码的汇编语言示例:

; 假设这是Boot ROM中的启动代码片段,使用ARM汇编语法  ; 设置时钟源  
SET_CLOCK_SOURCE:  MOV R0, #CLOCK_SOURCE_VALUE  STR R0, [CLOCK_SOURCE_REGISTER]  ; 初始化内存控制器  
INIT_MEMORY_CONTROLLER:  MOV R0, #MEMORY_CONTROLLER_INIT_VALUE  STR R0, [MEMORY_CONTROLLER_REGISTER]  ; 配置中断向量表  
CONFIG_INTERRUPT_VECTOR_TABLE:  LDR R0, =INTERRUPT_VECTOR_TABLE_BASE  LDR R1, =DEFAULT_HANDLER_ADDRESS  STR R1, [R0] ; 假设只是简单地设置默认中断处理函数地址  ; 跳转到主程序存储区  
JUMP_TO_MAIN_PROGRAM:  LDR R0, =MAIN_PROGRAM_START_ADDRESS  BX R0  

; 其他必要的硬件初始化操作…
这段汇编代码非常基础,只是展示了如何直接操作硬件寄存器进行初始化。在实际中,Boot ROM中的代码会更为复杂,并且会根据具体的硬件平台而有所不同。

3. U-Boot引导加载程序的执行

U-Boot在嵌入式系统的启动过程中扮演着核心角色。它负责完成一系列关键任务,以确保操作系统能够顺利加载和运行。

  1. 硬件资源的进一步初始化
    在U-Boot启动后,它会继续初始化芯片上的其他硬件资源,如串口通信、以太网控制器等。这些初始化操作使得U-Boot能够与外部设备进行通信,并获取必要的配置信息。

  2. 设备驱动加载与测试
    U-Boot支持多种外设驱动,并能够根据系统的硬件配置动态加载相应的驱动。在加载驱动后,U-Boot还会进行设备功能测试,以确保外设的正常工作。

  3. 环境变量配置
    U-Boot维护了一套环境变量,用于存储系统的配置信息。这些环境变量可以在U-Boot的命令行接口中进行设置和修改,为操作系统的启动提供必要的配置参数。

  4. 操作系统镜像的加载
    U-Boot会从存储设备(如Flash、SD卡等)中读取操作系统的镜像文件,并将其加载到内存中。在加载过程中,U-Boot会进行必要的校验和验证,以确保镜像文件的完整性和正确性。

  5. 启动参数的传递
    在加载操作系统之前,U-Boot会将必要的启动参数(如内存布局、设备树信息等)传递给操作系统。这些参数对于操作系统的初始化至关重要。

以下是U-Boot中加载并启动Linux内核的示例代码:

int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  
{  unsigned long addr;  int rcode = 0;  if (argc < 3)  return CMD_RET_USAGE;  addr = simple_strtoul(argv[1], NULL, 16);  // 将内核镜像地址转换为长整型  rcode = do_bootm(cmdtp, 0, addr, argv[2]);  // 调用do_bootm函数加载并启动内核  return rcode;  
}  int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  
{  /* ... 省略了其他代码 ... */  // 加载内核镜像到内存  if (load_image(image) < 0) {  printf("## Error: Unable to load %s\n", image->name);  return 1;  }  // 配置启动参数  setup_start_of_ram_disk();  // 将控制权传递给内核  theKernel(0, machine_id, atags_pointer);  /* ... 省略了其他代码 ... */  return 0;  
}

U-Boot 中,启动参数通常是通过设置 bootargs 环境变量来传递的。bootargs 变量包含了传递给 Linux 内核的命令行参数。这些参数可以指定根文件系统类型、网络配置、串口配置等。可以在 U-Boot 的命令行界面中设置 bootargs 环境变量。例如:

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait

上面的命令设置了 bootargs 变量,指定了控制台输出到串口ttyS0,波特率为 115200,根文件系统位于 /dev/mmcblk0p2 分区,以读写模式挂载,并等待根文件系统就绪。

4. Linux操作系统加载与初始化

当Linux操作系统的镜像文件被加载到内存后,U-Boot会将控制权交给Linux内核。Linux内核在启动过程中会执行以下任务:

  1. 解压与设置:内核首先会解压自己,然后设置页表、初始化内存管理等核心功能。
  2. 设备驱动初始化:内核会加载并初始化各种设备驱动,使得操作系统能够识别和管理系统的硬件设备。
  3. 挂载根文件系统:内核会挂载指定的根文件系统,为后续的用户空间程序提供文件访问服务。

由于这部分代码较为复杂且庞大,这里只给出其大致流程:

void start_kernel(void)  
{  /* ... 省略了其他代码 ... */  // 初始化内存管理  mm_init();  // 初始化设备驱动  driver_init();  // 挂载根文件系统  if (!mount_root_fs())  panic("Unable to mount root fs on ");  /* ... 省略了其他代码 ... */  // 启动init进程  pid_t pid = kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);/* ... 省略了其他代码 ... */// 等待init进程执行完毕  while (1) {  if (!pid_alive(pid)) {  break;  }  /* 等待一段时间或处理其他事件 */  schedule();  }  /* 如果init进程退出,则系统进入panic状态 */  panic("Init process exited");
}

5. init进程初始化与管理

当Linux内核完成初始化后,它会启动用户空间的第一个进程——init进程。在采用systemd作为init进程的系统中,systemd会负责后续的初始化工作:

  1. 服务管理:systemd会启动并管理系统的各种服务,如SSH、Web服务器等。
  2. 日志管理:systemd会收集并记录系统的日志信息,方便后续的问题排查和性能分析。
  3. 资源监控:systemd会对系统的资源进行监控和管理,确保系统的稳定运行。

systemd的配置文件通常位于/etc/systemd/目录下,它定义了各种服务的启动顺序和依赖关系。systemd会根据这些配置文件来管理系统中的服务。

以下是systemd服务单元文件的一个简单示例:

[Unit]  
Description=Example Service  
After=network.target  [Service]  
ExecStart=/usr/sbin/sshd  
Restart=always  [Install]  
WantedBy=multi-user.target

在这个示例中,[Unit]部分描述了服务的基本信息,[Service]部分定义了服务的启动命令和重启策略,而[Install]部分则指定了服务所属的目标(target)。

systemd通过读取这些单元文件,并根据其中的指令来启动、停止、重启和管理服务。它还提供了日志管理、资源监控等功能,确保系统的稳定运行。

6. 应用程序的启动

当系统进入可用状态后,用户的应用程序可以开始启动。这些应用程序可能包括图形用户界面程序、后台服务、数据分析工具等,它们负责执行用户特定的任务和功能。

对于通过systemd管理的应用程序,systemd会读取服务单元文件中的指令,并根据定义的依赖关系和启动顺序,自动启动这些服务。服务单元文件可能指定了应用程序的启动命令、工作目录、环境变量等,以确保应用程序在正确的环境下运行。

除了systemd管理的服务外,用户还可以通过命令行或其他界面工具手动启动应用程序。这些应用程序可能需要读取配置文件、建立网络连接、打开文件或数据库连接等初始化操作,以准备执行其任务。

7. 用户交互与系统运行

一旦所有必要的服务和应用程序都启动完毕,嵌入式产品就进入了正常运行状态,用户可以开始与产品进行交互。

对于带有图形用户界面的产品,用户可以通过触摸屏、键盘或鼠标等输入设备与系统进行交互。系统会根据用户的操作执行相应的命令,更新界面状态,并提供反馈。

对于没有图形用户界面的产品,用户可能通过串口、网络或其他通信接口与系统进行交互。系统接收用户的指令或数据,执行相应的任务,并返回结果或状态信息。

在系统运行过程中,内核和systemd会持续监控系统状态和服务运行情况,确保系统的稳定性和安全性。如果发生错误或异常情况,系统可能会采取相应的措施,如重启服务、记录日志或触发警报等。

8. 总结

嵌入式产品从硬件上电到应用全部启动的过程是一个复杂而有序的流程,涉及多个组件和阶段的协同工作。硬件上电与初始化、引导加载程序的执行、操作系统的加载与初始化、systemd初始化与管理以及应用程序的启动等阶段共同构成了这一过程。通过深入理解这一过程,我们可以更好地进行嵌入式产品的开发和维护,确保系统的稳定运行和满足用户需求。

在实际开发中,还需要根据具体的硬件平台、操作系统和应用程序需求进行定制和优化。例如,可以调整U-Boot的配置参数以适应不同的硬件环境,优化Linux内核的启动参数以提高启动速度,以及定制systemd的服务单元文件以满足特定的服务管理需求。这些定制和优化工作将有助于提高嵌入式产品的性能和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/731088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能合约语言(eDSL)—— proc_macro实现合约init函数

我们通过属性宏来实现合约的init函数&#xff0c;call函数其实和init是类似的&#xff1b; GitHub - XuHugo/xwasm 构建属性宏&#xff0c;要在cargo.toml里面设置一些参数&#xff0c;这是必须的。一般来说&#xff0c;过程宏必须是一个库&#xff0c;或者作为工程的子库&…

向爬虫而生---Redis 探究篇8<保障缓存和持久化数据一致性的研究与实现(初) `探索篇`>

前言: 随着我们的生活越来越数字化,我们对数据的依赖变得无所不在。无论是在购物网站上浏览商品、在社交媒体上与朋友互动,还是在工作中处理大量的业务数据,数据都成了我们生活的重要组成部分。 当我们使用应用程序或网站时,我们希望能够获得快速、即时的响应。这就是缓存出…

Rust基础教程

Rust基础教程 Rust简介安装RustRust rustup第一个Rust应用Rust项目管理工具Cargo使用RustRover开发Rust应用使用VSCode开发Rust应用Cargo项目结构分析Rust关键字和标识符Rust命名规范Rust注释Rust变量Rust不可变变量Rust可变变量Rust常量Rust常量和不可变变量的区别Rust隐藏变…

基于 HBase Phoenix 构建实时数仓(3)—— Phoenix 安装

目录 一、主机规划 二、Phoenix 安装 1. 解压、配置环境 2. 将 phoenix-server-hbase-2.5-5.1.3.jar 文件复制到 HBase 的 lib 目录中 3. 重启 HBase 集群 4. 安装验证 &#xff08;1&#xff09;连接 HBase &#xff08;2&#xff09;视图映射 &#xff08;3&#xf…

thingsboard如何自定义udp-transport

0、参考netty实现udp的文章 https://github.com/narkhedesam/Netty-Simple-UDP-TCP-server-client/blob/master/netty-udp/src/com/sam/netty_udp/server/MessageDecoder.java 调试工具使用的是:卓岚TCP&UDP调试工具 1、在common\transport下面创建udp模块,仿照mqtt的创…

Linux配置.bashrc文件导致各种命令(vim、sudo)失效。

Linux配置.bashrc文件导致各种命令&#xff08;vim、sudo&#xff09;失效。 起因是 nvcc-V一直报错&#xff1a;-bash&#xff1a;nvcc&#xff1a; command not found 踩坑记录&#xff1a;上网一查说是没有配置cuda的环境变量。于是去修改了bashrc文件&#xff0c;在最下面…

一次生产环境上的dockerd启动失败原因分析

今夜原计划对 生产环境 上的 SDN 组件进行一次紧急扩容操作的&#xff0c;但业务基础环境中的 Docker-Engine 启动不起来了、原定计划也就无法继续进行了。 尽管查清了基础业务环境中的故障原因&#xff0c;但金主DD说今天先不干了&#xff0c;那就整理整理思路写篇流水账吧 。…

【漏洞复现】帮管客 CRM jiliyu SQL注入漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

ubuntu下vscode+STM32CubeMX+openocd+stlinkv2搭建STM32开发调试下载环境

1、换源 清华源 # 默认注释了源码镜像以提高 apt update 速度&#xff0c;如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restr…

nginx-排查一次大文件无法正常下载问题

目录 问题现象&报错信息 问题现象以及分析 nginx报错信息 问题解决 方法1&#xff1a;配置proxy_max_temp_file_size 方法2&#xff1a;关闭proxy_buffering 参考文档 问题现象&报错信息 问题现象以及分析 文件正常从后端服务器直接下载时&#xff0c;一切正常…

hive常见时间函数

1.时间戳和日期相互转换函数 具体执行结果在后面备注标注出来。主要为时间戳转换为日期函数&#xff0c;和将日期转换为时间戳函数 -- 1.时间戳转化为日期函数 -- from_unixtime(bigint unixtime[, string format]) 其中第一个参数必须为bigint类型 select from_unixtime(166…

通过esp32cam拍摄图片上传至PC并通过YOLO进行目标检测

通过esp32cam拍摄图片上传至PC并通过YOLO进行目标检测 一.通过esp32cam拍摄照片并上传至PC二.训练自己的数据集三.AutoDL AI算力云的使用1.账号注册2.GPU选取3.GPU使用4.开机训练 四.数据集的使用 一.通过esp32cam拍摄照片并上传至PC 文章链接: https://blog.csdn.net/qq_6297…

北京市气象站点日值数据(降雨气温风速日照蒸发气压地温湿度)

气象数据一直是一个价值较高的数据&#xff0c;它被广泛用于各个领域的研究当中。气象数据包括有气温、气压、相对湿度、降水、蒸发、风向风速、日照等多种指标&#xff0c;但是包含了这些全部指标的气象数据却较难获取&#xff0c;即使获取到了也不能随意分享。 北京&#xf…

学习JavaEE日子 Day24 TreeSet,内置比较器,外置比较器,HashMap

Day24 TreeSet 1.TreeSet 1.1 TreeSet的使用 注意&#xff1a;TreeSet的使用和HashSet一样 public class Test01 {public static void main(String[] args) {//创建TreeSet集合的对象TreeSet<String> set new TreeSet<>();//添加元素set.add("麻生希"…

机器学习-可解释性机器学习:随机森林与fastshap的可视化模型解析

一、引言 机器学习在当今社会扮演着日益重要的角色&#xff0c;但黑盒模型的不可解释性限制了其应用范围。因此&#xff0c;可解释性机器学习成为研究热点&#xff0c;有助于提高模型的可信度和可接受性。本文旨在探讨随机森林和fastshap作为可视化模型解析工具的应用&#xff…

【生态适配】亚信安慧AntDB数据库与OpenCloudOS、TencentOS Server五款产品完成兼容互认

日前&#xff0c;亚信安慧AntDB数据库与OpenCloudOS8、OpenCloudOS9、TencentOS Server 2、TencentOS Server 3、TencentOS Server 4五款操作系统完成兼容互认。经过严格测试&#xff0c;亚信安慧AntDB数据库与这五款操作系统兼容良好&#xff0c;整体运行稳定。 图1&#xff1…

在Anaconda3的conda中创建虚拟环境下载opencv

opencv下载全流程 一、下载Anaconda 记得从官方网格站进行下载&#xff0c;会有一些慢 下载后进行配置 b站讲解视频&#xff08;非本人&#xff08;平台大神讲解&#xff09;&#xff09; 二、打开conda控制台 这里的两个都可以进行下载 通常我们受用anaconda prompt 三、…

Git基于master创建新分支

在工作中&#xff0c;当有一个新需求的时候&#xff0c;需要基于master进行开发&#xff0c;就需要新建分支&#xff0c;并建立本地和远程分支的关联。 1、先切换到master 分支 git checkout master 2、然后将远程master 分支最新代码拉取到本地master分支 git pull 3、然…

【DevOps基础篇】Docker进阶高级技巧使用

【DevOps基础篇】Docker进阶高级技巧使用 目录 【DevOps基础篇】Docker进阶高级技巧使用清理垃圾删除悬空卷删除已退出的容器删除悬空镜像自动删除交互式容器检查Docker资源美观的JSON和jq处理显示整个Docker信息仅显示插件列出连接到‘bridge’网络的所有容器的IP地址监视容器…

数字人ai直播软件突破AI大模型技术,改变未来科技格局!

数字人AI直播软件在AI大模型技术上的突破&#xff0c;将不可避免地改变未来科技格局。这一突破让人们看到了AI技术的无限可能性&#xff0c;并为未来的科技发展打开了新的大门。 AI大模型技术是近年来人工智能领域的一个热点&#xff0c;它通过构建庞大、复杂的神经网络模型&a…