构建嵌入式liunx系统.docx
- 文档编号:4420833
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:11
- 大小:21.28KB
构建嵌入式liunx系统.docx
《构建嵌入式liunx系统.docx》由会员分享,可在线阅读,更多相关《构建嵌入式liunx系统.docx(11页珍藏版)》请在冰豆网上搜索。
构建嵌入式liunx系统
构建嵌入式liunx系统
4.1.1基础知识
由于一般嵌入式开发系统存储容量有限,在裁减和定制Linux,运用于嵌入式系统前,通常需要在PC机上建立一个用于目标机的交叉编译环境,也就是将各种二进制工具程序集成为工具链,其中包括如GNU的链接器(ld)、GNU的汇编器(as)、ar(产生修改和解开一个存档文件)、C编译器(gcc)以及C链接库(glibc)。
本文以在Linux系统上针对目标机arm为例,介绍了跨平台开发工具链的建立过程。
2什么是交叉编译?
简单地说,交叉编译就是在一个平台上生成在另一个平台上执行的代码。
这里的平台包括体系结构(Architecture)和操作系统(OS)。
同一个体系结构可以运行不同的操作系统,同样,同一个操作系统也可以在不同的体系结构上运行。
举例来说,x86Linux平台是Intelx86体系结构和Linuxforx86操作系统的统称。
为什么要用交叉编译?
原因有两个。
一是目标平台所需要的bootloader以及OS核心还没有建立时,需要作交叉编译。
二是目标机设备不具备一定的处理器能力和存储空间,即单独在目标板上无法完成程序开发,所以只好求助宿主机。
这样可以在宿主机上对即将在目标机上运行的应用程序进行编译,生成可以在目标机上运行的代码格式,然后移植到目标板上,也就是目前嵌入式程序开发的Host/Target模式。
3对于i386的理解
如果单纯说i386、i686,就是指平时所说的CPU类型。
从Linux内核设计上讲,i386是架构,i486/586/686这些CPU的架构都是i386,所以很多linux方面的设计都是基于i386。
简单地说,i386跟ppc,alpha,arm等放在一起时就是指架构,跟i586,i686放在一起指处理器型号,一个是横向的,一个是纵向的。
4.1.2GUN跨平台开发链的建立过程
1选定软件版本
要想选用适当的版本,以保证建立的工具链可用,就必须找到适合主机和目标板的组合。
这些可以自己测试,也可以从网上寻找已经测试过的版本组合,即binutils、gcc、glibc的版本组合。
我用的宿主机为redhat-9.0,目标机arm,选择的版本如下:
-----------------------------------------------------------------------------
binutils-2.11.2.tar.gz包含有ld、ar、as等一些产生或者处理二进制文件的工具。
gcc-core-2.95.3.tar.gz包含GCC的主体部分。
gcc-g++2.95.3.tar.gz可以使GCC编译C++程序。
glibc-2.2.4.tar.gzlibc是很多用户层应用都要用到的库,即C链接库。
glibc-linuxthreads-2.2.4.tar.gzlibc用于支持Posix线程单独发布的压缩包。
linux-2.4.21.tar.gz+rmk1Linux的内核及其支持ARM的补丁包。
-----------------------------------------------------------------------------
你可以尝试选定更新的版本,编译无法通过时,依次使用较旧的版本。
即时发现新版本组合能够编译成功,仍然需要测试建立的工具链是否可以使用。
你可以从FTP网站ftp:
//ftp.gnu.org/gnu/或者任何其他的镜像网站下载GNU工具链的各个组件:
binutils包位于binutils目录,gcc包位于gcc目录,而glibc包与glibc-linuxthreads包放在glibc目录。
下面给出上面选用的各个版本的下载路径。
-----------------------------------------------------------------------------
binutils-2.11.2.tar.gz
ftp:
//ftp.gnu.org/gnu/binutils/binutils-2.11.2.tar.gz
gcc-core-2.95.3.tar.gz
ftp:
//ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz
gcc-g++2.95.3.tar.gz
ftp:
//ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz
glibc-2.2.4.tar.gz
ftp:
//ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz
glibc-linuxthreads-2.2.4.tar.gz
ftp:
//ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz
linux-2.4.21.tar.gz+rmk1
ftp:
//ftp.kernle.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz
ftp:
//ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/patch-2.4.21-rmk1.gz
-----------------------------------------------------------------------------
2建立工作目录
我的用户名为lqm,所以所有的工作都在/home/lqm下面建立完成。
输入命令用红色标记,结果用绿色。
***************************************************
$cd/home/lqm进入工作目录
$pwd查看当前目录
/home/lqm
$mkdirembedded-system创建工具链文件夹
$ls查看/home/lqm建立的所有文件
embedded-system
***************************************************
现在已经建立了顶层文件夹embedded-system,下面在此文件夹下建立如下几个目录:
-----------------------------------------------------------------------------
setup-dir存放下载的压缩包
src-dir存放binutils、gcc、glibc解压之后的源文件
kernel存放内核文件,对内核的配置和编译工作也在此完成
build-dir编译src-dir下面的源文件。
这是GNU推荐的源文件目录与编译目录分离的做法。
tool-chain交叉编译工具链的安装位置
program存放编写程序
doc说明文档和脚本文件
-----------------------------------------------------------------------------
下面建立目录,并且下载源文件。
***************************************************
$pwd
/home/lqm/
$cdembedded-system
$mkdirsetup-dirsrc-dirkernelbuild-dirtool-chainprogramdoc
$ls
build-dirdockernelprogramsetup-dirsrc-dirtool-chain
$cdsetup-dir
$wgetftp:
//ftp.gnu.org/gnu/binutils/binutils-2.11.2.tar.gz下载源文件
$wgetftp:
//ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz
$wgetftp:
//ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz
$wgetftp:
//ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz
$wgetftp:
//ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz
$wgetftp:
//ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz
$wgetftp:
//ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/patch-2.4.21-rmk1.gz
$ls
binutils-2.11.2.tar.gzgcc-g++-2.95.3.tar.gzglibc-linuxthreads-2.2.4.tar.gz
patch-2.4.21-rmk1.gzgcc-core-2.95.3.tar.gzglibc-2.2.4.tar.gzlinux-2.4.21.tar.gz
$cd../build-dir
$mkdirbuild-binutilsbuild-gccbuild-glibc建立编译目录
***************************************************
3输出环境变量
在建立与使用某些工具程序时,可能会用到这些目录的路径,如果设计一个简短的命令脚本,设定适当的环境变量,则可以简化操作过程。
下面就建立命令脚本hjbl:
***************************************************
$pwd
/home/lqm/embedded-system/build-dir
$cd../doc
$mkdirscripts
$cdscripts
$vihjbl用文本编辑器emacs编译环境变量脚本
-----------------------------------------------------------------------------
在随后打开的emacs编辑窗口中输入下面内容(如果在命令行界面下,则必须要用到vi文本编辑器,emacs则不可以):
exportPRJROOT=/home/lqm/embedded-system
exportTARGET=arm-linux
exportPREFIX=$PRJROOT/tool-chain
exportTARGET_PREFIX=$PREFIX/$TARGET
exportPATH=$PREFIX/bin:
$PATH
保存后关闭emacs窗口,如果要在目前的窗口中执行此脚本,即让环境变量生效,还需要执行下面的语句:
-----------------------------------------------------------------------------
$.hjbl(注意:
在点和hjbl之间有一个空格)
$cd$PRJROOT验证环境变量是否生效
$ls
build-dirdockernelprogramsetup-dirsrc-dirtool-chain
***************************************************
该环境变量的作用时间仅仅在Terminal当前窗口,如果将窗口关闭,开启一个新的窗口,则环境变量实效,需要重新执行下面的命令:
$./home/lqm/embedded-system/doc/scripts/hjbl
说明:
TARGET变量用来定义目标板的类型,以后会根据此目标板的类型来建立工具链。
参看表1。
目标板的定义与主机的类型是没有关系的,但是如果更改TARGET的值,GNU工具链必须重新建立一次。
PREFIX变量提供了指针,指向目标板工具程序将被安装的目录。
TARGET_PREFIX变量指向与目标板相关的头文件和链接库将被安装的目录。
PATH变量指向二进制文件(可执行文件)将被安装的目录。
表1TARGET变量值
实际的目标板
TARGET变量值
PowerPC
powerpc-linux
ARM
arm-linux
MIPS(bigendian)
mips-linux
MIPS(littleendian)
mipsel-linux
SuperH4
sh4-linux
4内核头文件的配置
内核头文件的配置是建立工具链的第一步。
它与后面将要执行的其他步骤有着类似性,大多需要执行下面几步操作:
1、解压缩包
2、为跨平台开发设定包的配置
3、建立包
4、安装包
***************************************************
$pwd
/home/lqm/embedded-system/
$cdkernel
$tarxvzf../setup-dir/linux-2.4.21.tar.gz解压缩
$gunzip../setup-dir/patch-2.4.21-rmk1.gz
$cdlinux-2.4.21
$patch–p1<../../setup-dir/patch-2.4.21-rmk1给Linux内核打补丁
$makeARCH=armCROSS_COMPILE=arm-linux-menuconfig配置
$makedep
-----------------------------------------------------------------------------
变量ARCH和CROSS_COMPILE的值与目标板的架构类型有关。
如果使用PPC目标板,则ARCH=ppcCROSS_COMPILE=ppc-linux-。
如果使用i386目标板,则ARCH=i386CROSS_COMPILE=i386-linux-。
makemenuconfig是以文本菜单方式配置。
makexconfig是以图形界面方式配置。
makeconfig是纯文本方式界面配置。
一般选择makemenuconfig,注意在选项SystemTypes中选择正确的硬件类型。
配置完退出并保存,检查一下的内核目录中的kernel/linux-2.4.21/include/linux/version.h和autoconf.h文件是不是生成了,这是编译glibc是要用到。
version.h和autoconf.h文件的存在,说明你生成了正确的头文件。
然后,建立工具链需要的include目录,并将内核头文件复制过去。
-----------------------------------------------------------------------------
$cdinclude
$ln-sasm-armasm#可以查看一下,经过编译可以自动生成。
如果已经生成连接,则不必写
$cdasm
$ln-sarch-epxaarch#同上说明
$ln-sproc-armvproc#同上说明
#这些是针对makefile文件作出的修改
$mkdir–p$TARGET_PREFIX/include
$cp–r$PRJROOT/kernel/linux-2.4.21/include/linux$TARGET_PREFIX/include
$cp–r$PRJROOT/kernrl/linux-2.4.21/include/asm-arm$TARGET_PREFIX/include/asm
***************************************************注意:
1、不必再每次重新设定内核配置之后重建工具链,除非你变更了处理器或系统的类型。
工具链只需要一组可供目标板使用的有效头文件即可,这些头文件在前面的程序中早就已经提供了。
2、asm-linux文件夹放到目标文件夹$TARGET_PREFIX/include/时要更改名称为asm,因为配置文件的include包含都是
这也是交叉编译的不同之处。
否则就会出现类似下面的错误提示:
-----------------------------------------------------------------------------
done
_udivsi3
_divsi3
_umodsi3
_modsi3
_dwmd_lnx
libgcc1.s:
438:
asm/unistd.h:
Nosuchfileordirectory
make[1]***[libgcc1-asm.a]error1
-----------------------------------------------------------------------------
5binutils(二进制工具程序)的设置
binutils包中的工具常用来操作二进制目标文件。
该包中最重要的两个工具就是GNU汇编器as和链接器ld。
***************************************************
$cd$PRJROOT/src-dir
$tarxvzf../setup-dir/binutils-2.11.2.tar.gz
$cd$PRJROOT/build-dir/build-binutils
$../../src-dir/binutils-2.11.2/configure--target=$TARGET--prefix=$PREFIX
$make
$makeinstall
$ls$PREFIX/bin验证安装的结果是否正确
arm-linux-addr2linearm-linux-ldarm-linux-readelf
arm-linux-ararm-linux-nmarm-linux-size
arm-linux-asarm-linux-objcopyarm-linux-strings
arm-linux-c++filtarm-linux-objdumparm-linux-strip
arm-linux-gasparm-linux-ranlib
***************************************************
注意:
每个工具的文件名的前缀都是前面为TARGET变量设定的值。
如果目标板是i386-linux,那么这些工具的文件名前缀就会是i386-linux-。
这样就可以根据目标板类型找到正确的工具程序。
3.6初始编译器的建立
开始只能建立支持C语言的引导编译器,因为缺少C链接库(glibc)的支持。
等到glibc编译好之后,可以重新编译gcc并提供完整的C++支持。
***************************************************
$cd$PRJROOT/setup-dir
$mvgcc-core-2.95.3.tar.gzgcc-2.95.3.tar.gz#重命名
$cd$PRJROOT/src-dir
$tarxvzf../setup-dir/gcc-2.95.3.tar.gz
$cd$PRJROOT/build-dir/build-gcc
$../../src-dir/gcc-2.95.3/configure--target=$TARGET--prefix=$PREFIX--without-headers
--enable-languages=c
--------------------------------------------------------------------------------
因为是交叉编译器,还不需要目标板的系统头文件,所以需要使用--without-headers这个选项。
--enable-language=c用来告诉配置脚本,需要产生的编译器支持何种语言,现在只能支持C语言。
--disable-threads是因为threads需要glibc的支持。
准备好了Makefile文件,进行编译之前,需要修改src-dir/gcc-2.95.3/gcc/config/arm/t-linux文件,在TARGET_LIBGCC2_CFLAGS中添加两个定义:
-Dinhibit_libc-D__gthr_posix_h,否则会报错。
-----------------------------------------------------------------------------
$make
$makeinstall
***************************************************
3.7建立C库(glibc)
这一步是最为繁琐的过程。
目标板必须靠它来执行或者是开发大部分的应用程序。
glibc套件常被称为C链接库,但是glibc实际产生很多链接库,其中之一是C链接库libc。
因为嵌入式系统的限制,标准GNUC链接库显得太大,不适合应用在目标板上。
所以需要寻找C链接库的替代品,比如uClibc。
在这里,现以标准GNUC为例建立工具链。
***************************************************
$cd$PRJROOT/src-dir
$tarxvzf../setup-dir/glibc-2.2.4.tar.gz
$tarxvzf../setup-dir/glibc-linuxthreads-2.2.4.tar.gz--directory=glibc-2.2.4
$cd$PRJROOT/build-dir/build-glibc
$CC=arm-linux-gcc../../src-dir/glibc-2.2.4/configure--host=$TARGET--prefix=”/usr”
--enable-add-ons--with-headers=$TARGET_PREFIX/include
$make
$makeinstall_root=$TARGET_PREFIXprefix=””install
-----------------------------------------------------------------------------
在这里设定了install_root变量,指向链接库组件目前所要安装的目录。
这样可以让链接库及其头文件安装到通过TARGET_PREFIX指定的与目标板有关的目录,而不是建立系统本身的/usr目录。
因为之前使用--prefix选项来设定prefix变量的值,而且prefix的值会被附加到install_root的值之后,成为链接库组件的安装目录,所以需要重新设定prefix的值。
这样所有的glibc组件将会安装到$TARGET_PREFIX指定的目录下。
-------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 构建 嵌入式 liunx 系统
![提示](https://static.bdocx.com/images/bang_tan.gif)