专业汉语词典知识平台,分享汉字词语知识、历史文学知识解答!

励北网
励北网

嵌入式linux入门基础教程

来源:小易整编  作者:小易  发布时间:2023-02-23 10:12
摘要:嵌入式linux入门基础教程01嵌入式Linux是什么嵌入式Linux跟桌面Linux一样,是一个操作系统。从单片机走过来的童鞋往往习惯于直接控制寄存器,事必躬亲,从零开始实现想要的功能。而在嵌入式Linux的世界里,我们首先要抛弃这个思想...

工欲善其事 必先利其器——IDE篇

其实Linux下有许多功能强大的IDE环境,因为从某种意义上说,Linux是专为开发者准备的操作系统,这个东西当然少不了,在这里为读者介绍一些比较常用的IDE。
KDevelop
这是一个用Qt开发的IDE,其主要支持的语言是C / C++,
Eclipse
近年来,eclipse可以说发展极为迅速,它不仅是一个以java为主的开发平台,其功能强大的插件体系结构使得它可以被当作各种应用程序来使用。作为各种插件的载体,eclipse提供了完整的GUI接口,用户完全可以借助eclipse来只关心自己想做的工作。

山高月晓 水落石出——IDE后台的故事 GCC篇

前面我们简要介绍了一些IDE环境,其中所有C/C++相关程序的编译都是由GCC来完成的,而IDE只不过起到了一个收集编译信息和为我们的项目生成makefile等作用(后面我们会提到)。出于目前Linux开发的特点,C仍是系统开发的主流语言。所以,对GCC有一个全面的了解是很有必要的,一旦IDE不能满足你的需求,我们要有手工打造程序的能力,而且出于学习的目的,我们往往不需要IDE生成的那些复杂的文件,为一个Hello world生成2M多的文件显然是多余的。
GCC的全称是GNU Compiler Collection,从这个名字我们不难看出,GCC代表着一个编译器的集合,目前GCC可以支持C, C++, Objective-C, Objective-C++, Fortran, Java, and Ada等语言。但是出于一般性考虑,我们这里只讨论GCC中的C/C++部分。
目前GCC的最新发布版是4.0.0,但是这个版本由于使用了新技术和新的编码规范,很多旧的代码都需要修改才可以通过编译,所以并不推荐使用这个版本。而相对稳定的新版本目前是3.4.4,大家可以到GNU的主页上更新下载。那么究竟GCC强大在哪里,如何使用?下面我就通过几个简单而实际的例子带你看看GCC提供的强大功能。

通过Helloworld的编译熟悉GCC的基本使用方法

似乎为所有新语言提供一个Hello World样本程序已经成为了一种不成文的标准,人们通过它来认识语言的一些基本要素。在这里,我们使用一个Hello World来看看如何用GCC生成可执行文件。
把上面的文件存成helloworld.c,之后打开控制台,输入如下的命令
gcc helloworld.c –o helloworld
如果一切正常的话,你的控制台上应该没有任何输出。用ls查看你的工作目录,你会发现目录下多了一个名为helloworld的可执行文件,之后,执行
./hellworld就会看到这个程序的输出了。
很简单不是吗?但是学过计算机的朋友都应该知道,程序的编译过程要分为下图所示的过程而GCC的强大之处就在于它允许你在上面所示的任何一个过程中停下来查看中间结果,并对其加以控制。
1. 预处理
首先是预处理过程,GCC的-E选项可以让GCC在预处理后停止编译,并向标准输出打印预处理过后的文件。下面的-o用于指定输出文件的文件名。
gcc –E hellowrold.c –o helloworld.cpp
下面是helloworld.cpp的一部分的内容,我们看到,文件已经包含了stdio.h中的内容。
如果我们想执行下一步的编译过程,可以继续使用GCC的-x 选项,该选项用于显示指定文件的后缀名(而不是让编译器根据后缀来自行判断)。我们比较常用的language type有如下几种,(如果读者想获得更为完整参数说名,请参考GCC manual):
l c c-header c-cpp-output
l c++ c++-header c++-cpp-output
l assembler assembler-with-cpp
另外,下表列出了常用的GCC后缀名

嵌入式linux入门基础教程


当然,你也可以省略掉language type的部分,这时候GCC会根据文件的后缀名自行判断,就像你没有使用该选项一样。
下面继续我们的编译过程
2. 编译
如果我们想获得编译后的源文件可以使用-S选项,该选项让gcc只执行编译(生成汇编文件)而不进行汇编(生成目标文件),此时,我们可以用-o选项指定输出的汇编文件的名称。
gcc –S helloworld.cpp –o hellowrld.S
3. 汇编
另外,我们还可以使用GCC的-c选项来编译和汇编源文件而不链接,此时-o指定的输出文件就是编译后的目标文件名:
gcc –x c++ -c helloworld.cpp –o helloworld.o
4. 链接
最后,我们可以利用GCC来把我们刚才生成的.o文件链接成可执行程序
gcc helloworld.o –o helloworld
这一次,我们使用了-o选项指定了可执行文件名,也就是说,根据输入文件类型的不同,-o有着不同的含义。
5. 函数库的链接和包含文件
对于我们编写的任和一个程序,没有库函数的支持是不可想象的,而当我们要使用的头文件和函数库不在GCC默认的搜索路径下的时候(例如OpenGL、Qt、KDE、Boost等),我们就需要手工来告诉GCC他们的位置。
先来看头文件路径的指定。我们可以利用-I来指定我们希望GCC去搜索的头文件目录,例如我们要使用X11的程序,我们就要使用下面的选项再来看库函数的设置:我们通过-L和-l两个命令行选项完成任务。其中-L用于告诉GCC在中去寻找函数库,而-l选项则告诉GCC使用用户指定的程序库。在Linux中,函数库的命名是遵循UNIX约定的,即lib{lib name},例如libsocket.so,所以当你需要告诉GCC使用这些库的时候,你就可以使用-lsocket选项。通常,这两个命令是结合在一起使用的,例如引用X11程序库的时候,我们可以这样:
–L/usr/X11R6/lib –lX11
另外,GCC在默认情况下使用共享库来链接程序,而当你想链接静态库的时候,一定要使用-static选项,例如-lncurses -static
在这一部分的最后,我们对编译时用到的GCC常用命令做一个简要的总结

嵌入式linux入门基础教程


上面,我们提到了关于GCC编译的常用命令,这里另外补充一些帮助性的常用命令,他们可以让你对GCC的基本配置和使用作一个了解。
在这部分的最后,我们来谈一谈关于构建软件时链接参数的设定问题。在上面的第5部分我们已经提到了,函数库的使用是需要-L和-l一起配合来使用的,但实际上,往往一个像样的程序需要很多库的支持,例如,如果你需要编写一个GTK程序,我们需要下面的链接参数:
-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 –lm,看上去有些吓人,你可能会问,我如何知道需要这些呢,如果我想编写KDE的程序呢,还有OpenGL呢?其实,情况比你想象的要好很多,在/usr/bin目录下,有很多名为xxx-config的脚本,它们的作用就是向用户显示编译链接程序时使用的参数的。这些脚本可以接受一些参数,比较常用的有—libs用于列出链接特定程序时使用的程序库,另外--cflags用于生成头文件的包含目录,也就是上面我们提到的-I参数。于是,对于GTK程序,我们可以使用下面的命令来编译:
gcc gtksource.c `gtk-config –libs --cflags`
当然,为每一种程序写一个config显然不是一个好办法,目前新的开发包都使用pkg-config这个脚本来生成链接参数。你可以使用pkg-config –list-all查看pkg-config支持的所有链接参数
当你在上面这份列表中查到了自己想要程序包时,就可以使用下面的命令来编译程序了
gcc .suffix `pkg-config --libs --cflags`

让GCC帮助你更好的工作

上面我们简单介绍了GCC的常用命令行选项,其实GCC的功能比上面提到的那些要丰富得多,GCC对代码的警告、优化、调试等方面提供了丰富的支持,下面我们就从一些例子来看看GCC提供的这些功能。
1.对问题代码提出警告
GCC对程序代码提供了完整的检查功能,由于C/C++语言本身的特点,很多错误都是程序员无意间犯下的,例如使用了未定义的变量、在bool表达式中使用了=而不是==等等问题,利用GCC提供的代码检查功能,我们可以让编译器为我们找到这些问题,避免运行时发生灾难。
首先,我们来看一个“问题代码”

/* test_warning.c We use this file to check the warning facilities provided by GCC*/#include#includevoid main() { /* main should return int*/int a, b;long long l = 2.2; /* long long type is GNU extension, not standard ANSI / ISO type*/miss_decl(); /* We call an undeclared function*/if (a = 0) /* May be we want == here instead of =*/printf (“a really equals to 0?/n”);if (b != 0) /* We used uninitialized variables*//* %d and “We should put b here” don’t match*/printf(“We make a mistake again! b = %d/n”, “We should put b here”);};void miss_decl() {/* /* This type of annotation is prohibited*/printf(“We should put the declaration before it’s been used!/n”);}

上面这些代码故意制造了很多编程中出现的常见问题,接下来,我们就用这段代码来检测一下GCC提供的各种常用的警告设施。
首先,我们不使用任何警告设施编译上面的程序
gcc test_warning.c –o test_warning
默认情况下,GCC会给出输出,其中GCC识别出了main函数不标准(warning)以及使用了未声明的函数(error)两个问题,但是其他的GCC并未察觉。
利用-pedantic找出不符合ANSI / ISO标准的代码
执行下面的命令:
gcc –pedantic test_warning.c –o test_warning
可以看到,这次GCC以警告的形式报告了代码中long long的使用,但是要说明的是我们并不能依赖这个选项来保证我们的代码完全符合ANSI / ISO标准,因为该选项只报告ANSI C要求编译器进行检察的内容。另外,你还可以使用-pedantic-errors让GCC把所有的警告都变成错误。
利用-Wformat检查printf中的参数不匹配问题
执行下面的命令:gcc –Wformat test_warning.c –o test_warning
利用-WComment找出注释中的错误
执行下面的命令:gcc –WComment test_warning.c –o test_warning
利用-Wparentheses查找bool表达式中的=错误
执行下面的命令:gcc –Wparentheses test_warning.c –o test_warning
 用-Wuninitialized查找未初始化变量的使用
执行下面的命令:gcc –O –Wuninitialized test_warning.c –o test_warning
值得说明的是,在使用这个选项的时候,一定要配合上-O(后面我们会提到)选项
利用-Wimplicit-function-declaration / -Werror-implicit-function-declaration检查未声明函数的使用。
执行下面的命令:gcc -Wimplicit-function-declaration test_warning.c –o test_warning
另外-Werror-implicit-function-declaration和-Wimplicit-function-declaration作用是类似的,只是如果你使用了未声明的函数,前者会把它认为是一个错误。
如果你只是想对你的代码进行全面的检查,你大可不必把上面的选项一并列出来,GCC提供了-Wall选项,含义就是列出所有代码中的警告
执行下面的命令:gcc –Wall test_warning.c –o test_warning
如果你想走另一个极端,也就是不想让gcc输出任何警告,那么使用-w选项,该选项禁止所有的警告
执行下面的命令:
gcc –w test_warning.c –o test_warnin
<输出结果>
对于上面所有的选项,你都可以把它们和-Werror选项一起使用,这样就可以把所有的警告都变成错误。另外,如果你只是想对代码进行检查而并不执行编译的话,可使用-fsyntax-only选项,像下面的命令这样
gcc –fsyntax-only test_warning.c
基本上来说,我们常用的一些警告选项就是这些,而其中-Wall更是我们极为常用的功能。
2. 优化选项
这一部分的内容可以分成两部分,一部分是让编译器对代码进行分析后,进行的代码优化,另一部分是我们可以为编译器制定一些关于硬件的信息,让他生成对硬件结合的更好的代码,而我们之所以要用源代码来编译程序,很多情况下,是出于这方面的原因。
首先来看代码优化,从代码的整体优化上,GCC提供了下面的选项
-O –O1
这两个选项的含义是一样的,GCC将执行减少代码尺寸和执行时间的优化,对于那些会严重影响编译时间的优化选项,这个级别的优化并不会执行。
-O2
在这一级别GCC将会提供所有支持的优化,但这其中并不包括以空间换时间的优化手段,例如编译器不会使用循环展开和函数内联。和-O相比,该选项进一步加快了编译时间和生成代码的性能。
-O3
除了-O2提供的优化选项外,还指定了-finline-functions,-funswitch-loops和-fgcse-afer-reload选项,目的只有一个就是全力执行代码优化。
-Os
这个选项是专门用来优化代码尺寸的,-Os打开了所有-O2级别中不会显著增长代码尺寸的优化选项
-O0
该选项代表不执行优化
在这里要说明的是,尽管GCC提供了1~3和s这4个整体优化选项,但从实际的优化效果上来看,往往O3优化出来的程序的效率并不是最高的,而大部分情况下我们都在使用-O2,如果你希望获得最高的效率利益,那么不妨这4个选项都试试。另外,其实这些选项只不过是GCC提供的很多单方面优化的一个组合,如果你想了解更为具体的优化内容,可以去查看GCC手册,出于篇幅限制,这里不细谈了。最后要记住的一点是,如果你的程序是用于高精度数值计算的,那么记住不要使用上面任何的优化选项。
下面来看基于硬件优化,由于这部分和计算机硬件相关,这里仅用Intel的CPU做一些说明。
对于所有为Intel和AMD x86-64提供的优化选项都是用m开头的,下面写一些常用的选项:
-march
该选项用来指定CPU的类型,常用的有i386 / i486 / i586 / pentium-mmx / i686 / pentium2 / pentium3 / pentium-m / pentium4 / pscott / k6 / athlon / athlon-4 / k8等等,读者可以根据自己的情况进行指定。
-mfpmath
该选项用于指定浮点运算单元的类型。包括:387
使用标准的数学协处理器:sse
使用SSE指令集提供的标量浮点运算。在Pentium3 / Athlon-4以及更新的芯片上支持这个特性。另外,在pentium4以及AMD x86-64处理器上,SSE2还可以进行双精度浮点计算。
sse,387
混合使用387数学协处理器和SSE指令集,该选项可以充分的利用CPU的浮点寄存器和xmm寄存器,但是该选项还处在试验阶段。
-malign-double
该选项使得GCC把double / long double / long long类型的变量在4字节或2字节地址上对齐,在Pentium级的CPU上,这会使得代码的执行速度更快,当然带来的代价是需要更多的内存来执行程序。
-mmmx –msse –msse2 –msse3 –m3dnow
这些选项用来启动内置函数直接使用这些处理器扩展指令的功能。在编译3D或多媒体程序的时候,使用他们是非常有效的。
3. 对调试的支持
当程序出错的时候,我们可以在Visual Studio中轻松的进行调试,而在Linux中,一旦出现Segmentation Fault,似乎我们除了用眼睛去看代码就没有更好的选择了,其实情况不然,用GCC向程序加入一些适当的调试信息,我们可以利用GDB去调试程序。在这里,我们介绍最为常用的-g和-ggdb选项。
先来看-g。该选项可以利用操作系统的“原生格式(native format)”生成调试信息。GDB可以直接利用这个信息。尽管我们可以把-O和-g放在一起使用,但是,这种做法是极为不推荐的。
如果你想用GDB来调试程序,那么你可以使用-ggdb来让GCC为GDB生成更为丰富的调试信息,但是,此时你就不能用其他的调试器来进行调试了。
最后要说明的是,上面这两个选项都可以接受一个输出调试信息的级别,默认的级别是2。如果你指定1级(-g1),那么GCC会生成最少的调试信息,这包括函数和全局变量的描述信息,但是对于局部变量和行号等信息,在这个级别是不会输出的。另外一个级别是3级(-g3),在这一级别上,GCC会为程序中的所有宏定义和符号生成调试信息。
最后
通过阅读今天的这篇文章,希望童鞋们能过对想学习Linux开发中用到的一些基本的技术和知识有一个了解,并且能够自己动手开始做些试验性的工作,其实,这里还有很多问题没有谈到,例如利用GDB进行调试、利用make管理工程、利用autoconf为程序生成配置脚本、利用CVS管理程序源文件等等,这些问题有待在今后一起交流。

05嵌入式Linuxer进阶之路

Linux开发工程师

01

首先成长为一名Linux开发工程师,这是最基本的目标,他应该具备如下的素质:
(1)了解Linux基本概念和基本操作(历史,文化,起源)(命令行,配置,操作,开发模式)
(2)会使用Linux平台下的编辑器vi(默认安装,占内存小,方便向嵌入式移植)
(3)会使用Linux平台下的编译器GCC(相应的十几个命令行参数)
(4)会使用Linux平台下的管理工具Make(与Makefile相配合,尤其用于大项目中多平台移植的情况下)
(5)会使用Linux平台下的调试器GDB(可以了解底层硬件,及汇编指令)

嵌入式工程师

02

他更关心的是将来在哪一目标机上运行,不关心操作系统,进行的更多与编程相关的工作:
(1)合格的C程序的程序员(理解基本的控制结构:循环、分支、数组、指针)
(2)基本的编程思想(编程实践中总结算法)
(3)程序的编译和链接
(4)可执行文件内部(段、起始地址、如何加载执行)
(5)目标机处理器体系结构
(6)知道处理器的外设即System on Chip(内部存储结构及外设驱动)
(7)汇编语言及指令(主要是用在加载过程中)

系统工程师

04

系统工程师夹在驱动工程师及应用工程师这两个层次之间,他要对系统有一个整体的概念,系统主要是指操作系统,往往理论有余而实践不足:
(1)进程管理与调度(知道进程间的切换与调度,多任务)
(2)内存管理(建立MMU页表,知道从虚地址到物理地址的映射)
(3)驱动管理(管理设备,编写设备驱动,加载设备驱动)
(4)文件系统(制作文件系统,文件系统的读写,甚至驱动有时也被当成文件系统来管理)
(5)网络协议知识(协议实现作为上层应用与底层驱动之间的衔接)
(6)图形系统知识(支持多窗口及管理窗口,包括窗口切换,窗口移动和覆盖)

嵌入式Linux系统工程师

05

(1)嵌入式Linux基本概念
(2)交叉编译
(3)Linux内核开发和调试工具
(4)启动代码移植(修改Uboot,Vivi等)
(5)内核交叉编译(Linux不支持芯片时要芯片级的移植,支持芯片时要板级的移植)
(6)根文件系统制作
(7)设备驱动程序开发
下面针对一个简单的"hello world"程序来区分一下以上所讲的工程师之间的区别:
#include<stdio.h>
int main(void)
{
printf("hello world!\n");
}
初级程序员看到的是:
a、头文件
b、主函数main
c、子函数printf
d、函数调用
e、入口参数
f、参数返回

本文地址:百科问答频道 https://www.neebe.cn/wenda/903277_2.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!


百科问答
小编:小易整编
相关文章相关阅读
  • LINUX虚拟化是什么意思?

    LINUX虚拟化是什么意思?

    Linux虚拟化是把一台PC上的Linux系统装到一个物理主机上,同时可以在同一台物理主机上运行多个操作系统,这样可以让数据中心或大型机器获得更大的效能和空间。虚拟化技术可以在物理机上虚拟出多台虚拟机,这样每台虚拟机上的Linux系统就不...

  • linux的hostname(主机名)修改详解

    linux的hostname(主机名)修改详解

    Linux操作系统的hostname是一个kernel变量,可以通过hostname命令来查看本机的hostname。也可以直接cat/proc/sys/kernel/hostname查看。#hostname#cat/proc/sys/...

  • linux入侵提权(服务器提权)方法

    linux入侵提权(服务器提权)方法

    利用mysqlroot提权方法mysql5.x里面引入了一个system函数,这个函数可以执行系统命令,当mysql以root登陆的时候,就可以利用这个函数执行命令,当然是在权限许可的范围内。一般我们按照常规思路,搞到mysql的ro...

  • 详解Linux中hdparm命令查看硬盘信息的用法

    详解Linux中hdparm命令查看硬盘信息的用法

    功能说明:显示与设定硬盘的参数。语  法:hdparm[-CfghiIqtTvyYZ][-a][-A][-c][-d][-k][-K][-m][-n...

  • fuser软件在Linux系统下的使用方法

    fuser软件在Linux系统下的使用方法

    在Linux中,fuser工具可用来查询文件的用户,除此之外,fuser还有很多用途,能够搭配参数使用,下面小编将针对fuser工具的使用方式给大家做个详细介绍,希望对你有所帮助。lsof也具备类似的功能,它也能够找出正在对指定文件访问的进...

  • CloudLinux是什么

    CloudLinux是什么

    CloudLinux是一个基于CentOS的Linux发行版,是专为虚拟主机开发的操作系统。CloudLinux可以有效的限制共享账户占用资源,使得每台服务器能够放置更多地账户,并且更稳定。CloudLinux是一个基于Ce...

  • Linux是什么操作系统

    Linux是什么操作系统

    Linux是一套免费使用和自由传播的类Unix操作系统,是一个多用户、多任务、支持多线程和多CPU的操作系统,它能运行主要的UNIX工具软件、应用程序和网络协议,它支持32位和64位硬件;具有稳定、开源、免费、安全、高效的特点操作系统是指直...

  • SELinux 是什么意思

    SELinux 是什么意思

    安全增强型Linux(SELinux)是专门为Linux内核制作的安全模块,采用C编程语言编写,支持访问控制安全策略的功能,包括强制访问控制(MAC)。安全增强型Linux(SELinux)是专门为Linux内核制作的安全模块,它支持...

  • 周排行
  • 月排行
  • 年排行

精彩推荐