您的位置:首页 > 运维架构 > Linux

读书笔记《Building embedded linux system》Chapter 6 根文件系统内容

2009-06-07 13:26 423 查看
对于root fileSystem的官方描述为FHS(FileSystem hierachy Stardard)。在根目录下的最高级目录都有明确的目的,然而很多是作为多用户系统的,而嵌入式系统对这些规则的遵循可以比较松动。

根目录系统

/binEssential user command binaries
/bootStatic files used by the bootloader --》根据我们的bootloader以及他的配置,可能可以删除。这取决于我们的bootloader是否可以在kernel启动之前从根文件系统中获得kernel的image。

/devDevices and other special files

/etcSystem configuration files, including startup files

/homeUser home directories -》用于扩展的用户环境,可删除

/libEssential libraries, such as the C library, and kernel modules

/mediaMount points for removable media

/mntMount points for temporarily mounted filesystems -》用于扩展的用户环境,可删除

/optAdd-on software packages -》用于扩展的用户环境,可删除

/procVirtual filesystem for kernel and process information

/rootRoot user's home directory -》用于扩展的用户环境,可删除

/sbinEssential system administration binaries

/sysVirtual filesystem for system information and control (buses, devices, and drivers)

/tmpTemporary files,chmod 1777 tmp,这是确保由创建的用户来进行删除。

/usrSecondary hierarchy containing most applications and documents useful to most users, including the X server。在里面建立bin,sbin,lib三个子目录。其他的字目录例如man、src、local都可能无需在嵌入式OS中使用。
/varVariable data stored by daemons and utilities,建立lib, lock, log, run, tmp,使用chmod 1777 tmp
我们可以字啊$PRJROOT下面建立rootfs ,在里面建立上面的文件系统。甚至可以更狠地删除/tmp和/var,但是可以会危害到其他的操作,不建议这样处理。这种删除的处理只是基于是否有用的考虑,不会对size有什么影响。可以更狠地删除/proc和/sys如果不需要虚拟文件系统,但是一些基本的命令,例如ps,mount,ifconfig,modprobe需要使用 /proc,而更多的应用也需要使用/sys,除非我们限定嵌入式系统非常有限的使用范围,否则不要这样处理。

lib库文件

/bin /sbin /usr/bin /usr/sbin的区别。/bin用于保存用户和系统管理员的基本(或者基础)二进制文件,/sbin用于保存系统管理员所需,但是一般用户不需要的二进制文件,/usr/bin 和/usr/sbin的差异类似,他们保存的不是基本二进制文件。在/lib中保存用于系统启动和应用于基本命令,而/usr/lib则保存其他的 lib,例如perl5在/usr/lib/perl5中有lib。

lib有四种格式:

libLIBRARY_NAME-GLIBC_VERSION.so,例如libc-2.9.so,libcidn-2.9.so

libLIBRARY_NAME.so.MAJOR_REVISION_VERSION,例如libc.so.6 -> libc-2.9.so,libcidn.so.1 -> libcidn-2.9.so

libLIBRARY_NAME.so,例如libcidn.so -> libcidn.so.1

静态库:libLIBRARY_NAME.a,例如libc.a,libcrypt.a

-rwxr-xr-x 1 wei wei 105210 05-15 16:09 libcrypt-2.9.so

-rw-r--r-- 1 wei wei 139684 05-15 16:09 libcrypt.a

lrwxrwxrwx 1 wei wei 13 05-15 16:09 libcrypt.so -> libcrypt.so.1

lrwxrwxrwx 1 wei wei 15 05-15 16:09 libcrypt.so.1 -> libcrypt-2.9.so

对比这些命名方式,glibc的库比较特别,它动态链接库ld的格式为ld-GLIBC_VERSION.so,ld- linux.so.MARHOR_REVISION_VERSION(ARM,i386,m68k)或者 ld.so.MAJOR_REVISION_VERSION(MIPS,PowerPC)。这不是一个真正的库,ld.so是ELF二进制loader触发用来将动态链接库加载到应用程序的存贮空间中。

在嵌入式操作系统中,我们如果想在host查看应用使用了哪些动态链接库,需要使用 cross-platform的readelf来替代ldd,例如powerpc-linux-readelf。

对于target的文件系统,需要将相关(所需)的lib拷贝至rootfs/lib中。需要libLIBRARY_NAME-GLIBC_VERSION.so和libLIBRARY_NAME.so.MAJOR_REVISION_VERSION。文件系统的建立包括:lib、kernel modules,kernel Images

#将全部的lib文件copy到我们的target的lib中,当然我们也可以只选取我们需要的部分

cd ${TARGET_PREFIX}/lib

cp *-*.so ${PRJROOT}/rootfs/lib

cp -d *.so.[*0-9] ${PRJROOT}/rootfs/lib

cp libSegFault.so libmemusage.so libpcprofile.so ${PRJROOT}/rootfs/lib

#如果我们不需要所有的lib,选择其中的某些有用的部分,我们可以如下进行操作

cd ${TARGET_PREFIX}/lib

for file in libc libcrypt libdl libm libpthread libresolv libutil

do

cp $file-*.so ${PRJROOT}/rootfs/lib

cp -d $file.so.[*0-9] ${PRJROOT}/rootfs/lib

done

cp -d ld*.so* ${PRJROOT}/rootfs/lib

#如果我们选择了libnss_*.so,其中libnss_file和libnss_dns常用,需要将nsswitch.conf文件放置在/etc中,并根据需要进行配置。

cp ${PRJROOT}/build-tools/src-glibc/glibc-20081113T2206/nss/nsswitch.conf ${PRJROOT}/rootfs/etc

#lib文件是比较大的,可以采用strip进行裁剪,如下,原来的大小为12.488M,整理后为2.812M,空间大大地减少了。当然如果我们对空间大小不敏感,现在的存贮容量也越来越大,我们也可以不进行此步骤。

i586-linux-strip ${PRJROOT}/rootfs/lib/*.so

#copy内核模块,并在etc/下增加modprobe.conf文件(用于给出模块的参数,步骤不太详细,可能echo > ${PRJROOT}/rootfs/etc/modprobe.conf就可以了)。

cp -a ${PRJROOT}/images/myproject/modules-2.6.29-menlow/* ${PRJROOT}/rootfs

echo > ${PRJROOT}/rootfs/etc/modprobe.conf

#copy 相关的kernel image

mkdir ${PRJROOT}/rootfs/boot

cp ${PRJROOT}/images/myproject/bzImage-2.6.29-menlow ${PRJROOT}/rootfs/boot/vmlinuz--2.6.29-menlow

cp ${PRJROOT}/images/myproject/System.map-2.6.29-menlow ${PRJROOT}/rootfs/boot/

cp ${PRJROOT}/images/myproject/2.6.29-menlow.config ${PRJROOT}/rootfs/boot/config-2.6.29-menlow

设备文件

以太网是不作为设备文件,这点比较特殊。静态设备文件指只需要创建一次。

[wei@wei rootfs]$ ls /dev/ttyS1* -l

crw-rw---- 1 root uucp 4, 65 05-31 08:55 /dev/ttyS1

第一字母表示类型,c表示character,b表示block,后面的4是major号码,65是minor号码,这是内核用于需要驱动管理的依赖。

建立静态设备文件:

cd ${PRJROOT}/rootfs/dev

[wei@wei dev]$ su -m

?ü??£o

[root@wei dev]# mknod -m 600 mem c 1 1

[root@wei dev]# mknod -m 666 null c 1 3

[root@wei dev]# mknod -m 666 zero c 1 5

[root@wei dev]# mknod -m 644 random c 1 8

[root@wei dev]# mknod -m 600 tty0 c 4 0

[root@wei dev]# mknod -m 600 tty1 c 4 1

[root@wei dev]# mknod -m 600 ttyS0 c 4 64

[root@wei dev]# mknod -m 666 tty c 5 0

[root@wei dev]# mknod -m 600 consol c 5 1

[root@wei dev]# chmod 644 random

[root@wei dev]# chmod 600 tty0 tty1 ttyS0

[wei@wei dev]$ ln -s /proc/self/fd fd

[wei@wei dev]$ ln -s fd/0 stdin

[wei@wei dev]$ ln -s fd/1 stdout

[wei@wei dev]$ ln -s fd/2 stderr

在几年前linux2.4的版本中,在/dev中有1万8千个设备文件,但是在2.6的版本中,通过动态设备文件的方式大大地减少了。静态设备文件的一个问题,就是我们无法通过查看/dev文件来确定这个设备是否真实存在或者有效,由此引入动态设备文件系统,在/dev中的只有可以使用的设备。在 linux2.6中,通过udev来实现,它将设备mount在/sys,使得设备、驱动等信息可以在user space中,他克服了热插脚本/sbin/hotplug甚多不足,并最终取代了它。

需要安装udev

[wei@wei udev-142]$ ./autogen.sh

[wei@wei udev-142]$ make CROSS_COMPILE=i586-linux- DESTDIR=${PRJROOT}/rootfs install

在rootfs/lib/udev/, rootfs/etc/udev/, rootfs/etc/scsi_id.config

udev 等待当设备插入或者卸除时来自内核的uevents,根据消息内容或者在/sys中的设备信息在udev的rules中寻找匹配,如果找到,就生成或者删除设备文件,执行驱动的加载或者卸载,或者提醒用户空间的程序。这些信息是通过netlink socket来传递的。

Busybox

在linux中有大量Unix的的命令,我们不能期待通过交叉编译分别将他们编译出来,我们可以借助一些系统的app,例如busybox。在moblin中如果编译busybox,需要下载ncurses-devel

busybox和kernel在配置一样相似,如果使用缺省,可以用defconfig,也可以使用menuconfig来进行配置。

Busybox settings --->

Build option --->

[*] Build BusyBox as a static binary (no shared libs) 这是对于小的系统Busybox以及小部分的lib,不需要整个C库,使得系统更为简单的和小巧。我想在moblin中并不需要这样处理。

Linux System Utilities ---> (查过,下面这个属于缺省打开)

[*] mdev

[*] Support /etc/mdev.conf

[ ] Support command execution at device addition/removal

必须选择 mdev 选项, 否则不能启用udev。

执行 make install进行编译,编译完后,会出现_install目录,包含bin、sbin、usr三个目录和一个linuxrc文件。

$ make ARC=x86 CROSS_COMPILE=i586-linux- CONFIG_PREFIX=${PRJROOT}/rootfs install

Busybox是一个工具的整合,将ls,ps,等等命令链接指向busybox,busybox可提供这些工具的功能。无需我们分别来编译这些工具集合。

[wei@wei bin]$ pwd

/home/wei/workspace/mywork/moblin/rootfs/bin

[wei@wei bin]$ ls -l

?? 1460

lrwxrwxrwx 1 wei wei 7 06-03 11:48 addgroup -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 adduser -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 ash -> busybox

-rwxr-xr-x 1 wei wei 1490596 06-03 11:48 busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 cat -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 catv -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 chattr -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 chgrp -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 chmod -> busybox

lrwxrwxrwx 1 wei wei 7 06-03 11:48 chown -> busybox

同样在sbin/,usr/bin ,usr/sbin中的命令也指向该 busybox

我们在etc/profile

[wei@wei rootfs]$ cd etc

[wei@wei etc]$ cat profile

#Set Path

PATH=/bin:/sbin:/usr/bin:/usr/sbin

export PATH

#set other libary path 这里填写非lib/的其他库的位置。

#LD_LIBRARY_PATH=

#export LD_LIBRARY_PATH

系统启动

主要有System V init和busybox两种方式。moblin使用system V init的方式,我们分别对它以及busybox作为系统启动进行尝试:

原始的sysvinit 2.86,这个也可以在ftp://ftp.cistron.nl/pub/people/miquels/sysvinit中下载,可以看到这个自2004之后就没有再更新,可能已经相当之成熟。

$ cd ${PRJROOT}/sysapps/sysvinit-2.86/src

$ make CC=i586-linux-gcc

$ make BIN_OWNER="$(id -un)" BIN_GROUP="$(id -gn)" ROOT=${PRJROOT}/rootfs install

可以将原来指向busybox的bootlogd, halt, init, killall5, last, mesg, mountpoint, pidof, poweroff, reboot, runlevel, shutdown, suloing, telinit, utmpdmp, wall更新为sysvinit的编译结果。我们不使用root权限来进行编译所以需要指定用户和所在用户组。由于嵌入式操作系统一般都不是多用户系统,所以对用户权限设置不敏感。如果我们需要多用户的方式,可以使用root权限,但是需要非常小心,任何在root权限下面的操作都是需要谨慎。我们也可以用普通用户编译,然手在rootfs中修改这些命令的权限。

Busybox在example里面有inittab,我们可以将它copy我们的rootfs/etc目录下面。根据initab中:

::sysinit:/etc/init.d/rcS

我们在etc/下面建立了init.d目录,以及rcS文件,rcS文件,我们给出:

#!/bin/sh

# Set Path

PATH=/bin:/sbin:/usr/bin:/usr/sbin

# Remount the root filesystem in read-write (requires /etc/fstab)

mount -n -o remount,rw /

# Mount /proc filesystem

mount /proc

# Start the network interface

#/sbin/ifconfig eth0 192.168.1.2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: