如何制作Linux根文件系统

如何制作Linux根文件系统,第1张

文件系统一直以来都是所有类Unix *** 作系统的一个重要组成部分,也可以认为是嵌入式Linux系统区别于其他一些传统嵌入式 *** 作系统的重要特征,它给Linux带来了许多强大和灵活的功能,同时也带来了一些复杂性。我们需要清楚的了解根文件系统的基本结构,以及细心的选择所需要的系统库、内核模块和应用程序等,并配置好各种初始化脚本文件,以及选择合适的文件系统类型并把它放到实际的存储设备的合适位置。

Linux的根文件系统以树型结构组织,包含内核和系统管理所需要的各种文件和程序,一般说来根目录”/”下的顶层目录都有一些比较固定命名和用途。

下面列出了一个Linux根文件系统中的比较常见的目录结构:

/bin 存放二进制可执行命令的目录

该目录下存放所有用户都可以使用的、基本的命令,这些命令在挂接其它文件系统之前就可以使用,所以/bin目录必须和根文件系统在同一个分区中。

/bin目录下常用的命令有:cat,chgrp,chmod,cp,ls,sh,kill,mount,umount,mkdir,m knod,[,test等“[”命令其实就是test命令,我们在利用Busybox制作根文件系统时,在生成的bin目录下,可以看到一些可执行的文件,也就是可用的一些命令。

/dev 存放设备文件的目录

该目录下存放的是设备文件握册,设备文件是Linux中特有的文件类型,在Linux系统下,以文件的方式访问各种设备,即通过读写某个设备文件 *** 作某个具体硬件。比如通过"dev/ttySAC0"文件可以 *** 作串口0,通过"/dev/mtdblock1"可以访问MTD设备的第2个分区。

/etc 存放系统管理和配置文件的目录

该目录下存放着各种配置文件,对于PC上的Linux系统,/etc目录下的文件和目录非常多,这些目录文件是可选的,它们依赖于系统中所拥有的应用程序,依赖于这些程序是否需要配置文件。在嵌入式系统中,这些内容可以大为精减。

/home 用户主目录,比如用户user的主目录就是/home/user,可以用~user表示

用户目录,它是可选的,对于每个普通用户,在/home目录下都有一个以用户名命名的子目录,里面存放用户相关的配置文件。

/lib 存放动态链接共享库的目录

该目录下存放共享库和可加载(驱动程序),共享库用于启动系统。运行根文件系统中的可执行程序,比如:/bin /sbin 目录下的程序。

/sbin存放系统管理员使用的管理程序的目录

该目录下存放系统命令,即只有管理员能够使用的命令,系统命令还可以存放在/usr/sbin,/usr/local/sbin目录下,/sbin目录中存放的是基 本的系统命令,它们用于启动系统,修复系统等,与/bin目录相似,在挂接其他文件系统之前就可以使用/sbin,所以/sbin目录必须和根文件系统在同一个分区中。

/sbin目录下常用的命令有:shutdown reboot fdisk fsck等,本地用户自己安装的系统命令放在/usr/local/sbin目录下。

/tmp 公用的临时文件存储点

用于存放临时文件,通常是空目录,一些需要生成临时文件的程序用到的/tmp目录下,所以/tmp目录必须存在并可以访问。

/root 系统管理员的主目录

根用户的目录,与此对应,普通用户的目录是/home下的某个子目录。

/mnt 系统提供这个目录是让用户临时挂载其他的文件系统。

用于临时挂载某个文件系统首笑的挂接点,通常是空目录,也可以在里面创建一引起空的子目录,比如/mnt/cdram /mnt/hda1 。用来临时挂载光盘、硬盘。

/proc 虚拟文件系统,可直接访问这个目录来获取系统信息。

这是一个空目录,常作为proc文件系统的挂接点,proc文件系统是个虚拟的文件系统,它没有实际的存储设备,里面的目录,文件都是由内核临时生成的,用来表示系统的运行状态,也可以 *** 作其中的文件控制系统。

/usr 最庞大的目录,要用到的应用程序和文件几乎都在这个目录。段芹宏

/usr目录的内容可以存在另一个分区中,在系统启动后再挂接到根文件系统中的/usr目录下。里面存放的是共享、只读的程序和数据,这表明/usr目录下的内容可以在多个主机间共享,这些主要也符合FHS标准的。/usr中的文件应该是只读的,其他主机相关的,可变的文件应该保存在其他目录下,比如/var。/usr目录在嵌入式中可以精减。

/var 某些大文件的溢出区

与/usr目录相反,/var目录中存放可变的数据,比如spool目录(mail,news),log文件,临时文件。

---------------------------------------------------------------------

一、移植环境:

1、 Ubuntu 10.10发行版

2、 u-boot.bin

3、 目标机:FS_S5PC100平台

4、 交叉编译器 arm-cortex_a8-linux-gnueabi-gcc

---------------------------------------------------------------------

二、移植步骤

1、 源码下载

我们选择的版本是busybox-1.17.3.tar.bz2下载路径为:

http://busybox.net/downloads/

2、 解压源码

$ tar xvf busybox-1.17.3.tar.bz2

3、 进入源码目录

$ cd busybox-1.17.3

4、 配置源码

$ make menuconfig

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-cortex_a8-linux-gnueabi-) Cross Compiler prefix

() Additional CFLAGS

5、 编译

$ make

6、 安装

busybox默认安装路径为源码目录下的_install

$ make install

7、 进入安装目录下

$ cd _install

$ ls

bin linuxrc sbin usr

8、 创建其他需要的目录

$ mkdir dev etc mnt proc var tmp sys root

9、 添加库

在_install目录下创建一个lib文件夹,将工具链中的库拷贝到lib目录下

$ mkdir lib

$ cp /home/linux/x-tools/arm-cortex_a8-linux-gnueabi/arm-cortex_a8-linux-gnueabi/lib/* ./lib/

删除lib下的所有目录、.o文件和.a文件,对库进行瘦身以减小文件系统的大小

$ rm *.o *.a

$ arm-cortex_a8-linux-gnueabi-strip lib/*

10、 添加系统启动文件

在etc下添加文件inittab

$ vim /etc/inittab

文件内容如下:

#this is run first except when booting in single-user mode.

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

# /bin/sh invocations on selected ttys

# Start an "askfirst" shell on the console (whatever that may be)

::askfirst:-/bin/sh

# Stuff to do when restarting the init process

::restart:/sbin/init

# Stuff to do before rebooting

::ctrlaltdel:/sbin/reboot

在etc下添加文件fstab

$ vim /etc/fstab

文件内容如下:

#device mount-point typeoptions dump fsck order

proc /proc procdefaults    0 0

tmpfs  /tmp tmpfs defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /dev tmpfs defaults 0 0

这里我们挂在的文件系统有三个proc、sysfs和tmpfs,在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持

修改内核配置:

$ make menuconfigFile systems --->

Pseudo filesystems --->

[*] Virtual memory file system support (former shm fs)

[*] Tmpfs POSIX Access Control Lists

重新编译内核

$ make zImage

在etc下创建init.d目录,并在init.d下创建rcS文件

$ mkdir /etc/init.d -p

$ vim /etc/init.d/rcS

rcS文件内容为:

#!/bin/sh

# This is the first script called by init process

/bin/mount -a

为rcS添加可执行权限:

$ chmod +x init.d/rcS

在etc下添加profile文件

$ vim /etc/profile

文件内容为:

#!/bin/sh

export HOSTNAME=farsight

export USER=root

export HOME=root

#export PS1="\[\u@\h \W\]\$ "

export PS1="[$USER@$HOSTNAME \W]\# "

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

LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

export PATH LD_LIBRARY_PATH

11、 设备文件创建

根文件系统中有一个设备节点是必须的,在dev下创建console节点

$ mknod dev/console c 5 1

重要:新制作的文件系统尺寸若超出8M,删除不需要的库文件。

选定 busybox-1.9.2.tar.bz2 这个版本, 以静态方式编译, 即生成的 busybox 不需要共享库的支持就能运行。这样卖伏做我们就不需要布署程序库了。缺点是自己写的 arm-linux 程序在这个根文件系统中是不能运行的,因为缺少共享脊御程序库的支持。不过不用担心,通过在目标机里以挂接 NFS 的方式, 将宿主机的 arm-linux-gcc 编译器的库文件挂到 arm-linux 的 /lib 下, 就可完美的运行我们自己的程序了。

现在开始制作静态链接库的根文件系统。

1、准备根文件系统

首先准备制作工具BusyBox1.9.2。

准备交叉编译工具arm-linux-gcc 3.3.2。

在机器上建立rootfs的文件夹

#mkdir rootfs

在rootfs中建立linux系统中典型的文件夹

#cd rootfs

#mkdir root home bin sbin etc dev usr lib tmp mnt sys proc

#mkdir usr/lib usr/bin

#pwd

/home/su/rootfs

2、解压源码包

#tar xjf busybox-1.9.2.tar.bz2

#cd busybox-1.9.2

3、修改 Makefile,

#vi Makefile

将Makefile中的

CROSS_COMPILE ?=

改为

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

注:这个版本中野携的 busybox 用 3.4.1 的 arm-linux-gcc 编译有些问题, 用 3.3.2 版则可顺利编译。

4、定制 busybox

选择busybox下全部的可执行程序

#make defconfig

进到配置选项

#make menuconfig

设置静态编译方式

Busybox Settings --->Build Options --->[*] Build BusyBox as a static binary (no shared libs)

Busybox Settings --->Install Options --->中输入建立根文件系统的文件所在的路径/home/su/rootfs。

其它的默认。

确保 [*] Build BusyBox as a static binary (no shared libs) 被选中,保存退出

5、执行 make 编译

#make

编译出错, 信息如下:

applets/applets.c:15:2: warning: #warning Static linking against glibc produces buggy executables

applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).

applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400

applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.

applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections

applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.

applets/applets.c:21:2: error: #error Aborting compilation.

make[1]: *** [applets/applets.o] Error 1

按照提示,修改文件 applets/applets.c 第 21 行, 将

#error Aborting compilation.

注释掉:

执行 make 重新编译

#make

编译通过, busybox 被生成了, 然后执行

#make install

busybox 就被安装到指定的路径下了/home/su/rootfs,这时可发现rootfs下多了个liunxrc的文件,bin、sbin下也多了很多文件。用ls –l命令查看其中的一个文件,可发现其是链接到busybox的一个连接符,所以我们之后在目标机上运行的命令大多都会调用busybox这个文件的。

若之前忘了指定路径,默认生成到临时目录busybox-1.9.2/_install 下了。

6、编写配置/etc下的初始化程序(可省略)

最简单的做法是把busybox-1.9.2/examples/bootfloppy/etc下的全部文件拷到目标文件的etc目录下

#cd /home/su/busybox-1.9.2/examples/bootfloppy/etc

#cp –rf * /home/su/rootfs/etc

也可自己写这些文件。

7、把rootfs做成镜像

#mkcramfs rootfs rootfs.cramfs

8、把rootfs.cramfs烧写到目标机中。

9、运行目标机

这时会遇到一个错误信息:

Can’t open tty2

Can’t open tty3

Can’t open tty4

解决办法:把/rootfs/etc/ inittab 文件的第三行“tty2::askfirst:-bin/sh”删除掉。

返回到第7步重做。

现实中,动态编译的方法更适合工程的需要,所以一般是采用动态的方法编译根文件系统的。若选择动态编译的办法,大体方法还是一样的,存在一些不同之处是:

不同之处之一是:

进到配置选项

#make menuconfig

选择动态方式

Busybox Settings --->Build Options --->[*] Build Shared libbusybox

不同之处之二是:

上面静态编译出现的出错信息不会出现了,所以不需对程序做任何修改,但还是必须用arm-linux-gcc 3.3.2编译,否则还是会有麻烦。

不同之处之三是(最大的不同之处):

编译完成后,需进到rootfs目录的lib中,往里面添加一些库文件

#cd /home/su/rootfs/lib

这里有点麻烦,我怎么知道需要什么库文件的支持呢?

最简单的办法是把arm-linux-gcc 3.3.2下的整个lib库拷进来,简单省事。但是这么做存在一个问题,做出的根文件系统非常大。

另一个办法是:

#cd /home/su/rootfs/bin

#arm-linux-readelf busybox | grep shared

这样就可以显示出系统运行起来需要什么库文件,再把相应的库文件拷到/home/su/rootfs/lib下。一般而言,系统库用到两个:动态链接器ld-linux.so和c函数库Glibc,Glibc包括:

ld-linux:动态链接库,必需

libc: 标准c函数库,必需

libm: 数学库,一般需要

libdl: 用于动态装载共享库,较少用到

libcrypt: 加密附加库,需要认证的程序用到,较少用

libpthread: POSIX线程库,一般需要

如果需要某个函数库,我们可以将这些库和对应的符号链接拷到目标根文件系统的/lib目录下。简单起见,应该使用-d选项或-a选项调用cp命令,这样可保留完整的符号链接信息。

例:

#cp –a libc.so.6 /home/su/rootfs/lib/

为了减少运行时库的大小,我们应该使用交叉编译版本即arm-linux-gcc 3.3.2的strip工具来处理根文件系统的库文件,把二进制文件中的包含的符号表和调试信息删除掉。

例:

#arm-linux-strip /home/su/rootfs/lib/*.so

注意:

使用busybox做文件系统时,运行make命令,系统会马上显示:

没有/dev/null这个文件

但是还是能最终编译出根文件系统,问题出在重启linux系统,机器进不去了。提示出错,信息如下:

/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system

/etc/rc.d/rc.sysinit: line 200:/dev/null: read-only file system

.

.

.

***An error occured during the file system check.

***Dropping you to a shellthe system will reboot

***when you leave the shell

Give root password for maintenance

(or type Control-D to continue):

解决办法:

按提示输入root用户的密码,回车,可看到

(Repair filesystem)1#:

依次输入命令:

(Repair filesystem)1# mount -n -o remount,rw /

(Repair filesystem)1# rm -f /dev/null

(Repair filesystem)1# mknod -m 0666 /dev/null c 1 3

(Repair filesystem)1# reboot

问题解决。

内核编译:

make menuconfig配置相应的平台,然后保存退出直接make命令就可以编译了。

文件系统制作:

一般都羡春大用busybox开源软森姿件来做,下载,解压,然后make menuconfig配置你想要的属性,然后保存退出,make就可以了,然后make install就会在目录下看到__install的目录就是你要的兄竖根文件系统目录了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8177262.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存