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

嵌入式Linux(Exynos 4412)笔记

一、系统移植课程导学

1. 计算机系统层次结构

1)计算机系统层次划分



  • 三层架构:嵌入式系统作为计算机系统的分支,分为硬件层(最下层)、操作系统层(中间层)和应用程序层(最上层APP)
  • 特殊性质:嵌入式系统是特殊的计算机系统,但同样遵循这三层架构

2)硬件层介绍及作用

  • 组成要素:包括内存、CPU、硬盘等核心硬件,以及SOC内部的各种硬件接口控制器(如GPIO、PWM、I2C、ADC等)
  • 核心功能:实现计算机与外界的数据/信号输入输出,是信息交互的物理基础
  • 控制方式:通过寄存器配置直接控制硬件工作(无操作系统时)

3)操作系统层介绍及作用

  • 双重作用:
    • 向下管理:统一管理计算机系统的软硬件资源
    • 向上服务:为应用程序提供API接口(函数调用)
  • 设计哲学:"向下管理硬件,向上提供接口",应用程序无需了解底层实现细节
  • 典型接口:如文件操作(open/close/read/write)、进程管理(fork/pthread_create)等

4)应用程序层(APP)介绍

  • 开发特点:使用操作系统提供的API开发特定功能应用
  • 优势体现:开发者只需关注功能实现,无需了解硬件细节(如文件存储位置、网络协议实现等)
  • 典型示例:基于Linux系统的各类应用软件

2. 之前介绍复习

1)应用开发与顶层开发

  • 本质特征:使用操作系统提供的API进行开发
  • 课程示例:IO课程(文件操作函数)、并发程序(进程线程函数)、网络编程(socket函数)、数据库操作函数等
  • 共同特点:都是教授操作系统提供的特定功能函数的使用方法

2)操作系统提供的API

  • IO接口:open/close/read/write等文件操作函数
  • 进程管理:fork/pthread_create等进程线程函数
  • 网络通信:socket/listen/connect/accept等网络函数
  • 开发范式:调用现成API而不关心底层实现(如TCP协议栈实现)

3)Linux操作系统的五大功能



  • 进程管理:创建/调度/销毁进程的机制实现
  • 内存管理:内存分配(malloc)/释放(free)及虚拟内存管理
  • 网络协议:集成TCP/UDP/IP等协议栈实现
  • 文件系统:磁盘/文件管理的底层实现(如ext4文件系统)
  • 设备管理:硬件设备驱动管理(LED/ADC/屏幕等)

4)ARM课程的学习内容

  • CPU原理:通过汇编语言理解程序执行机制
  • 接口技术:I2C/UART/GPIO/ADC/RTC等硬件接口实验
  • 学习目的:
    • 理解处理器工作原理
    • 掌握无系统时的硬件控制方法(直接寄存器配置)
    • 为驱动开发打基础(系统下的硬件管理方式不同)
  • 系统差异:
    • 无系统:直接配置寄存器控制硬件
    • 有系统:通过设备文件控制硬件(驱动开发范畴)
  • 底层开发本质:开发操作系统本身,包括硬件管理模块的实现

3. 系统移植的意义

1)系统移植定义



  • 核心任务:将Linux系统安装到基于ARM处理器的开发板上
  • 应用场景:嵌入式设备(如机器人控制)需要轻量化的开发板运行系统,而非直接使用电脑
  • 对比传统方式:之前ARM开发板无操作系统,只能运行基础C语言程序

2)系统移植的意义

  • 功能限制:未装系统时无法调用任何系统函数(如IO操作、进程线程、网络通信等)
  • 开发效率:所有功能需自行实现,仅能完成小型项目
  • 移植优势:安装系统后可调用标准库函数,直接运行上层应用程序
  • 典型示例:printf/sleep等基础函数在无系统时需要自行实现

4. 移植的目的

1)不同架构处理器指令集不兼容

  • 架构差异:ARM与x86等不同架构CPU的汇编指令集完全不同(如除法指令支持)
  • 内核实现:Linux内核包含大量汇编代码,需针对特定处理器架构编写
  • 兼容问题:用ARM汇编编写的内核无法在x86平台运行,反之亦然

2)相同架构不同板卡驱动代码不兼容

  • 外设差异:相同处理器(如三星4412)在不同开发板上外设连接方式不同
  • 实例说明:LED可能连接GPX2-7或GPX2-6引脚,需修改寄存器配置代码
  • 平台相关代码:驱动程序等与硬件直接交互的代码需随硬件变更而修改

3)Linux内核的通用性与配置需求

  • 源码特性:官方提供的是通用内核源码,未针对特定硬件优化
  • 获取方式:下载得到的是C/汇编源代码,需自行编译(区别于Windows镜像)
  • 匹配需求:必须修改源码使其适配目标硬件平台(处理器架构+外设电路)

4)移植工作的核心:软硬件匹配

  • 配置本质:修改内核源码中的平台相关代码(汇编指令+驱动程序)
  • 工作流程:下载源码→配置适配→编译→安装
  • 时间分配:80%时间用于配置适配,仅20%用于实际安装
  • 医学类比:类似器官移植的血型匹配,需确保软硬件参数完全兼容

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

嵌入式系统层次结构

计算机系统分为三层:硬件层(CPU、内存等)、操作系统层(管理硬件、提供API)、应用程序层(APP开发)

操作系统的作用(向下管理硬件,向上提供接口)

⭐⭐

应用开发 vs 底层开发

应用开发:调用操作系统API(如文件IO、进程线程函数);底层开发:开发操作系统本身(如硬件控制、寄存器配置)

函数调用限制(无系统时无法调用标准库函数)

⭐⭐⭐

系统移植的意义

将Linux系统安装到ARM开发板,使应用层程序可在开发板运行(解决无系统时编程局限性)

为何需要移植(官方源码与硬件不匹配)

⭐⭐⭐⭐

移植的核心工作

配置源码(匹配硬件平台)→ 编译 → 安装,重点在硬件与软件的适配(如寄存器配置、外设电路差异)

平台相关代码(不同硬件需修改汇编/驱动代码)

⭐⭐⭐⭐

课程特点

1. 实践性强(无需写代码,侧重配置与安装); 2. 需掌握汇编/C/Shell等语言基础; 3. 重方法轻细节(掌握移植流程而非研究源码)

学习误区(过度关注Linux源码细节)

⭐⭐⭐

移植流程示例

下载源码 → 配置(适配硬件)→ 编译 → 安装到开发板

关键步骤优先级(配置>编译>安装)

⭐⭐⭐⭐

二、系统移植过程

1. Windows装机

1)系统安装前的准备

  • 系统镜像: 相当于操作系统的压缩包或安装包,可以从系统之家等网站下载,是安装系统的必备文件
  • U盘启动盘: 需要准备一个U盘并刷入引导程序(如老毛桃、大白菜),这类程序的功能是引导和安装系统镜像到电脑磁盘中

2)BIOS设置与启动方式

  • BIOS本质: 基本输入输出系统(Basic Input Output System),是电脑出厂时固化在主板上的程序,不是操作系统
  • 主要功能: 设置硬件参数(如CPU虚拟化功能开关),其中最重要的设置项是启动方式
  • 启动方式选择: 决定电脑开机后首先运行哪个介质中的程序(U盘/硬盘/光驱),安装系统时需要设置为U盘启动

3)系统安装过程

  • 关键步骤:
    • 开机按特定键(F2/F10等)进入BIOS
    • 设置U盘为第一启动项
    • 重启后自动运行U盘中的引导程序(老毛桃等)
    • 通过引导程序将系统镜像安装到硬盘
  • 耗时说明: 系统文件复制安装是最耗时的环节,需要耐心等待完成

4)驱动程序的安装

  • 驱动功能: 使硬件设备(显卡/网卡/声卡等)能够正常工作的软件程序
  • 常见问题: 新装系统后可能出现硬件无法使用的情况(如不能上网、显示异常等)
  • 解决方案:
    • Windows自带部分通用驱动
    • 需要手动安装特定硬件厂商提供的专用驱动
    • 确保驱动版本与硬件型号匹配

5)应用程序的安装

  • 系统分层:
    • 底层:硬件设备
    • 中间层:操作系统
    • 上层:应用程序(如QQ/PS/视频软件等)
  • 安装原则: 根据实际需求选择安装,如通讯、图像处理、影音娱乐等不同用途的应用
  • 功能实现: 应用程序通过调用操作系统提供的API接口实现特定功能

2. Linux系统移植

1)准备工作

  • 准备内容:
    • Linux内核镜像: 类似于Windows系统安装包,是Linux系统的核心部分。
    • SD卡启动盘: 用于存储引导程序,以便从SD卡启动并安装系统。这里使用的是SD卡而非U盘。
  • 引导程序:
    • U-Boot: 在嵌入式系统中常用的引导程序,用于引导和安装操作系统,类似于Windows下的老毛桃、大白菜等工具。

2)选择启动方式



  • BIOSBL0:
    • BIOS: 电脑主板上的固化程序,用于设置启动方式等。需开机后进入BIOS界面选择。
    • BL0: 开发板(如4412处理器)芯片内固化的代码,类似于BIOS,但设置方式不同。
  • 拨码开关: 开发板上用于选择启动方式的开关,不同位置代表不同启动方式(如SD卡启动、eMMC启动等)。设置拨码开关需在断电情况下进行,上电后开发板会根据拨码开关的位置选择启动介质。

3)安装Linux系统

  • 安装步骤:
    • 拨码开关设置: 将拨码开关拨到SD卡启动位置。
    • 上电: 开发板上电后,BL0代码会检测拨码开关位置,并执行SD卡中的程序。
    • 运行U-Boot: SD卡中的U-Boot引导程序运行起来,通过U-Boot界面安装Linux内核镜像到开发板(如eMMC)。

4)安装驱动程序

  • 驱动需求: Linux系统安装完成后,开发板上的部分硬件可能无法正常工作,因为Linux系统可能不包含这些硬件的驱动程序。
  • 安装驱动: 需要手动安装对应硬件的Linux驱动程序,如网卡驱动、LED驱动等。

5)安装应用程序

  • 应用程序安装: 根据需求在开发板上安装各种应用程序,实现特定功能。

3. Windows装机与Linux系统移植的比较

  • 相似性: Linux系统移植的步骤与Windows装机过程类似,都包括准备系统镜像、选择启动方式、安装系统、安装驱动和应用程序等步骤。
  • 差异性:
    • 启动方式设置: Windows通过BIOS设置,Linux开发板通过拨码开关设置。
    • 引导程序: Windows下可能使用老毛桃、大白菜等工具,Linux下则常用U-Boot。
  • 移植工作: 在安装Linux系统之前,还需要对源代码进行配置和编译工作,使其适配特定的开发板。这是Linux系统移植中特有的步骤,Windows装机则不涉及。

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

嵌入式系统移植概述

介绍嵌入式系统移植在课程体系中的位置及意义

-

课程目的

给开发板安装Linux系统,便于应用层程序移植

-

学习难点

涉及细节性实验,易迷失方向

实验细节与整体目的关联

系统移植内容

不仅安装Linux,还需安装uboot、文件系统等

Linux与uboot等区别

系统移植宏观过程

回顾Windows装机过程,类比嵌入式Linux系统移植

类比理解

Windows装机准备

系统镜像、U盘启动盘(老毛桃等)

-

BIOS设置

设置启动方式(U盘启动)

BIOS与启动方式

安装系统

通过引导程序安装系统镜像

-

驱动安装

安装网卡、显卡等驱动

-

应用程序安装

根据需求安装QQ、微信等APP

-

嵌入式Linux系统移植准备

Linux内核镜像、SD卡启动盘(uboot)

U盘与SD卡启动区别

BL0设置

通过拨码开关选择启动方式(SD卡启动)

BIOS与BL0设置方式

安装Linux系统

通过uboot安装Linux内核镜像

uboot与老毛桃功能对比

驱动安装

安装LED、网卡等驱动

Linux与Windows驱动区别

应用程序移植

移植IO、进程等代码到开发板

-

移植工作

配置、修改、编译Linux源代码

安装与移植的区别

三、开发板启动过程

1. 动态图解释开发板启动过程

1)Exynos 4412手册

  • 地址映射表复习
    • 芯片概述: Exynos 4412 SCP是一款32位RISC处理器,采用Cortex-A9架构,具有低功耗、高性能特点,内置128位总线架构和多种硬件加速器。
    • 地址空间特性:
      • 采用32位地址总线,寻址空间为

        2322^{32}232

        =4GB
      • 通过内存映射表将4GB空间划分为不同功能区域
    • 地址映射表定义:
      • 将CPU可访问的4GB空间按功能划分为不同区域
      • 每个区域对应特定硬件资源(内存、寄存器等)
      • 示例区域:0x00000000-0x00010000为iROM区域
    • 关键区域划分:
      • 0x00000000-0x00010000: 64KB iROM(内部只读存储器)
      • 0x02000000-0x02010000: 64KB iRAM(内部随机存储器)
      • 0x10000000-0x14000000: 特殊功能寄存器区
      • 0x40000000-0xA0000000: 1.5GB 外部内存扩展区
      • 0xA0000000-0xFFFFFFFF: 1.5GB 外部内存扩展区
    • iROM详解

      • 物理特性:
        • 位于芯片内部,大小为64KB
        • 地址范围:0x00000000-0x00010000
        • 内容由三星预先烧录,不可修改
      • 功能特性:
        • 存储BL0(Boot Loader 0)程序
        • CPU上电后PC寄存器默认值为0,首先执行iROM中的BL0
        • 类比PC机的BIOS固件
    • 其他关键区域

      • iRAM区域:
        • 地址:0x02000000-0x02060000
        • 大小:256KB
        • 芯片内部高速内存
      • SFR区域:
        • 地址:0x10000000-0x14000000
        • 用于控制各类硬件外设的寄存器
        • 包括GPIO、UART、I2C等控制器寄存器
      • 外部内存区:
        • 共3GB空间(0x40000000-0xFFFFFFFF)
        • 通过内存控制器连接外部DRAM
        • 实际开发板通常配置1GB物理内存
    • 地址映射原理
      • 设计目的:
        • 解决有限地址空间分配问题
        • 实现不同类型存储器的统一寻址
        • 隔离不同硬件资源的访问冲突
      • 实现方式:
        • 通过内存控制器实现地址解码
        • 不同地址范围触发不同片选信号
        • 示例:访问0x10000000自动选择SFR总线

2)开发板各组成部分作用解析

  • iROM及固件BL0
    
    • iROM特性:位于处理器内部,地址从

      0x0000_00000x0000\_00000x0000_0000

      开始,是芯片上电后最先执行的存储区域
    • BL0功能:
      • 固化在iROM中的初始引导程序
      • 执行基本硬件初始化(时钟、内存等)
      • 读取启动设备选择信号
      • 负责将第二级引导程序加载到内存
  • 拨码开关及其作用
    • 物理结构:开发板上有4位拨码开关(标号1-4),位于按键旁
    • 核心功能:设置启动介质选择,不同组合对应不同启动方式:
      • OFF ON ONOFF\ ON\ ONOFF ON ON

        :eMMC启动
      • ON OFF OFFON\ OFF\ OFFON OFF OFF

        :SD卡启动
    • 配置参考:开发板丝印层提供状态对照表,明确各组合对应的启动方式
  • 外扩内存条RAM
    
    • 硬件配置:
      • 4片256MB内存芯片组成1GB容量
      • 位于主控芯片Exynos4412周围
    • 地址分配:
      • 物理地址范围:

        0x4000_00000x4000\_00000x4000_0000

        0x8000_00000x8000\_00000x8000_0000

      • 芯片预留3GB扩展空间,实际只使用前1GB
      • 0x8000_00000x8000\_00000x8000_0000

        0xFFFF_FFFF0xFFFF\_FFFF0xFFFF_FFFF

        保留未使用
  • SD卡的作用
    
    • 系统移植用途:存储Uboot和Linux系统镜像
    • 启动特性:
      • 属于外存设备,程序需加载到内存执行
      • 通过拨码开关选择SD卡启动模式
      • BL0会检测到SD卡启动后自动加载其中程序
  • eMMC的作用
    
    • 硬件特性:
      • 相当于电脑硬盘,位于核心板右下角
      • 非易失性存储,断电数据不丢失
    • 系统运行机制:
      • 安装Linux系统的最终存储位置
      • 系统运行时从eMMC加载到内存执行
      • 包含三部分:Linux内核、设备树(dtb)、根文件系统

3)开发板启动过程动态演示

  • BL0阶段:
    • 上电后首先执行iROM中的BL0
    • 初始化基础硬件环境(时钟、内存控制器等)
    • 读取拨码开关确定启动介质
    • 将SD卡中的uboot复制到内存(SD卡启动时)
  • Uboot阶段:
    • 初始化更复杂的硬件环境(堆栈、网卡、串口等)
    • 从eMMC加载三部分到内存:
      • Linux内核
      • 设备树(dtb) - 存储硬件配置信息
      • 根文件系统 - Linux运行所需的文件集合
  • Linux启动:

    • 初始化系统环境
    • 挂载根文件系统(将文件系统内容读入内存使用)
    • 完成启动后进入正常工作状态
  • 关键组件关系:
    • 设备树(dtb):分离驱动代码与硬件信息,便于硬件变更
    • 根文件系统:包含系统运行所需的配置文件、库文件等
    • 三者关系:Linux内核 + 设备树 + 根文件系统 = 完整Linux系统

4)开发板启动过程总结

  • BL0的执行与启动方式选择
    
    • BL0执行机制:开发板上电后首先运行SOC内部iROM中固化的代码(BL0),这段代码先对基本的软硬件环境(时钟等)进行初始化
    • 启动方式检测:BL0会检测拨码开关位置获取启动方式,根据拨码开关选择从SD卡或eMMC启动
    • 程序加载原理:选择SD卡启动时,BL0会将SD卡中的uboot搬移到内存运行(外存程序需加载到内存才能执行)
  • U-Boot的加载与运行
    
    • 初始化工作:uboot运行后首先对开发板上的软硬件环境做进一步初始化,包括网卡初始化、串口初始化等
    • 系统加载三步骤:
      • 将Linux内核从外存搬到内存
      • 将设备树(dtb)从外存搬到内存
      • 将根文件系统(rootfs)从外存搬到内存
    • 加载必要性:这三个组件在外存无法直接执行,必须通过uboot加载到内存才能运行
  • Linux系统的加载与运行
    
    • 运行顺序:uboot完成加载后结束运行,Linux开始接管系统
    • 初始化过程:Linux首先对系统环境做初始化,包括基本的软硬件初始化
    • 组件关系:Linux内核和设备树(dtb)共同组成完整的Linux系统
  • 根文件系统的挂载
    • 挂载时机:Linux初始化完成后才进行根文件系统挂载
    • 挂载方式:
      • 常规方式:从内存挂载(如实验演示)
      • 常用方式:通过网络挂载(实际开发更常用)
    • 功能作用:根文件系统包含Linux运行所需的各类文件
  • 启动过程总结与实验说明

    • 执行程序序列:
      • iROM中的BL0
      • uboot
      • Linux内核+设备树
      • 根文件系统
    • 实验注意事项:实际实验中根文件系统通常通过网络挂载,与演示的内存挂载方式不同

5)系统移植步骤总结

  • 移植必要性:要使开发板正常启动,必须预先安装四个组件
  • 免移植组件:BL0是芯片固化的,无需移植
  • 需移植组件:

    • uboot移植(如移植到SD卡)
    • Linux内核移植(包含设备树,移植到eMMC)
    • 根文件系统移植(移植到eMMC)
  • 移植顺序:与程序运行顺序保持一致
    • uboot移植
    • Linux内核+设备树移植
    • 根文件系统移植
  • 存储介质选择:不同组件可能安装在不同存储介质(SD卡/eMMC)

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

开发板启动过程

上电后依次执行:BL0(固化在iROM)→ uboot(从SD卡加载)→ Linux内核+设备树(从eMMC加载)→ 挂载根文件系统

BL0的自动执行机制与地址映射关系(零地址固定分配)

⭐⭐⭐⭐

地址映射表

4412芯片的4GB地址空间划分:iROM(64K)、iRAM(256K)、寄存器区(1GB)、外扩内存预留区(15GB)

外扩内存实际使用1GB(0x40000000-0x80000000),剩余地址未使用

⭐⭐⭐

uboot作用

1. 初始化基础硬件 2. 加载Linux内核+设备树到内存 3. 加载根文件系统到内存

设备树与内核的关系(必须同时加载)

⭐⭐⭐⭐

根文件系统

Linux运行时依赖的文件集合(非代码),需提前加载到内存供内核挂载

与普通文件系统的区别(挂载时机与用途)

⭐⭐⭐

系统移植步骤

1. 移植uboot到SD卡 2. 移植Linux内核+设备树到eMMC 3. 移植根文件系统到eMMC

移植顺序与启动流程的严格对应关系

⭐⭐⭐⭐

拨码开关配置

通过1234拨码组合选择启动方式(如SD卡启动:ON-OFF-OFF)

不同开发板的拨码规则差异(需查丝印表格)

⭐⭐

四、开发板启动过程(续)

1. BL0的初始化与拨码开关检测

  • 执行顺序:开发板上电后首先执行固化在芯片内部iROM中的BL0程序
  • BL0功能:
    • 硬件初始化:对软硬件环境进行基本初始化
    • 启动检测:检测拨码开关状态确定启动方式(如SD卡启动)
  • 存储特性:BL0由三星公司固化在芯片内部,无需用户移植

2. BL0根据拨码开关加载程序

  • 加载机制:
    • 检测到SD卡启动方式后,BL0将SD卡中的U-Boot程序复制到内存
    • 必要性:外存(SD卡)中的程序无法直接运行,必须加载到内存才能执行
  • 内存特性:内存中的程序可直接被CPU运行,而外存程序需要先加载

3. U-Boot的启动与初始化

  • 启动流程:
    • BL0结束后U-Boot开始运行
    • 同样先对软硬件环境进行基本初始化
  • 加载内容:将外存中的Linux内核、设备树(dtb)和根文件系统(rootfs)加载到内存

4. U-Boot加载Linux内核与文件系统

  • 加载必要性:
    • 系统组件安装在外存(断电不丢失)
    • 但运行必须加载到内存(CPU只能直接运行内存中的程序)
  • 加载顺序:U-Boot依次加载内核→设备树→根文件系统到内存

5. Linux系统的启动与文件系统挂载

  • 启动过程:
    • Linux内核运行并进行初始化
    • 成功启动后挂载根文件系统
  • 完整系统:内核+文件系统共同构成可运行的完整Linux系统

6. 系统移植的步骤与顺序

  • 移植组件:
    • BL0(已固化,无需移植)
    • U-Boot
    • Linux内核
    • 设备树
    • 根文件系统
  • 移植顺序:遵循代码运行顺序,先移植U-Boot

7. 移植的首要任务:安装U-Boot

  • 首要工作:在SD卡中刷入U-Boot
  • 后续目标:学会使用U-Boot进行系统引导

五、Boot loader

1. Boot loader的基本功能



  • 定义:操作系统运行前执行的小段代码(非操作系统本身)
  • 核心功能:
    • 环境初始化:将软硬件环境初始化到适合操作系统运行的状态
    • 系统引导:加载操作系统到内存(从外存到内存)
    • 参数传递:为Linux内核准备并传递启动参数
    • 命令执行:支持执行用户命令(类似shell命令)
  • 与U-Boot关系:U-Boot是嵌入式Linux最常用的具体Bootloader实现

2. 常见的Bootloader



  • 分类特点:
    • 通用性:多数Bootloader针对特定平台或系统
    • ARM支持:仅少数支持ARM架构(如U-Boot、RedBoot)
  • 选择原因:
    • 平台兼容:U-Boot支持多种架构(包括ARM)
    • 系统兼容:专为Linux设计,非专用引导程序
    • 行业标准:嵌入式开发领域最广泛使用的Bootloader

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

BL0 功能

三星芯片固化的初始程序,负责硬件初始化、检测启动方式(如SD卡),并将外部存储器代码加载到内存

BL0 与 uboot 的分工(BL0 仅加载 uboot,uboot 加载内核)

⭐⭐

uboot 作用

1. 初始化软硬件环境; 2. 加载 Linux 内核、设备树、根文件系统到内存; 3. 向内核传递参数; 4. 支持用户命令

传参机制(类似函数调用前准备参数)与内存/外存运行差异

⭐⭐⭐

Linux 系统启动流程

BL0 → uboot → 内核初始化 → 挂载根文件系统

各阶段依赖关系(如内核需依赖 uboot 加载)

⭐⭐⭐⭐

Boot Loader 定义

统称引导加载程序(如 uboot),负责操作系统运行前的环境准备

Boot Loader ≠ 操作系统(仅为操作系统运行做铺垫)

⭐⭐

uboot 特殊性

嵌入式开发通用引导程序,支持 ARM 架构和 Linux 系统

与其他 Boot Loader(如 RedBoot)的兼容性对比

⭐⭐⭐

系统移植顺序

1. uboot → 2. Linux 内核 → 3. 设备树 → 4. 根文件系统

BL0 无需移植(芯片固化)

⭐⭐⭐⭐

六、SD卡启动盘制作

1. SD卡的存储结构



  • 基本单位:SD卡以扇区(块)为单位存储数据,每个扇区大小为

    512Byte512Byte512Byte,与内存的字节寻址方式不同

  • 编号规则:所有扇区从0开始线性编号,类似内存地址的排列方式

1)SD卡以扇区为单位存储

  • 与内存的区别:
    • 内存:以字节为单位(8bit),每个字节有唯一地址(0,1,2...连续排列)
    • SD卡:以扇区/块为单位(512Byte),在Linux系统中被称为块设备
  • 类比说明:如同书本分页存储,每个扇区相当于书的一页,但每页固定为512字节容量

2)零扇区存储分区表

  • 特殊用途:第0扇区专门存储分区表(类似书籍目录页),记录全部分区范围信息
  • 分区表示例:如8G SD卡可分为:
    • 第1-100扇区:分区1
    • 第101-200扇区:分区2
  • 保护机制:该扇区不可随意写入,否则会导致分区信息丢失

3)后续扇区可自定义分区和格式化

  • 自由管理区域:第1扇区及之后的空间允许用户:
    • 按需划分多个分区(类似电脑的C/D/E盘)
    • 对各分区独立格式化
  • 使用建议:可根据不同用途划分区域,如系统区、数据存储区等

4)SD卡启动与程序搬移

  • 启动流程:
    • 开发板选择SD卡启动模式
    • 处理器执行固化在iROM中的BL0代码
    • BL0自动从SD卡第1扇区开始搬移程序到内存
  • 关键特性:BL0不会搬移第0扇区(分区表所在位置)

5)uboot应存储于第一扇区开始的空间

  • 存储规范:
    • uboot必须从第1扇区开始存储(约500KB大小)
    • 实际占用连续多个扇区(如1000个扇区)
  • 错误示例:
    • 存于第0扇区 → 不被BL0读取
    • 存于第100扇区 → 前99扇区内容缺失
  • 剩余空间:uboot之后的空间可自由分区格式化,如:
    • 存放系统镜像
    • 作为数据存储区

2. 实验手册

1)实验环境

  • Ubuntu系统:实验在Ubuntu系统下进行,需要将u-boot镜像文件拷贝到家目录下
  • 开发板型号:使用FS4412实验平台进行uboot烧写验证

2)实验步骤

  • u-boot镜像准备
    
    • 文件获取:从资料中获取u-boot-fs4412.bin文件
    • 拷贝操作:将镜像文件拷贝到Ubuntu家目录下
    • 文件验证:通过ls命令确认文件已成功拷贝
  • 实验步骤详解
    
    • 制作空镜像

      • dd命令:
        • 功能:用于转换和复制文件
        • 参数说明:
          • if=/dev/zero:输入文件,生成全零内容
          • of=zero.bin:输出文件名
          • count=1:块数量,1块=512字节
      • 执行命令:sudo dd if=/dev/zero of=zero.bin count=1
      • 验证输出:显示"1+0 records in/out"表示成功
    • 追加uboot
      
      • 合并原理:
        • SD卡结构:第0扇区存储分区表,从第1扇区开始存放uboot
        • 合并目的:在uboot前添加512字节空数据,确保烧写时uboot从第1扇区开始
      • 执行命令:cat zero.bin u-boot-fs4412.bin > win-u-boot-fs4412.bin
      • 验证方法:通过ls命令查看生成的新文件
    • 制作1M空镜像
      
      • 清除目的:擦除SD卡中原有数据
      • 计算方法:
        • 1块=512字节
        • 2048块=1MB
      • 执行命令:sudo dd if=/dev/zero of=clear.bin count=2048
      • 验证大小:使用du -MH命令确认文件大小为1MB
    • 拷贝文件
      
      • 传输文件:
        • win-u-boot-fs4412.bin
        • clear.bin
      • 传输方法:通过VMware共享文件夹或直接拖拽
    • 插入SD卡
      
      • 识别问题:
        • 若Windows不识别,可能被Ubuntu占用
        • 解决方法:在虚拟机可移动设备中断开SD卡连接
      • 验证方法:在"此电脑"中查看SD卡盘符
    • Win32DiskImager烧写
      
      • 烧写步骤:
        • 先烧写clear.bin清空SD卡
        • 再烧写win-u-boot-fs4412.bin
      • 工具使用:
        • 选择镜像文件
        • 选择SD卡设备
        • 点击Write开始烧写
      • 成功标志:显示"Write Successful"
    • 拔出SD卡并验证
      
      • 硬件操作:
        • 将SD卡插入开发板
        • 设置拨码开关为SD卡启动模式
      • 验证方法:
        • LED2灯点亮
        • 串口终端显示uboot启动信息
      • 常见问题:
        • LED亮但终端无输出:检查串口连接
        • 无任何反应:检查烧写过程和启动模式设置

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

SD卡存储结构

SD卡以扇区(块)为单位存储,每块512字节,编号从0开始;第0块存储分区表,类似硬盘分区信息

内存按字节寻址 vs SD卡按块寻址

⭐⭐

Uboot烧录原理

BL0固件从SD卡第1块开始加载程序,需确保uboot镜像从第1块写入

烧录工具默认从第0块写入,需前置512字节空块对齐

⭐⭐⭐

镜像制作步骤

1. 生成512字节空镜像 2. 合并空镜像与uboot.bin 3. 擦除SD卡原有数据 4. 烧录合并后的镜像

dd命令参数:if=/dev/zero(输入空数据)、count=2048(生成1MB文件)

⭐⭐⭐⭐

开发板启动验证

拨码开关设为SD卡启动,串口终端显示uboot版本及硬件信息,LED2亮起为成功标志

串口无输出时检查接线/启动模式

⭐⭐

关键命令

dd if=/dev/zero of=zero.bin count=1(生成空块); cat zero.bin uboot.bin > final.bin(镜像合并)

输出重定向>与dd的of=参数区别

⭐⭐⭐

七、ubuntu的使用

Ubuntu的使用在系统移植课程中至关重要,后续将Linux系统安装到开发板或从外存加载到内存运行均需通过Ubuntu完成。Ubuntu的熟练程度直接影响系统移植工作的效率,因此本次课程内容为重点内容。

1.uboot模式

Uboot有两种工作模式:

  • 自启动模式
  • 交互模式

1) 自启动模式

自启动模式指Ubuntu启动后进入倒计时阶段,若未进行人为干预,倒计时结束后将自动执行自启动命令。自启动命令通常用于加载和启动Linux内核。

2) 交互模式

交互模式指在Ubuntu倒计时阶段人为干预(如按下Enter键),系统将停止加载Linux内核并停留在Ubuntu界面。交互模式下可输入并执行Ubuntu命令,类似于电脑开机时进入BIOS的操作逻辑。

2.uboot命令

1) 帮助命令

  • 例题:查看uboot支持的所有命令
  • help命令用于查看Ubuntu支持的所有命令,执行后系统将列出全部可用命令,例如bootm(加载内核)、cp(拷贝内存)、erase(擦除存储内容)等。
  • help命令后接具体命令可查看其使用方法,例如输入help loadb将显示loadb命令的格式及参数说明,包括二进制文件下载地址和波特率设置。

2) 环境变量命令

  • 打印环境变量命令
  • printenv命令用于打印Ubuntu环境变量,包括波特率、网卡型号、IP地址、子网掩码等关键配置信息。
  • 执行printenv后,系统输出环境变量列表,例如ipaddr= - - - 150表示当前IP地址,serverip表示服务器IP地址。
  • setenv命令用于修改环境变量,格式为setenv [变量名] [新值],例如setenv ipaddr - - - 100可将IP地址修改为 - - - 100。
  • 通过setenv ipaddr - - - 100修改IP地址后,需注意环境变量仅临时保存在内存中,断电后恢复默认值。若需永久保存,需将配置写入外存(如SD卡或eMMC)。
  • setenv命令用于将环境变量保存至外部存储器。通过help命令可查看saveenv功能说明,该命令实现环境变量的持久化存储。
  • 环境变量查看:执行printenv显示当前IP地址为 - 150
  • 环境变量修改:通过setenv IPaddr - - - 100更新IP地址
  • 环境变量保存:saveenv命令将修改后的环境变量写入MMC存储器
  • 验证持久化:重启开发板后执行printenv确认IP地址永久变更为 - - - 100

3) 常用环境变量

printenv命令可列出全部环境变量,其中关键环境变量包括:

ipaddr

  • ipaddr为开发板/U-Boot的IP地址配置项。必须与Ubuntu主机处于同一网段,若Ubuntu IP为 - - - x,则U-Boot需对应配置为 - - - x系列地址。

serverip

  • serverip定义TFTP服务器地址。当U-Boot作为TFTP客户端从Ubuntu下载文件时,该变量必须设置为Ubuntu主机的实际IP地址。

bootdelay

  • bootdelay控制自启动模式前的倒计时秒数(默认3秒)。通过setenv bootdelay 5及saveenv可修改为5秒,重启后倒计时变更为54321序列。该参数适用于调整系统启动等待时间。

八、uboot网络传输命令

1. loadb命令

  • 功能:通过Kermit协议从串口下载二进制文件到指定内存地址
  • 特点:
    • 基于串口通信,速度较慢
    • 常用于ARM开发环境
  • 使用方法:
    • 命令格式:loadb <内存地址>
    • 示例:loadb 0x41000000 将文件下载到内存0x41000000处

1)tftp命令

  • 功能:通过TFTP协议从网络服务器下载文件到指定内存地址
  • 特点:
    • 基于网络通信,速度比loadb快很多
    • U-Boot内置支持,无需额外安装客户端
  • 使用方法:
    • 完整格式:tftp [loadAddress] [hostIPaddr:]bootfilename
    • 简化格式:tftp <内存地址> <文件名>
    • 示例:tftp 0x41000000 interface.bin
  • 使用前的准备工作
    • 网络配置要求:
      • 必须使用桥接模式连接
      • 开发板与服务器必须在同一网段
      • 需要正确配置IP地址、子网掩码和网关
  • 服务器端配置
    
    • 必须安装TFTP服务器:
      • Ubuntu安装命令:sudo apt-get install tftpd-hpa tftp-hpa
      • 每次重启后需要启动服务:sudo service tftpd-hpa restart
    • 工作目录:
      • 默认在/tftpboot目录
      • 下载文件必须放在此目录下
      • 文件权限需设置为777:sudo chmod 777 <文件名>
  • 客户端配置

    • 关键环境变量:
      • ipaddr:开发板IP地址(必须与服务器同网段)
      • serverip:TFTP服务器IP地址(必须与Ubuntu主机IP一致)
      • netmask:子网掩码(通常255.255.255.0)
      • gatewayip:网关地址
    • 检查方法:
      • 使用printenv命令查看当前环境变量
      • 使用setenv和saveenv修改并保存配置
  • 常见问题排查
    • 网络连通性测试:
    • 成功显示"host is alive",失败显示"is not alive"
    • 使用ping命令测试:ping <服务器IP>
    • 常见问题:
      • 防火墙未关闭(需关闭Windows防火墙)
      • 网卡选择错误(必须选择有线网卡)
      • 网线未直连(开发板与电脑需直连)
      • IP地址配置错误(必须同网段不同IP)
  • 实际下载示例
    • 下载步骤:
      • 将测试文件放入/tftpboot目录
      • 设置文件权限:sudo chmod 777 interface.bin
      • 执行下载命令:tftp 0x40008000 interface.bin
      • 运行程序:go 0x40008000
    • 注意事项:
      • 下载过程中"#"表示传输进度
      • 超时会显示"T",需检查网络连接
      • 下载完成后会显示传输字节数

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

Uboot网络通信支持

Uboot环境变量包含网络相关配置(如IP address、server IP),说明其内置网络协议支持

区分环境变量作用(IP address为开发板IP,server IP为服务器IP)

⭐⭐

TFTP协议原理

轻量级文件传输协议,用于开发板与服务器(如Ubuntu)间文件传输

需明确服务器需安装TFTP服务端,开发板通过Uboot内置客户端下载

⭐⭐⭐

TFTP命令使用

格式:tftp <内存地址> <文件名>(如tftp 0x41000 interface.bin)

省略server IP时默认使用环境变量中的server IP值

⭐⭐⭐⭐

网络配置前提

1. 开发板与服务器需直连网线; 2. 确保Ubuntu桥接模式且选择有线网卡; 3. 关闭Windows防火墙

常见错误:桥接模式选错网卡或未关闭防火墙

⭐⭐⭐⭐⭐

TFTP服务器配置

1. Ubuntu安装tftpd-hpa服务; 2. 文件需放入/tftpboot目录并设置权限为777

每次重启需手动重启服务:sudo service tftpd-hpa restart

⭐⭐⭐

故障排查步骤

1. ping测试网络连通性; 2. 检查环境变量server IP一致性; 3. 验证文件权限及服务状态

超时问题多因网络配置或服务未启动

⭐⭐⭐⭐

TFTP与Loadb对比

TFTP:基于网卡,速度快; Loadb:基于串口,速度慢

优先使用TFTP传输大文件

⭐⭐

九、uboot的使用

1. 存储器访问命令

1)mmc read

  • 功能:将EMMC中指定扇区的内容读取到内存指定地址
  • 命令格式:mmc read <addr> <blk#> <cnt>
    • addr:内存目标地址
    • blk#:EMMC起始扇区编号(1扇区=512字节)
    • cnt:读取的扇区数量
  • 应用场景:系统移植时加载存储在EMMC中的程序到内存运行
  • 操作示例:mmc read 0x40008000 0x800 0x1表示从EMMC的0x800扇区读取1个扇区数据到内存0x40008000地址

2)mmc write



  • 功能:将内存指定地址的内容写入EMMC指定扇区
  • 命令格式:mmc write <addr> <blk#> <cnt>
    • addr:内存源地址
    • blk#:EMMC目标起始扇区编号
    • cnt:写入的扇区数量
  • 设备选择:第一个参数0表示EMMC,1表示SD卡
  • 实际应用:
    • 写入前需通过tftp将文件下载到内存(如tftp 41000000 interface.bin)
    • 典型命令:mmc write 0x41000000 0x800 0x1将内存0x41000000的1个扇区数据写入EMMC的0x800扇区
  • 验证方法:断电重启后使用mmc read重新读取验证数据完整性
3)命令组合使用
  • 完整工作流:
    • 通过tftp下载文件到内存
    • 使用mmc write写入EMMC
    • 断电验证持久化存储
    • 上电后使用mmc read加载到内存
    • 通过go命令执行程序
  • 系统移植应用:
    • 安装Linux系统时写入EMMC
    • 系统启动时从EMMC加载到内存
  • 注意事项:
    • 文件小于512字节仍需写入完整1个扇区
    • 重要数据建议写入后立即验证读取

2. 自启动环境变量

1)bootcmd

bootcmd作用演示

bootcmd自动执行演示:

  • 定义:bootcmd是uboot中一个重要的自启动环境变量,不是命令而是环境变量
  • 功能:可以设置1到多个uboot命令的集合(多个命令用

    \textbackslash;\textbackslash;\textbackslash;

    分隔)
  • 执行机制:在自启动模式下,uboot会按bootcmd中命令的顺序逐条执行
  • 典型应用:常用于设置自动下载和执行程序的命令序列
    • 典型应用场景:
      • 自动下载并执行程序:setenv bootcmd tftp 40008000 interface.bin$\textbackslash;$go 40008000
      • 自动从eMMC读取并执行:setenv bootcmd mmc read 0 0x40008000 0x800 0x1$\textbackslash;$go 40008000
    • 优势:实现开发板上电后自动完成程序加载和执行,无需人工干预
    • 系统级应用:
      • 可扩展用于自动加载和启动Linux系统
      • 典型流程:加载内核→加载设备树→加载文件系统→启动内核
    • 重要性:是系统移植和启动流程中的核心配置项
    • 注意事项:
      • 命令顺序必须符合执行逻辑
      • 各命令参数需要根据实际硬件配置调整
      • 错误配置可能导致系统无法正常启动

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

MMC命令

用于读写外部存储器(如SD卡、eMMC)的命令集合,包含子命令(mmc read/mmc write/mmc erase等)

参数含义:addr(内存地址)、block(存储块起始编号)、cnt(块数量)

⭐⭐⭐

mmc read

从外存读取数据到内存,示例:mmc read 0x40008000 0x800 0x1(从eMMC的0x800块读1块到内存0x40008000)

易混淆点:第一个参数是目标内存地址,第二个是外存块编号

⭐⭐

mmc write

将内存数据写入外存,示例:mmc write 0x40008000 0x800 0x1(将内存0x40008000的数据写入eMMC的0x800块)

关键操作:需先通过tftp下载文件到内存再写入外存

⭐⭐⭐⭐

bootcmd环境变量

自启动命令集合,Uboot倒计时结束后自动执行其包含的命令(如tftp下载+go执行)

语法规则:多条命令用\;分隔,如setenv bootcmd "tftp 0x40008000 test.bin\; go 0x40008000"

⭐⭐⭐⭐

eMMC与SD卡操作

通过mmc命令的编号区分设备(如0为eMMC,1为SD卡)

易错点:设备编号需与硬件实际连接匹配

⭐⭐

Uboot命令链

结合tftp+mmc write+mmc read+go实现程序固化与自启动

典型流程:下载→写入eMMC→重启后读取→执行

⭐⭐⭐⭐

十、通过tftp加载内核和根文件系统

1. 内核的安装与加载

1)通过tftp加载内核和根文件系统

  • Linux内核镜像

    • 核心文件:包含两个关键文件
      • uImage:Linux系统的内核镜像文件,大小为2.87MB(3,019,120字节)
      • exynos4412-fs4412.dtb:设备树文件,大小为34KB
    • 内核镜像特性

      • 轻量级优势:
        • 嵌入式领域选择Linux的主要原因之一是其轻量级特性
        • 相比安卓/Windows等大型系统,Linux内核仅2.87MB,适合资源有限的嵌入式设备
        • 能在低配置硬件(如性能较弱的CPU/小内存)上流畅运行
    • 设备树文件

      • 功能说明:
        • 后缀.dtb表示Device Tree Binary(设备树二进制文件)
        • Linux系统运行时必需的文件,包含硬件配置信息
        • 文件大小仅33.5KB,修改日期与内核镜像同步(2021/4/6)
    • 文件部署流程
      • 操作步骤:
        • 进入Ubuntu的TFTP工作目录:/tftpboot
        • 使用sudo mv命令移动两个文件到目标目录
        • 验证结果:通过ls命令确认uImage和.dtb文件存在
      • 注意事项:
        • 需要root权限操作(使用sudo)
        • 文件路径需完整指定(含文件名和扩展名)
  • 根文件系统镜像
    • 文件准备与权限修改

      • 文件拷贝要求:
        • 需将Linux内核镜像目录下的"uImage"和"exynos4412-fs4412.dtb"拷贝至ubuntu的tftp工作目录
        • 需将根文件系统镜像目录下的"ramdisk"同样拷贝至tftp工作目录
      • 权限修改:

        • 执行命令:$sudo chmod 777 /tftpboot/*
        • 原因:保证后续实验顺利,避免因权限不足导致下载失败
        • 注意:必须修改所有相关文件的权限为777(可读可写可执行)
      • 操作验证:
        • 使用ls命令确认目录下存在三个关键文件:
          • exynos4412-fs4412.dtb
          • ramdisk.img
          • uImage
    • TFTP服务器重启
      
      • 重启命令:
        • $sudo service tftpd-hpa restart
      • 注意事项:
        • 每次重启Ubuntu后都必须重新启动TFTP服务
        • 必须确保网络配置正确,桥接模式需连接到有线网卡
        • 验证方法:检查虚拟机网络设置是否桥接到"Realtek PCIe GBE Family Controller"
    • 开发板与电脑连接
      • 硬件连接要求:
        • 必须使用串口线和网线直连开发板与电脑
        • 禁止通过路由器连接,必须直连
        • 网线另一端必须连接电脑网口
      • 交互模式进入:
        • 连接后需进入uboot交互模式
        • 使用SecureCRT等工具通过串口连接(如COM4)
    • uboot启动参数设置
      ​​​​​​​

      • IP地址设置:
        • 命令:# setenv ipaddr ***.***.***.***
        • 关键要求:必须与Ubuntu服务器在同一网段
        • 验证方法:在Ubuntu执行ifconfig查看IP(如192.168.1.200)
      • 服务器IP设置:

        • 命令:# setenv serverip xxx.xxx.xxx.xxx
        • 必须设置为Ubuntu的IP地址(如192.168.1.200)
        • 验证命令:printenv查看当前uboot参数
      • 自启动环境变量:
        • 命令:# setenv bootcmd tftp 0x41000000 uImage;tftp 0x42000000 exynos4412-fs4412.dtb;tftp 0x43000000 ramdisk.img;bootm 0x41000000 0x43000000 0x42000000
        • 内存地址分配:
          • 0x41000000:内核镜像(uImage)
          • 0x42000000:设备树文件(dtb)
          • 0x43000000:根文件系统(ramdisk)
        • 执行顺序:先下载三个文件到指定内存地址,再通过bootm命令启动
  • 应用案例
    • 设置bootcmd命令

      • 启动目标:通过uboot将Linux内核镜像、设备树文件和根文件系统从Ubuntu的TFTP服务器加载到开发板内存并运行
      • 关键文件:
        • uImage:Linux内核镜像
        • exynos4412-fs4412.dtb:设备树文件
        • ramdisk.img:根文件系统镜像
      • 内存地址规划:
        • 0x41000000:存放Linux内核镜像(uImage)
        • 0x42000000:存放设备树文件(exynos4412-fs4412.dtb)
        • 0x43000000:存放根文件系统(ramdisk.img)
      • 地址选择原则:
        • 必须位于物理内存范围内(0x40000000-0x80000000)
        • 各文件地址间隔16MB空间(0x42000000-0x41000000=16MB)
        • 实际文件大小验证:
          • uImage:2.9MB
          • exynos4412-fs4412.dtb:36KB
          • 远小于分配的16MB空间
      • 内存映射关键点:
        • 物理内存范围:0x40000000-0x80000000(共1GB)
        • 保留区域:
          • 0x40000000-0x41000000:用于uboot传参
          • 0x80000000之后:未使用空间
        • 地址分配原因:
          • 避免与uboot及其参数区域冲突
          • 保证足够的空间裕度
      • 命令结构:
    • bootm命令详解:
      • 功能:启动Linux内核并传递参数
      • 参数顺序:
        • 内核地址(必需)
        • 根文件系统地址(无则用"-")
        • 设备树地址(无则用"-")
      • 参数传递机制:告知内核各组件在内存中的位置
    • 操作步骤:
      • 设置bootcmd环境变量
      • 使用saveenv保存配置
      • 开发板重启后自动执行
    • 注意事项:
      • TFTP服务器需提前配置好文件
      • 地址必须使用十六进制格式
      • 各命令间用分号分隔
      • 最后需要执行bootm启动内核
    • 内存布局验证:
      • 0x41000000-0x42000000:16MB空间存放2.9MB的uImage
      • 0x42000000-0x43000000:16MB空间存放36KB的dtb文件
      • 0x43000000-0x44000000:16MB空间存放根文件系统
    • 冲突避免:
      • 各文件有独立地址空间
      • 与uboot参数区无重叠
      • 预留足够空间裕度
  • 设置自启动参数bootargs
    • bootargs环境变量介绍
      • 定义:bootargs是uboot中用于设置Linux系统启动参数的重要环境变量
      • 作用:告诉内核文件系统和设备树的位置,使开发板能运行Linux系统
      • 组成:包含根文件系统类型、网络文件系统路径、控制台设置等多项参数
    • 设置bootargs参数

      • 基本命令:setenv bootargs <参数列表>
      • 参数格式:
        • root=/dev/nfs:指定根文件系统类型为NFS
        • nfsroot=<服务器IP>:<路径>:设置NFS服务器地址和工作目录
        • rw:设置文件系统可读写权限
        • console=ttySAC2,115200:指定控制台使用串口2,波特率115200
        • init=/linuxrc:指定init进程位置
        • ip=<开发板IP>:设置Linux启动后的IP地址
    • bootargs参数详解
      • 服务器IP:必须填写Ubuntu虚拟机的实际IP地址(如192.168.1.200)
      • NFS路径:需对应Ubuntu中NFS服务的工作目录(如/opt/4412/rootfs)
      • 开发板IP:必须与服务器在同一网段(如192.168.1.100)
      • 保存设置:使用saveenv命令将参数永久保存到MMC中
      • 验证方法:通过printenv命令检查bootargs参数是否设置正确
      • 注意事项:
        • 路径和IP地址需根据实际环境调整
        • 参数之间用空格分隔
        • 大小写敏感(如ttySAC2必须大写)
        • 设置完成后必须执行保存操作

2、实验后检查

1) 检查网络设置

  • 关键步骤:
    • 使用网线连接开发板与电脑
    • 给开发板重新上电
    • 观察uboot是否能通过tftp加载和启动内核
    • 检查启动时是否能挂载根文件系统(ext2)
    • 启动完成后在终端输入linux shell命令测试功能
  • 注意事项:
    • TFTP服务必须重启确保可用
    • 需要验证IP地址设置正确性(包括server IP)
    • 网络不通时可先执行ping命令测试连通性

2)重启开发板

  • 环境变量:
    • bootargs=console=ttySAC2,115200 init=/linuxrc ip=192.168.1.100
    • bootcmd=tftp 0x41000000 uImage;tftp 0x42000000 exynos4412-fs4412.dtb;tftp 0x43000000 ramdisk.img;bootm 0x41000000 0x43000000 0x42000000
    • ethaddr=11:22:33:44:55:66
  • 硬件信息:
    • CPU: Exynos4412@1000MHz
    • DRAM: 1 GiB
    • MMC容量: 14910 MB

3)下载文件与启动内核



  • 下载流程:
    • 下载uImage内核镜像到0x41000000地址(3019120字节,约2.9MiB)
    • 下载设备树文件exynos4412-fs4412.dtb到0x42000000地址(34358字节)
    • 下载ramdisk.img根文件系统到0x43000000地址(2544147字节,约2.4MiB)
  • 传输速率:
    • uImage下载速度:98.6 KiB/s
    • 设备树文件下载速度:332 KiB/s
    • 根文件系统下载速度:676.8 KiB/s

4) 开发板启动流程回顾



  • 启动阶段:
    • BL0阶段:
      • 运行三星固化的iROM程序
      • 检测拨码开关状态(当前为SD卡启动模式)
      • 将SD卡第一个扇区的uboot搬移到内存
    • Uboot阶段:
      • 初始化软硬件环境
      • 打印版本信息(U-Boot 2013.01)
      • 显示CPU型号和频率(Exynos4412@1000MHz)
      • 显示内存信息(DRAM: 1 GiB)
    • 内核加载:
      • 执行bootcmd中的四条命令
      • 通过TFTP协议依次下载三个必要文件
      • 使用bootm命令启动内核(0x41000000)
  • 校验过程:
    • 对下载的每个文件进行校验和验证
    • 显示各文件的加载地址和入口点
    • 内核启动后显示版本信息(Linux version 3.14.0)

3、开发板启动过程

1) Linux内核启动

  • 启动阶段划分:
    • uboot阶段:在"Starting kernel..."打印前由uboot执行,负责加载内核镜像、设备树和ramdisk
    • 内核阶段:启动信息显示Linux版本为3.14.0,基于ARMv7架构的Exynos4412处理器
  • 关键初始化过程:
    • CPU识别:检测到ARMv7四核处理器(CPU0-CPU3),主频1GHz
    • 内存管理:总内存256528页,采用zone内存分配策略
    • 设备树加载:从地址0x42000000加载扁平设备树(FDT)
    • 命令行参数:包含NFS根文件系统挂载参数root=/dev/nfs nfsroot=192.168.1.200:/opt/4412/rootfs
  • 驱动加载:
    • 串口驱动:注册ttySAC0-3四个串口设备
    • USB驱动:EHCI主机控制器初始化完成
    • 网络协议栈:TCP/IP协议族注册,包含TCP cubic拥塞控制算法
  • 根文件系统挂载:最终通过VFS挂载ext2格式的根文件系统,完成启动流程

2) 执行Linux命令

  • 基本操作验证:
    • 目录浏览:ls命令显示标准Linux目录结构(/bin, /etc, /dev等)
    • 文件操作:支持touch test.txt创建文件,cd切换目录
    • 命令提示符:显示为[root@farsight]#,表示root用户登录
  • 终端优化:
    • 通过session option调整终端配色方案,使目录(蓝色)与文件(白色)区分更明显
    • 支持标准Linux命令如cat、echo等busybox精简版工具
  • 典型目录内容:
    • /bin:包含基础命令如ash、busybox、ls等
    • /dev:设备文件目录
    • /proc:内核与进程信息虚拟文件系统
    • 注意:由于使用NFS根文件系统,实际存储位于服务器192.168.1.200的/opt/4412/rootfs路径

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

Uboot环境变量

boot cmd自启动环境变量的作用与设置方法

环境变量设置格式与内存地址计算

⭐⭐⭐⭐

Linux内核加载

通过TFTP协议加载uImage内核镜像到0x41000地址

内存空间分配计算与冲突避免

⭐⭐⭐⭐

设备树加载

EXYNOS4412-fs4412.dtb设备树文件加载到0x42000地址

设备树文件大小校验(36KB)

⭐⭐⭐

根文件系统加载

RAMDISK镜像加载到0x43000地址

NFS工作目录配置要求

⭐⭐⭐⭐

bootm命令

启动参数格式:bootm <内核地址> <根文件系统地址> <设备树地址>

参数顺序不可颠倒

⭐⭐⭐⭐⭐

内存映射

4412芯片内存分布(0x40000000-0x80000000)

实际可用内存1GB与地址空间规划

⭐⭐⭐⭐

启动流程

BL0→Uboot→Linux内核的完整启动链条

Start Kernel标志位识别

⭐⭐⭐⭐

文件权限设置

chmod 777确保TFTP传输权限

服务器文件权限配置要点

⭐⭐

网络配置

开发板IP(192.168.1.100)与服务器IP(192.168.1.200)同网段验证

直连网线要求

⭐⭐⭐

实验验证

成功启动后Linux命令行操作验证

控制台主题设置技巧

⭐⭐

十一、通过EMMC加载内核和根文件系统

1. 给开发板上电并下载镜像

1)开发板上电与镜像下载

  • 操作步骤:
    • 给开发板重新上电
    • 在uboot交互模式下进行操作
    • 下载并安装镜像文件到EMMC存储器
  • 注意事项:
    • 需要连接网线和串口线
    • 确保网络连接正常

2)TFTP命令下载内核镜像

  • 命令格式:tftp <内存地址> <文件名>
    • 示例:tftp 0x41000000 uImage
  • 功能说明:
    • 从Ubuntu系统下载Linux内核镜像(uImage)到开发板内存
    • 内存地址0x41000000为镜像加载位置
  • 执行过程:
    • 网络传输速度约为314.5 KiB/s
    • 传输完成后显示字节数:3019120 (2e1170 hex)

3)MMC命令写入内核镜像



  • 命令格式:mmc write <设备号> <内存地址> <EMMC块号> <块数>
    • 示例:mmc write 0 0x41000000 0x800 0x1734
  • 参数说明:
    • 设备号0表示EMMC存储器
    • 内存地址0x41000000存放下载的uImage
    • EMMC块号0x800(2048)为写入起始位置
    • 块数0x1734(5940)为需要写入的块数
  • 存储布局:
    • 前2048块保留给uboot
    • 内核镜像从2048块开始存储

4)计算内核镜像占用块数

  • 计算方法:
    • 使用du -mh uImage查看镜像大小为2.9MB
    • 转换为字节数:

      2.9×1024×1024=3040870.42.9 \times 1024 \times 1024 = 3040870.42.9×1024×1024=3040870.4

      字节
    • 计算块数:

      3040870.4÷512≈59403040870.4 \div 512 \approx 59403040870.4÷512≈5940

    • 转换为十六进制:5940 = 0x1734
  • 注意事项:
    • EMMC是块设备,每次操作以512字节为一块
    • uboot命令默认使用十六进制数值
    • 计算时要留出足够空间避免覆盖其他数据

2. 计算所占空间并写入EMMC

1)将内核镜像写入EMMC



  • 内存地址分配:内核镜像下载到内存地址

    0x41000000,该地址后续会被设备树覆盖但不会影响安装过程

  • 空间计算:
    • 内核镜像大小2.9MB(3019120字节)
    • EMMC块大小512字节,共需5896.71875块(约0x1700块)
  • 写入命令:
    • 从EMMC块0x800开始写入0x2000块(足够存放内核)
  • 空间占用:0x800到0x2800块区域存放uImage

2)下载设备树到内存

  • 下载命令:
  • 特性说明:
    • 设备树文件较小(36KB)
    • 会覆盖内存中原有内核镜像,但因已完成安装不影响后续操作
  • 空间计算:
    • 实际大小34358字节(0x8636)
    • 需72块(十进制),换算十六进制为0x48块

3)将设备树写入EMMC

  • 写入位置选择:必须避开内核镜像区域(0x2800之后)
  • 写入命令:
  • 实际占用:
    • 起始块:0x2800
    • 结束块:0x3000
    • 实际只需0x48块,0x800为预留空间

4)下载根文件系统镜像到内存



  • 镜像特性:
    • 文件名为ramdisk.img
    • 大小2.5MB(2544147字节)
  • 下载命令:

5)将根文件系统镜像写入EMMC

  • 写入位置:0x3000块开始
  • 写入命令:
  • 空间分配:
    • 实际需要约0x1300块
    • 分配0x2000块(到0x5000)留有充足余量
  • 完整布局:
    • 0x0000−0x0800:保留区(可后续存放uboot)

    • 0x0800−0x2800:内核镜像

    • 0x2800−0x3000:设备树

    • 0x3000−0x5000:根文件系统

3. 修改uboot启动参数

1)修改uboot启动参数的原因

  • 启动方式变更: 从原先通过TFTP从服务器下载镜像改为从EMMC本地加载镜像,提高启动效率
  • 参数保存问题: 原设置可能因命令过长导致保存失败,需要调整格式

2)设置环境变量bootcmd

  • 命令结构: 使用setenv bootcmd命令设置自启动环境变量
  • 格式注意: 当命令过长时,建议用单引号将整个值括起来,如'mmc read...'
  • 参数保存: 设置完成后必须执行saveenv保存参数

3)从EMMC加载Linux内核

  • 命令格式: mmc read 0 0x41000000 0x800 0x2000
  • 参数说明:
    • 0: 表示EMMC设备号
    • 0x41000000: 目标内存地址
    • 0x800: 源扇区号(对应EMMC中的0x800扇区)
    • 0x2000: 读取块数(与写入时保持一致)

4)从EMMC加载设备树

  • 命令格式: mmc read 0 0x42000000 0x2800 0x800
  • 关键参数:
    • 0x42000000: 设备树内存地址(与内核地址区分)
    • 0x2800: 设备树在EMMC中的存储位置
    • 0x800: 设备树占用的块数

5)从EMMC加载根文件系统

  • 命令格式: mmc read 0 0x43000000 0x3000 0x2000
  • 地址分配:
    • 0x43000000: 根文件系统专用内存地址
    • 0x3000: 文件系统在EMMC中的起始扇区
    • 0x2000: 文件系统大小(与写入时一致)

6)启动Linux内核

  • 启动命令: bootm 0x41000000 0x43000000 0x42000000
  • 参数顺序:
    • 内核镜像地址(0x41000000)
    • 根文件系统地址(0x43000000)
    • 设备树地址(0x42000000)

7)保存设置

  • 保存方法: 执行saveenv命令
  • 常见问题: 当命令过长时保存可能失败
  • 解决方案:
    • 使用单引号包裹整个命令字符串
    • 通过文本编辑器整理格式后再粘贴
    • 确认保存后使用printenv检查设置

4. 开发板启动过程

1)EMMC加载Linux内核及rootfs

  • 启动方式:通过EMMC存储介质加载Linux内核镜像、设备树和文件系统
  • 启动命令:
    • mmc read 0 0x41000000 0x800 0x2000:将uImage从EMMC读到内存
    • mmc read 0 0x42000000 0x2800 0x800:将设备树从EMMC读到内存
    • mmc read 0 0x43000000 0x3000 0x2000:将文件系统从EMMC读到内存
    • bootm 0x41000000 0x43000000 0x42000000:启动内核

2)启动流程详解

  • 内核加载:
    • 读取Linux-3.14.0内核镜像,大小2.9MiB
    • 加载地址:0x40008000
    • 校验和验证通过
  • ramdisk加载:
    • 读取压缩的ramdisk镜像,大小2.4MiB
    • 加载地址:0x00000000
  • 设备树加载:
    • 使用FDT(Flattened Device Tree) blob
    • 地址:0x42000000

3)内核启动过程

  • CPU初始化:
    • 检测到4个ARMv7处理器核心
    • 主频1000MHz
    • 采用SMP对称多处理架构
  • 内存管理:
    • 总内存:1GiB
    • 可用内存:1014372K/1032192K
  • 设备初始化:
    • 检测到USB 2.0控制器
    • 初始化dm9000网卡
    • 挂载ext2文件系统

4)网络配置参数

  • 网络设置:
    • ipaddr=192.168.1.100
    • netmask=255.255.255.0
    • gatewayip=192.168.1.1
    • serverip=192.168.1.200
  • 启动参数:
    • bootargs=root=/dev/nfs nfsroot=192.168.1.200:/opt/4412/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.1.100
    • bootdelay=5:自动启动倒计时5秒

5)两种启动方式对比

  • 网络启动:
    • 适用于开发调试阶段
    • 依赖网络环境
    • 便于快速更新内核和文件系统
  • EMMC启动:
    • 适用于产品发布阶段
    • 从本地存储加载
    • 启动更稳定可靠
    • 是项目定型的标准做法

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

Linux系统加载方式

通过TFTP从服务器加载内核镜像、设备树、根文件系统到开发板内存

需配置TFTP服务器路径,依赖网络环境

⭐⭐⭐

EMMC本地加载方案

将内核镜像、设备树、根文件系统写入EMMC指定扇区,启动时通过mmc read加载到内存

扇区地址计算(如0x800起始存内核)、块大小换算(需按512字节/块转换)

⭐⭐⭐⭐

Uboot命令操作

tftp下载文件到内存 → mmc write写入EMMC → mmc read读取到内存 → bootm启动内核

地址冲突风险(如多次使用0x410000需覆盖前次内容)

⭐⭐⭐

开发板存储布局

EMMC分区规划:0x000-0x800预留 → 0x800-0x2800内核 → 0x2800-0x3000设备树 → 0x3000-0x5000根文件系统

空间预留逻辑(避免覆盖uboot或后续扩展区域)

⭐⭐⭐⭐

产品化部署要点

脱离网络依赖,所有系统文件固化到EMMC,确保断电不丢失

扇区分配合理性(需兼容未来升级)

⭐⭐⭐⭐

十二、通过tftp加载内核通过nfs挂载根文件系统

1. 根文件系统镜像目录复制解压

1)NFS挂载准备工作

  • 文件选择:使用rootfs.tar而非ramdisk.img进行NFS共享,因为前者是原始文件集合,后者是单个镜像文件
  • 目录配置:NFS工作目录已预先配置为/opt/4412/rootfs(实验三中完成)
  • 文件差异:
    • ramdisk.img:适用于直接烧写到EMMC或加载到内存的镜像文件
    • rootfs.tar:包含原始文件结构的压缩包,更适合NFS共享

2)文件系统部署步骤

  • 文件拷贝:
    • 必须使用sudo权限操作根目录下的文件
    • 源文件路径根据VMware共享文件夹位置可能变化
  • 解压操作:
    • 解压过程相当于在根目录创建新文件,需要管理员权限
    • 解压后生成完整的Linux目录结构(bin、sbin、etc等)
  • 清理操作:
    • 压缩包删除为可选操作,不影响系统运行
    • 保留压缩包可节省后续重新部署时间

3)U-Boot参数配置

  • 启动命令:
    • 通过TFTP协议加载内核(uImage)和设备树(.dtb)
    • 0x41000000和0x42000000为内存加载地址
  • 参数保存:
    • 必须执行保存操作使配置永久生效
    • 开发板重启后会保持这些启动参数

2. 修改uboot的启动参数

1)修改启动参数的原因



  • 变更需求:由于系统启动方式发生改变,原启动参数不再适用,需要重新配置
  • 参数作用:bootcmd参数控制uboot的自动启动流程,需要与当前NFS挂载方式匹配

2)连接串口线

  • 连接方式:通过COM4串口线连接开发板
  • 交互准备:连接后需等待进入uboot交互模式

3)打印环境变量

  • 查看命令:使用printenv命令显示当前环境变量
  • 关键参数:
    • bootcmd=tftp 0x41000000 uImage;tftp 0x42000000 exynos4412-fs4412.dtb;bootm 0x41000000-0x42000000
    • bootargs=root=/dev/nfs nfsroot=192.168.1.200:/opt/4412/rootfs rw console=ttySAC2,115200 init=/linux

4)设置新的启动参数

  • 设置命令:
  • 参数说明:
    • 0x41000000:Linux内核镜像加载地址
    • 0x42000000:设备树文件加载地址
    • -:表示根文件系统不存储在内存中
  • 保存操作:执行saveenv命令永久保存新参数
  • 注意事项:
    • 参数中的"-"两边必须有空格
    • 不再需要下载根文件系统镜像到开发板

3. 重启nfs服务器

  • 重启命令:sudo service nfs-kernel-server restart
  • 验证方法:显示四个"OK"表示重启成功
  • 必要性:每次Ubuntu重启后都需要执行此操作以确保NFS服务可用

4. 给开发板通电观察内核启动和挂载情况

1)通过tftp加载内核与设备树



  • 启动流程:
    • 开发板上电后通过TFTP协议从服务器(192.168.1.200)加载uImage内核文件到内存地址0x41000000
    • 同时加载设备树文件exynos4412-fs4412.dtb到0x42000000地址
    • 传输速度达到322.3 KiB/s,完成3019120字节(约2.9MB)的传输
  • 关键参数:
    • 开发板IP:192.168.1.100
    • 服务器IP:192.168.1.200
    • 内核加载地址:0x41000000
    • 设备树加载地址:0x42000000

2)nfs挂载根文件系统

  • 挂载过程:
    • 内核启动后通过NFS协议挂载位于192.168.1.200:/opt/4412/rootfs的根文件系统
    • 挂载成功后显示"VFS: Mounted root (nfs filesystem) on device 0:10"
    • 释放未使用的内核内存228K
  • 文件系统特点:
    • 文件实际存储在Ubuntu主机,开发板通过网络访问
    • 在Ubuntu创建/删除文件会实时反映在开发板(如test.c文件)
    • 开发板执行命令如ls可直接看到共享目录内容
  • 验证方法:
    • 在Ubuntu的/opt/4412/rootfs目录下创建文件
    • 开发板立即可见并可操作该文件
    • 删除操作也会双向同步

3)交叉编译与程序执行

  • 编译差异:
    • Ubuntu默认gcc生成x86架构可执行文件(Intel 80386)
    • 开发板需要arm-none-linux-gnueabi-gcc生成ARM架构可执行文件
  • 执行验证:
    • x86程序在开发板报"Exec format error"
    • ARM程序在开发板可正常输出"Hello World"
  • 开发优势:
    • 省去每次下载程序到开发板的步骤
    • 直接通过nfs共享可执行文件
    • 保持Ubuntu的开发环境,使用交叉编译器生成目标平台程序
  • 关键命令:

5. uboot自启动参数环境变量



  • 文件准备:需将uImage内核镜像和设备树文件exynos4412-fs4412.dtb拷贝至ubuntu的tftp工作目录
  • 权限设置:执行$sudo chmod 777 /tftpboot/*修改文件权限
  • 服务器重启:通过$sudo service tftpd-hpa restart重启tftp服务

1)bootargs环境变量介绍



  • 本质属性:是uboot传递给Linux内核的启动参数集合,uboot本身并不使用这些参数
  • 核心功能:包含内核启动所需的挂载方式、文件系统路径、控制台配置等关键信息
  • 传递机制:uboot执行bootm命令时会自动将bootargs内容传递给正在启动的Linux内核

2)bootargs参数设置格式

  • 标准结构:采用参数名=参数值的键值对形式,多个参数间用空格分隔
  • 典型示例:setenv bootargs root=/dev/nfs nfsroot=192.168.1.200:/opt/4412/rootfs rw console=ttySAC2,115200
  • 参数验证:若参数设置错误会导致内核启动失败或卡死在挂载阶段

3)root参数与nfs挂载

  • 挂载方式:root=/dev/nfs指定内核通过NFS网络文件系统挂载根文件系统
  • 必要性:告知内核不使用本地存储设备,而是从网络服务器获取根文件系统
  • 错误影响:若误设为本地设备路径会导致内核找不到有效文件系统而启动失败

4)nfsroot参数与网络文件系统路径

  • 路径格式:nfsroot=<服务器IP>:<绝对路径>如nfsroot=192.168.1.200:/opt/4412/rootfs
  • 精确匹配:必须与NFS服务器实际导出路径完全一致,包括大小写和符号
  • 调试技巧:可通过在服务器执行showmount -e验证NFS共享路径是否正确

5)rw参数与文件读写权限

  • 权限控制:rw表示开发板对服务器文件具有读写权限(对应ro为只读)
  • 实际效果:允许在开发板直接修改服务器文件,如删除或创建新文件
  • 开发优势:省去重复烧写步骤,实现"修改即生效"的高效开发模式

6)console参数与串口打印



  • 设备指定:console=ttySAC2确定使用开发板的第二个串口作为控制台
  • 波特率匹配:115200必须与实际硬件连接使用的波特率严格一致
  • 调试技巧:若更改串口号(如改为ttySAC3),需同步调整物理串口线连接位置

7)ip参数与Linux启动IP

  • 地址分配:ip=192.168.1.100设置内核启动后的默认IP地址
  • 网络要求:必须与服务器IP处于同一网段且未被其他设备占用
  • 验证方法:内核启动后执行ifconfig命令可查看生效的IP配置

知识小结

知识点

核心内容

考试重点/易混淆点

难度系数

Linux系统加载方式对比

TFTP方式:将内核镜像、设备树文件、根文件系统镜像通过TFTP加载到开发板内存; eMMC方式:将系统文件安装到开发板外部存储器; TFTP+NFS方式:内核通过TFTP加载,根文件系统通过NFS网络共享

三种方式的应用场景差异: - TFTP适合开发调试阶段; - eMMC适合产品量产阶段; - TFTP+NFS是开发效率最高的方式

⭐⭐⭐

NFS网络文件系统原理

将Ubuntu中的根文件系统目录通过NFS共享给开发板,实现: - 开发板直接访问主机文件; - 实时同步修改(演示文件创建/删除双向同步); - 省去文件传输步骤

NFS服务配置要点: - 必须设置正确的服务器IP和工作目录路径; - 每次Ubuntu重启需重启nfs服务

⭐⭐

交叉编译环境

ARM架构程序开发流程: 1. 在x86主机编写代码; 2. 用arm-none-linux-gnueabi-gcc编译; 3. 直接在开发板执行

常见错误: - 使用x86编译器生成无法在ARM运行的程序; - 文件权限问题(需sudo操作)

⭐⭐⭐⭐

u-boot环境变量解析

bootargs参数详解: - root=/dev/nfs 指定NFS挂载方式; - nfsroot=192.168.1.200:/opt/4412/rootfs 设置服务器路径; - console=ttySAC2,115200 指定调试串口; - ip=192.168.1.100 设置开发板IP

参数错误会导致: - 内核启动失败; - 文件系统挂载异常; - 串口无输出

⭐⭐⭐⭐

开发效率优化

TFTP+NFS方案优势: - 避免频繁刷写eMMC; - 代码修改实时生效; - 支持完整的Linux系统调用; - 可直接运行主机编译的程序(需交叉编译)

典型应用场景: - 驱动开发; - 系统移植; - 应用调试

⭐⭐

http://www.dtcms.com/a/354197.html

相关文章:

  • 3459. 最长 V 形对角线段的长度
  • 设计模式理解
  • Nishang PowerShell工具:原理详解+使用方法+渗透实战
  • Go+Gdal 完成高性能GIS数据空间分析
  • 深度学习:常用的损失函数的使用
  • “java简单吗?”Java的“简单”与PHP的挑战:编程语言哲学-优雅草卓伊凡
  • 白话FNN、RNN、Attention和self-attention等
  • 《从有限元到深度学习:我的金属疲劳研究进阶之路》
  • 反内卷加速全产业链价值重塑 通威股份等行业龙头或率先受益
  • 基于 C# OpenCVSharp 的模板匹配检测技术方案
  • 计算机日常答疑,一起寻找问题的最优解
  • select
  • SM4加密算法
  • Karatsuba
  • 前端工程化与AI融合:构建智能化开发体系
  • 4-4.Python 数据容器 - 字典 dict(字典 dict 概述、字典的定义与调用、字典的遍历、字典的常用方法)
  • CPU 虚拟化之Cpu Models
  • 代码随想录刷题Day43
  • 时间轮定时器HashedWheelTimer
  • WSL设置静态IP
  • window程序打包
  • Libvio网站与客户端访问故障排查指南(专业版)
  • 什么是低空经济?
  • JMeter 5.3 性能测试:文件下载脚本编写与导出文件接收完整指南
  • QT鼠标事件中的QMouseEvent :e
  • 深度学习---卷积神经网络CNN
  • PLC_博图系列☞基本指令”S_ODT:分配接通延时定时器参数并启动“
  • HTML5超详细学习内容
  • 程序(进程)地址空间(1)
  • 基于MATLAB/Simulink的单机带负荷仿真系统搭建