参考资料

本篇内容主要参考 韦东山的《嵌入式Linux应用开发完全手册V5.2_IMX6ULL_Pro开发板.pdf》

具体课程见
百问网嵌入式专家-韦东山嵌入式专注于嵌入式课程及硬件研发

实践环境为百问网官方开发板
100ASK_IMX6ULL-Pro

目标系统组成

Linux系统启动流程

一个有效的根文件系统集成了
第三方和内部的所有软件组件。涉及组件的下载、提取、配置、编译和安装,并可能修复问题和调整配置文件。

  • 一个基本的根文件系统至少需要


    • 传统的目录层次结构,包括/bin、/etc、/lib、/root、/usr/bin、/usr/lib、/usr/share、/usr/sbin、/var、/sbin。
    • 一套基本实用程序,至少提供 init 程序、shell 和其他传统的 UNIX 命令行工具。这通常由 BusyBox 提供。
    • 安装在/lib 中的 C 库和相关库(线程库、数学库等)。一些配置文件,如/etc/inittab,以及初始化脚本/etc/init.d。
  • 在大多数嵌入式 Linux 系统通用的基础之上,可以添加第三方或内部组件。

几种解决方案:

  • 手动操作
  • 系统构建工具
  • 发行版或现成的文件系统

组件构建工具

  • Makefile
  • autotools
  • CMake

系统构建工具

可以使用不同的工具来自动化构建目标系统的过程,包括内核,有时还包括工具链。

  • 以正确的顺序自动下载、配置、编译和安装所有组件,有时在应用补丁修复交叉编译问题之后。
  • 已经支持大量的包,应该符合您的主要要求,并且易于扩展。
  • 构建变得可重现,这允许轻松更改某些组件的配置、升级它们、修复错误等。

常见的系统构建工具

  • Buildroot,由社区开发,
    https://buildroot.org


    • 项目主要特点


      • 制作启动映像
      • 从源代码构建所有组件
      • 注重简单
    • 支持:根文件系统映像、内核、引导加载程序、工具链的自由组合

  • OpenWRT,最初是无线路由器 Buildroot 的一个分支,现在是一个更通用的项目,
    https://openwrt.org

  • OpenEmbedded,更灵活但也更复杂,
    http://www.openembedded.org
    及其工业化版本 Yocto 项目。

发行版Linux系统

Linux系统

  • 一种自由和开放源码的类UNIX操作系统,内核创建于1991-10-5,加上用户空间和应用程序之后成为Linux系统。

  • 遵循 GNU通用公共许可证(GPL),任何个人和机构都可以自由使用,修改和再发布。


    • GNU 是一个自由的操作系统,其内容软件完全以GPL方式发布(编译套件 GCC,C库 glibc,核心工具组 coreutils,调试器 GDB等)

发行版Linux
:Linux distribution(GNU/Linux 发行版,为一般用户预先集成好Linux操作系统和各种应用软件,以软件包管理系统进行应用管理)

  • 商业发行版本:Ubuntu(支持x86,arm等不同的处理器架构),Red Hat(主要支持x86),SUSE
  • 社区发行版本:Debain,Fedora, Arch
  • 国内衍生Linux发行版本:Deepin,优麒麟

嵌入式Linux系统

嵌入式Linux系统框架

嵌入式Linux系统构建

开发环境搭建

基础软件安装

百问网提供了 Ubuntu 配置命令脚本,支持一键下载安装

git clone https://e.coding.net/weidongshan/DevelopmentEnvConf.git

cd DevelopmentEnvConf

sudo ./Configuring_ubuntu.sh

配置交叉编译工具链

工具链:一组编程工具,用于开发软件,创建软件产品。包括编译器和链接器,C库,调试器,头文件,二进制实用程序等等

交叉编译工具链:一组工具,用来将源代码构建为可以运行在其他平台的二进制代码,将构建环境和目标环境分隔开(不同的CPU架构,ABI,OS,Clib)

SDK(software development kit):一个更广泛的集合,除了工具链外,还包括为 Target 目标架构构建的库、头文件,以及示例代码、文档、开发指南等资源。

交叉编译构建过程:

  • Build(构建机器),使用 GCC 的源码,制作交叉编译工具链。
  • Host(主机),使用交叉编译工具链,编译出程序。
  • Target(目标机器),程序执行的地方。

本地工具链:build == host == target。

交叉编译工具链:build == host!= target

系统定义描述了一个系统:CPU 架构、芯片厂商、操作系统、ABI、C 库。

  • <arch>-<vendor>-<os>-<libc/abi>(完整名称);
  • <arch>-<os>-<libc/abi>。

arm-foo-none-eabi
,针对 ARM 架构的裸机工具链,来自供应商 foo。

arm-unknown-linux-gnueabihf
,针对 ARM 架构的 Linux 工具链,使用来自未知供应商的 EABlhf ABI 和 glibc C 库。

armeb-linux-uclibcgnueabi
,针对 ARM big-endian 的 Linux 工具链架构,使用 EABl ABI 和 uClibc C 库。

下载100ask_imx6ull 开发板的 BSP:

git clone https://e.coding.net/codebug8/repo.git

mkdir -p 100ask_imx6ull-sdk && cd 100ask_imx6ull-sdk

../repo/repo init -u https://gitee.com/weidongshan/manifests.git -b linux-sdk -m imx6ull/100ask_imx6ull_linux4.9.88_release.xml --no-repo-verify

../repo/repo sync -j4

交叉编译工具链配置

交叉工具链的主要内容

配置过程主要是设置 PATH, ARCH 和 CROSS_COMPILE 三个环境变量:

export ARCH=arm
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
  • 永久生效:修改用户配置文件
    vim ~/.bashrc
  • 临时生效:直接执行命令,只对当前终端有效

系统构建

Bootloader: Uboot

Bootloader 是在操作系统运行之前运行的一段代码,用于引导操作系统,并支持下载和调试。

U-Boot 是一个开源的主引导加载程序,并含有多种命令以便调试系统。它适用于多种计算机体系结构,包括 ARM,RISC-V 和 x86。

不同的开发板对应不同的配置文件,配置文件位于 u-boot 源码的“configs/”目录。

对于 IMX6ULL Pro 版,u-boot 的编译过程如下(编译 uboot前必须先配置好工具链等开发环境):

cd /home/book/100ask_imx6ull-sdk/Uboot-2017.03
make distclean
make mx6ull_14x14_evk_defconfig 
make

编译完成之后生成 u-boot-dtb.imx,可以烧在 TF 卡、EMMC 上

# 将u-boot-dtb.imx 文件烧写到 EMMC 上:
echo 0 > /sys/block/mmcblk1boot0/force_ro 
dd if=u-boot-dtb.imx of=/dev/mmcblk1boot0 bs=512 seek=2 
echo 1 > /sys/block/mmcblk1boot0/force_ro

Linux Kernel 和模块

编译驱动程序之前要先编译内核:

  • 驱动程序要用到内核文件
  • 编译驱动时用的内核、开发板上运行到内核,要保持一致
  • 同理,更换板子上的内核后,板子上的其他驱动也要更换

流程说明

  1. 获取配套的交叉编译工具链


    • SOC原厂提供:NXP ST Rockchip Amlogic Allwinnertech等。
    • 社区下载:Linrao Debian ARM Bootlin
  2. 下载kernel源码


  3. Host下配置开发环境


    • 安装必要依赖包
    • 解压配置合适的工具链
  4. 指定编译板子配置文件

    make BOARDNAME_defconfig

  5. 编译


    • 编译内核镜像
      make -jN
    • 编译设备树
      make dtbs
    • 编译安装模块驱动
      make modules

编译内核

源码镜像

  • vmlinux,未压缩的原始内核映像,ELF 格式,用于调试目的,但无法启动。

  • arch/
    /boot/*image,是最终可以启动的压缩后的内核镜像文件:


    • bzImage for x86,
    • zImage for ARM,
    • Image.gz for RISC-V,
    • vmlinux.bin.gz for ARC等。
  • arch/
    /boot/Image,也可以引导的未压缩内核映像。

  • arch/
    /boot/dts/*.dtb,编译的设备树文件(某些架构)。

  • 所有内核模块,分布在内核源代码树中,作为 .ko(内核目标)文件。

配置编译环境
:指定架构和编译器,以及单板的配置文件

不同的开发板对应不同的配置文件,配置文件位于内核源码 arch/arm/configs/ 目录。

IMX6ULL_Pro开发板 kernel 的编译过程如下:

cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88
make mrproper
make 100ask_imx6ull_defconfig
make zImage -j8
make dtbs

编译完成后,在 arch/arm/boot 目录下生成 zImage 内核文件, 在 arch/arm/boot/dts 目录下生成设备树的二进制文件 100ask_imx6ull14x14.dtb

编译安装内核模块

  • 使用内核模块可以支持更多不同的设备外设。
  • 模块使无需重启即可轻松开发驱动程序:加载、测试、卸载、重建、加载...
  • 有助于将内核映像大小保持在最小(在 PC 的 GNU/Linux 发行版中必不可少)。
  • 对于减少启动时间也很有用:您无需花时间初始化稍后才需要的设备和内核功能。

注意:一旦加载,在系统中拥有完全控制权和权限。没有特别的保护。这就是为什么只有 root 用户才能加载和卸载模块。

编译:

cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
make modles

安装内核模块到Ubuntu内的某一个目录备用:

cd ~/100ask_imx6ull-sdk/Linux-4.9.88/
make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs modules_install

编译设备树

  • 目标单板所需的硬件设备信息。
  • 一般用于嵌入式设备。

设备树文件要与目标单板配套使用。一般和内核镜像存放同一位置。

内核源码目录下执行
make dtbs

安装内核和模块到开发板

mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
cp /mnt/zImage /boot
cp /mnt/100ask_imx6ull-14x14.dtb /boot
cp /mnt/lib/modules /lib -rfd

替换对应的目录中文件,重启开发板即可完成更新 zImage、dtb、模块

完整的系统

根文件系统与 busybox

Linux 系统需要一组基本的程序才能工作,包括一个 init 程序、一个 shell 以及用于文件操作和系统配置的各种基本实用程序。在普通的 GNU/Linux 系统中,这些程序由不同的项目提供。

Busybox 本身包含了很多 Linux 命令,但是要编译其他程序或者某些依赖库,需要手工下载、编译。 如果想做一个极简的文件系统,可以使用 Busybox 手工制作。

文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)

  • 数据存取


    • 使用硬盘和光盘这样的存储设备,并维护文件在设备中的物理位置
    • 通过网络协议(如 NFS、SMB 等)提供的或者暂存于内存上
    • 虚拟文件(如 proc 文件系统)
  • 用户访问管理


    • 不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名
    • 不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成

根文件系统:被挂载在特定层次结构的 root 位置,由“/”标识

  • mount 和 umount 是程序,是文件系统中的文件。所以在安装至少一个文件系统之前无法使用
  • 不能用普通的挂载命令挂载,由内核直接挂载,根据“root=”内核选项进行设置。当没有可用的根文件系统时,内核会崩溃
  • 支持从不同位置挂载,包括存储设备(硬盘,SD卡等),NFS和内存。

busybox 在根文件系统:

Buildroot

Buildroot 是一组 Makefile 和补丁,可自动化地为嵌入式系统构建完整的、可启动的 Linux 环境(包括 bootloader、Linux 内核、包含各种 APP的文件系统)。

  • 可以自动构建所需的交叉编译工具链,创建根文件系统,编译 Linux 内核映像,并生成引导加载程序用于目标嵌入式系统。并支持所有步骤的任何独立组合。
  • 使用简单:类似内核的menuconfig
  • 支持大量的实用软件包,比如 QT等

构建说明

  • 所有的构建都会输出到顶层目录下的 output/目录内。
    O = output
    。另外也支持 out-of-tree 构建。
  • 配置文件作为.config 存储在顶级 Buildroot 源目录中。
    CONFIG_DIR = $(TOPDIR),TOPDIR = $(shell pwd)

IMX6ULL_Pro 编译过程

cd ~/100ask_imx6ull-sdk/Buildroot_2020.02.x

#选择配置界面
make menuconfig

# 单独编译内核
make linux-rebuild

# 进入内核配置选项
make linux-menuconfig

# 单独编译 u-boot
make uboot-rebuild

# 单独编译某个软件包
make <pkg>-rebuild

# 进入 busybox 配置选项
make busy-box-menuconfig

# 生成系统 sdk
make sdk

配置文件说明

编译系统

cd /home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x
make clean
make 100ask_imx6ull_pro_ddr512m_systemV_qt5_defconfig
make all -j4

镜像文件说明

buildroot2020.02.x/output/images/

  • 100ask_imx6ull-14x14.dtb
    【设备树文件】
  • rootfs.ext2
  • rootfs.ext4
  • rootfs.tar
  • rootfs.tar.bz2
    【打包并压缩的根文件系统,用于NFSROOT启动】
  • 100ask-imx6ull-pro-512d-systemv-v1.img
    【完整的系统镜像,用于烧写EMMC和SD卡】
  • uboot-dtb.imx
    【Uboot镜像】
  • zImage
    【内核镜像】

系统烧录

USB 模式烧录

使用 USB 烧写工具:

使用命令行

  • 执行脚本命令


    • sudo ./bin/uuu scripts/basic/emmc/write_all.clst #烧写整个系统
  • 对于裸机程序,名字各有不同,没有提供固定的脚本


    • sudo ./bin/uuu -b emmc(or sd) firmware/u-boot-dtb_fastboot_100ask.imx files/led.imx #把 led.imx 烧到 EMMC

在开发板上直接烧写

烧写 u-boot

  • 将uboot镜像u-boot-dtb.imx拷贝到开发板根目录


    • 烧写 EMMC

      echo 0 > /sys/block/mmcblk1boot0/force_ro 					//取消此分区的只读保护 
      dd if=u-boot-dtb.imx of=/dev/mmcblk1boot0 bs=512 seek=2 	//实际烧写命令 
      echo 1 > /sys/block/mmcblk1boot0/force_ro 					//打开此分区的只读保护
      
    • 烧写 SD/TF

      dd if=u-boot-dtb.imx of=/dev/mmcblk0 bs=512 seek=2

更新内核或设备树

开发板使用的内核名为 zImage,设备树名为 100ask_imx6ull-14x14.dtb。 保存在开发板的/boot 目录中,只要替换/boot 目录下的文件后重启即可完成更新

烧写 SD/TF 卡

Windows SD/TF 卡烧录工具

格式化:

烧写镜像:

Ubuntu下使用命令行烧录 SD/TF 卡

在 Ubuntu 下可以更精细地操作 SD/TF 卡:把 sdcoard.img 整个烧写到卡上,单独烧写 u-boot 到卡上,甚至挂接卡上的文件系统后单独更新里面的文件。

  • 识别 SD/TF 卡:使用 dmesg 命令获取设备挂载的设备节点

  • 更新整个系统镜像:使用 dd 命令烧写 sdcard.img 镜像文件到 /dev/sdb 设备


    • sudo dd if=sdcard.img of=/dev/sdb
  • 只更新卡上的 u-boot:使用 dd 命令烧写 uboot的imx 镜像文件到 /dev/sdb 设备


    • sudo dd if=u-boot-dtb.imx of=/dev/sdb bs=1k seek=1 conv=fsync
  • 更新 SD/TF 卡中的内核和设备树


    • 对于曾经烧写过的 SD/TF 卡,上面已经有分区。使用 vmware 连接 TF 卡设 备后,Ubuntu 系统系统会自动挂载 tf 卡内的分区文件系统


      • 执行
        df -h
        命令找到对应目录,将其中的内核镜像拷贝到开发板 /boot 目录后重启

标签: none

添加新评论