零.前言
上一篇已经完成了内核的基本移植,并且支持NAND FLASH读写,这篇只需要制作保存在NAND FLASH的文件系统,那么一个基本的LINUX系统就建立了。
一.准备制作
建立根目录,该目录就要我们要移植到目标板上的目录,对于嵌入式的文件系统,根目录下必要的目录包括bin,dev,etc,usr,lib,sbin。
用shell脚本创建根文件系统的目录结构
首先 touchbuild_fs.sh
然后进行编辑,用vim,键入以下内容:
#!/bin/sh
echo "------Create rootfs directons......"
mkdir rootfs
cd rootfs
echo "--------Create root,dev......"
mkdir root dev etc bin sbin mnt sys proc lib home tmp var usr
mkdir usr/sbin usr/bin usr/lib usr/modules
mkdir mnt/usb mnt/nfs mnt/etc mnt/etc/init.d
mkdir lib/modules
chmod 1777 tmp
cd ..
echo "-------make direction done---------"
二.配置,编译,安装busybox
Busybox 官方网站:http://www.busybox.net/
编译默认 busybox配置
#make defconfig
#make
手工配置:构建一个具有特殊需求的嵌入式设备
#make menuconfig
#make
#make install
由于我在”makemenuconfig”的交叉编译前缀配置(BusyboxSettings->build Options->CrossCompile prefix)老是不成功,因此我修改了根目录下的Makefile,把arch和编译工具链头修改了
CROSS_COMPILE ?=/usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-
ARCH ?= arm
网上资料也提供了另一种方法:
#make menuconfig
#make ARCH=arm CROSS_COMPILE=arm-linux-
#make install
制定安装路径的方法:
make
makeCONFIG_PREFIX=/home/noted2011/rootfs/rtfs install
三.制作文件系统
在 dev 目录下,创建两个设备节点 :#mknod console c 5 1
#mknod null c 1 3
进入 etc 目录,添加文件 :
1. 拷贝 Busybox-1.19.2/examples/bootfloopy/etc/* 到当前目录下。
# cp -r ../../busybox-1.19.2/examples/bootfloopy/etc/* ./
包括的文件 :fstab 、 init.d 、 inittab 、 profile
2. 拷贝 /etc/passwd 、 /etc/group 、 /etc/shadow 到当前目录下。
# cp /etc/passwd ./
# cp /etc/group ./
# cp /etc/shadow ./
把 passwd 文件中的第一行: root:x:0:0:root:/root:/bin/bash 中的 /bin/bash ,改成 /bin/ash ,因为文件
系统的 bin 目录下没有 bash 这个命令,而是用 ash 代替 bash ,所以在用用户名密码登录的时候 ( 如
telnet) ,会出现 “cannot run /bin/bash: No such fileor directory” 的错误。
3. 修改 inittab 文件:
内容如下:
console::sysinit:/etc/init.d/rcS
ttyS0::respawn:-/bin/sh
s3c2410_serial0::askfirst:-/bin/sh
::once:/usr/sbin/telnetd -l /bin/login
::ctrlaltdel:/bin/umount -a -r
4. 修改 fstab 文件 , 内容如下:
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
var /dev tmpfs defaults 0 0
5. 修改 init.d/rcS 文件,内容如下:
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
#echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /var/lock
/bin/hostname -F /etc/sysconfig/HOSTNAME
ifconfig eth0 192.168.0.15 up
/sbin/telnetd
说明:这里的 ip 地址根据自己的需求进行配置。
6. 修改 profile 文件,内容如下:
# Ash profile
# vim: syntax=sh
# No core files by default
#ulimit -S -c 0 > /dev/null 2>&1
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
echo " Processing /etc/profile... "
echo "Done"
export USER LOGNAME PS1 PATH
7. 新建 sysconfig 文件夹,在里面新建 HOSTNAME 文件,内容为: OK2440
说明:以上操作都是在 etc 目录下进行的。
8. 拷贝库文件:
进入 lib 目录,拷贝交叉编译器的库文件到 lib 目录下
写一个 cp.sh 脚本
#!/bin/sh
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib/
for file in libc libcrypt libdl libm libpthread libresolv libutil
do
cp $file-*.so /home/noted2011/rootfs/rtfs/lib/
cp -d $file.so.[*0-9] /home/noted2011/rootfs/rtfs/lib/
done
cp -d ld*.so* /home/noted2011/rootfs/rtfs/lib/ 由于交叉编译器的库文件比较多,体积较大,所以需要裁剪一下库文件,只保留常用的库文
件。
arm-linux-strip -s /home/noted2011/rootfs/rtfs/lib*
四、 制作调试工具 strace
使用 strace 可以跟踪程序执行时系统调用的相关信息,因此它是一个功能非常强大的调试和分析诊断工具。由于 Linux 系统中并没有包含程序,所以需要自己移植,整个移植过程非常简单。
1. 从 SourceForge 上下载 strace 的代码, http://sourceforge.net/projects/strace/
2. 解压 tar xvjf strace-4.5.20.tar.bz2
3. 配置 ./configure --host=arm-linux CC=arm-linux-gcc LD=arm-linux-ld
4. 编译,直接敲 make 即可,不用选择 “-static” 链接选项
5. strip , arm-linux-strip ./strace
6. 最后使用 file ./strace 查看编译结果,编译好的 strace 程序只有 200 多 K 。
最后将 strace 拷贝到 /home/noted2011/rootfs/rtfs /usr/sbin 目录下,即可使用。
五、 制作文件系统镜像
找一个 mkyaffs2image 工具
cd /home/noted2011/rootfs
./mkyaffs2image rootfs/ rootfs.yaffs
六、 可能出现的问题
1. 问题 1
Freeing init memory: 148K
ramdisk_execute_command=/linuxrc
linuxrc used greatest stack depth: 6072 bytes left
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[<c003169c>] (dump_backtrace+0x0/0x114) from [<c02c0a84>](dump_stack+0x18/0x1c)
r6:c03ae324 r5:c03c8ca4 r4:c03c8ca4
[<c02c0a6c>] (dump_stack+0x0/0x1c) from [<c02c0aec>](panic+0x64/0x180)
[<c02c0a88>] (panic+0x0/0x180) from [<c0049f2c>] (do_exit+0x7c/0x6d4)
r3:cf82ba80 r2:cf82bc94 r1:cf82bc60 r0:c0360377
[<c0049eb0>] (do_exit+0x0/0x6d4) from [<c004a608>](do_group_exit+0x84/0xb8)
[<c004a584>] (do_group_exit+0x0/0xb8) from [<c0058c04>](get_signal_to_deliver+0x348/0x384)
r4:0830009f
[<c00588bc>] (get_signal_to_deliver+0x0/0x384) from [<c0030338>](do_signal+0x70/0x600)
[<c00302c8>] (do_signal+0x0/0x600) from [<c00308e8>](do_notify_resume+0x20/0x64)
[<c00308c8>] (do_notify_resume+0x0/0x64) from [<c002daf8>](work_pending+0x24/0x28)
r4:beea9bf0
OK
搜索了网上的资料后,使用 arm-linux-gcc 4.0.0 以上的编译器编译内核时需要加上这个配置:
Kernel Features --->
[*] Use theARM EABI to compile thekernel
[*] Allow old ABI binaries to run with this kernel (EXPERIMENTA)
重新编译内核后,加载到单板上执行,初始化成功。
四. 制作Cramfs文件系统
Cramfs是专门为小而且简单的文件系统设计的,压缩比很高,用于在ROM芯片或者CD上存储文件系统。
JFFS/JFFS2都是开源的日志文件系统,最适合在Flash芯片上使用。
YAFFS是第一种专门为NAND Flahs时间的文件系统。
*制作自己的cramfs文件系统
Cramfsck用于解压cramfs文件系统
Mkcramfs用于制作cramfs文件系统