xym-ee
  • 计算机与嵌入式开发学习
  • 1-1.编程基础
    • C 语言
      • C 中的数据
      • C 语言基础
      • 字符输入输出
      • 函数
      • 数组和指针
      • 字符串处理
      • 存储类别
      • 文件 I/O
      • 复杂数据类型
      • 位操作
      • 预处理和 C 库
    • 数据结构和算法入门
    • leetcode 刷算法题
      • 递归与栈
      • 二叉树与递归
      • 回溯问题
      • 动态规划 1
    • 基本工具和使用
      • shell
      • shell 脚本
      • vim 编辑器
      • 命令行数据整理
      • 命令行环境和配置
  • 1-2.计算机系统基础(CSAPP)
    • 1.计算机基础
    • 2.数据的表示
    • 3.加减运算
    • 4.乘除运算
    • 5.程序的表示转换和链接
    • 6.IA32指令
    • 7.过程调用
    • 10.程序的链接
  • 1-3.数字电路、计算机组成
    • 1.数字电路、virtual circuit board
    • 2.计算机组成/steam:Turing Complete
    • 3.微机原理与接口技术(8086)
  • 1-4.计算机网络
    • 1.从浏览器开始
    • 2.协议栈和网卡
    • 3.网络设备
    • 4.运营商、接入网
    • 5.服务器
    • 6.数据返回浏览器
    • socket编程
  • 1-5.操作系统
    • 0.绪论
      • 1.应用视角的操作系统
      • 2.硬件视角的操作系统
      • 3.数学视角的操作系统
      • 4.状态机模型的应用
    • 1.并发
      • 1.并发 bug 的解决思路
      • 2.互斥
      • 3.同步
      • 4.信号量
      • 5.真实并发
      • 6.调试技巧
      • 7.os kernel 实现
    • 2.虚拟化
      • 1.操作系统上的进程
      • 2.进程的地址空间
      • 3.系统调用和unix shell
      • 4.C 标准库的实现
      • 5.linux 操作系统
      • 6.可执行文件和加载
      • 7.动态链接和加载
      • 8.内核的实现
      • 9.fork 的应用
    • 3.持久化
      • 1.存储设备的原理
      • 2.输入输出设备模型
      • 3.设备驱动程序
      • 4.文件系统 API
      • 5.fat 和 unix 文件系统
      • 6.持久数据的可靠性
    • 总结
  • 2-1.嵌入式裸机开发
    • 嵌入式系统通信接口与协议
    • cortex-m 内核芯片裸机开发
    • MPU
  • 2-2.中等规模系统开发
    • LVGL 图形库
    • 裸机开发的软件框架
    • 基于 rtos 开发
  • 2-3.armv7-m架构与 rtos 原理
    • armv7-m 架构
    • rt-thread 内核实现
    • rt-thread 驱动开发
  • 3-1.linux 应用开发基础
  • 3-2.linux 镜像构建
    • uboot 使用
    • uboot 适配
    • uboot 启动分析
    • uboot 自定义命令
    • linux 内核适配
    • linux 内核启动分析
    • busybox 根文件系统构建
  • 3-3.linux 驱动开发
    • 驱动开发基础
    • sysfs
    • led 驱动
    • 设备树
    • pinctrl 和 gpio 子系统
    • 并发控制
由 GitBook 提供支持
在本页
  • 嵌入式 linux 的构成
  • 系统启动流程(imx6ull)
  • bootloader
  • linux kernel
  • root filesystem

这有帮助吗?

3-2.linux 镜像构建

上一页3-1.linux 应用开发基础下一页uboot 使用

最后更新于11个月前

这有帮助吗?

这部分的内容

  • 一个能用的 linux 系统需要什么东西?

  • bootlader

  • kernel 和 device tree

  • root filesystem

嵌入式 linux 的构成

下面列出的这些是嵌入式 linux 的主要组件

包含

  • 引导加载器

  • linux kernel

  • C 运行时库

  • 系统共享库

  • 根文件系统

系统启动流程(imx6ull)

芯片本身有 96KB ROM 和 128KB RAM,开发板上外挂了 8GB eMMC 和 512MB DDR。

芯片 ROM 里为 NXP 的 boot ROM,根据硬件数码开关的值选择刚通电时必要的动作。再完成复位的,CPU 去 0000 0000 拿指令,这里是内部 ROM 的起始地址。也即这里的代码是 XIP 执行的,此芯片的内部 ROM 是 Nor Flash。

boot ROM 里的代码要根据拨码开关的配置将持久化存储设备里更大的代码搬到 DDR 中。这部分并不需要太多代码上的东西需要关注,对使用者来说,就是拨开关的事情。

u-boot 开始运行后,后面的启动过程由 uboot 完成。

u-boot 将内核镜像 zImage 和 设备树二进制文件 .dtb 加载到 DDR 的指定位置,并给 kernel 一些参数,然后就直接跳转到内核的启动地址开始执行了。

kernel 还要执行各种初始化,如启动 MMU 等,在 arch/arm/kernel/head.s 中完成,最后执行 init/main.c 中的 start_kernel() 函数。

这里会根据 u-boot 给的参数挂载根文件系统,然后执行根文件系统里的第一个用户进程 init

bootloader

在 linux 启动前,需要一小段代码来初始化系统。这段代码与所用机器设备有很大的相关性。linux 对 bootloader 的要求很低。最低要求:

  • 配置好 DDR

  • 在正确的内存地址加载内核映像(zImage)和设备树(*.dtb)

  • (非必须)在正确的内存地址加载内存磁盘设备(initrd)

  • 设置内核的启动参数(bootargs)

通常,引导加载器会在启动内核前初始化一个串口输出调试信息。现在 u-boot 几乎已经成了 arm linux 的标准引导加载器。

uboot 体积小,功能丰富,启动快。最终用户对 uboot 运行并不感兴趣,甚至感觉不到 uboot 的存在。用户更希望程序在开机后尽快运行,因此 uboot 里只对必要的硬件做初始化就行。也就是说,如果 uboot 必须要通过网络加载 linux kernel,不得已才去初始化网卡。除非 uboot 要从磁盘或者 USB 设备中加载文件,否则不要初始化任何磁盘或 USB设备。

uboot 可以调试,他的一个重要功能是在启动阶段把信息输出到控制台(通常是一个串口,因此 uboot 需要初始化一个串口)

linux kernel

linux 内核是 linux 系统的底层软件。它负责管理硬件,运行用户态软件,并且负责系统的整体安全性和完整性。

系统调用是应用程序和Linux内核之间的基本接口,也是用户态应用程序与内核交互的唯一途径。换句话说,它是用户态和内核态之间的桥梁。严格意义来说,用户态和内核态的根本区别是,用户态应用程序不能随意访问内核态资源,从而确保了系统的安全稳定。系统调用提升了用户进程的权限。

C 运行时库会把系统调用封装的更加易用。在这些封装函数中,有一些函数只是比系统调用函数稍微增加了些代码(仅仅进行参数检查和参数设置),而另一些函数则添加了额外的一些功能。如纯计算的数学库。

root filesystem

根文件系统是所有文件(包括设备节点)存储的地方,这些文件以一定的文件层次结构组织在一起。通常根文件系统挂载到“/”。根文件系统包含所有的二进制文件、应用程序和数据。

根文件系统中文件夹的结构由FHS(文件系统结构标准)定义。FHS定义了很多文件类型和文件夹的名字、路径和权限。这样可以确保不同Linux发行版本的兼容性,同时允许应用程序做出预设:到哪里可以找到特定的系统文件和配置。

嵌入式 linux 体系结构
启动流程