ARM Linux根文件系统(Root Filesystem)的制作

来源:本站
导读:目前正在解读《ARM Linux根文件系统(Root Filesystem)的制作》的相关信息,《ARM Linux根文件系统(Root Filesystem)的制作》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《ARM Linux根文件系统(Root Filesystem)的制作》的详细说明。
简介:介绍根文件系统的组成:目录、Shell、库、脚本。

目录

根文件系统要包含这些必须有的目录:/dev、/bin、/usr、/sbin、/lib、/etc、/proc、/sys

/dev是devfs(设备文件系统)或者udev的挂在点所在。在使用devfs的内核里如果没有/dev,根本见不到Shell启动的信息,因为内核

找不到/dev/console;在使用udev的系统里,也事先需要在/dev下建立console和null这两个节点。关于devfs和udev的

区别,网上很多文章说。当然如果你的内核已经不支持devfs了(2.6.12以后),可以使用纯纯的静态节点。也就是用mknod人工生成。

/bin、/usr/bin、/usr/sbin、/sbin是编译Busybox这个Shell时候就有的,用于存放二进制可执行文件,就不多解释了。

/lib用于存放动态链接库。网上很多文章都说静态编译Busybox,可以省去建库的麻烦过程。这样做只能让Busybox启动,我们自己写的,或者是编译的软件包还是需要动态库的。除非全部静态编译,你可以试试,一个Helloworld就要几百k。关于库的内容后面仔细说。

/etc是用来存放初始化脚本和其他配置文件的。关于初始化脚本的内容后面仔细说。

/proc是用来挂载存放系统信息虚拟文件系统——“proc文件系统”,“proc文件系统”在内核里面可以选。如果没有“proc文件系统”,很多Shell自己的命令就没有办法运行,比如ifconfig。“proc文件系统”不像devfs可以自动挂载,它需要使用初始化脚本挂载。另外,udev也需要“proc文件系统”的支持。

/sys用于挂载“sysfs文件系统”,“sysfs文件系统”在内核里面可以选。目前我认为它就是给udev提供支持的,呵呵。“sysfs文件系统”也需要使用初始化脚本挂载。

另外还可以有/tmp、/mnt、/swp、/var这样的不是嵌入式系统必须的目录,在说完Shell的制作之后,我再谈建立目录的事情。

Shell

Shell很简单,就是Busybox,上网下载一个来:http://www.busybox.net/downloads/。说Busybox和arm-linux-gcc有兼容性问题,不过我觉得那是比较低版本的时代问题了,我用Busybox

1.8.2和arm-linux-gcc

3.4.1/3.3.2都可以。解压缩以后找到Makefile里面的ARCH和CROSS_COMPILE,改成:

ARCH?= arm

CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux-

当然CROSS_COMPILE由你自己的编译器位置决定,然后

# make menuconfig

# make

# make install

注意配置的时候把一些uCLinux

Only的东西去掉,不然会错;配置的时候还可以修改安装位置,默认是在Busybox下的“_install”。

之后就可以在Busybox生成的Shell基础上建立根文件系统了,我就用命令来说吧,Busybox在/home/lxz/busybox,根文件系统在/home/lxz/rootfs

# mkdir /home/lxz/rootfs

# cd /home/lxz/busybox/_install

# cp -r ./ /home/lxz/rootfs

# cd /home/lxz/rootfs

# mkdir dev

# mkdir etc

# mkdir lib

# mkdir proc

# mkdir sys

# mkdir tmp

如果不用devfs,下面的命令是必须的。必须以root用户执行(用su命令可以切换为root,切换后用exit命令可以返回普通用户):

# cd /home/lxz/rootfs/dev

# mknod -m 660 console c 5 1

# mknod -m 660 null c 1 3

如果不使用devfs没有这两个静态节点,console的提示根本就看不到,出现的现象可能是内核提示Free init

memory: XXK之后,Warning: Unable to

find a initial

console之类的,具体的单词记得不是很准确。我没有试过使用udev的时候没有这两个静态节点的情况,反正放了也不影响把/dev挂载为tmpfs。

如果使用udev,还需要把udevd、udevstart、udevadmin这三个文件放到/sbin里面(我使用udev-117,网上介绍较多的udev-100有9个文件要放)。

库可是一件非常麻烦的事请。我建议初学者拷贝买的开发板里面带的文件系统的库,如果开发板的文件系统是映像,只需要把映像挂载在某个目录下就可以访问,假设映像叫做rootfs.cramfs,可以这样

# mkdir /home/lxz/evb_rootfs

(切换为root用户)

# mount -o loop rootfs.cramfs /home/lxz/evb_rootfs

(可以切换为普通用户)

# cd /home/lxz/evb_rootfs/lib

# cp -r ./ /home/lxz/rootfs/lib

一般开发板里都会带有很多库,但是总体积却比较大。可以删掉一些不用的库来减小体积,但是,呵呵,我也不知道那些库具体含有什么函数,什么情况删什么;也

许以后我会把这部分补上。如果觉得库体积太大,也可以自己编译glibc或者uclibc,但是这是非常繁琐的事请——目前我认为库应该和编译器arm-

linux-gcc一起制作。有个傻瓜式的方案是使用cross-tool,下载地址:http://www.kegel.com/crosstool/。虽然cross-tool是用来制作交叉编译器的,但是其过程中生成的glibc却可以作为副产品为我们所用。cross-tool的使用可以看我之前的这篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!274.entry。

在成功制作了交叉编译器之后,就可以从cross-tool的目录里把glibc取出来,假设cross-tool的路径是/home/lxz

/cross-tool,编译出的编译器叫做arm-linux-gnu-gcc,gcc版本3.4.5,glibc版本2.3.6,想要把glibc库

拷贝到/home/lxz/glibc,下面的操作还是用命令来说明。

# cd

/home/lxz/cross-tool/build/arm-linux-gnu-gcc/gcc-3.4.5-glibc-2.3.6/build-glibc

# ../glibc-2.3.6/configure --prefix=/home/lxz/glibc

# make install

等候安装结束

# cd /home/lxz/glibc

# cp -r lib /home/lxz/rootfs

这样就把glibc的大部队拷贝好了,但是这样还两个库,我们继续

# cd

/home/lxz/cross-tool/build/arm-linux-gnu-gcc/gcc-3.4.5-glibc-2.3.6/build-gcc/gcc

# cp libgcc_s.so* /home/lxz/rootfs/lib

还缺少一个libtermcap库,这个就稍微有些麻烦。libtermcap-2.0.8-35-armv4l源码包的下载地址是http://www.netwinder.org/mirror/pub/netwinder/SRPMS/nw/9/libtermcap-2.0.8-35.src.rpm,你也可以在这里http://www.netwinder.org/allsrpms.html找到其他版本的。假设libtermcap-2.0.8-35.src.rpm下载到了/home/lxz/libtermcap,下面继续用命令说明。

# cd /home/lxz/libtermcap

# rpm2cpio libtermcap-2.0.8-35.src.rpm | cpio -ivd

# tar xvjf termcap-2.0.8.tar.bz2

接下来要打13个补丁,很汗啊,请一定按照下面的顺序来打补丁

# patch -p0 -i termcap-2.0.8-shared.patch

# patch -p0 -i termcap-2.0.8-setuid.patch

# patch -p0 -i termcap-2.0.8-instnoroot.patch

# patch -p0 -i termcap-2.0.8-compat21.patch

# patch -p0 -i termcap-2.0.8-xref.patch

# patch -p0 -i termcap-2.0.8-fix-tc.patch

# patch -p0 -i termcap-2.0.8-ignore-p.patch

# patch -p0 -i termcap-buffer.patch

# patch -p0 -i termcap-2.0.8-bufsize.patch

# patch -p0 -i termcap-2.0.8-colon.patch

# patch -p0 -i libtermcap-aaargh.patch

# patch -p0 -i termcap-2.0.8-glibc22.patch

# patch -p0 -i libtermcap-2.0.8-ia64.patch

然后到/home/lxz/libtermcap/termcap-2.0.8里,找到Makefile,修改其中的CC和AR,

CC = /usr/local/arm/3.4.1/bin/arm-linux-gcc

AR = /usr/local/arm/3.4.1/bin/arm-linux-ar

当然,你的编译器在哪里就改成相应的内容。如果嫌麻烦,可以从本站资料页面下载我已经打好补丁,修改好Makefile的包,地址http://cid-4201fdc93932ddaf.skydrive.live.com/self.aspx/EE%e5%b0%8f%e7%ab%99%e7%90%90%e7%a2%8e%e6%96%87%e4%bb%b6/termcap-2.0.8.tar.bz2。需要注意的是,这个包里CC

= arm-linux-gcc、AR = arm-linux-ar,请设置好缺省路径。然后就可以编译了:

# cd /home/lxz/libtermcap/termcap-2.0.8

# make

# ln -s libtermcap.so.2.0.8 libtermcap.so.2

# cp libtermcap.so* /home/lxz/rootfs/lib

这样,Shell启动所需要的基本库就都备齐了。但是,这些库里面还含有调试信息,体积稍大,可以把这些信息去掉(当然不去掉也没有什么影响)。

# cd /home/lxz/rootfs/lib

# arm-linux-strip *.so*

至此,库就制作好了。

脚本

有了以上的东西,Shell还是不能正常工作。可能会是内核提示Free init

memory:

XXK之后就什么输出也没有了,这时候向终端敲入文字,可以显示;就是没有终端提示符,不理会输入的命令。这是因为初始化脚本没有启动Shell。下面介绍这些脚本。

首先是/etc/inittab。内核启动、根文件系统挂载之后所必须的一个文件,其中列举了Shell和整个系统初始化、关闭所需的命令。如果你想让

Shell出现,那么只需要加入这么一行“::askfirst:/bin/ash”。当然如果在编译Busybox的时候选择的shell不是

“ash”,而是hush、lash、msh之类,那就改成相应的东西。除了启动Shell,inittab还干了很多事情,我就用我的inittab来

说明了。注意,在编译Busybox的时候要选上touch、syslogd、klogd等命令。

# Startup the system

null::sysinit:/bin/mount

-o remount,rw /

null::sysinit:/bin/mount

-t proc proc /proc

null::sysinit:/bin/mount

-a

null::sysinit:/bin/hostname

-F /etc/hostname

# Now run any rc scripts

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

# Now invoke shell

::askfirst:/bin/ash

# Logging junk

null::sysinit:/bin/touch

/var/log/messages

null::respawn:/sbin/syslogd

-n -m 0

null::respawn:/sbin/klogd

-n

# Stuff to do for the 3-finger

salute

::ctrlaltdel:/sbin/reboot

# Stuff to do before rebooting

null::shutdown:/usr/bin/killall

klogd

null::shutdown:/usr/bin/killall

syslogd

null::shutdown:/bin/umount

-a -r

null::shutdown:/sbin/swapoff

-a

好,把上面这些储存为inittab,启动系统。应该出现两个提示,没有/etc/fstab和/etc/init.d/rcS。目前我的理解/etc/fstab是用来执行mount

-a命令的,里面是文件系统的挂载表。还是用我的fstab来说明。

#

/dev/root

/

ext2

rw,noauto

0 1

proc

/proc

proc

defaults

0 0

devpts

/dev/pts devpts

defaults,gid=5,mode=6200

0

tmpfs

/tmp

tmpfs

defaults

0 0

sysfs

/sys

sysfs

defaults

0 0

还有/etc/init.d/rcS,这在PC上是用来执行/etc/init.d下所有初始化脚本的一个脚本,呵呵,请原谅我不懂得怎么写这种脚本,对

于嵌入式系统,根本不需要这么复杂,直接写在/etc/init.d/rcS里面了。还是用我的/etc/init.d/rcS来说明,其中启动udev

的那些指令对于使用静态设备节点和devfs的系统不适用。

# Start udev

/bin/mount -t tmpfs tmpfs /dev

/sbin/udevd --daemon

/sbin/udevstart

# Configure net interface

/sbin/ifconfig lo 127.0.0.1 up

/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo

/sbin/ifconfig eth0 192.168.2.25 netmask 255.255.255.0

/sbin/route add default gw 192.168.2.1

如果用的是udev,还必须有udev的配置脚本。这个写起来有些麻烦,我们可以直接用udev自己带的那些脚本,位置在udev目录下的

etc/udev/udev.conf和etc/udev/rules.d里面的文件。把这些放到根文件系统中去,etc/udev/udev.conf

变为根文件系统的/etc/udev/udev.conf,etc/udev/rules.d里面的文件变为/etc/udev/rules.d里面的文

件。

提醒:《ARM Linux根文件系统(Root Filesystem)的制作》最后刷新时间 2024-03-14 01:04:12,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《ARM Linux根文件系统(Root Filesystem)的制作》该内容的真实性请自行鉴别。