交叉编译、软硬链接

什么是交叉编译?交叉编译是一个行为,是在一个平台上生成另一个平台上的可执行代码。

  • 本地编译:本地编译可以理解为,在当前编译平台下,编译出来的程序只能放到当前平台下运行。平时我们常见的软件开发,都是属于本地编译:比如,我们在 x86 平台上,编写程序并编译成可执行程序。这种方式下,我们使用 x86 平台上的工具,开发针对 x86 平台本身的可执行程序,这个编译过程称为本地编译。
  • 交叉编译:交叉编译可以理解为,在当前编译平台下,编译出来的程序能运行在体系结构不同的另一种目标平台上,但是编译平台本身却不能运行该程序:比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM 平台的程序,编译得到的程序在 x86 平台上是不能运行的,必须放到 ARM 平台上才能运行。
  • 宿主机(host) :编辑和编译程序的平台,一般是基于X86的PC机,通常也被称为主机。
  • 目标机(target):用户开发的系统,通常都是非X86平台。host编译得到的可执行代码在target上运行。
  • prefix:交叉编译器的安装位置。
  • 比如:我们在windows上面编写51和32的代码,并编译成可执行代码,如xx.hex,是在C51上面运行不是在windows上面运行,交叉编译的发生在keil(集成环境上面)。同样:我们在ubuntu(linux)上面编写树莓派的代码,并编译成可执行代码,如xx.out,是在树莓派上面运行不是在ubuntu(linux)上面运行。

为什么要交叉编译?

  • 有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征

  • 有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器

  • 有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。

  • 在项目的起始阶段,目的平台尚未建立,因此需要做交叉编译,以生成我们所需要的bootloader(启动引导代码)以及操作系统核心

  • 其次,当目的平台能启动之后,由于目的平台上资源的限制,当我们编译大型程序时,依然可能需要用到交叉编译。

  • Speed: 目标平台的运行速度往往比主机慢得多,许多专用的嵌入式硬件被设计为低成本和低功耗,没有太高的性能

  • Capability: 整个编译过程是非常消耗资源的,嵌入式系统往往没有足够的内存或磁盘空间

  • Availability: 即使目标平台资源很充足,可以本地编译,但是第一个在目标平台上运行的本地编译器总需要通过交叉编译获得

  • Flexibility: 一个完整的Linux编译环境需要很多支持包,交叉编译使我们不需要花时间将各种支持包移植到目标板上

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

要进行交叉编译,我们需要在主机平台上安装对应的交叉编译工具链(cross compilation tool chain),然后用这个交叉编译工具链编译我们的源代码,最终生成可在目标平台上运行的代码。常见的交叉编译例子如下:

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

交叉编译工具链的安装:

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

  • 首先下载树莓派的交叉编译工具链,下载地址点这里,点击download下载即可。
    在这里插入图片描述

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

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

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

  • 下面记录在ubuntu上面安装树莓派的交叉编译工具,首先在上方的那个网址下载交叉编译工具到与虚拟机共享的文件夹,然后将压缩包拷贝到虚拟机使用指令cp /mnt/hgfs/Sharefromwindows/tools-master.zip .
    在这里插入图片描述

  • 然后使用指令进行解压:unzip tools-master.zip,解压完成后会出现tool-master这个文件夹,进入这个文件夹,可以看到arm-bcm2708,所需要的交叉编译工具就是在这里,进入这个文件夹gcc-linaro-arm-linux-gnueabihf-raspbian-x64因为我的虚拟机(宿主机)是64位的所以选择这个文件夹,如果是32位的用gcc-linaro-arm-linux-gnueabihf-raspbian这个文件夹夹里面的。进入自己对应的文件夹,然后进入bin目录下,可以看到很多绿色的可执行文件
    在这里插入图片描述

  • 我们要用的交叉编译工具就是浅蓝色的那个软连接(相当于windows下面的快捷方式)arm-linux-gnueabihf-gcc,可以使用指令:./arm-linux-gnueabihf-gcc -v查看交叉编译1器的版本相关信息,和查看gcc版本的指令类似:gcc -v

  • 在ubuntu里面编译一个可执行代码,可以通过file testone来查看文件的属性,如下图所示:x86-64 表示只能运行在64位的X86的机子上,这样在可执行程序就不能在树莓派上面跑。
    在这里插入图片描述

  • 如果想要在树莓派上面运行,就要使用指令编译:arm-linux-gnueabihf-gcc testone.c -o testone这样生成的testone就可以在ARM平台上面运行。
    在这里插入图片描述

  • 可以使用指令:scp testone pi@192.168.43.136:/home/pitestone是要移动到树莓派的可执行文件,192.168.43.136是树莓派的ip地址,冒号后面是将文件放到树莓派的哪一个位置。可以看到绿色的可执行文件testone然后可执行。
    在这里插入图片描述

  • 如果将一个只能在x86运行的代码,移动到树莓派上面,则会报错:-bash: ./testone: cannot execute binary file: Exec format error表示不能解析这个二进制文件。同样我们可以将项目二代码的服务端移到树莓派上面运行,客户端在虚拟机上面运行。

客户端:
在这里插入图片描述
服务端:
在这里插入图片描述

带WiringPi库的代码如何在上位机进行交叉编译?

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

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

  • 进入解压后的WiringPi文件夹,然后打开INSTALL这个文件夹,查看如何下载,这里显示直接执行build文件即可(编译wiringPi库生成动态库,编译时需要链接,但是它是使用的gcc编译器,编译出来库是只能运行在x86平台上的),然后将会下载到/usr/local/lib这个目录下,然后可以使用指令:arm-linux-gnueabihf-gcc demo.c -I /home/fhn/wringPi/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
    在这里插入图片描述

  • 正常情况下我们先要交叉编译wiringPi库,编译出适合树莓派的库,这时候交叉编译可执行程序的时候,链接库的格式也是正确的。那么我们可以将树莓派的wiringPi库拿到虚拟机,libwiringPi.so就这个动态库,但是这是个软连接(相当于快捷方式)
    在这里插入图片描述

  • 使用指令:ls -l |grep libwiringPi.so可以看出这个文件是指向libwiringPi.so.2.50这个动态库的。所以我们需要将这个动态库发送到ubuntu里面,使用指令:scp libwiringPi.so.2.50 fhn@192.168.43.112:/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 创建软连接,下面有详细的讲解软硬链接,创建软连接后使用指令:arm-linux-gnueabihf-gcc hc.c -I /home/fhn/wringPi/WiringPi/wiringPi -L . -lwiringPi -o hc进行编译,其中:-I /home/fhn/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 号才是文件的唯一标识而非文件名。文件名只是为了方便人们的记忆和适用。
    在这里插入图片描述

  • 如上述命令 “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 : 真正存储文件内容。

软硬连接:
在 Windows 系统中,快捷方式是指向原始文件的一个链接文件。可以让用户从不同的位置来访问原始的文件;原文件一旦被删除或剪切到其他地方后,会导致链接文件失效。但是在 Linux 系统中,"快捷方式"就不太一样 ,在 Linux 系统存在硬链接和软链接两种文件。

  • 硬链接(hard link) : 可以将它理解为一个 “指向原始文件 inode(储存原始文件信息) 的指针”,系统不为它分配独立的 inode 和 文件。所以,硬链接文件与原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的 innode 连接数就会增加 1 ; 而且只有当该文件的 inode 连接数为 0 时,才算彻底将它删除。因此即便删除原始文件,依然可以通过硬链接文件来访问。需要注意的是,我们不能跨分区对文件进行链接。可以使用指令:ln fileName newFileName为原文件fileName 创建硬链接newFileName
  • 软链接(symbolic link) : 等同于 Windows 系统下的快捷方式。仅仅包括所含链接文件的路径名字。因此能链接目录,也能跨文件系统链接。但是,当删除原始文件后,链接文件也将失效。
  • 总结:硬链接是指向原始文件 inode的指针,而软连接则是仅仅包括所含链接文件的路径名字

ln - 新建链接:ln 用于创建软或硬链接。
在这里插入图片描述

  • 软链接示例 :ln -s helloWorld sHelloWorld
  • 硬链接示例 :ln helloWorld hardHelloWorld

问题:

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

软硬连接参考博文、交叉编译参考博文、软硬连接精彩博文、交叉编译工具链下载的另一种方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272162.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linus下安装maven

下载maven安装包 wget http://mirror.bit.edu.cn/apache/maven/binaries/apache-maven-3.2.2-bin.tar.gz 解压 tar -zxvf apache-maven-3.2.2-bin.tar.gz 配置maven环境变量 查看maven解压后安装包目录 vi /etc/profile 进入最底部,按insert,添加环境变量&#x…

linux内核开发基础(linux内核源码、树莓派源码编译、SD卡挂载)

首先下载树莓派linux内核源码: 下载网址:https://github.com/raspberrypi/linux在树莓派使用指令:uname -r查看当前树莓派的版本号,然后选择对应的linux内核版本号进行下载。 将linux内核源码从共享文件夹拷贝到SYSTEM文件夹&am…

Linux实时查看进程命令top笔记

top命令是Linux下常用的性能分析工具,能够实时显示Linux系统中各个进程的资源占用状况,类似于Windows系统的任务管理器功能。 top命令的语法格式: top [-] [d] [p] [q] [c] [C] [S] [s] [n] 常用参数说明 d 指定每两次屏幕信息刷新之间的时间…

文件系统(文件系统目录结构、磁盘分区、虚拟文件系统)、linux内核结构框图

什么是文件系统? 常规认知就是根目录下那些文件,但其实并不是那样。文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织…

Linux进程终止命令kill或kill all​笔记

在linux命令下,如果需要终止某个进程,可以使用kill或者killall等命令来实现。终止命令的原理都是向linux内核发送一个系统操作的信号以及某个进程的ID,然后系统内核会根据指定的进程ID进行相应的处理。 kill命令典型的用法:首先使…

linux驱动(驱动编译、字符设备驱动框架、交叉编译树莓派驱动、树莓派驱动本地编译)

什么是驱动: 驱动就是对底层硬件设备的操作进行封装,并向上层提供函数接口。 设备分类: linux系统将设备分为3类:字符设备、块设备、网络设备。 字符设备:指只能一个字节一个字节读写的设备,不能随机读取…

docker启动报错  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --

docker启动报错 : (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --to-destination 172.17.0.2:9876 ! -i docker0: iptables: No chain/target/match by that name. 解决方案: systemctl restart docker

最详细的docker安装rocketMQ教程来了

RocketMQ是一款分布式、队列模型的消息中间件,是由阿里巴巴设计的,具有以下特点: 支持严格的消息顺序 支持Topic与Queue两种模式 亿级消息堆积能力 比较友好的分布式特性 同时支持Push与Pull方式消费消息 历经多次天猫双十一海量消息考验…

树莓派IO口驱动代码的编写、微机总线地址、物理地址、虚拟地址、BCM2835芯片手册

地址总线: 百度百科解释: 地址总线 (Address Bus;又称:位址总线) 属于一种电脑总线 (一部份),是由CPU 或有DMA 能力的单元,用来沟通这些单元想要存取(读取/写入&#xff…

夺命雷公狗---DEDECMS----26dedecms面包屑导航的实现

我们在很多项目里面都会用到面包屑导航,而dedecms里面也是给我们封装好面包屑导航的了,如下图所示: 在dede里面实现面包屑导航主要用到{dede:field.position/}标签,我们首先来修改下article_movie.htm内容页的模版文件: 我们修改成…

rust油桶用什么打_草莓用什么膨大素好?草莓膨大剂什么时间打?草莓用什么肥料膨大...

农资365公众号,了解更多生根、根腐、重茬、土传、枯黄萎、根烂病、防治根结线虫、微生物菌肥、膨大坐果、抗病增产的防治方法!草莓含有丰富的营养,并且种植效益较高,其种植范围也比较广。草莓种植期间有很多因素影响草莓果实膨大&…

docker安装kafka,超级简单的

简介 kafka是一个分布式消息队列。具有高性能、持久化、多副本备份、横向扩展能力。生产者往队列里写消息,消费者从队列里取消息进行业务逻辑。一般在架构设计中起到解耦、削峰、异步处理的作用。 kafka对外使用topic的概念,生产者往topic里写消息&…

Linux中常见的环境变量笔记

1、变量:BASHBash Shell的全路径比如:echo $BASH2、变量:BASH_VERSIONBash Shell的版本号3、变量:EUID记录当前用户的UID。root用户值为0。4、FUNCNAME在用户函数体内部,记录当前函数体的函数名。5、变量:H…

消防信号二总线有没电压_春晓161#地块人防工程消防电源监控系统的设计与应用...

涂志燕安科瑞电气股份有限公司,上海 嘉定 201801;摘要:本文简述了消防设备电源的组成原理,分析了消防设备电源监控系统在应用中的设计依据和相关规范。通过安科瑞消防设备电源监控系统在春晓161#地块项目的实例介绍,阐…

大学慕课数据结构单元测试——华中科技大学

第一章绪论单元测试 一、单选(2分) 1、​___C__ 是数据的最小单位。 A.信息项 B.数据元素 C.数据项 D.表元素 2、​以下说法不正确的是 ___B___。 A.数据元素是数据的基本单位 B.数据项可由若干个数据元素构成 C.数据可由若干个数据元素构成 D.数据项是不可分割的最小…

RocketMQ同步刷盘和异步刷盘

刷盘机制 同步刷盘和异步刷盘 在broker配置文件里修改参数配置是同步还是异步

vim模式下报错E37: No write since last change No write since last change for buffer “ “

报错如下图所示: 网上的解决方法: 文件为只读文件,无法修改。使用命令:w!强制存盘即可在vim模式下,键入以下命令::w!存盘后在使用vim命令检查是否保存,如未保存,编辑后重复以上操作…

Linux中Shell中取消变量和特殊变量的笔记

1、取消变量取消变量也就是将变量从内存中释放出去,可以使用unset 后面加变量名即可,当然函数的释放同样可以采用该方式处理。比如:name"123"echo ${name}输出:123unset nameecho ${name}输出:#取消函数示例…

光华科技光刻胶_【收藏】6天5板!21只光刻胶概念(名单)“出炉”!

连板数量21家中迪投资5板,宁波联合 神驰机电 神马电力4板,汉缆股份 华盛昌 浙江鼎力3板,海航投资世联行 飞龙股份 安洁科技 京威股份 三丰智能 容大感光 晶瑞股份 奥飞数据 光大嘉宝 电子城博天环境 兆易创新 聚辰股份2板二、科技股&#xff…

20159302 《网络攻击与防范》第四周学习总结

本节学习内容为网络攻击环境的配置。在此过程中,我们至少需要一台靶机,一台攻击机。在此选用windows server 2000为靶机,kali系统为攻击机。 一、系统的安装 根据之前发布的kali系统的安装过程,依据此流程进行windows server的安装…