上一篇文章当中,说了说怎样搭建nfs服务器的过程,这也是制作根文件系统前必须的准备工作,当然也可以用其他方法,但从调试的角度来说,还是nfs最适合了。这篇文章咱们正式开始制作根文件系统,主要内容如下:
1.制作根文件系统;
2.测试制作的根文件系统。
一.制作根文件系统
所谓制作根文件系统,就是创建各种目录,并且在里面创建各种文件。要是你对linux主机下的根目录比较了解的话,你可能会比较熟悉这些目录了,比如在/bin、/sbin目录下存放各种可执行程序,在/etc目录下存放配置文件,在/lib目录下存放库文件。在制作时,咱们要用到busybox,下面是对busybox的简介,是从百度百科里复制的,介绍的挺明白。如下:
BusyBox 是一个集成了一百多个最常用linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例如grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Android 系统的自带的shell。
下面开始制作
1.在linux主机的根目录下,创建nfsroot文件夹,在里面创建mknfsroot文件,文件的内容如下,你可以直接复制到你创建的文件里面
#!/bin/sh
echo "------Create rootfs directons start...--------"
mkdir rootfs
cd rootfs
echo "--------Create root,dev....----------"
mkdir bin boot dev etc home lib mnt proc root sbin sys tmp usr var
mkdir etc/init.d etc/rc.d etc/sysconfig
mkdir usr/sbin usr/bin usr/lib usr/modules
echo "make node in dev/console dev/null"
mknod -m 666 dev/console c 5 1
mknod -m 666 dev/null c 1 3
mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
mkdir var/lib var/lock var/run var/tmp
chmod 1777 tmp
chmod 1777 var/tmp
echo "-------make direction done---------"
其实,这就是一个脚本,你仔细看看,就是创建一些文件、文件夹以及改变文件或文件夹权限等操作。上面所做的工作是制作文件系统所必须完成的工作,你也可以一步一步来完成,但用这种方式更简单,也不容易出错。保存好,文件内容后,改变mknfsroot文件的可执行权限,命令是:chmod a+x mknfsroot 。运行脚本,[root@localhost nfsroot]# ./mknfsroot ,运行的结果如下:
------Create rootfs directons start...--------
--------Create root,dev....----------
make node in dev/console dev/null
-------make direction done---------
这时,你在你的nfsroot目录下应该能发现一个rootfs目录,你可以进去看看,里面就是通过脚本创建的一些文件及文件夹,你可能会发现跟你linux主机根目录下很相似,那好,下边咱们介绍介绍根文件系统中顶层目录,也就是这些文件夹的作用了,如下:
bin 存放所有用户都可以使用的、基本的命令。
sbin 存放的是基本的系统命令,它们用于启动系统、修复系统等。
usr 里面存放的是共享、只读的程序和数据。
proc 这是个空目录,常作为proc 文件系统的挂载点。
dev 该目录存放设备文件和其它特殊文件。
etc 存放系统配置文件,包括启动文件。
lib 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序
boot 引导加载程序使用的静态文件。
home 用户主目录,包括供服务账号锁使用的主目录,如FTP。
mnt 用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。
opt 给主机额外安装软件所摆放的目录。
root root 用户的主目录
tmp 存放临时文件,通常是空目录。
var 存放可变的数据,如日志等。
上面的脚本就创建了这些目录,在上面脚本执行过程创建的两个设备文件console 和null非常重要,这两文件和控制台设备有关,在前面提到过的在内核挂载文件系统时出现的告警“Warning: unable to open an initial console”与之有关。
其中,mknod命令格式如下:
mknod [OPTION]... NAME TYPE [MAJOR MINOR]
参数-m, --mode=MODE,表示指定用户操作权限,console和null表示文件名,c 表示是字符设备,后面的两个数字分别表示主设备号和次设备号。
改变了tmp 目录的使用权,让它开启sticky 位,为tmp 目录的使用权开启此位,可确保tmp 目录底下建立的文件,只有建立它的用户有权删除。尽管嵌入式系统多半是单用户,不过有些嵌入式应用不一定用root 的权限来执行,因此需要遵照根文件系统权限位的基本规定来设计。
2.编译Busybox
刚开始的时候就介绍了Busybox,我用的是友善mini2440里面自带的Busybox-1.13.3,当然你也可以用更新的。把busybox-1.13.3拷贝到linux主机的一个目录下,以下是操作:
(1)tar xvzf busybox-1.13.3-mini2440.tgz
(2)进入刚才解压后的目录busybox-1.13.3
(3)修改busybox-1.13.3目录下的Makefile文件
在gedit打开的Makefile中,定位到164行附近,修改如下:
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
CROSS_COMPILE ?= arm-linux-
# bbox: we may have CONFIG_CROSS_COMPILER_PREFIX in .config,
# and it has not been incl? yet... thus using an awkward syntax.
... ...
定位到189行附近,修改如下:
ARCH ?= arm
# Architecture as present in compile.h
UTS_MACHINE := $(ARCH)
然后保存。
(4)配置busybox,在busybox-1.13.3目录下运行:make menuconfig 命令,进入配置界面
下面只列出了要注意的地方,没有列出的默认即可。
<1>、Busybox Settings--->
Build Options--->
[*] Build BusyBox as a static binary (no shared libs)
[ ] Force NOMMU build
[*] Build with Large File Support (for accessing files > 2 GB)
(arm-linux-) Cross Compiler prefix //指定编译前缀,按回车就可进行修改
Installation Options --->
[*] Don't use /usr //选中该项可以避免buysbox被安装到宿主机系统的/usr目录下,破坏宿主机系统。
Applets links (as soft-links) --->
(/nfsroot/rootfs) BusyBox installation prefix //这里需要指定busybox的安装路径,按回车即可输入。
Busybox Library Tuning --->
[*] Support for /etc/networks
[*] Command line editing
(1024) Maximum length of input
[*] vi-style line editing commands
(15) History size
[*] History saving
[*] Tab completion
[*] Username completion
[*] Fancy shell prompts
<2>Linux Module Utilities--->
(/lib/modules)Default directory containing modules
(modules.dep)Default name of modules.dep
下面是在busybox 中配置对dev 下设备类型的支持,dev 的创建有手动创建、使用devfs 文件系统创建和?v创建三种方法,而?v的一个简化版是busybox 自带的mdev ,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox 为基础构建嵌入式linux 的根文件系统时,使用它是最优的选择。
<3>Linux System Utilities --->
[*]Support /etc/mdev.conf
[*]Support command execution at device addition/removal
<4>Init Utilities --->
“Support reading an inittab file”应该选中,这样可以根据自己编写的inittab文件初始化;“Support running commands with a controlling-tty”应该选中,否则会提示非常困扰的“/bin/sh: can't access tty; job control turned off”的提示,尽管可以进入控制台命令行。
(5)编译busybox到指定目录
[root@localhost busybox-1.13.3]# make CONFIG_PREFIX=/nfsroot/rootfs install
在rootfs 目录下会生成目录bin、sbin、usr 和文件linuxrc 的内容。这也就是把linux的一些命令放到根文件系统里的特定文件或文件夹里了。
3.建立根文件系统的动态库
虽然通过编译busybox生成了我们需要的可执行文件,但现在在目标板上仍然无法运行,需要添加lib库来支持可执行文件运行。可以使用uclibc和glibc来构建lib库。由于编译lib库相对复杂,而我们又有现成的lib库可以使用,这里我们就实行拿来主义。现成的lib库就在我们的交叉编译工具arm-linux-gcc的目录下,在本人主机上的绝对路径为/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib,进入到这个文件夹后,运行:cp *so* /nfsroot/rootfs/lib -d ,把lib目录下的所有文件及文件夹拷贝到咱们新建的nfs服务器的共享目录下的lib,这里注意后面-d,这是为了不拷贝链接。
4.建立所建根文件系统目录下etc的配置文件
(1) 建立/etc/group系统用户组配置文件,内容如下:
root:*:0:
daemon:*:1:
bin:*:2:
sys:*:3:
adm:*:4:
tty:*:5:
disk:*:6:
lp:*:7:lp
mail:*:8:
news:*:9:
u p:*:10:
proxy:*:13:
kmem:*:15:
dialout:*:20:
fax:*:21:
voice:*:22:
cdrom:*:24:
floppy:*:25:
tape:*:26:
s o:*:27:
a io:*:29:
ppp:x:99:
500:x:500:plg
501:x:501:fa
(2)建立passwd系统密码文件,内容如下:
root::0:0:root:/:/bin/sh
ftp::14:50:FTP User:/var/ftp:
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
nobody:*:99:99:Nobody:/:
sky::502:502:Linux User,,,:/home/sky:/bin/sh
[root@localhost rootfs]# ls ./etc
group init.d passwd rc.d sysconfig
(3) 在etc/sysconfig 目录下新建主机文件名HOSTNAME,内容为"tiny210"。
[root@localhost rootfs]# cat >>./etc/sysconfig/HOSTNAME
tiny210
[root@localhost rootfs]#
当录入完文件内容“tiny210”并回车后需要按下Ctrl+C组合键结束录入状态。此时该文件内容为:“tiny210",这句话就是我们在文件系统里面看到那个“[root@ tiny210 /]”。
(4)新建etc/inittab 系统init进程配置文件,将下面内容复制并粘贴其中:
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a –r
要记住赋予其可执行属性
[root@localhost rootfs]# chmod a+x ./etc/inittab
(5)新建etc/init.d/rcS系统启动加载项文件,将下面内容复制并粘贴其中:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S //运行的级别
prevlevel=N
umask 022 //文件夹的掩码
export PATH runlevel prevlevel
echo "----------munt all----------------"
mount -a //挂载/etc/fstab/文件指定的所有的文件系统
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
echo "***********************************************"
echo "************booting to tiny210 *****************"
echo "Kernel version:linux-3.3.5"
echo "the fans:singleboy"
echo "Date:2013.9.8"
echo "***********************************************"
/bin/hostname -F /etc/sysconfig/HOSTNAME
rcS是系统启动后执行的第一个脚本文件,如果想把自己编写的应用程序设置为开机启动,在本文件中中加入运行该程序的命令即可。然后使用以下命令改变 rcS 的执行权限:
Chmod +x rcS
[root@localhost rootfs]# chmod +x ./etc/init.d/rcS
(6)新建etc/fstab 系统挂载文件系统列表文件,将下面内容复制并粘贴其中:
#device mount-point type option dump fsck order
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
mdev /dev ramfs defaults 0 0
(7)新建etc/profile用户环境配置文件,将下面内容复制并粘贴其中:
#Ash profile
#vim:syntax=sh
#No core file by defaults
#ulimit -S -c 0>/dev/null 2>&1
USER="id -un"
LOGNAME=$USER
PS1='[\u@\h \W]\$'
PATH=$PATH
HOSTNAME='/bin/hostname'
export USER LOGNAME PS1 PATH
修改环境变量PS1(命令行提示符),可以使用vi编辑/etc/profile文件,在最后加上:
export PS1='[\u@\h \W]\$ '
即可,其中\u显示当前用户账号,\h显示当前主机名,\W显示当前路径,\$显示'$'符号
\W 代替 \w 就可以实现绝对路径到相对路径的转换
下面简单说说环境下默认的特殊符号所代表的意义:
\d :代表日期,格式为weekday month date,例如:"Mon Aug 1"
\H :完整的主机名称。例如:我的机器名称为:fc4.linux,则这个名称就是fc4.linux
\h :仅取主机的第一个名字,如上例,则为fc4,.linux则被省略
\t :显示时间为24小时格式,如:HH:MM:SS
\T :显示时间为12小时格式
\A :显示时间为24小时格式:HH:MM
\u :当前用户的账号名称
\v :BASH的版本信息
\w :完整的工作目录名称。家目录会以 ~代替
\W :利用basename取得工作目录名称,所以只会列出最后一个目录
\# :下达的第几个命令
\$ :提示字符,如果是root时,提示符为:# ,普通用户则为:$
(8) 建立etc/mdev.conf (mdev设备配置文件)、 net.conf (网络配置文件件),mime.types: MIME(Multipurpose Internet Mail Extensions) 内容均为空。
[root@localhost rootfs]# touch ./etc/mdev.conf
[root@localhost rootfs]# touch ./etc/net.conf
[root@localhost rootfs]# touch ./etc/mine.types
(9)建立boa WEB服务器文件配置文件
在etc/boa目录,并在boa目录中建立boa.conf文件,内容为空。
[root@localhost rootfs]# mkdir ./etc/boa
[root@localhost rootfs]# touch ./etc/boa/boa.conf
(10)先建立etc/rc.d/init.d目录
[root@localhost rootfs]# mkdir ./etc/rc.d/init.d
然后建立etc/rc.d/init.d/httpd文件
[root@localhost rootfs]# gedit ./etc/rc.d/init.d/httpd
将下面内容复制并粘贴:
#!/bin/sh
base=boa
# See how we were called.
case "$1" in
start)
/usr/sbin/$base
;;
stop)
pid=`/bin/pidof $base`
if [ -n "$pid" ]; then
kill -9 $pid
fi
;;
esac
exit 0
(11)新建etc/resolv.conf,DNS配置文件,存放访问外网时需要DNS 的信息,内容如下:
nameserver 61.144.56.100
(12)在/home/sky目录,与etc目录passwd文件中的sky相对应
[root@localhost rootfs]# mkdir ./home/sky
5.编译并安装内核模块
首先就进入到linux内核顶级目录下,在前面咱们已经编译的linux-3.3.5的源代码目录下执行:
[root@localhost linux-3.3.5]# make modules
等到编译完成后,安装编译好的模块:
[root@localhost linux-3.3.5]# make modules_install ARCH=arm INSTALL_MOD_PATH=/nfsroot/rootfs
经过上面的操作,就把linux内核和咱们制作的根文件系统联系了起来。
6.配置linux内核以及重新编译
(1)进入linux-3.3.5源代码目录下,通过命令:vim .config ,在打开的配置文件中往下翻,直到看到红色的一行,把其中的console=ttySAC1改为console=ttySAC0 , 其他的不用变。
#
# Boot options
#
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC0,115200 init=/linuxrc"
# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
在内核目录下命令终端中执行make menuconfig ,在打开的配置菜单-> Boot options --->回车可以看到刚才的修改结果,如下图:
上面的高亮部分就是上面我们修改的部分,当然我们可以在这块按Enter键后修改,但这样修改没有上面的方法方便,不过这个看你自己喽。
(2)使内核支持对nfs boot的支持
首先应该配置选中对DM9000网卡驱动的支持,由于我们在移植DM9000的时候说过了,所以就省略了,要是不知道怎么选,那就在看看吧。额外的配置如下,make menuconfig 进入界面后,选中File systems-------> ,并进入该目录,然后在其中选中Network file systems------>选项,再进入选中下图中高亮的部分,如下图:
选中高亮部分后,会出现额外的两项,选中这两项时分别又会出现额外的两项,都依次选中。就是在Root file system on NFS选项之前的,在NFS client support选项后的都选中,接下来再选中Root file system on NFS这个选项,如下图:
这就配置好了,是内核支持nfs boot了。
(3)重新编译内核
上面配置好之后,保存配置,然后重新 make uImage 编译内核,等编译完之后,把编译好的uImage拷贝到咱们的tftpboot目录下,这就万事俱备,只差测试了,哈哈,下面开始测试。
二.测试根文件系统
(1)打开开发板的电源,同时打开你电脑上的超级终端,首先在你超级终端中,设置boot参数,设置的命令是:setenv bootargs=root=/dev/nfs nfsroot=192.168.186.30:/nfsroot/rootfs,nolock ip=192.168.186.13:192.168.186.30:192.168.0.1:255.255.255.0::eth0:off console=ttySAC0,115200
mem=512M ,注意我在命令中红色的nolock以及ip地址要和你实际的向匹配等,要是没有这个nolock,可能测试的结果是打不开文件系统,所以一定要加上。
(2)通过ping命令测试,是否开发板和电脑主机能通过网线连通,如果可以,用tftp服务器重新下载内核,应该可以正常工作,如果不行,可以重新启动一下nfs服务器,service nfs restart 或者看防火墙是否关闭,我测试通过了,就看你的了。
下一篇咱们再进一步地探讨根文件系统,使之能够烧写到flash当中,come on!