嵌入式学习笔记(二)——嵌入式Linux开发构成之简介

2019-07-12 17:07发布

针对这两天对嵌入式Linux学习进行总结,因本人刚刚开始学习,文章内容仅供参考,对嵌入式诸多内容恐有遗漏与错误之处,烦请各位指正。 引用文章: https://www.crifan.com/files/doc/docbook/embedded_linux_dev/release/html/embedded_linux_dev.html嵌入式Linux软件开发 https://blog.csdn.net/ultraman_hs/article/details/52838989zImage和uImage的区别联系 https://blog.csdn.net/wang93it/article/details/72763538zImage与uImage的区别 https://blog.csdn.net/LEON1741/article/details/78159754浅谈linux中的根文件系统(rootfs的原理和介绍)

什么是嵌入式Linux

首先需要知道的是,嵌入式Linux不等同于桌面级或服务器版本的Linux。Linux桌面环境只是嵌入式linux的一个开发工具,开发环境。例如gcc编译器,make工具来开发我们的嵌入式linux应用程序,对于嵌入式开发工程师来说,没有必要花费那么多的精力和时间去研究linux桌面版和服务器的应用,只要能了解最基本的操作即可。 本人使用的是Win10和Ubuntu16.04双系统,有关系统安装的问题请自行百度。需要注意的是对于笔记本电脑而言,安装双系统的Ubuntu会出现一些预想不到的问题,例如分辨率显示不正常,显卡驱动难安装等,推荐使用主机安装。还有一种方式是把ubuntu系统安装在U盘里,这种方式便携性很高,但安装更加困难,有U盘传输速度限制等,不推荐。 嵌入式Linux根据百度百科的解释:
嵌入式Linux 是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。
简单来说,就是在嵌入式系统中运行的Linux系统,相比于桌面级的功能要少很多,同时体积也小许多,只为了特定功能进行定制的Linux系统。

嵌入式Linux开发环境

典型的嵌入式Linux的开发,其最基本的流程是:

1、搭建嵌入式开发环境:制作和配置交叉编译器环境

搭建环境,保证有交叉编译器可以使用,用于后续交叉编译。 交叉编译器,在百度百科中解释为
在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码
在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译,这个编译过程就叫交叉编译。简单地说,就是在一个平台上生成另一个平台上的可执行代码。举个例子,在嵌入式中,由于系统的资源有限,不能像在Windows系统中可以直接编辑代码后编译运行,而是需要在其他平台,比如说Windows平台先进行编译,再把编译好的可执行文件烧录到嵌入式系统中,这个过程就是交叉编译。

2、移植Bootloader:最典型的就是Uboot

移植uboot 修改更新uboot,在其中添加对应的功能支持,修复bug等等。 U-Boot,在百度百科中解释为
U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。U-Boot的作用是系统引导。
系统引导指的是将操作系统内核装入内存并启动系统的过程。而uboot的优点在于,他不仅仅支持Linux系统的引导支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, android嵌入式操作系统。同时,还支持多个处理器系列,如PowerPC、ARM、x86、MIPS,其他优点可自行百度。

3、移植Linux的内核kernel

移植,裁剪Linux kernel,之后再去交叉编译出所需要的uImage等系统镜像文件。 操作系统内核,在百度百科的解释为
操作系统内核是指大多数操作系统的核心部分。它由操作系统中用于管理存储器、文件、外设和系统资源的那些部分组成。操作系统内核通常运行进程,并提供进程间的通信。严格地说,内核并不是计算机系统中必要的组成部分。
操作系统(英语:Operating System,简称OS)是管理计算机硬件和软件资源的程序,同时也是计算机系统的核心与基石。而操作系统内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。 zImage和uImage的区别 linux内核源码经过编译后会生成一个elf格式的可执行程序,叫vmlinux或vmlinuz,这个是原始的未经任何处理加工的原版内核elf文件,其经过制作加工成烧录镜像的文件就叫Image(这个制作烧录镜像主要目的就是缩减大小,节省磁盘)。然而linux的作者们觉得Image还是太大了所以对Image进行了压缩,并且在image压缩后的文件的前端附加了一部分解压缩代码,构成了一个压缩格式的镜像就叫zImage。 而uImage是u-boot使用bootm命令引导的Linux压缩内核映像文件格式,是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。它是uboot专用的映像文件,它是在zImage之前加上一个长度为 64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。这使得uboot在引导内核时,就能自动找到内核的内置。 原则上uboot启动时应该给他uImage格式的内核镜像,但是实际上uboot中也可以支持zImage,是否支持就看是否定义了LINUX_ZIMAGE_MAGIC这个宏。所以大家可以看出:有些uboot是支持zImage启动的,有些则不支持。但是所有的uboot肯定都支持uImage启动。

4、制作自己的根文件系统系统(rootfs)

需要注意的是,此处所说的制作文件系统,分两大步骤:
  • 用工具制作出最基本的文件系统的文件内容
比如用BuildrootCrosstool-NG或者其他工具,制作出自己的基本的文件系统的文件内容
  • 用对应文件系统制作工具制作出文件系统镜像
再用专门的文件系统制作工具,去基于之前的文件系统的所有的文件内容,制作成对应的镜像文件。比如用Yaffs2的工具制作出Yaffs2的文件系统镜像文件。根据自己所选择的根文件系统的类型不同,选择对应的不同的工具去制作对应的根文件系统。 根文件系统,在百度百科的解释为
根文件系统首先是内核启动时所mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。
对于文件系统,其是对一个存储设备上的数据和元数据进行组织的机制。一篇oracle的技术文章中的一句话说明了其重要性
尽管内核是 Linux 的核心,但文件却是用户与操作系统交互所采用的主要工具。这对 Linux 来说尤其如此,这是因为在 UNIX 传统中,它使用文件 I/O 机制管理硬件设备和数据文件
根文件系统首先是一种文件系统,该文件系统不仅具有普通文件系统的存储数据文件的功能,但是相对于普通的文件系统,它的特殊之处在于,它是内核启动时所挂载(mount)的第一个文件系统,内核代码的映像文件保存在根文件系统中,系统引导启动程序会在根文件系统挂载之后从中把一些初始化脚本(如rcS,inittab)和服务加载到内存中去运行。根文件系统之所以在前面加一个”根“,说明它是加载其它文件系统的”根“,那么如果没有这个根,其它的文件系统也就没有办法进行加载的。 一套linux体系,只有内核本身是不能工作的,必须要rootfs(上的etc目录下的配置文件、/bin /sbin等目录下的shell命令,还有/lib目录下的库文件等···)相配合才能工作。 关于Linux各目录作用引用一篇文章中的内容进行记录以备查询:
  • 根文件系统各个常用目录简介
正常来说,根文件系统至少包括以下目录:
  1. /etc/:存储重要的配置文件。
  2. /bin/:存储常用且开机时必须用到的执行文件。
  3. /sbin/:存储着开机过程中所需的系统执行文件。
  4. /lib/:存储/bin/及/sbin/的执行文件所需的链接库,以及Linux的内核模块。
  5. /dev/:存储设备文件。
注:五大目录必须存储在根文件系统上,缺一不可。
  • linux文件系统的常用目录
Linux文件系统中一般有如下几个目录: 1、/bin目录 
该目录下存放所有用户都可以使用的、基本的命令,这些命令在挂接其它文件系统之前就可以使用,所以/bin目录必须和根文件系统在同一个分区中。 
/bin目录下常用的命令有:cat,chgrp,chmod,cp,ls,sh,kill,mount,umount,mkdir,mknod,test等,我们在利用Busybox制作根文件系统时,在生成的bin目录下,可以看到一些可执行的文件,也就是可用的一些命令。
2、/sbin 目录 
该目录下存放系统命令,即只有管理员能够使用的命令,系统命令还可以存放在/usr/sbin,/usr/local/sbin目录下,/sbin目录中存放的是基本的系统命令,它们用于启动系统,修复系统等,与/bin目录相似,在挂接其他文件系统之前就可以使用/sbin,所以/sbin目录必须和根文件系统在同一个分区中。 
/sbin目录下常用的命令有:shutdown,reboot,fdisk,fsck等,本地用户自己安装的系统命令放在/usr/local/sbin目录下。
3、/dev目录 
该目录下存放的是设备文件,设备文件是Linux中特有的文件类型,在Linux系统下,以文件的方式访问各种设备,即通过读写某个设备文件操作某个具体硬件。比如通过”dev/ttySAC0”文件可以操作串口0,通过”/dev/mtdblock1”可以访问MTD设备的第2个分区。
4、/etc目录 
该目录下存放着各种配置文件,对于PC上的Linux系统,/etc目录下的文件和目录非常多,这些目录文件是可选的,它们依赖于系统中所拥有的应用程序,依赖于这些程序是否需要配置文件。在嵌入式系统中,这些内容可以大为精减。
5、/lib目录 
该目录下存放共享库和可加载(驱动程序),共享库用于启动系统。运行根文件系统中的可执行程序,比如:/bin /sbin 目录下的程序。
6、/home目录 
用户目录,它是可选的,对于每个普通用户,在/home目录下都有一个以用户名命名的子目录,里面存放用户相关的配置文件。
7、/root目录 
根用户的目录,与此对应,普通用户的目录是/home下的某个子目录。
8、/usr目录 
/usr目录的内容可以存在另一个分区中,在系统启动后再挂接到根文件系统中的/usr目录下。里面存放的是共享、只读的程序和数据,这表明/usr目录下的内容可以在多个主机间共享,这些主要也符合FHS标准的。/usr中的文件应该是只读的,其他主机相关的,可变的文件应该保存在其他目录下,比如/var。/usr目录在嵌入式中可以精减。
9、/var目录 
与/usr目录相反,/var目录中存放可变的数据,比如spool目录(mail,news),log文件,临时文件。
10、/proc目录 
这是一个空目录,常作为proc文件系统的挂接点,proc文件系统是个虚拟的文件系统,它没有实际的存储设备,里面的目录,文件都是由内核临时生成的,用来表示系统的运行状态,也可以操作其中的文件控制系统。
11、/mnt目录 
用于临时挂载某个文件系统的挂接点,通常是空目录,也可以在里面创建一引起空的子目录,比如/mnt/cdram /mnt/hda1 。用来临时挂载光盘、硬盘。
12、/tmp目录 
用于存放临时文件,通常是空目录,一些需要生成临时文件的程序用到的/tmp目录下,所以/tmp目录必须存在并可以访问。
 

下一步学习中,预计开始进行嵌入式Linux的开发,详细操作上面描述的过程