欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 嵌入式Linux应用开发(速记版)

嵌入式Linux应用开发(速记版)

2024/10/24 15:13:02 来源:https://blog.csdn.net/qq_42190402/article/details/141496311  浏览:    关键词:嵌入式Linux应用开发(速记版)

第一章 嵌入式Linux的组成

        嵌入式Linxu系统,就相当于一套完整的PC软件系统。

        u-boot用来加载Linxu内核到内存,包括内核初始化所需的脚本和服务,内核运行所需的库

        内核运行第一个挂载的系统就是rootfs(根文件系统),根文件系统系统了根目录“/”

第二章 IMX6ULL Pro开发板基本操作

2.1 基本介绍

        MX6U芯片,ARM Cortex A7内核。

        此处仅供学习,不针对某芯片,基本操作章节仅提供类似参考。

2.1.1 开发环境

        Ubuntu开发环境,可使用搭建好开发环境的Docker系统镜像。

2.1.2 核心软件

交叉编译工具链,arrch64-linux-gnu-gcc,由 Linaro 公司基于 GCC 推出的的 ARM 交叉编译工具。

引导程序,uboot

linux内核,rk356x-linux,不同板子有不同的适应内核,联系厂家。

2.1.3 文件系统

        Busybox,集成了常用linux命令和工具的工具箱。

        Buildroot,嵌入式系统构建工具,可以根据配置文件自动构建交叉编译工具链内核镜像根文件系统以及各种用户空间软件包。

        Yocto,一个帮助用户定制Linux系统的开源项目。

        像交叉编译工具链`arm-buildroot-linux-gnueabihf-gcc`就是 Buildroot 提供的交叉编译工具链中的一个组件,用于在主机系统上编译针对 ARM 架构的软件。 

2.1.4 文件挂载到目录树

        使用MobaXterm软件可以通过串口打开板子的内核。进行调试、发送、接收板子的数据、查看板子的文件系统。

        开发板可以通过NFS将目录挂载到开发环境的文件系统上。

mount -t nfs -o nolock,vers=3 192.168.5.11:/home/nfs /mnt

        mount 是挂载命令。

        -t nfs 指定要挂载的文件系统类型为 nfs。

        -o 用于传递挂载选项。

        nolock 表示禁用文件锁定机制。

        vers=3 表示使用 NFS 协议的版本 3。

        ip:/home/nfs 是 NFS 服务器的 IP 地址和共享目录的路径。

        /mnt 是本地目录。

        挂载成功以后,通过板子访问/mnt和通过ubuntu访问/home/nfs其实访问的就是一个目录。

2.1.5 文件传递

                FileZilla 软件TFTP 软件可以在开发板、Ubuntu、Windos三者间互传文件。

2.2 开发环境配置

2.2.1 下载BSP

        不同开发板有不同的板级支持包(BSP)

        BSP 包含了针对该硬件平台的驱动程序引导加载程序操作系统内核配置文件系统等必要的软件组件,以便支持该硬件平台上的软件运行。

        repo工具可用于管理多个git仓库。如果BSP需要使用git下载,则需要先配置好repo工具。

        其实就是把板子支持的Linux内核下载下来了。

2.2.2 配置交叉编译工具链

        交叉编译工具链用来在ubuntu主机上编译应用程序,编译后的文件可在arm等平台运行。

        修改用户目录下的 shell 配置文件,`.bashrc`。配置环境变量。

        设置交叉编译工具主要是设置 ARCHCROSS_COMPILEPATH 三个环境变量。交叉编译工具的目标平台的架构,可执行文件路径,交叉编译工具的前缀。

//环境变量 ARCH ,用来指定目标平台的架构
export ARCH=arm  //环境变量 CROSS_COMPILE ,用来指定交叉编译工具的前缀
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-//将交叉编译工具的路径添加到环境变量PATH目录中,shell中使用可执行文件名,会在PATH中找
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin

        `.bashrc` 文件是用于配置 shell 的初始化文件,位于用户的主目录下(`~/.bashrc`)。

        当用户登录时或启动一个新的交互式 Bash shell 时,`.bashrc` 文件会被执行,用于设置环境变量、定义别名、配置 shell 行为等。

        如果只在命令行运行 export 来设置环境变量,则只对当前终端有效。

        测试环境变量是否配置成功,可使用 echo $变量名 来查看shell打印的内容。也可以使用工具链名 -v 来查看工具链版本号。

第三章 开发板第一个APP实验

        .c文件写好,需要编译后在ubuntu上运行,或者交叉编译后到ARM开发板上运行。

        gcc 编译后机器指令是x86的,只能在PC上运行。

        使用配置好的交叉编译工具arm-buildroot-linux-gnueabihf-gcc编译.c文件,生成可执行文件,就可以把可执行文件放到nfs挂载的文件夹下,然后板子用shell命令直接执行。

第四章 开发板第一个驱动实验

4.1 前提

        编译驱动程序之前要先编译内核。 因为驱动程序要用到内核文件。比如驱动程序中包含的头文件,#include <asm/io.h>,其中的asm是一个符号链接,指向特定架构的汇编语言头文件目录,需要在编译内核时生成

        编译驱动时用的内核和开发板上的内核要一致。开发板上运行的内核是出厂时烧录的,编译驱动时的内核和驱动运行时的内核不一致会导致问题,因此要把自己编译出来的内核放到板子上去,代替原来的内核。

        板子上的内核更换后,其他驱动也要换。因此在编译第一个驱动程序之前,要先编译内核、模块,并且放到板子上去。

4.2 编译内核

      不同开发板对应不同的厂商配置文件,位于arch/arm/configs目录。

内核编译过程
make mrproper  //清理内核源代码目录,删除生成的配置文件、编译生成的文件等临时文件
make 100ask_imx6ull_defconfig//是一个用于生成特定于 100ask 公司的 i.MX6ULL 处理器的默认配置的命令,是内核编译中的一部分。
make zImage -j4//命令会编译 Linux 内核并生成 zImage 格式的内核镜像文件,同时使用 4 个并行任务来加速编译过程。
make dtbs//命令的作用是编译设备树源文件(通常是以 `.dts` 或 `.dtsi` 后缀结尾的文件),生成设备树二进制文件(`.dtb` 文件),以便在内核启动时使用。

        编译完成后,在 arhc/arm/boot 目录下生成 zImage 内核镜像文件,在 arhc/arm/boot/dts 目录下生成设备树的二进制文件 100ask_imx6ull-14x14.dtb。

        编译得到的内核镜像和设备树文件拷贝到挂载文件夹nfs_rootfs下备用。

4.3 编译安装内核模块

4.3.1 编译内核模块

//在内核源码文件夹下执行
//编译所有内核模块的源代码,生成.ko文件保存在内核lib文件夹下
make modules

4.3.2 安装内核模块到ubuntu目录中备用

//在内核源码文件夹下执行
//make用于编译模块 modules_install安装模块到指定目录
make ARCH=arm ARCH=ARM INSTALL_MOD_PATH=/home/nfs_rootfs modules_install

tree命令可以查看目录结构,需要apt install安装。

4.4 安装内核和模块到开发板上

        将内核镜像zImage文件设备树dtb文件,和模块文件lib/module复制到挂载的文件夹下,就等于复制到了开发板上。最后重启开发板,就会自动使用新的zImage、dtb、驱动模块了。

4.5 编译led驱动

        编译驱动要使用makefile,来帮助执行shell指令。

        make 命令会直接执行目录下的Makefile文件。

        编译完成后生成led.ko。

4.6 在开发板安装驱动模块

//echo > 指令可以将字符串写入文件,用来关闭cpu状态灯,之后才能对使用驱动对其操作。(有些板子可能状态等已经关了)。
echo none > /sys/class/leds/cpu/trigger

        在开发板串口终端上执行  'insmod 模块名' 即可安装相应的驱动模块。

//安装模块
insmod 100ask_led.ko

        安装完成后使用 lsmod 查看是否安装成功。

        如果没有更新板子上的内核,会出现 Invaild paramerters错误。

         也可以使用 insmod -f 强行安装,会提示说内核被污染,但不影响使用。

4.7 执行测试程序

        驱动模块安装成功后,可以使用测试程序 ledtest 来控制 led 灯的状态。

//执行ledtest文件,控制设备/dev/100ask_led0,关闭off
[root@100ask:~]# ./ledtest /dev/100ask_led0 off

第五章 构建Bootloader、内核、文件系统

5.1 解压编译bootloader

5.1.1 Bootloader介绍

        Bootloader是在操作系统运行之前运行的一段代码,用于启动操作系统,完成操作系统必要初始化设置。

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

5.1.2 编译uboot镜像

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

//在uboot源码文件下
//恢复源代码目录到一个干净状态,以便重新开始编译过程。
make distclean
//生成一个配置文件,其中包含了适用于该开发板的默认配置选项,用于编译 Linux 内核
make mx6ull_14x14_evk_defconfig
//执行Makefile,生成u-boot-dtb.imx
make
//将mmcblk1boot0设备的只读属性设置为可写
echo 0 > /sys/block/mmcblk1boot0/force_ro//使用dd工具将u-boot-dtb.imx文件的内容写入到指定扇区
//`bs=512` 指定了每次读写的块大小为 512 字节,
//`seek=2` 表示从第三个扇区(512字节 * 2)开始写入数据。
dd if=u-boot-dtb.imx of=/dev/mmcblk1boot0 bs=512 seek=2

5.2 编译Linux Kernel模块

        Linux内核是一种开源的类Unix操作系统宏内核。Android操作系统底层也是Linux。Ubuntu属于Linux的发行版。

        使用内核及内核模块前需要将其编译,安装到ubuntu开发板。详细步骤在4.2/4.3/4.4章节。

5.3 Buildroot用法

5.3.1 Buildroot简介

        制作根文件系统有很多方法:

1、使用Busybox手工制作

        Busybox本身包含了很多linux命令。但是要编译其他程序的话需要手工下载、编译,需要依赖库,也需要手工下载、编译这些依赖库。

        极简的文件系统可以使用Busybox手工制作。

2、使用Buildroot自动制作

        Buildroot是一个自动化程度很高的系统,可以看作一组Makefile和补丁,可以在里面配置、编译内核、uboot、rootfs。在编译某些APP时,它会自动去下载源码、依赖库,自动编译程序。

        Buildroot的语法类似Makefile。

        Buildroot 运行于 Linux 平台,可以使用交叉编译工具为多个目标板构建嵌入式 Linux 平台。

        Buildroot 可以自动构建所需的交叉编译工具链,创建根文件系统,编译 Linux 内核映像,并生成引导加载程序用于目标嵌入式系统,或者它可以执行这些步骤的任何独立组合。

3、使用Yocto

        NXP、ST等公司的官方开发包使用的是Yocto,但是Yocto语法复杂,而且工程较大。不适合初学者。

什么是init系统服务?

        init系统服务是守护进程,其进程号为 1。用来产生其它所有进程。Linux 系统在引导时加载 Linux 内核后,便由 Linux 内核加载 init 程序,由 init 程序完成余下的引导过程,比如加载运行级别,加载服务,引导 Shell/图形化界面等等。

Linux内核是linux系统的核心组件,负责管理硬件并提供进程管理、文件系统、设备驱动等功能。

什么是systemv守护进程?

        System V(SysV)是一种 Unix 操作系统的版本。在 systemv 中,在内核加载后运行的第 1 个程序被称为 init系统服务(守护进程)。Init 做一些事情,其中之一就是加载一系列脚本来启动各种系统服务,例如网络,ssh 守护程序等。System V 中的运行级别描述了某些状态,例如:
        运行级别 0:暂停
        运行级别 1:单用户模式
        运行级别 6:重新启动

        SystemV有一个问题就是需要为服务的启动设置严格的优先级顺序。

        比如想在SystemV启动时运行网络文件系统(NFS)客户端,由于网络正常工作前启动NFS没有任何意义,因此必须等待网络正常工作才能启动SystemV,SystemV init的这种做法为服务的启动设置了严格的优先级顺序。每个服务都有一个优先级编号,init 会按优先级顺序启动服务。

什么是Systemd守护进程? 

        以d作为系统守护进程的后缀是Unix的惯例。

        Systemd 是 Linux 操作系统的一套中央化系统及设置管理程序(init),包括有守护进程、程序库以及应用软件。其开发目标是实现系统初始化时服务的并行启动,同时达到降低 Shell 的系统开销的效果,最终代替现在常用的 System V 与 BSD 风格的 init 程序。目前绝大多数的 Linux
发行版都已采用 systemd 代替原来的 System V。

        将 service(服务)、target(运行模式,类似于运行级别)、mount、timer、snapshot、path、socket、swap 等称为 Unit。比如,一个 auditd 服务(就是 auditd.service)就是一个Unit,一个 multi-user.target 运行模式也是一个 Unit,其中不同的服务通过 systemctl 来进行统一管理,例如重启一个 sshd 服务,需要执行 systemctl restart sshd 命令,同样的如果添加一个启动程序需要自己定义一个 service 服务才可以。

5.4 开发板使用 NFS 根文件系统

        根文件系统就是类似Windos的C盘。里面存放有必须的APP、库文件、配置文件。

        Buildroot 编译完成之后生成的 rootfs.tar.bz2,可以解压之后放到 NFS 服务器(Ubuntu服务器)上作为 NFS 文件系统供开发板使用。

        使用 NFS 根文件系统时,我们一般还会在 u-boot 使用 tftpboot 命令从 Ubuntu 或Windows 中下载内核镜像文件 zImage 和设备树文件 dtb。这时,Ubuntu 上既要配置 NFS 服务,也要配置 TFTP 服务。

        使用 NFS 根文件系统时,涉及 xImage、设备树、根文件系统rootfs。在 Uboot 中设置启动参数使用ubuntu的某个目录作为根文件系统(记得rootfs放里面)。

        开发板开机后,mobaxterm工具显示串口消息,其实是进入了Uboot界面。

        设置好 主机和开发版的IP地址,设置好 nfs文件系统所在目录,使用run netroot指令就可以运行文件系统。

 

 可以用工具烧写或更新部分系统。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com