嵌入式Linux开发基础知识

1、程序设计重要概念

一个程序本质上都是由 bss段、data段、text段三个段组成。这三个小鬼,在裸机开发中非常重要。因为它们涉及到程序运行时内存大小的分配。?!先来看看它们究竟有什么特殊功能,是骡子是马,拉出来溜溜嘛。

Ⅰ、bss段

通常是用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零。为什么要清零,因为bss段属于静态内存分配,也就是说等到需要用到时才会在栈中分配内存空间。

Ⅱ、data段

用于存放在编译阶段(而非运行时)就能确定的数据,可读可写。也是通常所说的静态存储区,赋了初值的全局变量、常量和静态变量都存放在这个域。data段其实包含读写数据段和只读数据段。只读数据段存放了 const 修饰的变量

Ⅲ、text段

 用于存放程序代码的区域,编译时确定,只读。更进一步讲是存放处理器的机器指令,当各个源文件单独编译之后生成目标文件,经连接器链接各个目标文件并解决各个源文件之间函数的引用,与此同时,还得将所有目标文件中的.text段合在一起,但不是简单的将它们“堆”在一起就完事,还需要处理各个段之间的函数引用问题。

2、连接脚本LDS

由于每个程序都由bss段、data段、text段组成,但是如何这些零散的段合成一个可执行文件。此时,就需要lds出马了。肯定又有疑问,lds是什么鬼啊?

lds属于脚本语言,也是有语法的。具体作用:指明text段、data段、bss段的存放地址以及运行地址。这里先不贴出代码。后续结合Makefile进行编译比较清楚。

3、Makefile

哈哈哈,怎么还有呢,单片机开发没有这么多要求啊!Makefile规定了如何编译工程文件,将所有的.c文件编译成可执行文件。其实Makefile还依赖于编译工具链。编译工具链了解gcc和arm-linux-gcc即可,前者编译的程序只能在x86上运行,后者编译的程序可以在arm板上运行。如何使用,后面结合例程会比较有印象。

4、常见汇编语法

接触过单片机都知道,代码运行是从main函数开始的,C语言是需要栈的,arm开发板是空白的,所以需要用汇编做一些初始化工作,然后调用main函数,进入C语言环境运行。

Ⅰ、基本语法

标号

操作码 操作数 1, 操作数 2, … ; 注释。

标号的作用是让汇编器来计算程序转移的地址。操作码是指令的助记符,它的前面必须有至少一个空白符, 通常使用一个“Tab”键来产生,汇编其实是机器指令的抽象,有兴趣可以了解指令集。不同指令对应不同的操作数,操作数1通常是指令结果的存储地址,通常是寄存器。具体代码不在这里贴出。可以参考杜春雷《ARM架构与编程》

5、基本环境搭建

开发最重要的还是平台,Java有Java平台和eclipse,单片机有keil平台,那么arm采用什么平台开发呢?采用Linux平台,?,那我们先安装个Linux系统吧,这里在Vmware虚拟机环境中安装Ubuntu。镜像地址:百问网->资料下载->002_JZ2440资料光盘_20180516(免费)->资料光盘->A盘->ubuntu-16.04.2-x64-100ask-for win7,8,10 64bit.zip;虚拟机:百问网->资料下载->002_JZ2440资料光盘_20180516(免费)->资料光盘->A盘->VMware-player-12.5.7-for win7,8,10 64bit.zip,安装Vmware之后选择打开虚拟机,即可进入Linux环境。

6、简单的Linux命令

ls:列出当前目录的文件

touch:创建新文件

rm:删除文件

mkdir:创建文件夹

rmdir:删除文件夹

mv:移动文件

copy:拷贝文件

cat:查看文件内容

gedit:程序图形编辑器

vi:vi编辑器

man:命令使用手册

info/help:帮助手册

这些命令都是可以带上参数的,使用时查看帮助手册,这里不贴出详细使用说明。

 

7、字节序

ARM寄存器有32位,均采用小字节序,也就是说对于0x12345678这样的数字,78是存放在低地址上的。

 

8、Linux命令进阶

 

Ⅰ、find命令

看名字就知道是跟查找有关系的命令。

格式:find 目录名 选项 查找条件

例子:find /work/001/ -name "test.txt"

条件支持通配符

注意:

1)如果没有指定查找目录,则为当前目录。

find . -name "*.txt" 其中.代表当前路径

find -name "*.txt" 没加路径,默认是当前路径下查找

 

2)find还有一些高级的用法,如查找最近几天(几个小时)之内(之前)有变动的文件

 

Ⅱ、grep命令

用来查找文件中符合条件的字符串

格式:grep [选项] [查找模式] [文件名]

例子:

grep -n "abc" test.txt 在test.txt中查找字符串abc

grep -rn "abc" * 在当前目录递归查找字符串abc

 

注意:

可以加入-w全字匹配。

r(recursive):递归查找

n(number):显示目标位置的行号

 

Ⅲ、file命令

识别文件类型

格式:file 文件名

例子:file ~/.bashrc 为ASCII 编码的text类型

 

Ⅳ、which/whereis命令

查询命令或者应用程序的所处位置

格式:which 命令名/应用程序名

例子:

which pwd 定位到/bin/pwd 

which gcc 定位到/usr/bin/gcc 

whereis pwd 查找到可执行程序的位置/bin/pwd和手册页的位置/usr/share/man/man1/pwd.1.gz

 

Ⅴ、gzip、bzip2命令

压缩或者解压缩

格式:gzip [选项] [文件名]

例子:gzip -l pwd.1.gz

gzip -k mypwd.1 得到了一个.gz结尾的压缩文件

gzip -kd 压缩文件名 该压缩文件是以.gz结尾的单个文件

常用选项:

-l(list) 列出压缩文件的内容 

-k(keep) 在压缩或解压时,保留输入文件。 

-d(decompress) 将压缩文件进行解压缩

 

1)如果gzip不加任何选项,此时为压缩,压缩完该文件会生成后缀为.gz的压缩文件

并删除原有的文件,所以说,推荐使用gzip -k来压缩源文件。

2)相同的文件内容,如果文件名不同,压缩后的大小也不同。

3)gzip只能压缩单个文件,不能压缩目录。

 

Ⅵ、tar命令

既然gzip,bzip不能压缩、解压多个文件,那么肯定有其他命令来完成。

格式:

1)、压缩

ar -czvf 压缩文件名 目录名

如: tar czvf dira.tar.gz dira

2)、查看

tar tvf 压缩文件名

如:tar tvf dira.tar.gz

3)、解压

tar xzvf 压缩文件名

tar xzvf 压缩文件名 -C 指定目录

如: tar xzvf dira.tar.gz 解压到当前目录

如: tar xzvf dira.tar.gz -C /home/book 解压到/home/book

 

tar常用选项:

-c(create) 表示创建用来生成文件包

-x:表示提取,从文件包中提取文件

-t可以查看压缩的文件。 -z使用gzip方式进行处理,它与”c“结合就表示压缩,与”x“结合就表示解压缩。

-j使用bzip2方式进行处理,它与”c“结合就表示压缩,与”x“结合就表示解压缩。

-v(verbose)详细报告tar处理的信息

-f(file)表示文件,后面接着一个文件名。

-C <指定目录> 解压到指定目录

 

Ⅶ、gcc与arm-linux-gcc编译工具链

一个程序从文本变成可执行文件的步骤:预处理、编译、汇编、链接

老生常谈了。

1)#开头的命令称为预处理命令,预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个.i文件中等待进一步处理。

2)编译就是把C/C++代码(比如上述的.i文件)翻译成汇编代码

3)汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件)。反汇编是指将机器代码转换为汇编代码,这在调试程序时常常用到。

4)链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

 

这些跟gcc/arm-linux-gcc有什么关系呢?

 

gcc -E -o 预处理文件.i 源文件.c #预处理

gcc -S -o 汇编文件.s 预处理文件.i #编译

gcc -c -o 二进制文件.o 汇编文件.s #汇编

gcc -o 可执行文件.bin 二进制文件.o #链接

 

注意:

gcc -lc 链接libc库文件,其中libc库文件中就实现了printf等函数

gcc -nostdlib 链接时请勿使用标准系统启动文件或库。没有启动文件

对于BootLoader、Linux内核,常用第二种,它们不需要标准库函数支持

Ⅷ、动态链接和静态链接

链接还有分类的:动态和静态,有什么区别呢?

动态链接:链接时采用动态库进行链接,生成的程序在运行时需要加载所需要的库,这样生成的程序体积比较小,但是必须依赖所需要的动态库。

静态链接:生成的程序包含程序运行所需要的全部库,可以直接运行,不过静态链接生成的程序体积较大。

 

对应gcc语法:

gcc -c -o hello.o hello.c

gcc -static -o hello_static hello.o

你可能感兴趣的:(随手笔记)