这本书讲解了从一无所有到整个embedded系统的整个构建过程。大概的过程有:决定系统组件,配置及建
立内核,建立根文件系统,设置引导软件与配置.下面较详细地说下下:
首先介绍一下书中n多的英文缩写:
ISA:Industry Standard Architecture
PCI:Peripheral Component Interconnect
PCI-SIG:PCI Special Interest Group(PCI专则小组)
PCMCIA:Personal Computer Menory Card International Association(可以让嵌入式系统更具弹性并
且易扩充)
PC/104:为了解决ISA机械规格的特点.与ISA有相同的电气信号,但机械规格易于扩充且坚固耐用.
VME:Versa Module Eurocard(Motorola,Mostek,Signetics合作开发的与处理器无关的总线)
CompactPCI:
SCSI:Small Computer System Interface
USB:Universal Serial Bus
IEEE1394:FireWire--Apple交给IEEE的
GPIB:General-Purpose Interface Bus(就是HP的HP-IB总线)
I2C:Inter-Integrated Circuit(集成电路间-最初由Philips提出)
MTD:memory technology device
DOC:DiskOnChip
CFI:Common Flash Interface
JEDEC:JEDEC Solid State Technology Association
NFTL:Nand Flash Translation Layer
FTL:Flash Translation Layer
ATA-ATAPI(IDE的真名)
IrDA:Infrared Data Association(红外线数据协会)
IrTTY:用来支持与16550-UART兼容的IrDA端口
IEEE 802.11(无限网络)
CAN(Controller Area Network控制器局域网络)
ARCnet:Attached Resource Computer NETwork
然后:
(以书章节为序,以作者述为具)
第四章:开发工具
1.组织自己的实际项目工作空间,eg.build-tools,kernel,rootfs,sysapps,tools
1.1 export PROJECT=daq-module
export PRJROOT=/home/karim/control-project/${PROJECT}
cd $(PRJROOT)
2.安装GNU跨平台开发工具链
2.1 任何交叉开发,需要二进制工具程序集成工具链:eg:ld,gas,ar,c编译器(gcc),c连接库(glibc)
2.2 从ftp://ftp.gnu.org/gun/下载组件:binutils,gcc,glibc,glibc-linuxthreads,[glibc-rypt
(glibc<2.2)]到$(PRJROOT)/build-tools
2.3 根据主机和目标板的型号,组合binutils,gcc,glibc的不同版本.(以PPC host,i386
target,binutils 2.10.1,gcc 2.5.3,glibc 2.2.3为例)
2.4 在建立跨平台工具链之前,将需要原生的工具链以及主机的一组有效的内核头文件.这些头文件一般
在/usr/include/linux,/usr/include/asm,/usr/include/asm-generic中
2.5 建立工具链要5步,分别是:内核头文件的设置,二进制工具程序设置,引导编译器的设置,C链接库的
设置,完整编译器的设置
2.5.1 大部分的工具链建立步骤都为:解包,为跨平台开发设定包的配置,建立包,安装包
2.5.1 工具链将会建立在$(PRJROOT)/build-tools中,建立的组件被安装在$(PRJROOT)/tools中
2.6 建立新的环境变量
export PROJECT=daq-module
export PRJROOT=/home/karim/control-project/${PROJECT}
export TARGET=i386-linux
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}${TARGET}
export PATH=${PREFIX}/bin:${PATH}
cd $(PRJROOT)
2.7 TARGET变量的完整清单见glibc源码包.eg
PowerPc powerpc-linux
ARM arm-linux
MIPS(big endian)mips-linux
MIPS(li endian) mipsel-linux
SuperH 4 sh4-linux
2.8准备build-tools dir
cd ${PRJROOT}/build-tools
mkdir build-binutils build-boot-gcc build-glibc build-gcc
2.9内核头文件的设置,
2.9.1 从kernel.org下载选定版本的内核到${PRJROOT}/kernel中
2.9.2 tar xzvf linux-2.4.18.tar.gz
2.9.3 mv linux linux-2.4.18
2.9.4 cd linux-2.4.18
2.9.5 make ARCH=i386 CROSS_COMPILE=i386-linux- menuconfig(参见第五章)
2.9.6 mkdir -p ${TARGET_PREFIX}/include
cp -r include/linux / ${TARGET_PREFIX}/include
cp -r include/asm-i386/ ${TARGET_PREFIX}/include/asm
cp -r include/asm-generic/ ${TARGET_PREFIX}/include
2.10 binutils的设置
2.10.1 binutils contains as,ld
,gasp,ar,nm,objcopy,objdump,ranlib,readelf,size,strings,strip,c++filt,addr2line
2.10.2 cd ${PRJROOT}/build-tools
tar xvfz binutils-2.10.1.tar.gz
cd build-binutils
../binutils-2.10.1/configure --target=$TARGET --prefix=${PREFIX}
make
make install
ls ${PREFIX}/bin
i386-linux-ar,i386-linux-ld...........
2.11引导编译器的设置
2.11.1 cd ${PRJROOT}/build-tools
tar zxvf gcc-2.95.3.tar.gz
cd build-boot-gcc
../gcc-2.95.3/configure --target=${TARGET} --prefix=${PREFIX} /
--without-headers --with-newlib --enable-language=c
make all-gcc
make install-gcc
ls ${PREFIX}/bin
增加了i386-linux-gcc......
2.12 C链接库的设置
cd ${PRJROOT}/build-tools
tar zxvf glibc-2.2.3.tar.gz
tar zxvf glibc-linuxthreads-2.2.3.tar.gz --directory=glibc-2.2.3
cd build-gcc
CC=i386-linux-gcc ../glibc-2.2.3/configure --host=${TARGET}/
--prefix="/usr" --enable-add-ons/
--with-headers=${TARGET_PREFIX}/include
(在链接库家你期间,会建立三组链接库:共享链接库,静态链接库,具有统计信
息的链接库)
make
make install_root=${TARGET_PREFIX} prefix="" install
(如果host和target的架构一样,make install上设置cross_compiling=yes)
最后,libc.so文件的设置:
cd ${TARGET_PREFIX}/lib
cp ./libc.so ./libc.so.orig
编辑libc.so,将绝对路径改为相对路径.eg./lib/libc.so.6-->libc.so.6
2.13 完整编译器的设置
cd ${PRJROOT}/build-tools/build-gcc
../gcc-2.95.3/configure --target=${TARGET} --prefix=${PREFIX} /
--enable-language=c,c++
make all
make install
2.14 完整工具链的设置
2.14.1 在${PRJROOT}/tools下有:bin ,i386-linux,include,info,lib,man,share
2.14.2 在${PRJROOT}/tools/i386-linux下有:
bin,etc,include,info,lib,libexec,sbin,share,sys-include
2.14.3 一些文件名前缀中没有目标板名称的主机工具称许会被安装到${PREFIX}/
${TARGET}/bin中,建议将主机二进制文件移到合适的目录中
需要移动的工具程序包括ar,as,gcc,ld,nm,ranlib,strip.可以用file命令查看这些文
件的确是主机二进制文件:
cd ${PREFIX}/${TARGET}/bin
file as ar gcc ld nm ranlib strip
查找移往的合适目录:
i386-linux-gcc -print-search-dirs
发现有programs:${PREFIX}/lib/gcc-lib/i386-linux/2.95.3,就是这个目录
.
mv as ar gcc ld nm ranlib strip/
${PREFIX}/lib/gcc-lib/i386-linux/2.95.3
2.14.4 在应用程序只会到${PREFIX}/${TARGET}/bin目录寻找工具程序的情况下,我们还要为这
些重新配置的二进制文件建立符号连接
for file in as ar gcc ld nm ranlib strip
do
ln -s ${PREFIX}/lib/gcc-lib/i386-linux/2.95.3/$file .
done
2.15 最后,想要节省空间的话,可以选择舍弃${PRJROOT}/builds-tools中的内容.
2.16 可以用uClibc,diet libc替代glibc,这里不说.
第五章 内核方面的考虑
1.选择内核
让目标板取得可用的内核,必须找到专门负责开发相应处理器架构的团队所提供的内核版本。
以ARM为例,可以到http://www.arm.linux.org.uk/developer/通过ftp和rsync取得.但是有些提供的只是
patch,所以一般可以这样.在http://www.kernel.org下载一般的2.4.18内核,并从
http://www.arm.linux.org.uk/上下载2.4.18-rmk15补丁,用补丁修改过后,就得到2.4.18-rmk15内核,
包含了ARM为基础的系统所需要的功能.
上面的rmk扩展名表示内核经Russell King维护过,如果以-np为扩展名,则由Nicolas Pitre维护
过,handhelds.org的Familiar的开发者们,则会为内核加上-hh的扩展名.
像上章一样,下载内核后,可以放在${PRJROOT}/kernel目录中.
2.内核配置
在配置好内核后,会生成一个.config文件以及建立过程其余步骤将用到的一些符号连接和头文
件.
2.1 内核配置选项
菜单中重要的就是用来为目标板选择处理器架构的选项.此选项的名称因架构而异.
也可以配置每种架构的硬件支持的选项.
2.2 设定配置的方法
make config,menuconfig,xconfig,oldconfig不详将区别了.
要检查内核配置菜单,只需在命令行上键入适当的命令以及参数.
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
(可根据实际target改变)
2.3 管理多种配置
可将生成的.config文件保存,移动.然后再用内核生成新的不同的.config,作为新的
配置.
2.4 使用EXTRAVERSION变量
该变量的值会被附加在内核的版本编号之后,成为内核建立完成后的最终版本编号.
可以编辑内核源码主目录中的Makefile文件,并将该变量该为你要的值.
3.编译内核
3.1 建立依存关系
要想顺利建立内核,内核源码树里各个Makefile必须知道这些依存关系.依存关系建立
期间会在内核源码树中每个子目录中产生一个隐藏的.depend文件.此文件内含子目录里各文件所依存的
头文件清单.如同其他靠make建立的软件,自从上次完成建立以来.如果要重新建立内核,只有在与头文件
有依存关系的文件被改动后才需要经过重新编译的程序.
一般用make ARCH=arm CROSS_COMPILE=arm-linux- clean dep
3.2 建立内核
make ARCH=arm CROSS_COMLILE=arm-linux- zImage
3.3 建立模块
make ARCH=arm CROSS_COMPILE=arm-linux- modules
如果需要清理内核的源码,让它恢复到配置设定,依存关系建立或编译之前的初始状态,
可以使用如下的命令:
make ARCH=arm CROSS_COMPILE=arm-linux- distclean
这个命令会清除前面几个阶段产生的文件,包括.config,所有目标文件以及内核映象.
4.安装内核
4.1 管理多个内核映象
有时“使用多个内核映象来测试目标板”很有用.以作者的设置来说,这些映象会被放
到${PRJROOT}/images中
对每个内核配置来说,需要复制四个档案:压缩的内核映象,未压缩的内核映象,内
核符号映射文件以及配置文件.他们的文件名分别是:zImage(bzImage),vmlinux,System.map,.config。
可以下相应的目录下找到这些文件。
然后以内核命名的方式复制这些文件:
cp arch/arm/boot/zImage ${PRJROOT}/images/zImage-2.4.18-rmk5
cp vmlinux ${PRJROOT}/images/vmlinux-2.4.18-rmk5
cp System.map ${PRJROOT}/images/System.map-2.4.18-rmk5
cp .config ${PRJROOT}/images/2.418-rmk5.config
4.2 安装内核模块
内核源码的Makefile文件包含的modules_install建立目标可用来安装内核模块.缺省
情况下,内核模块会被安装在/lib/modules中.然而,因为我们使用的是交叉开发环境,所以必须指示
Makefile将模块安装到另一个目录.
将模块安装到与内核映象类似的目录.以2.4.18-rmk5为例,把模块安装到
${PRJROOT}/images/modules-2.4.18-rmk5目录中。此目录稍后会被复制到目标板的根文件系统中,供目
标板上相应的内核使用。用下面的命令安装:
make ARCH=arm CROSS_COMPILE=arm-linux- /
INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.4.18-rmk5 module_install
一旦复制好模块后,内核就会根据模块果农国军程序执行时的要求,试着建立模块依存
关系。因为depmod这个用来建立模块依存关系的工具程序,并非用来处理交叉编译的模块,所以会失败
。这时,我们需要Busybox了。
从http://www.busybox.net/将Busybox包的副本下载到${PRJROOT}/sysapps中,并在
此处取出源码(下载>0.69.5的版本)。接着从存放Busybox源码的目录将scripts/depmod.pl命令复制到
${PRJROOT}/bin中。
现在可以建立目标板模块的依存关系了
depmod.pl /
-k ./vmlinux -F ./System.map /
-b ${PRJROOT}/images/modules-2.4.18-rmk5/lib/modules> /
${PRJROOT}/images/modules-2.4.18-rmk5/bin/modules/2.4.18-rmk5/modules.dep
5.实地测试