linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发

交叉编译

  • 一、交叉编译概念
  • 二、为什么要交叉编译
    • 交叉编译的基本知识
  • 三、什么是交叉编译链
    • 3.1 交叉编译链的命名规则
    • 3.2 交叉编译工具链(交叉编译器)是什么?
  • 四、交叉编译工具链安装
    • 1. 临时有效(关闭窗口就无效了)
    • 2. 永久有效(多少个窗口都可以)
  • 五、交叉编译服务器客户端
    • 总结交叉编译
  • 六、带WiringPi库的交叉编译
  • 七、软链接
    • 软链接概念
    • 如何生成软链接(重点)
  • 八、硬链接
    • 硬链接概念
    • 如何生成硬链接

一、交叉编译概念

交叉编译是一个行为 ,是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。

我们vi test.c / gcc test.c 是编辑代码和编译代码,没有交叉

编译:是一个平台上生成在该平台上可执行的代码
交叉编译:是在一个平台上生成,在另一个平台上的可执行代码

交叉编译

例如: 我们在windows 上面编写C51代码,并编译成可执行代码,如xxx.hex ,是在C51上面运行,不是在windows上运行

我们在linux 上面编写树莓派代码,并编译成可执行代码,如a.out,是在树莓派上面运行,不是在ubuntu上运行

例如:C51 交叉编译的发生在keil (集成环境上面)
stm32开发

二、为什么要交叉编译

  • 既然我们已经有了主机编译器,那为什么还要交叉编译呢?

有时是因为目的平台上不允许或不能够安装我们所需要的编译器,比如C51

  1. 有时候是因为目的平台上的资源贫乏无法运行我们所需要编译器
  2. 有时又是因为目的平台还没有建立连操作系统都没有,根本谈不上运行什么编译器

平台运行需要至少两样东西: bootloader(启动引导代码)以及操作系统核心

  • 既然可以交叉编译,那还要主机编译干吗?

交叉编译是不得已而为之!与主机编译相比,交叉编译受的限制更多,虽然在理论上我们可以做任何形式的交叉编译,但事实上,由于受到专利、版权、技术的限制,并不总是能够进行交叉编译

交叉编译的基本知识

  • 宿主机(host) :编辑和编译程序的平台,一般是基于X86的PC机,通常也被称为主机。
  • 目标机(target):用户开发的系统,通常都是非X86平台。host编译得到的可执行代码在target上运行。

交叉编译要用到的工具
交叉编译器、交叉编译工具链

三、什么是交叉编译链

明白了什么是交叉编译,那我们来看看什么是交叉编译链。

首先编译过程是按照不同的子功能,依照先后顺序组成的一个复杂的流程,如下图:
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第1张图片
那么编译过程包括了预处理、编译、汇编、链接等功能。既然有不同的子功能,那每个子功能都是一个单独的工具来实现,它们合在一起形成了一个完整的工具集。

同时编译过程又是一个有先后顺序的流程,它必然牵涉到工具的使用顺序,每个工具按照先后关系串联在一起,这就形成了一个链式结构。

因此,交叉编译链就是为了编译跨平台体系结构的程序代码而形成的由多个子工具构成的一套完整的工具集。同时,它隐藏了预处理、编译、汇编、链接等细节,当我们指定了源文件(.c)时,它会自动按照编译流程调用不同的子工具,自动生成最终的二进制程序映像(.bin)。

注意:严格意义上来说,交叉编译器,只是指交叉编译的gcc,但是实际上为了方便,我们常说的交叉编译器就是交叉工具链。本文对这两个概念不加以区分,都是指编译链

3.1 交叉编译链的命名规则

我们使用交叉编译链时,常常会看到这样的名字:

arm-none-linux-gnueabi-gcc
arm-cortex_a8-linux-gnueabi-gcc
mips-malta-linux-gnu-gcc

其中,对应的前缀为:

arm-none-linux-gnueabi-
arm-cortex_a8-linux-gnueabi-
mips-malta-linux-gnu-

这些交叉编译链的命名规则似乎是通用的,有一定的规则:

arch-core-kernel-system
  • arch: 用于哪个目标平台。
  • core: 使用的是哪个CPU Core,如Cortex
    A8,但是这一组命名好像比较灵活,在其它厂家提供的交叉编译链中,有以厂家名称命名的,也有以开发板命名的,或者直接是none或cross的。
  • kernel: 所运行的OS,见过的有Linux,uclinux,bare(无OS)。
  • systen:交叉编译链所选择的库函数和目标映像的规范,如gnu,gnueabi等。其中gnu等价于glibc+oabi;gnueabi等价于glibc+eabi。

注意:这个规则是一个猜测,并没有在哪份官方资料上看到过。而且有些编译链的命名确实没有按照这个规则,也不清楚这是不是历史原因造成的。如果有谁在资料上见到过此规则的详细描述,欢迎指出错误。

3.2 交叉编译工具链(交叉编译器)是什么?

一般由编译器、连接器、解释器和调试器组成,就是为了编译、链接、处理和调试跨平台体系结构的程序代码。

  • 在Windows PC上,利用ADS(ARM开发环境),使用armcc编译器,则可编译出针对ARM CPU的可执行代码
  • 在Linux PC上,利用arm-linux-gcc编译器,可编译出针对Linux ARM平台的可执行代码
  • 在WindowsPC上,利用cygwin环境,运行arm-elf-gcc编译器,可编译出针对ARM CPU的可执行代码
  • 树莓派有flash和运行内存(RAM随机存储器),但是树莓派有时因为目标平台没有建立,连操作系统都没有,根本谈不上编译器。因此需要做交叉编译,以生成平台至少所需要的:bootloader(启动引导代码)以及 操作系统核心

四、交叉编译工具链安装

不同的平台用的交叉比编译器不同,就像我们在用keil编译51的代码时要选择对应的芯片,编译32的代码时也要选择对应的芯片,这其实都是在间接地选择了编译器。如果目标机是树莓派,那么我们将会用到树莓派的交叉编译工具链。

下载地址:https://github.com/raspberrypi/
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第2张图片

交叉编译工具链的安装有两种方法: ①临时有效 ②永久有效

把压缩包导入到linux 下 文件里

  1. 可以指令导入
  2. 可以U盘传入

linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第3张图片
导入后,用指令unzip tools-master.zip 进行解压
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第4张图片

解压完成后
在这里插入图片描述
我们进入cd arm-bcm2708/
在这里插入图片描述
cd gcc-linaro-arm-linux-gnueabihf-raspbian-x64
在这里插入图片描述
cd bin/ , 我们能看到一堆可执行文件
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第5张图片
我接下来会用到的工具,蓝色的是软链接
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第6张图片
我们ls -l 看一下 ,软连接实际上是假的,它真正用到的是 -> 后面的东西
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第7张图片

我们要编译时候,需要进很多目录后,会很麻烦。怎么办呢?

这就涉及到环境变量

1. 临时有效(关闭窗口就无效了)

临时有效:
将路径加入PATH环境变量(将命令加入终端,使命令使用更加方便,不用敲很长的路径),echo $PATH
显示当下的环境变量,然后使用指令:export PATH=设置新的环境变量

PATH (环境变量)
我们要想直接gcc编译,不敲前面的路径的话。我们需要进行环境变量设置。

我们echo $PATH 显示当前环境变量
在这里插入图片描述
我们修改环境变量临时有效
export PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/lessonPi/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

在这里插入图片描述
设置好后,我们回到根目录,就可以直接执行arm-linux-gnueabihf-gcc -v
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第8张图片

2. 永久有效(多少个窗口都可以)

永久有效
vi .bashrc打开工作目录下的.bashrc(隐藏文件),用来配置命令终端的,每次启动终端都会执行这个脚本。将上面的配置命令添加在这个文件的最后一行即可。然后source
/home/CLC/.bashrc使用这个指令是设置立即生效

去修改工作目录下的.bashrc 隐藏文件,配置命令终端的

我们打开指令 vi /home/CLC/.bashrc
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第9张图片
然后在脚本文件最后面写入 刚才的路径
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第10张图片
保存并退出。执行一下 source /home/CLC/.bashrc
source 加载配置文件,马上生效指令

这样就配置好了,无论,多少个窗口都可以执行 arm-linux-gnueabihf-gcc -v
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第11张图片
4.8.3 才是树莓派的交叉编译工具链
在这里插入图片描述

五、交叉编译服务器客户端

linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第12张图片
file test_1 :file是查看文件属性的意思

我们看到test_1 是只能运行到x86-64位的主机上,树莓派是不能运行test_1的

我们用交叉编译一下test.c

arm-linux-gnueabihf-gcc test.c -o test_2

我们看到test_2 是只能运行到ARM,这样树莓派就可以运行test_2了

我们传到树莓派上 ,输入指令: scp test_2 [email protected]:/home/pi
在输入树莓派的登录密码 ,在树莓派上就可以看到test_2 了
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第13张图片
在树莓派上就看到了test_2,并且可以执行。

我们把之前在linux上的文件都可以发给树莓派上。
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第14张图片
在树莓派上执行FTP客户端

总结交叉编译

交叉编译:

检测下交叉编译工具链对不对:

  • arm-linux-gnueabihf-gcc -v
  • 4.8.3
arm-linux-gnueabihf-gcc  xxx.c -o xxx

如何把编译生成的可执行文件下载到开发板上:

scp  xxx    pi@192.168.0.100:        /home/pi
指令 文件名 开发板用户名@ 开发板地址:开发板的绝对路径

六、带WiringPi库的交叉编译

需要先在宿主机上面(这里是ubuntu)安装wiringPi库

wiringPi库百度网盘:链接:https://pan.baidu.com/s/1cPIt-xZLye1DAQjq2yKzeg提取码:35vt

进入解压后的WiringPi文件夹,然后打开INSTALL这个文件夹,我们会查看如何下载,这里显示直接执行./build文件即可,会在./build unistall 生成(编译wiringPi库生成动态库,编译时需要链接,但是它是使用的gcc编译器,编译出来库是只能运行在x86平台上的),然后将会下载到/usr/local/lib这个目录下,起始是不容用的。

我们先用之前写的继电器组代码,试一下。从树莓派把demo2.c传到linux里
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第15张图片
然后可以使用指令:arm-linux-gnueabihf-gcc demo2.c但是会发现头文件不认识,因为我们之前学过了动态库,运用动态库的知识来解决。
首先我们要找到头文件
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第16张图片
然后可以使用动态库 指令: arm-linux-gnueabihf-gcc demo2.c -I /home/CLC/lessonPi/WiringPi/wiringPi -lwiringPi 来找。

发现还是报错
在这里插入图片描述
是因为链接wiringPi库的时候是链的/usr/local/lib这个目录下来链接 libwiringPi.so

但是file libwiringPi.so去查看这个文件的属性,发现这个文件的属性是在x86上面运行的,然而我们需要在ARM上面运行,所以是不兼容的
在这里插入图片描述

链接库的格式不对,是宿主机的平台所以会报错:/home/fhn/arm-tool/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/…/lib/gcc/arm-linux-gnueabihf/4.8.3/…/…/…/…/arm-linux-gnueabihf/bin/ld: cannot find -lwiringPi collect2: error: ld returned 1 exit status

  1. 正常情况下我们先要交叉编译wiringPi库,编译出适合树莓派的库,这时候交叉编译可执行程序的时候,链接库的格式也是正确的。
  2. 通过-I -L 来指定

那怎么解决这个问题呢?

我们可以将树莓派的wiringPi库拿到虚拟机libwiringPi.so就这个动态库,但是这是个 软连接(相当于快捷方式)
linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第17张图片
使用指令:ls -l |grep libwiringPi.so可以看出这个文件是指向libwiringPi.so.2.50这个动态库的。所以我们需要将这个动态库发送到ubuntu里面,使用指令:scp libwiringPi.so.2.50 [email protected]:/home/fhn/wringPi/WiringPi,就算将软连接发送到ubuntu也不会指向这个动态库,还需要我们自己创建动态库。

如果传输过程中出现错误:ssh: connect to host 192.168.43.112 port 22: Connection refused lost connection表示ubuntu没有安装ssh,在ubuntu里面下载ssh即可:sudo apt-get install ssh
在这里插入图片描述
使用指令ln -s libwiringPi.so.2.50 libwiringPi.so 创建软连接
在这里插入图片描述
在lessonPi目录下 (包含libwiringPi.so.2.50的目录)
输入命令:ln -s libwiringPi.so.2.50 libwiringPi.so 创建一个软链接
在这里插入图片描述
我们ls -l 看到有->接过,说明创建成功
在这里插入图片描述

下面有详细的讲解软硬链接

创建软连接后使用指令:arm-linux-gnueabihf-gcc demo2.c -I /home/CLC/wringPi/WiringPi/wiringPi -L. -lwiringPi -o jidianqi进行编译,其中:-I /home/CLC/wringPi/WiringPi/wiringPi是链接的wiringPi库的头文件-L是指定动态库在当前目录下去查找库文件
在这里插入图片描述

学习指令:
grep gcc * -nir在所有文件里面查找gcc字眼,n表示显示行号、i表示不区分大小写、n表示递归查找、*表示在所有文件里面去查找。

硬盘:

在介绍硬链接和软链接之前,首先介绍下硬盘相关的知识,主要是了解下 inode 。

  • 硬盘设备是由大量的扇区组成的。以 MBR 分区为例。每个扇区的容量为 512 字节。其中第一个扇区最重要。它里面保存着主引导记录与分区表信息。就第一个扇区来讲,主引导记录需要占用 446 字节,分区表为 64 字节,结束符占用 2 字节。其中分区表每记录一个分区信息就需要 16字节,这样一来,最多就只有4个分区信息可以写到第一扇区中,这4个分区就是4个主分区。
  • 第一个扇区最多只能创建出4个分区 ? 为了解决分区个数不够的问题,可以将第一个扇区的分区表中16个字节(原本要写入主分区信息)的空间(称之为扩展分区)拿出来指向另一个分区。
  • 也就是说,扩展分区并不是一个真正的分区,而像是有一个占用 16 字节的分区表空间的指针,一个指向另外一个分区的指针。这样一来,用户一般会选择使用3个主分区+1个扩展分区的方法,然后在扩展分区中创建无数个逻辑分区,从而来满足多分区(大于4个)的需求。
  • Linux 系统中有一个名为 superblock 的 “硬盘地图”。 Linux 并不是把文件内容直接写入到 superblock 中,而是在里面记录着整个文件系统的信息。Linux 把每个文件的权限与属性记录在 inode("索引节点:index node ")
    中,而且每个文件占用一个独立的 inode 表格,该表格的默认大小为 128 字节。里面记录着如下信息 :文件的访问权限(read、write、execute)、该文件的所有者与所属组(owner、group)、该文件的大小(size)、该文件的创建或内容修改时间(ctime)、该文件的最后一次访问时间(atime)、该文件的修改时间(mtime)、文件的特殊权限(SUID、SGID、SBIT)、该文件的真实数据地址(point)
  • 在 Linux 系统中 ,inode 号才是文件的唯一标识而非文件名。文件名只是为了方便人们的记忆和适用。

linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第18张图片

  • 如上述命令 “ls -li” 结果中的第一列就是文件的 inode 号。系统是通过 inode 号寻找正确的文件数据块。
  • 文件的实际内容则保存在 block 中(大小可以是 1KB、2KB 或 4KB),一个 inode 的默认大小为 128KB (在Ext3 文件系统中),记录一个 block 则消耗 4B 。当文件的 inode 被写满后,Linux 系统会自动分配出一个 Block块,专门用于像 innode 那样记录其他 block 块的信息,这样能把各个 block块的内容串到一起,就能够让用户读到完整的文件内容了。
  • 对于存储文件内容的的 Block 块,有以下两种常见情况,以 4KB 的 block 大小为例说明情况 : 文件很小(1KB) ,但依然会占用一个 block ,因此会潜在占用 3kb。 文件很大(5kb) , 那么会占用两个 block。

总结:

superBlock : 存储整个文件系统的信息。
inode : 存储文件的权限与属性。
data block : 真正存储文件内容。

七、软链接

软链接(symbolic link)
等同于 Windows 系统下的快捷方式。仅仅包括所含链接文件的路径名字。因此能链接目录,也能跨文件系统链接。但是,当删除原始文件后,链接文件也将失效。

软链接概念

在 Windows 系统中,快捷方式是指向原始文件的一个链接文件。可以让用户从不同的位置来访问原始的文件;原文件一旦被删除或剪切到其他地方后,会导致链接文件失效。
但是在 Linux 系统中,"快捷方式"就不太一样 ,在 Linux 系统存在硬链接和软链接两种文件。
ln -s 是linux中一个非常重要命令,一定要熟悉。它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,

具体用法是:ln -s 源文件 目标文件

【软链接】(像windos的快捷方式)
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息

-s 是代号(symbolic)的意思
这 里有两点要注意:

  1. ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化;
  2. ln -s ,它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间

软链接概念总结

  1. 软链接文件有类似于Windows的快捷方式
  2. 在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息
  3. 它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间

如何生成软链接(重点)

如何生成:

ln   -s   libwiringPi.so.2.50  libwiringPi.so
指令 参数  要链接的文件        软链接文件名字

在这里插入图片描述
在lessonPi目录下 (包含libwiringPi.so.2.50的目录)
输入命令:ln -s libwiringPi.so.2.50 libwiringPi.so 创建一个软链接
在这里插入图片描述
我们ls -l 看到有->接过,说明创建成功
在这里插入图片描述

八、硬链接

硬链接(hard link)
可以将它理解为一个 “指向原始文件 inode(储存原始文件信息) 的指针”,系统不为它分配独立的 inode 和 文件。所以,硬链接文件与原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的 innode 连接数就会增加 1 ; 而且只有当该文件的 inode 连接数为 0 时,才算彻底将它删除。因此即便删除原始文件,依然可以通过硬链接文件来访问。需要注意的是,我们不能跨分区对文件进行链接。可以使用指令:ln fileName newFileName为原文件fileName 创建硬链接newFileName

具体用法是:ln 源文件 目标文件

硬链接概念

软链接概念总结

  1. 它会在你选定的位置上生成一个和源文件大小相同的文件,无论是软链接还 是硬链接,文件都保持同步变化。

  2. 硬连接指通过索引节点来进行连接

  3. 硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功

  4. 文件真正删除的条件是与之相关的所有硬连接文件均被删除。

【硬链接】
硬连接指通过索引节点来进行连接。
在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。
在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。 硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能
其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

如何生成硬链接

如何生成:

ln      libwiringPi.so.2.50  libwiringPi.so
指令   要链接的文件        软链接文件名字

总结
硬链接是指向原始文件 inode的指针,而软连接则是仅仅包括所含链接文件的路径名字

linux&树莓派开发——“交叉编译&软硬链接“ 工作中必然用到的技术 实现不同主机间交互开发_第19张图片
软链接示例 :ln -s helloWorld sHelloWorld
硬链接示例 :ln helloWorld hardHelloWorld

问题:

硬链接占据空间吗 ?
比如我有一个 1G 的文件,现在我给这个文件建了一个硬链接。
那么会占据 2G 空间吗?
不会,之前我们说了硬链接是一个指针或者说是文件的引用,只占一点点空间,软连接不占用磁盘空间。

软硬连接参考博文、交叉编译参考博文

你可能感兴趣的:(ARM树莓派开发,Linux,开发,linux,unix,c语言,ubuntu)