分类: LINUX
2010-09-29 18:45:43
1、 建立工作目录(这里建议统一用这个路径,否则在指定安装路径及copy库文件的路径都要改)
设定工作目录为/root/build_rootfs/, 下载busybox到该目录
mkdir
2、 建立根目录, 该目录就是我们要移植到目标板上的目录,对于嵌入式的文件系统,根目录下必要的目录包括bin,dev,etc,usr,lib,sbin,proc。
cd /root/build_rootfs
mkdir rootfs
cd rootfs
mkdir bin dev etc usr lib sbin proc
mkdir usr/bin usr/sbin usr/lib
(解析各目录的作用)
/bin bin是Binary的缩写。这个目录存放着最经常使用的命令。
/sbin s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。
/dev dev是Device(设备)的缩写。该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。
/etc这个目录用来存放所有的系统管理所需要的配置文件和子目录。
/usr 我们要用到的很多应用程序和文件几乎都存放在usr目录下
/usr/bin存放着许多应用程序;
/usr/sbin存放root超级用户使用的管理程序;
/usr/lib存放一些常用的动态链接共享库和静态档案库;
/lib这个目录里存放着系统最基本的动态链接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。
/proc这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。这个目录的内容不在硬盘上而是在内存里.
3、 交叉编译busybox
busybox的源码可以从下载,这里我们下载一个
我们在配置busybox的时候是基于默认配置之上来配置的;先make defconfig就是把busybox配置成默认,然后再make menuconfig来配置busybox。
说明:我们在配置一个源代码包之前,可以先阅读源码包目录下的README和INSTALL文件以及Makefile的注释部分,也可以到网站以获取帮助。
的第二个问题2 有介绍怎么去配置。
(1)、在/root/build_rootfs解压
tar jxvf busybox-
mv busybox-
cd busybox
(2)、添加交叉工具链
export PATH=/usr/local/arm/
(3)、配置编译
make defconfig
make menuconfig
配置时,我们基于默认配置,再配置它为静态编译,安装时不要/usr路径,把Miscellaneous Utilities 下的“taskset”选项去掉,不然会出错。
如下(按Y就会选上,N不选):
如果您正在构建一个具有特殊需求的嵌入式设备,那就可以手工使用 menuconfig make 目标来配置 BusyBox 的内容。如果您熟悉 Linux 内核的编译过程,就会注意到 menuconfig 与配置 Linux 内核的内容所使用的目标相同。实际上,它们都采用了相同的基于 ncurses 的应用程序。
使用手工配置,我们可以指定在最终的 BusyBox 映像中包含的命令。我们也可以对 BusyBox 环境进行配置,例如包括对 NSA(美国国家安全代理)的安全增强 Linux(SELinux),指定要使用的编译器(用来在嵌入式环境中进行交叉编译)以及 BusyBox 应该静态编译还是动态编译。图 1 给出了 menuconfig 的主界面。在这里我们应该可以看到可以为 BusyBox 配置的不同类型的应用程序(applet)。
Busybox setting
->builds options
->[*] build busybox as a static binary(a)
->installitation options
->[*] don’t use /usr (b)
Miscellaneous Utilities ―> (c)
[ ] taskset
其他选项都是一些linux基本命令选项,自己需要哪些命令就编译进去,一般用默认的就可以了。保存退出。
(a)这个选项是一定要选择的,这样才能把busybox编译成静态链接的可执行文件,运行时才独立于其他函数库.否则必需要其他库文件才能运行,在单一个linux内核不能使他正常工作。
(b)这个选项也一定要选,否则make install后,busybox将安装在原系统的/usr下,这将覆盖掉系统原有的命令.选择这个选项后,make install后会在busybox目录下生成一个叫_install的目录,里面有busybox和指向他的链接.
( c)
Taskset命令能够为即将执行的程式或已有进程指定affinity属性,让该程式或进程运行在指定的CPU上。下面是几个例子:
taskset ?c 1 nohup perl pi.pl & ---指定在1号CPU上执行指定的perl程式
taskset ?c 1 ?P 10284 ---将10284号进程限定在1号CPU上执行
4、编译安装
Make ARCH=arm CROSS_COMPILE=arm-linux- CONFIG_PREFIX=/et10/build_rootfs/rootfs all install
(此时bin(195个
ARCH指定平台
CROSS_COMPILE指定交叉编译
CONFIG_PRRFIX指定安装的路径
由于/root/build_rootfs/rootfs/linuxrc 和/root/build_rootfs/rootfs/sbin/init 是同一个程序,可以把linuxrc删除,以节省空间。
此时U-BOOT启动参数应该设为:
setenv bootargs root=/dev/mtdblock2 init=/sbin/init console=ttySAC0,115200 display=sam320 men=
如果不rm linuxrc,则 init=/linuxrc
也可以先rm linuxrc,再手写脚本 linuxrc。通过linuxrc 中执行“exec /sbin/init”来执行sbin/init。(如果没有/linuxrc这个文件,还是init=/linuxrc也没所谓,因为系统默认运行/sbin/init。----su)
5、 copy C库
交叉应用程序的开发需要用到交叉编译的链接库,交叉编译的链接库是在交叉工具链的lib目录下;我们在移植应用程序到我们的目标板的时候,需要把交叉编译的链接库也一起移植到目标板上,这里我们用到的交叉工具链的路径是/usr/local/arm/
(1) .so动态库
A、实际的共享链接库(libname-version.so)
如:libc-
B、主修订版本的符号链接. (lib.so.version)
程序一旦链接了特定的链接库,它将会使用其符号链接,程序启动时,加载器在加载程序之前,会加载该文件。
如:libc.so.6
C、与版本无关的符号链接(libname.so)
这些符号链接的只要功能是为需要链接特定的链接库的所有程序提供一个通用的条目,与版本号无关。
如:libc.so
(2) .a静态库
静态链接库包文件
如:libc.a
(1)、进入链接库目录
cd /usr/local/arm/
编写一个shell文件,用于copy实际的共享链接库;主修订版本的符号链接;动态连接器及其符号链接到目标板根目录下的lib。
w 主要的动态链接库:
ld 动态链接器
libc 主C链接库
libcrypt 秘密学链接库
libdl 用来动态加载共享文件的动态库
libm 数学库
libpthread多线程库
还可以通过arm-linux-readelf命令来找出应用程序依赖于哪些动态链接库;
如:arm-linux-readelf -d hello; //hello只是打印一句“hello”的程序;
(注意:要声明编译器
(2)、vi cp.sh
内容如下:
for file in libc libcrypt libdl libm libnss_dns libnss_files libpthread libresolv libutil
do
cp $file-*.so /root/build_rootfs/rootfs/lib (1)
cp -d $file.so.[*0-9] /root/build_rootfs/rootfs/lib (2)
done
cp -d ld*.so* /root/build_rootfs/rootfs/lib (3)
cp -d libgcc_s*.so* /root/build_rootfs/rootfs/lib /*标准C库*/
cp -d libstdc++.so* /root/build_rootfs/rootfs/lib
cp -d * /root/build_rootfs/rootfs/usr/lib
cp -d libz.so* /root/build_rootfs/rootfs/usr/lib
#cp -d libpng*.so* /root/build_rootfs/rootfs/usr/lib
cp -d libjpeg.so* /root/build_rootfs/rootfs/usr/lib /*解码库*/
(-d 保持原来的链接属性)
(3)、保存退出
(1)第一个cp命令会复制实际的共享库
(2)第二个cp命令会复制符号链接本身
(3)第三个cp命令会复制动态连接器及其符合链接
(4)、执行刚编写的shell。
source cp.sh
( lib(20个
这样就把链接库复制过来了。
(5)、接着我们还要缩小复制过来的链接库的体积,如下(此时会提示2个文件找不到,可忽略。当需要这2个库时再拷贝进来即可):
arm-linux-strip –s /root/build_rootfs/rootfs/lib/lib*
(lib由
6、 建立配置文件
这里我们没有添加inittab(执行顺序)等文件,我们只是添加了一个c shell初始化时读取的文件。
内核启动的最后,会执行sbin/init程序,init程序在启动的最后会执行/bin/sh,sh在启动的时候会读取文件。
我们在/etc/profile文件里设定PATH,LD_RARYLIB_PATH环境变量,目的是配置用户程序运行的环境。
cd /root/build_rootfs/rootfs/etc
vi profile
内容如下
#!/bin/sh
echo "Set seaech library in /etc/profile"
export LD_LIBRARY_PATH=/lib:/usr/lib //定义查找可用共享对象的位置
echo "Set user path in /etc/profile"
export PATH=/bin:/sbin:/usr/bin:/usr/sbin //命令的路径
保存退出
7、 添加一个用户程序
进入工作目录
cd /root/build_rootfs/
编辑源文件
vi hello.c
内容如下
#include
main()
{
printf(“welcome to my rootfs\n”);
}
保存退出
交叉编译
arm-linux-gcc hello.c –o hello
复制到目标板的根目录
mv hello /root/build_rootfs/rootfs/usr/bin
8、 制作cramfs映像
找到mkcramfs工具,把它复制到“/root/build_rootfs”目录下。
或者在网上下一个
cramfs-1.1工具下载地址: 或则去官网
然后解压,make你就会看到有两个工具一个用于制作.cramfs,另一个是用来制作.jsff2文件系统的
cd /root/build_rootfs/
./mkcramfs rootfs rootfs.cramfs
rootfs.cramfs就是我们要烧写到目标板的映像文件
9、烧写rootfs.cramfs到3分区,启动开发板,运行hello程序。
将rootfs.cramfs文件拷贝到tftp下载的目录下,如拷贝到linux 系统中的/tftpboot目录;
开发板的u-boot通过tftp命令下载;
根据分区表来烧写;
10、U-BOOT下载和烧写:
烧写内核
tftp 30008000 zImage
nand erase 0x40000 0x
nand write 30008000 0x40000 0x
烧写根文件系统
tftp 30008000 rootfs.cramfs
nand erase 0x200000 0x1e00000
nand write 30008000 0x200000 0x1e00000
11、启动:
setenv bootargs root=/dev/mtdblock2 init=/sbin/init console=ttySAC0,115200 display=sam320 men=
setenv bootcmd nand read 0x30008000 0x40000 0x
saveenv
reset