嵌入式软件工程师&&太极拳
全部博文(548)
分类: 嵌入式
2012-01-07 10:43:41
文件系统主要完成系统内核之外的功能,提供文件组织结构, 功能模块(函数库,驱动),
应用程序等.本移植过程完成了 busybox+bash+ftp+vsftpd+telnetd+zlib,png,jpeg,tslib,opencv,qte4 的移植
系统环境:
硬件 :Intel p4 + 512 RAM
操作系统:Fedora8
软件版本: busybox-1.13.4+arm-linux-gcc-3.4.1+linux-2.6.22
一文件组织结构
1 目录组织形式(树)
基本的文件系统目录组成示例如下:
# 普通用户命令目录
bin
# 设备文件目录
dev
# 用户目录
home
# 默认的启动脚本,1 号进程 init 的执行程序
linuxrc
# 进程动态信息文件
proc
# 系统用户命令目录
sbin
# 临时文件目录
tmp
# 可变信息目录,如日志信息等
var
# 配置文件默认目录
etc
# 系统库默认目录
lib
# 系统模块的默认目录,如驱动模块等
|_ modules
# 挂载文件目录
mnt
# root 用户主目录
root
# 系统信息目录
sys
# 用户程序,库存放目录
usr
# 用户命令目录
|_ bin
# 用户的系统命令目录
|_ sbin
# 用户函数库目录
|_ lib
2 利用 busybox 创建基本的文件系统
(1)busybox 主要提供系统和用户命令集(如 ping, telnet, df ,rpm....)及启动脚本
(linuxrc 或 /sbin/init),
其实现思路就是把诸多可执行程序集成于一个大的程序,然后利用符号连接来传递启动
参数,如下 C 语言代码示例
#######################################################################
//busybox.c
#include
int main(int ac, char * av[])
{
printf("you are running sub progs : %s",av[0]);
return 0;
}
#gcc busybox.c -o busybox
#ln -s busybox ping
#./ping
#you are running sub progs : ./ping
#######################################################################
(2)busybox 的编译
i 首先修改 Makefile ,将以下两项改为
CROSS_COMPILE = /usr/local/arm/3.4.1/bin/arm-linux-
ARCH = arm
ii 在 make menuconfig 中
Busybox Settings --->
General Configuration --->
│[*] Use the devpts filesystem for Unix98 PTYs # for telnetd
Build Options --->
│[*] Build BusyBox as a static binary(no shared libs)
Installation Options --->
│[*] Don't use /usr
Busybox Library Tuning --->
│[*] vi-style line editing commands
|[*] Tab completion
Login/Password Management Utilities --->
|[ ] Support for shadow passwords
Linux System Utilities --->
│[*] mdev
|[*] Support /etc/mdev.conf
│[*] Support subdirs/symlinks
[*] mount
│[*] Support mounting NFS file systems
Miscellaneous Utilities --->
│[*] devfsd (obsolete) # for telnet
Networking Utilities --->
│[*] Support RPC services # for nfs mount
Shells --->
Choose your default shell (ash) --->
iii 其它配置根据需要裁减
iv 保存退出 Busybox ,
#make && make install
默认在 busybox-1.13.4/_install 目录中生成基本的文件系统, 包括以
下目录或文件
bin/ sbin/ linuxrc
该目录下包含了基本的 shell 命令, 其它目录的创建如下:
3 文件系统目录树的创建脚本:
#######################################################################
#!/bin/sh
DST=$1
if [$1 = ""]
then
DST=./
fi
cd $DST
mkdir -p bin dev etc lib proc sbin sys usr usr/bin usr/lib usr/sbin lib/modules
mkdir -p mnt tmp var mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
chmod 1777 tmp
mkdir -p home root
mknod -m 0666 dev/console c 5 1 # resolve error: could not open console...
mknod -m 666 dev/ptmx c 5 2 # for telnet
mknod -m 0666 dev/null c 1 3 # required by many procs
echo "done"
#######################################################################
将上述脚本保存为 mkfstree.sh, 并 chmod +x mkfstree.sh
然后 ./mkfstree.sh YOUR_DST_DIR ,将其它目录也创建到 busbox 生成的文件系统目录中
4 文件系统存储形式 cramfs jffs jffs2 yaffs yaffs2 nfs
cramfs, jffs, jffs2 yaffs yaffs2 文件系统的创建 都可以用 mkxxx 工具将 目录打包成相应数据结构的镜像
如: mkcramfs dir imgname.cramfs
mkyaffsimage dir yaffsname.img
这里主要介绍 yaffs2 文件系统的生成和烧写
1 从 下载 yaffs2.tar.gz , 解压,进入目录,
运行 patch-ker.sh $KERNEL_PATH 将内核增加 yaffs2 支持补丁
2 在 内核make menuconfig 时选择
<*> YAFFS2 file system support
<*> 512 byte / page devices
<*> Lets Yaffs do its own ECC
<*> 2048 byte (or larger) / page devices
<*> Autoselect yaffs2 format
<*> Disable lazy loading
<*> Turn off wide tnodes
<*> Turn off debug chunk erase check
3 make zImage
4 yaffs 文件系统安装
方法一: 用 yaffs 镜像安装
1) 先修改 yaffs2 解压目录下 util 文件夹中的 mkyaffsimage.c (修改方
法见下文)
2)在 shell 下 该目录中执行 make ,生成 mkyaffsimage 可执行程序,
3)再用 mkyaffsimage dir yaffsname.img
4)用友善之臂支持 yaffs 的 vivi,执行 loadyaffs root_yaffs u 进行下载
烧写(注意,不能用 load flash 方式)
方法二:
1) 先用 mount -t yaffs 挂载某个分区,如 mount -t
yaffs /dev/mtdblock5 /mnt/yaffs
2) 向 /mnt/yaffs 中拷入 文件系统的所有文件(不包括自身)即可
mkyaffsimage.c 的修改(略)参考
2 驱动模块
驱动模块的加载有两种方式:
第一种: 首先将驱动源码放在内核目录中,
修改 config.in 或 Kconfig 使其出现在 make menuconfig 菜单中,
修改 Makefile 以如 driver-$(CONFIG_MYDRIVER) +=mydriver.o
obj += driver-y
的形式将驱动加到内核模块中
且在 make menuconfig 要[*]选才行
另一种是单独编译,或在编译内核时[M]选, 然后将模块放在文件系统目录下(如
lib\modules),最后编写启动脚本用 insmod 命令将模块加到内核中
三 启动脚本的编写
1 文件系统的启动流程:
文件系统的启动可以通过修改内核启动参数来配置,如在 bootloader vivi 中
vivi> param set linux_cmd_line "noinitrd init=/linuxrc root=/dev/mtdblock4
rootfstyle=cramfs console=ttySAC0,115200"
vivi> boot
.....
其中 noinitrd 表示禁用 initrd 镜像(一个虚拟的小文件系统)的启动方式,
init= 指定 1 号 init 进程执行的命令,其值可以是
/linuxrc /sbin/init 或自己写的脚本, 若为脚本 有两点要注意,一是脚本第一行
要加上#!/bin/sh 的文件类型描述 信息, 二是要将其 chmod +x ,
否则内核启动时可能会出现 kernel panic , unableto execute /linuxrc 等等
的错误
启动流程:
内核启动后会按内核启动参数执行 init 进程,init 进程启动后会自动执行
/etc/inittab 脚本,如:
#######################################################################
::sysinit:/etc/init.d/rcS
::respawn:/bin/bash
::restart:/sbin/init
tty2::askfirst:/bin/bash
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
#######################################################################
第一行指令 init 进程启动后要执行的第一个本地脚本 /etc/init.d/rcS ,然
后用 rcS 来启动其它服务,
rcS 脚本示例如下:
#######################################################################
#!/bin/bash
echo "Processing etc/init.d/rcS"
hostname WALL_E
echo "Mount all...."
/bin/mount -a
mkdir -p var/lib var/lock var/log var/run var/tmp /tmp/empty
touch /var/log/vsftpd.log
chmod 666 /var/log/vsftpd.log
mkdir -p /var/ftp/pub
chmod 1777 var/tmp
chmod -R 666 /var/ftp
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
echo "starting mdev...."
mdev -s #
mkdir /dev/pts
mount -t devpts devpts /dev/pts
rm -fr /dev/ttyp[0-9]*
#mknod -m 0666 /dev/ptmx c 5 2
#echo "starting inetd....."
#/sbin/inetd
echo "set ip info....."
/sbin/ifconfig eth0 192.168.0.51
/sbin/ifconfig lo 127.0.0.1 up
echo "starting telnetd...."
/sbin/telnetd
echo "starting vsftpd ...."
/sbin/vsftpd &
#mknod -m 0666 /dev/console c 5 1
#mknod -m 666 /dev/ptmx c 5 2
#mknod -m 0666 /dev/null c 1 3
rm -fr /dev/ttyS*
ln -s /dev/s3c2410_serial0 /dev/ttyS0
ln -s /dev/s3c2410_serial1 /dev/ttyS1
ln -s /dev/s3c2410_serial2 /dev/ttyS2
echo "
========================================================================"
echo "| "
echo "| Wall-E rootfs for linux 2.6.22 "
echo "| "
echo "| arm-linux-gcc version 3.4.1 "
echo "| "
echo "| 2009-05-10 "
echo "| "
echo "
========================================================================"
#######################################################################
如 rcS 示例通常将要挂载的设备及其配置信息放在/etc/fstab , 然后用 mount -a 引用/etc/fstab 来挂载默认的设备,
nfs 文件系统就采用这种形式, /etc/fstab 示例如下:
#######################################################################
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
mdev /dev ramfs defaults 0 0
none /var ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
#######################################################################
四应用程序移植
系统程序和用户程序 大部分由 busybox 提供
这里主要介绍几个实用工具的配置和移植
1 inetd
busybox 集成了 inetd (超级网络服务)组件, 用它可以来启动 telnetd 和 ftpd 等服
务
inetd 启动的服务由/etc/inetd.conf 指定, /etc/inetd.conf 中的服务要参考
/etc/services 和 /etc/protocols 中
的规则来执行,典型示例如下:
inetd.conf
#######################################################################
#
ftp stream tcp nowait root /sbin/ftpd ftpd -l
#telnet stream tcp nowait root /sbin/telnetd telnetd
telnetstream tcp nowait
root /usr/sbin/telnetd /usr/sbin/telnetd
-l /bin/login
#######################################################################
/etc/services
#######################################################################
# service-name port/protocol [aliases ...] [# comment]
tcpmux 1/tcp
tcpmux 1/udp
ftp-data 20/tcp
ftp 21/tcp
ssh 22/tcp
ssh 22/udp
telnet 23/tcp
nameserver 42/tcp name
syslog 514/udp
#######################################################################
/etc/protocols
#######################################################################
ip 0 IP # internet protocol, pseudo protocol
number
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group management protocol
tcp 6 TCP # transmission control protocol
udp 17 UDP # user datagram protocol
#######################################################################
2 telnetd 配置
busybox 自带的 telnetd 就可以用,只是配置有点麻烦
1 telnetd 的登陆要启用伪终端设备/dev/pts,该类型的设备由传统的设备生成程
序
devfs 创建 ,然而在 2.6 的内核中
已经取消了 devfs ,而采用 udev(busybox 采用 udev 的简化版 mdev)来
实现
设备的创建 ,所以在配置内核时要确保以下
选项来增加对 pty 设备的支持
Device Drivers --->
Character devices --->
[*] Legacy (BSD) PTY support
(256) Maximum number of legacy PTY in use
同时,在配置 busybox 时也要增加 BSD PTY 设备和devfs 的支持
General Configuration --->
│[*] Use the devpts filesystem for Unix98 PTYs # for telnetd
Miscellaneous Utilities --->
│[*] devfsd (obsolete) # for telnet
2 在 linux 文件系统启动后要手动创建 telnetd 依赖的设备, 可用脚本 rcS 实现
mdev -s #udev 方式创建内核支持的设备结点
mkdir /dev/pts #pts 设备目录 ,for telnet
mount -t devpts devpts /dev/pts #格式化目录形式
rm -fr /dev/ttyp[0-9]* #删除无效的设备
#mknod -m 0666 /dev/ptmx c 5 2 #pts 的附属设备,可同/dev/null,dev/console 一样静态创建
3 busybox 自带的 telnetd 不知道啥问题不能随 inetd 自启动,这里采用 standalone
的方式,即
i 在配 busybox 时,选中
[*]telnetd
[*] Support standalone telnetd (not inetd only)
ii 在 rcS 中加入 /sbin/telnetd &
4 配置成功后启动信息如下:
telnet 192.168.0.51
Trying 192.168.0.51...
Connected to 192.168.0.51.
Escape character is '^]'.
WALL_E login: root
Password:
[WALL-E /]#
而在开发板环境中显示如下:
root login on 'pts/0'
5 登陆信息中根用户密码为空,涉及到 linux 系统帐户与权限管理,这里引入两个配置文件的介绍
i /etc/passwd
#######################################################################
root:$1$AHby/yWm$4rdc0aloVsnsYYSQWhAoG.:0:0:root:/:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:
nobody:x:99:99:Nobody:/:
#######################################################################
ii /etc/group
#######################################################################
root:x:0:root
ftp:x:50:
nobody:x:99:
#######################################################################