构建基本的嵌入式Linux根文件系统
其实在去年8月份我做系统移植时就构建好了一个可以用的根文件系统,但是那时是跟着别人的《Linux全线移植文档》做的。有些东西我也不清楚,只是跟着做,做出来能用就了事了,没有深究其中的规范,以及文件系统中哪些要,哪些不要。
趁着今年过年的几天假期,我移植重新移植了U-Boot1.3.1和Linux2.6.24到S3C2410及S3C2440后,我想好好的看看有
关文件系统构建方法和规范,整理整理构建根文件系统的文档。之后,我用了近一周的时间,慢慢研究《构建嵌入式Linux系统》这本书有关根文件系统的部
分,以及一些网上的参考资料,不断地实验。构建好了一个精简的根文件系统,下面我只介绍构建的过程和方法,至于原理我给出以下参考资料,自己看吧。
1、 《Linux系统移植》:
一个经典的Linux移植文档,共有95页的PDF文档,内容十分详细,里面有根文件系统的创建,还多地方都有下载(有的网站称之为《Linux系统全线移植文档》等等),很值得参考。在这里感谢文档的作者们。
2、 《构建嵌入式Linux系统》
必看!
里面对文件系统的构建讲的挺细。
3、 《Filesystem Hierarchy Standard》
Linux文件系统的标准规范。我只看到英文的。
其他再遇到不懂的就google,基本上都是Linux的相关知识,都是找得到的。
(1)创建根文件系统的基本目录结构。
我把这个过程做成了shell脚本(文件名为
mkroot
) ,很方便!
#
!
/
bin/
sh
echo "creatint rootfs dir......"
mkdir rootfs
cd rootfs
echo "making dir : bin dev etc lib proc sbin sys usr"
mkdir bin dev etc lib proc sbin sys usr #
必备的8个目录
mkdir usr/
bin usr/
lib usr/
sbin lib/
modules
# Don't use mknod ,unless you run this Script as root !
# mknod -m 600 dev/console c 5 1
# mknod -m 666 dev/null c 1 3
echo
"making dir : mnt tmp var"
mkdir mnt tmp var
chmod 1777 tmp
mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
mkdir var/lib var/lock var/log var/run var/tmp
chmod 1777 var/tmp
echo
"making dir : home root boot"
mkdir home root boot
echo "done"
在你想要建立根文件系统的地方,运行:
[
tekkamanninja@Tekkaman-
Ninja nfs]
$
.
/
mkroot
creatint rootfs dir.
.
.
.
.
.
making dir :
bin dev etc lib proc sbin sys usr
making dir :
mnt tmp var
making dir :
home root boot
done
[
tekkamanninja@Tekkaman-
Ninja nfs]
$
cd rootfs/
dev/
[
tekkamanninja@Tekkaman-
Ninja dev]
$
su
口令:
[
root@Tekkaman-
Ninja dev]
#
mknod -
m 600 console c 5 1;
mknod -
m 666 null
c 1 3;
exit
exit
[
tekkamanninja@Tekkaman-
Ninja dev]
$
(2
)配置、编译和安装Busybox-1.9.1
[
tekkamanninja@Tekkaman-
Ninja source]
$
tar -
xjvf busybox-
1.
9.
1.
tar.
bz2
修改Makefile
文件:
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
pwd
/
home/
tekkamanninja/
working/
source/
busybox-
1.
9.
1
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
kwrite Makefile
.
.
.
.
.
.
(
第151-
154行)
#
SUBARCH :
=
$(
shell uname -
m |
sed -
e s/
i.
86/
i386/
-
e s/
sun4u/
sparc64/
/
#
-
e s/
arm.
*
/
arm/
-
e s/
sa110/
arm/
/
#
-
e s/
s390x/
s390/
-
e s/
parisc64/
parisc/
/
#
-
e s/
ppc.
*
/
powerpc/
-
e s/
mips.
*
/
mips/
)
.
.
.
.
.
.
(
第174行附近)
#
ARCH ?
=
$(
SUBARCH)
#
CROSS_COMPILE ?
=
ARCH =
arm
CROSS_COMPILE =
/
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
bin/
arm-
9tdmi-
linux-
gnu-
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
make menuconfig
在原有的基础上修改如下:
Busybox Settings --->
Installation Options --->
[*] Don't use /usr
(
/home/tekkamanninja/working/nfs/rootfs
) BusyBox installation prefix
Busybox Library Tuning
--->
[*] Support for /etc/networks
[*]
Additional editing keys
[*]
vi-style line editing commands
(15)
History size
[*]
History saving
[*]
Tab completion
[*]
Username completion
[*]
Fancy shell prompts
Login/Password Management Utilities
--->
选项全部N
掉,后面单独使用
TinyLogin
。(因为集成的好像不是很好用,我自己的经验是这样)
Linux Module Utilities
--->
[N] Support version 2.2.x to 2.4.x Linux kernels
Shells
--->
---
Ash Shell Options
下的选项全选
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
make
.
.
.
.
.
.
LINK busybox_unstripped
Trying libraries:
crypt m
Library crypt is needed
Library m is needed
Final link with:
crypt m
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
make install
我是动态编译所以查看一下需要的动态库
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
/
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
bin/
arm-
9tdmi-
linux-
gnu-
readelf -
d busybox
Dynamic section at offset 0xac014 contains 22 entries:
Tag Type Name/
Value
0x00000001 (
NEEDED)
Shared library:
[
libcrypt.
so.
1
]
0x00000001 (
NEEDED)
Shared library:
[
libm.
so.
6
]
0x00000001 (
NEEDED)
Shared library:
[
libc.
so.
6
]
0x0000000c (
INIT)
0xc0f0
0x0000000d (
FINI)
0x97608
0x00000004 (
HASH)
0x80e8
0x00000005 (
STRTAB)
0xa3c0
0x00000006 (
SYMTAB)
0x8b30
0x0000000a (
STRSZ)
3371 (
bytes)
0x0000000b (
SYMENT)
16 (
bytes)
0x00000015 (
DEBUG)
0x0
0x00000003 (
PLTGOT)
0xbc0ec
0x00000002 (
PLTRELSZ)
2976 (
bytes)
0x00000014 (
PLTREL)
REL
0x00000017 (
JMPREL)
0xb550
0x00000011 (
REL)
0xb4e0
0x00000012 (
RELSZ)
112 (
bytes)
0x00000013 (
RELENT)
8 (
bytes)
0x6ffffffe (
VERNEED)
0xb400
0x6fffffff (
VERNEEDNUM)
3
0x6ffffff0 (
VERSYM)
0xb0ec
0x00000000 (
NULL
)
0x0
(3
)修改和创建必要的文件。
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
cp -
a examples/
bootfloppy/
etc/* /home/tekkamanninja/working/nfs/rootfs/etc/
[
tekkamanninja@Tekkaman-
Ninja busybox-
1.
9.
1]
$
cd ../../nfs/rootfs/etc
/
1
、增加为SHELL
导入全局变量的文件/etc/profile
[tekkamanninja@Tekkaman-Ninja etc]$ kwrite profile
#
/
etc/
profile:
system
-
wide .
profile file
for
the Bourne shells
echo
echo "Processing /etc/profile... "
#
no-
op
#
Set
search
library path
echo "Set search library path in /etc/profile"
export
LD_LIBRARY_PATH=
/
lib:
/
usr/
lib
#
Set
user path
echo "Set user path in /etc/profile"
PATH=
/
bin:
/
sbin:
/
usr/
bin:
/
usr/
sbin
export
PATH
#
Set
PS1
#
注意:ash 除了SHELL变量外,支持/u、/h、/W、/$、/!
、/n、/w 、/nnn(ASCII字符对应的八进制数)
#
以及/e[
xx;
xxm (
彩 {MOD}特效)
等等!
#
而且前面还要多加一个
'/'
!
echo "Set PS1 in /etc/profile"
export PS1="//e[05;32m[$USER@//w//a]//$//e[00;34m"
echo "Done"
echo
2
、增加初始化文件
[tekkamanninja@Tekkaman-Ninja etc]$ kwrite inittab
:
:
sysinit:
/
etc/
init.
d/
rcS
:
:
respawn:
-
/
bin/
login
:
:
restart:
/
sbin/
init
:
:
ctrlaltdel:
/
sbin/
reboot
:
:
shutdown
:
/
bin/
umount -
a -
r
:
:
shutdown
:
/
sbin/
swapoff -
a
[tekkamanninja@Tekkaman-Ninja etc]$ kwrite fstab
proc /
proc proc defaults 0 0
none
/
tmp ramfs defaults 0 0
mdev /
dev ramfs defaults 0 0
sysfs /
sys sysfs defaults 0 0
3
、增加初始化脚本
[tekkamanninja@Tekkaman-Ninja etc]$ kwrite init.d/rcS
#
!
/
bin/
sh
echo "----------mount all"
/
bin/
mount -
a
echo "----------Starting mdev......"
/
bin/
echo /
sbin/
mdev >
/
proc/
sys/
kernel/
hotplug
mdev -
s
echo "*********************************************************"
echo " Tekkaman Ninja 2440 Rootfs(nfs) 2008.2 "
echo " Love Linux ! ! @@ Love Ke Ke ! ! "
echo "********************************************************"
4
、删除备份文件
[tekkamanninja@Tekkaman-Ninja etc]$ rm *~ init.d/*~
5、为mdev
创建配置文件
[tekkamanninja@Tekkaman-Ninja etc]$ vi mdev.conf
创建一个mdev.conf
文件,内容可有可无。
(4
)
为使用用户登录功能移植
TinyLogin
1、下载
从
http://tinylogin.busybox.net/
下载
tinylogin-snapshot.tar.bz2
,并
解压
.
[tekkamanninja@Tekkaman-Ninja source]$
tar -xjvf tinylogin-snapshot.tar.bz2
2、修
改tinyLogin的Makefile
[tekkamanninja@Tekkaman-Ninja source]$ cd tinylogin
[tekkamanninja@Tekkaman-Ninja tinylogin]$ kwrite Makefile
指明
tinyLogin
使用
自己
的
算
法
来处
理用户密码
USE_SYSTEM_PWD_GRP =
false
.
.
.
.
.
.
CROSS =
/
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
bin/
arm-
9tdmi-
linux-
gnu-
CC =
$(
CROSS)
gcc
AR =
$(
CROSS)
ar
STRIPTOOL =
$(
CROSS)
strip
3、
编译并安装
[
tekkamanninja@Tekkaman-
Ninja tinylogin]
$
make PREFIX=
/
home/
tekkamanninja/
working/
nfs/
rootfs install
Aborting install -
-
You must be root,
otherwise I can
't.
make tinylogin be setuid root, which will cause it to fail.
make: *** [install]
错误 1
[
tekkamanninja@Tekkaman-
Ninja tinylogin]
$
su
口令:
[root@Tekkaman-Ninja tinylogin]# make PREFIX=/home/tekkamanninja/working/nfs/rootfs install
[root@Tekkaman-Ninja tinylogin]# exit
exit
我是动态编译所以查看一下需要的动态库
[
tekkamanninja@Tekkaman-
Ninja tinylogin]
$
/
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
bin/
arm-
9tdmi-
linux-
gnu-
readelf -
d tinylogin
Dynamic section at offset 0x9670 contains 21 entries:
Tag Type Name/
Value
0x00000001 (
NEEDED)
Shared library:
[
libcrypt.
so.
1]
0x00000001 (
NEEDED)
Shared library:
[
libc.
so.
6]
0x0000000c (
INIT)
0x9c40
0x0000000d (
FINI)
0x10160
0x00000004 (
HASH)
0x8128
0x00000005 (
STRTAB)
0x9070
0x00000006 (
SYMTAB)
0x85e0
0x0000000a (
STRSZ)
1430 (
bytes)
0x0000000b (
SYMENT)
16 (
bytes)
0x00000015 (
DEBUG)
0x0
0x00000003 (
PLTGOT)
0x19740
0x00000002 (
PLTRELSZ)
1064 (
bytes)
0x00000014 (
PLTREL)
REL
0x00000017 (
JMPREL)
0x9818
0x00000011 (
REL)
0x97c8
0x00000012 (
RELSZ)
80 (
bytes)
0x00000013 (
RELENT)
8 (
bytes)
0x6ffffffe (
VERNEED)
0x9758
0x6fffffff (
VERNEEDNUM)
2
0x6ffffff0 (
VERSYM)
0x9606
0x00000000 (
NULL
)
0x0
创
建
创建帐号及密码文件:
[
tekkamanninja@Tekkaman-
Ninja tinylogin]
$
cd .
.
/
.
.
/
nfs/
rootfs/
etc/
[
tekkamanninja@Tekkaman-
Ninja etc]
$
su
口令:
[
root@Tekkaman-
Ninja etc]
#
cp /
etc/
passwd .
;
cp /
etc/
shadow .
;
cp /
etc/
group .
[
root@Tekkaman-
Ninja etc]
#
kwrite passwd
root:
x:
0:
0:
root:
/
root:
/
bin/
sh
[
root@Tekkaman-
Ninja etc]
#
kwrite group
root:
x:
0:
root
[
root@Tekkaman-
Ninja etc]
#
kwrite shadow
root:
$
1$N8K8eEQe$.
XkJo3xcsjOE6vo1jW9Nk/
:
13923:
0:
99999:
7:
:
:
[
root@Tekkaman-
Ninja etc]
#
rm *
~
rm:是否删除 普通文件 “group~
”?
y
rm:是否删除 普通文件 “passwd~
”?
y
rm:是否删除 普通文件 “shadow~
”?
y
[
root@Tekkaman-
Ninja etc]
#
exit
exit
[
tekkamanninja@Tekkaman-
Ninja etc]
$
这
3
个文件
是从Host
中拷贝
过
来的
,只留下root
帐号
。
那么现在 root的登陆密码和Host的登陆口令一致了,可以登录后再修改以及创建新用户。(
若使用以上文件,则root
密码为
tekkaman
)
拷贝必需的动态库文件
[
tekkamanninja@Tekkaman-
Ninja lib]
$
cp -
d /
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
arm-
9tdmi-
linux-
gnu/
lib/
ld*
.
cp:
略过目录 “/
home/
tekkamanninja/
working/
gcc4.
1.
1/
gcc-
4.
1.
1-
glibc-
2.
3.
2/
arm-
9tdmi-
linux-
gnu/
arm-
9tdmi-
linux-
gnu/
lib/
ldscripts”
[
tekkamanninja@Tekkaman-
Ninja lib]