嵌入式Linux系统移植

嵌入式Linux系统移植是进行Linux驱动开发的基础,如果连Linux系统移植都完成不了,那就更不用说驱动开发了。因此,Linux系统移植至关重要。

嵌入式Linux系统的移植要点

  1. 搭建交叉开发环境
  2. bootloader的选择与移植
  3. kernel的设置、编译、移植和调试
  4. 根文件系统的制作

嵌入式Linux系统的移植基本步骤

  1. 安装交叉编译器
  2. 确定目标机、主机的连接方式
  3. 搭建主机-目标机数据传输通道
  4. 编译三大子系统(bootloader子系统、内核核心子系统、文件系统子系统)
  5. 烧写测试

一般而言,目标机、主机的连接方式有:

  • UART异步串行通信接口(速率低、实用性强)
  • USB串行通信接口(速率快、驱动要移植修改)
  • TCP/IP网络通信接口(速率快、驱动要移植)
  • Debug Jtag调试接口(方便快捷、价格昂贵)

相比较来说,UART、USB、TCP/IP连接方式的选择较多。

一般而言,交叉编译器可以选择芯片公司提供的已经编译好的工具链,通常前缀名有:

  • arm-none-linux-gnueabi- (简称为:arm-linux-
  • arm-none-eabi- (不针对linux操作系统)
  • arm-elf- (不针对linux操作系统)

当然,也可以选择自己构建新的交叉编译器。

注意注意:在【嵌入式Linux的移植】博文中,并不涉及制作交叉编译器、编译U-Boot、编译内核、编译根文件系统的内容,而是将已经制作/编译完成的成品进行试验并测试。至于它们的制作过程,会在后面的博文中讲解。

交叉编译器

为什么要有交叉编译?

一般情况下,需要在开发主机上(通常是PC机)开发出能够在目标机(通常是开发板)上运行的程序。

为什么需要交叉开发环境?主要原因有以下两点:

  1. 目标机的硬件资源有很多限制,比如cpu主频相对较低,内存容量较小等,想想让几百MHZ主频的目标机去编译一个Linux kernel会让我们等的不耐烦,相对来说,主机的速度更快,硬件资源更加丰富,因此利用主机进行开发会提高开发效率;

  2. 目标机的MCU体系结构和指令集与主机不同,因此需要安装交叉编译工具进行编译,这样编译的目标程序才能够在目标机上运行。

安装交叉编译器

本文使用的是友善之臂提供的arm-linux-gcc-4.5.1-v6-vfp-20120301版交叉编译工具:

sudo tar -zxvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz -C /

这样arm-linux-的相关文件就解压到了根目录下的opt目录中。

解压完成了,如何来使用呢?

使用简单方法:

arm-linux-gcc hello.c -o build

使用绝对路径方法:

/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-gcc hello.c -o build

使用简单方法需要在环境变量的PATH中添加路径,这样的话,有一个弊端,最好保证整个系统只有一个交叉编译器,不然会存在PATH的优先级等问题。

怎么在环境变量的PATH中添加路径?

sudo vi /etc/environment

在该文件中添加路径/opt/FriendlyARM/toolschain/4.5.1/bin,各个路径之间以分隔。添加完成后,需要更新一下,使环境变量生效:

source /etc/environment

可以通过以下命令查看是否添加成功:

echo $PATH

需要注意的是:

如果在64位Linux安装arm-linux-gcc-4.5.1交叉编译器,要先安装32位的库(arm-linux-gcc-4.5.1-v6-vfp-20120301是在32位的Linux下编译的)。

安装32位的库:

sudo apt-get install libc6:i386
sudo apt-get install lib32z1

本部分内容,可以参考博文安装arm-linux-gcc交叉编译器。

工具集介绍

readelf

顾名思义,就是读取ELF头信息的工具。ELF(Executable and Linkable Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且他们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。例如:

gcc hello.c -o hello
readelf -h hello

不添加arm-linux-前缀,就表示在x86上进行编译和查取ELF头信息。结果为:

ELF 头:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              EXEC (Executable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1入口点地址:                         0x400750程序头地址:                         64 (bytes into file)Start of section headers:          65016 (bytes into file)标志:                            0x0本头的大小:                         64 (bytes)程序头大小:                         56 (bytes)Number of program headers:         9节头大小:                          64 (bytes)节头数量:                             37字符串表索引节头:                     34

需要注意的是,运行一个程序首先进入入口点地址,然后再各种调用,最终进入main地址,运行main函数的内容。

可通过file命令查看文件属性

file hello

在运行结果中,最开始是ELF头,第二个是编译后可运行的平台。实际上,运行平台在ELF中的Machine字段中也标明出来了。如果通过arm-linux-gcc进行编译,那么ELF头和file命令中的结果,都会显示为ARM。

本部分内容,可以参考博文ELF格式文件详细分析。

其他工具集

  • size:查看编译后的文件各个段(text段、data段、bss段、dec段等)的大小信息
  • nm:查看符号信息(说白了就是一些函数和全局变量等,比如main地址,_start入口点地址等)
  • strip:删除符号表信息(减小文件的大小)
  • objcopy:将目标文件的一部分或者全部内容拷贝到另外一个目标文件中(用于将ELF头去掉,因为ARM裸机是不识别ELF头信息的)
  • objdump:反汇编(添加-d选项)

目标机、主机的连接方式

一般而言,目标机和主机之间采用TCP/IP网络通信的方式居多,常用的服务主要两个:TFTP服务NFS服务

TFTP服务

TFTP服务主要用于实现文件的下载,比如开发调试的过程中,主要用tftp把要测试的bootloader、kernel和文件系统直接下载到内存中运行,而不需要预先烧录到Flash芯片中。

一方面,在测试的过程中,往往需要频繁的下载,如果每次把这些要测试的文件都烧录到Flash中然后再运行也可以,但是缺点是:过程比较麻烦,而且Flash的擦写次数是由限的;另外一方面:测试的目的就是把这些目标文件加载到内存中直接运行就可以了,而tftp就刚好能够实现这样的功能,因此,更没有必要把这些文件都烧录到Flash中去。

nfs服务:

NFS服务主要用于实现网络文件的挂载,实际上是实现网络文件的共享

在开发的过程中,通常在系统移植的最后一步会制作文件系统,那么这是可以把制作好的文件系统放置在我们开发主机PC的相应位置,开发板通过nfs服务进行挂载,从而测试我们制作的文件系统是否正确,在整个过程中并不需要把文件系统烧录到Flash中去,而且挂载是自动进行挂载的,bootload启动后,kernel运行起来后会根据我们设置的启动参数进行自动挂载,因此,对于开发测试来讲,这种方式非常的方便,能够提高开发效率。

一般而言,U-Boot采用USB线或者SD卡烧写到Flash中,而内核、根文件系统都采用TFTP的方式传输到目标板,然后通过U-Boot的命令进行启动。

搭建主机-目标机数据传输通道

以笔记本为例,整个搭建示意图:

首先笔记本有两个网卡,分别为WiFi网卡和有线网卡。虚拟机同样也配置成双网卡模式,一个通过NAT模式与WiFi网卡相连,连接无线路由器的LAN口,再通过WAN口进行上网功能;另一个通过桥接模式与有线网卡相连,最终连接到目标板进行数据传输功能。

桥接模式

在这种模式下,使用VMnet0虚拟交换机,虚拟机就像是局域网中的一台独立的主机,与宿主计算机一样,它可以访问网内任何一台机器。

在桥接模式下,可以手工配置它的TCP/IP配置信息(IP、子网掩码等,而且还要和宿主机器处于同一网段),以实现通过局域网的网关或路由器访问互联网;还可以将IP地址和DNS设置成“自动获取”。

在桥接模式中,使用VMnet0虚拟交换机,此时虚拟机相当与网络上的一台独立计算机与主机一样,拥有一个独立的IP地址。

NAT模式

使用NAT模式,就是让虚拟机借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟系统里访问互联网

NAT模式下的虚拟机的TCP/IP配置信息是由VMnet8虚拟网络的DHCP服务器提供的,因此IP和DNS一般设置为“自动获取”,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯。

采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机器能访问互联网即可。

也就是说,桥接模式是为了加入主机的局域网,完成与主机之间的数据访问;NAT模式是为了通过主机,访问互联网。两者的目的不同!

不太理解的,可以参考链接:VMware中三种网络连接的区别。

【Linux】嵌入式Linux系统的移植(上篇:交叉编译器、连接方式)相关推荐

  1. 在Windows, Mac, Linux三种系统中分别获取wifi密码的方式

    在Windows, Mac, Linux三种系统中分别获取wifi密码的方式 1. Windows netsh wlan show profile name=wifi名称 key=clear | fi ...

  2. aarch64-linux-gnu交叉编译器二进制方式安装

    aarch64-linux-gnu交叉编译器二进制方式安装 安装方法 1.下载交叉编译器 aarch64-linux-gnu 2.创建文件夹 sudo mkdir /usr/local/arm 3.解 ...

  3. ina3221嵌入式linux,嵌入式Linux之我行——Linux-2.6.30.4在2440上的移植之文件系统

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 一.移植环境 主  机:VMWa ...

  4. linux进程自动启动,linux 嵌入式 自启动 系统自动登录-自动启动程序或脚本

    linux嵌入式开发板,设置系统自动登录和自动运行脚本或程序,下面一一进行说明. 一.系统自动登录 1.1.在实验板添加logintest脚本 logintest脚本位置:/home/root/    ...

  5. xscale linux内核编译,【记录】用交叉编译器arm-xscale-linux-gnueabi交叉编译一个基于嵌入式Linux的无线HART的项目...

    [背景] 手上有一个无线HART的源码,其是基于Eclipse的项目. 想要交叉编译该项目. 之前已经通过crosstool-ng弄出一个交叉编译器arm-xscale-linux-gnueabi了: ...

  6. 能装linux的嵌入式,试试一张软盘可装下Linux(嵌入式Linux)

    嵌入式Linux由一个几百KB的kernel(内核)和一些根据需要进行定制的系统模块组成.由于Linux是开放源代 码的操作系统,因此,其在嵌入式领域有其不可替代的成本和高度灵活性等优势. 将Linu ...

  7. 嵌入式硬件Linux,嵌入式linux硬件什么要求

    大部分使用者初次接触linux系统电脑时,都不知道电脑里面的硬件到底是什么,和外设硬件又是什么.为此学习啦小编为大家整理推荐了相关的知识,希望大家喜欢. 嵌入式linux硬件要求的详细说明 lscpu ...

  8. lcd命令 linux,嵌入式Linux裸机开发(十五)——LCD

    嵌入式Linux裸机开发(十五)--LCD 一.LCD简介 LCD(Liquid Crystal Display)是液晶显示器简称.LCD的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置T ...

  9. linux -- 嵌入式2.6.37wifi-vnt6656移植驱动

    [A]          2.6.32.2内核下的移植 这里是友善之臂提供的2.6.32.2内核 + VNT6656 WLAN源代码 1.20.03的编译和使用方法: 1.编译驱动模块 目前1.20. ...

  10. ndis拨号软件 linux,嵌入式linux系统下NDIS拨号

    一.USB端口信息 U8300C模块USB会枚举出6个逻辑端口,他们的枚举顺序.端口功能.端口名称如下表所示: 二.驱动集成 1.内核配置: make menuconfig 到内核时: Device ...

最新文章

  1. 名校计算机博士:拿到了五个工作机会,华为是最差的!
  2. 数据结构基础-Hash Table详解
  3. AI扫雷有多牛?他国纷纷来求师学艺(附完整教程)
  4. Winform中DevExpress的TreeList的入门使用教程(附源码下载)
  5. 阿里面试经历JAVA总结
  6. ubuntu系统目录介绍
  7. 对于人工智能的学习有哪些建议?【转】
  8. 使用HTML5 IndexDB存储图像和文件
  9. 专题:区块链与数据共享(上)
  10. BOOTSTRAP ---- 重要部分
  11. MIT6.006Lec03:插入排序,归并排序,递归树
  12. 湾区那些事儿 (二)
  13. 如何在windows下刷amd显卡的bios和简易救活教程
  14. Html - Json转excel文件
  15. WIN10专业版如何调整系统字体大小
  16. oracle中distance用法,distance的用法总结大全
  17. WPF做的金山词霸页面
  18. 演化模型(evolutionary model) 需求不明确+两次开发(实验开发+产品开发)
  19. 桂林理工大学 程序设计实践课程 实习报告
  20. “整合”还是“混合”——多因子组合的构建

热门文章

  1. java毕业生设计车辆调度管理系统计算机源码+系统+mysql+调试部署+lw
  2. Altium designer2020基础使用教程
  3. nas修改启动盘sn和mac
  4. 转给你身边的工程师!从零开始搭建一个完整AGV控制系统
  5. 联想台式计算机重装系统教程,联想台式机怎么重装系统?联想台式机重装系统教程...
  6. Excel应用{数据加工与公式函数}
  7. Maven的生命周期和插件
  8. Docker所在目录以及查询正在运行容器的所在位置
  9. 嵌入式:交换指令之SWP,MRS,MSR
  10. pytorch 模型中的bn层一键转化为同步bn(syncbn)