手把手教你制作根文件系统.docx

上传人:b****8 文档编号:9283813 上传时间:2023-02-04 格式:DOCX 页数:16 大小:24.53KB
下载 相关 举报
手把手教你制作根文件系统.docx_第1页
第1页 / 共16页
手把手教你制作根文件系统.docx_第2页
第2页 / 共16页
手把手教你制作根文件系统.docx_第3页
第3页 / 共16页
手把手教你制作根文件系统.docx_第4页
第4页 / 共16页
手把手教你制作根文件系统.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

手把手教你制作根文件系统.docx

《手把手教你制作根文件系统.docx》由会员分享,可在线阅读,更多相关《手把手教你制作根文件系统.docx(16页珍藏版)》请在冰豆网上搜索。

手把手教你制作根文件系统.docx

手把手教你制作根文件系统

详解制作根文件系统

一、FHS(FilesystemHierarchyStandard)标准介绍

当我们在linux下输入ls /的时候,见到的目录结构以及这些目录下的内容都大同小异,这是因为所有的linux发行版在对根文件系统布局上都遵循FHS标准的建议规定。

该标准规定了根目录下各个子目录的名称及其存放的内容:

目录名

存放的内容

/bin

必备的用户命令,例如ls、cp等

/sbin

必备的系统管理员命令,例如ifconfig、reboot等

/dev

设备文件,例如mtdblock0、tty1等

/etc

系统配置文件,包括启动文件,例如inittab等

/lib

必要的链接库,例如C链接库、内核模块

/home

普通用户主目录

/root

root用户主目录

/usr/bin

非必备的用户程序,例如find、du等

/usr/sbin

非必备的管理员程序,例如chroot、inetd等

/usr/lib

库文件

/var

守护程序和工具程序所存放的可变,例如日志文件

/proc

用来提供内核与进程信息的虚拟文件系统,由内核自动生成目录下的内容

/sys

用来提供内核与设备信息的虚拟文件系统,由内核自动生成目录下的内容

/mnt

文件系统挂接点,用于临时安装文件系统

/tmp

临时性的文件,重启后将自动清除

 

制作根文件系统就是要建立以上的目录,并在其中建立完整目录内容。

其过程大体包括:

∙编译/安装busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目录

∙利用交叉编译工具链,构建/lib目录

∙手工构建/etc目录

∙手工构建最简化的/dev目录

∙创建其它空目录

∙配置系统自动生成/proc目录

∙利用udev构建完整的/dev目录

∙制作根文件系统的jffs2映像文件

下面就来详细介绍这个过程。

二、编译/安装busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目录

这些目录下存储的主要是常用命令的二进制文件。

如果要自己编写这几百个常用命令的源程序,mygod,这简直是一个噩梦!

好在我们有嵌入式Linux系统的瑞士军刀——busybox,事情就简单很多。

1、从下载busybox-1.7.0.tar.bz2

2、tarxjvfbusybox-1.7.0.tar.bz2解包

3、修改Makefile文件

175ARCH           ?

=arm

176CROSS_COMPILE  ?

=arm-linux-

4、makemenuconfig配置busybox

busybox配置主要分两部分。

第一部分是BusyboxSettings,主要编译和安装busybox的一些选项。

这里主要需要配置:

1)、BuildOptions--BuildBusyBoxasastaticbinary(nosharedlibs),表示编译busybox时,是否静态链接C库。

我们选择动态链接C库。

2)、InstallationOptions--Appletslinks(assoft-links)--(X)assoft-links,表示安装busybox时,将各个命令安装为指向busybox的软链接还是硬链接。

我们选择软链接。

3)、InstallationOptions--(/work/nfs_root/fs_mini3)BusyBoxinstallationprefix,表示busybox的安装位置。

我们选择/work/nfs_root/fs_mini3

4)BusyboxLibraryTuning。

保留Commandlineediting以支持命令行编辑;保留Historysize以支持记忆历史命令;选中Tabcompletion和Usernamecompletion以支持命令自动补全

第二部分是Applets,他将busybox的支持的几百个命令分门别类。

我们只要在各个门类下选择想要的命令即可。

这里我们基本保持默认设置。

1)选中NetworkingUtilities--httpd下的Enable-uoption,以启用http服务器的功能allowstheservertorunasaspecificuser

5、编译busybox

make

6、安装busybox

makeinstall

安装完成后,可以看到在/work/nfs_root/fs_mini3目录下生成了binsbinusr/binusr/sbin目录,其下包含了我们常用的命令,这些命令都是指向bin/busybox的软链接,而busybox本身的大小不到800K:

dennis@dennis-desktop:

/work/nfs_root/fs_mini3$ls

bin linuxrc sbin usr

dennis@dennis-desktop:

/work/nfs_root/fs_mini3$ ls-lbin

total740

lrwxrwxrwx1dennisdennis     72010-04-0323:

57addgroup->busybox

lrwxrwxrwx1dennisdennis     72010-04-0323:

57adduser->busybox

lrwxrwxrwx1dennisdennis     72010-04-0323:

57ash->busybox

-rwxr-xr-x1dennisdennis7496322010-04-0323:

57busybox

lrwxrwxrwx1dennisdennis     72010-04-0323:

57cat–>busybox

而普通PC机上的ls命令就有差不多80K的大小:

dennis@dennis-desktop:

/work/nfs_root/fs_mini3$ls-l/bin/ls

-rwxr-xr-x1rootroot780042007-09-2920:

51/bin/ls

busybox以它娇小的身躯容纳了数以百计的命令代码,实在是让人佩服不已,其不愧嵌入式系统瑞士军刀之美誉。

据说,busybox的作者身患绝症,这更让人钦佩GNU开源软件的作者们。

三、利用交叉编译工具链,构建/lib目录

光有应用程序(命令)是不够的,因为应用程序本身需要使用C库的库函数,因此还必需制作forARM的C库,并将其放置于/lib目录。

mygod,要自己写C库的源代码吗?

不用!

还记得交叉编译工具链的3个组成部分吗?

交叉编译器、forARM的C库和二进制工具。

哈哈,forARM的C库是现成的,我们只需要拷贝过来就可以了。

遗憾的是:

整个C库目录下的文件总大小有26M。

而我们根文件系统所在分区不过区区16M而已,根本放不下。

怎么办呢?

dennis@dennis-desktop:

/work/nfs_root/fs_mini3$du-s--si/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib

26M    /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib

需要C库目录下所有的文件吗?

no,absolutelyno!

让我们来分析一下glibc库目录下内容的组成。

该目录下的子目录和文件共分8类:

∙目标文件,如crtn.o,用于gcc链接可执行文件

∙libtool库文件(.la),在链接库文件时这些文件会被用到,比如他们列出了当前库文件所依赖的其它库文件,程序运行时无需这些文件

∙gconv目录,里面是各种链接脚本,在编译应用程序时,他们用于指定程序的运行地址,各段的位置等

∙静态库文件(.a),例如libm.a,libc.a

∙动态库文件(.so、.so.[0-9]*)

∙动态链接库加载器ld-2.3.6.so、ld-linux.so.2

∙其它目录及文件

很显然,第1、2、3、4、7类文件和目录是不需要拷贝的。

由于动态链接的应用程序本身并不含有它所调用的C库函数的代码,因此执行时需要动态链接库加载器来为它加载相应的C库文件,所以第6类文件是需要拷贝的。

除此之外,第5类文件当然要拷贝。

但第5类文件的大小也相当大。

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$du-c--si*.so*

7.2M   total

需要全部拷贝吗?

非也,非也!

其实,需要哪些库完全取决于要运行的应用程序使用了哪些库函数。

如果我们只制作最简单的系统,那么我们只需要运行busybox这一个应用程序即可。

通过执行

dennis@dennis-desktop:

/work/nfs_root/fs_mini3$arm-linux-readelf-abin/busybox|grep'Shared'

0x00000001(NEEDED)                    Sharedlibrary:

[libcrypt.so.1]

0x00000001(NEEDED)                    Sharedlibrary:

[libm.so.6]

0x00000001(NEEDED)                    Sharedlibrary:

[libc.so.6]

可知:

busybox只用到了3个库:

通用C库(libc)、数学库(libm)、加密库(libcrypt),因此我们只需要拷贝这3个库的库文件即可。

但是每个库都有4个文件,4个文件都要拷贝吗?

当然不是。

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ls-llibcrypt[.-]*

-rwxr-xr-x1dennisdennis307002008-01-2205:

32libcrypt-2.3.6.so

-rw-r--r--1dennisdennis231182008-01-2205:

32libcrypt.a

lrwxrwxrwx1dennisdennis   132008-12-2215:

38libcrypt.so->libcrypt.so.1

lrwxrwxrwx1dennisdennis   172008-12-2215:

38libcrypt.so.1->libcrypt-2.3.6.so

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ls-llibm[.-]*

-rwxr-xr-x1dennisdennis 7790962008-01-2205:

31libm-2.3.6.so

-rw-r--r--1dennisdennis11342822008-01-2205:

32libm.a

lrwxrwxrwx1dennisdennis      92008-12-2215:

38libm.so->libm.so.6

lrwxrwxrwx1dennisdennis     132008-12-2215:

38libm.so.6->libm-2.3.6.so

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ls-llibc[.-]*

-rwxr-xr-x1dennisdennis14356602008-01-2205:

48libc-2.3.6.so

-rw-r--r--1dennisdennis27682802008-01-2205:

31libc.a

-rw-r--r--1dennisdennis    1952008-01-2205:

34libc.so

lrwxrwxrwx1dennisdennis     132008-12-2215:

38libc.so.6->libc-2.3.6.so

4个文件中的.a文件是静态库文件,是不需要拷贝的。

另外3个文件是:

∙实际的共享链接库:

libLIBRARY_NAME-GLIBC_VERSION.so。

当然需要拷贝。

∙主修订版本的符号链接,指向实际的共享链接库:

libLIBRARY_NAME.so.MAJOR_REVISION_VERSION,程序一旦链接了特定的链接库,将会参用该符号链接。

程序启动时,加载器在加载程序前,会检索该文件。

所以需要拷贝。

∙与版本无关的符号链接,指向主修订版本的符号连接(libc.so是唯一的例外,他是一个链接命令行:

libLIBRARY_NAME.so,是为编译程序时提供一个通用条目)。

这些文件在程序被编译时会被用到,但在程序运行时不会被用到,所以不必拷贝它。

关于共享库的2个符号链接的作用的特别说明:

当我们使用gcc   hello.c   -o   hello   -lm编译程序时,gcc会根据-lm的指示,加头(lib)添尾(.so)得到libm.so,从而沿着与版本无关的符号链接(libm.so->libm.so.6)找到libm.so.6并记录在案(hello的ELF头中),表示hello需要使用libm.so.6这个库文件所代表的数学库中的库函数。

而当hello被执行的时候,动态链接库加载器会从hello的ELF头中找到libm.so.6这个记录,然后沿着主修订版本的符号链接(libm.so.6->libm-2.3.6.so)找到实际的共享链接库libm-2.3.6.so,从而将其与hello作动态链接。

可见,与版本无关的符号链接是供编译器使用的,主修订版本的符号链接是供动态链接库加载器使用的,而实际的共享链接库则是供应用程序使用的。

通过以上分析,我们只需要拷贝3个库(每个库各1个主修订版本的符号链接和1个实际的共享链接库)以及动态链接库加载器(1个符号链接和1个实体文件)。

步骤如下:

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$mkdir/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp libcrypt-*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp-llibcrypt.so.*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp libm-*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp-llibm.so.*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp libc-*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp-llibc.so.*/work/nfs_root/fs_mini3/lib

dennis@dennis-desktop:

/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$cp-lld-*/work/nfs_root/fs_mini3/lib

四、手工构建/etc目录

/etc目录存放的是系统程序的主配置文件,因此需要哪些配置文件取决于要运行哪些系统程序。

即使最小的系统也一定会运行1号用户进程init,所以我们至少要手工编写init的主配置文件inittab。

busybox的inittab文件的语法、语义与传统的SYSV的inittab有所不同。

inittab文件中每个条目用来定义一个需要init启动的子进程,并确定它的启动方式,格式为:

:

:

例如:

ttySAC0:

:

askfirst:

-/bin/sh

表示子进程要使用的控制台,若省略则使用与init进程一样的控制台

表示运行级别,busyboxinit程序这个字段没有意义

表示init进程如何控制这个子进程

osysinit:

系统启动后最先执行,只执行一次,init进程等待它结束后才继续执行其它动作

owait:

系统执行完sysinit条目后执行,只执行一次,init进程等待它结束后才继续执行其它动作

oonce:

系统执行完wait条目后执行,只执行一次,init进程不等待它结束

orespawn:

启动完once进程后,init进程监测发现子进程退出时,重新启动它

oaskfirst:

启动完respawn进程后,与respawn类似,不过init进程先输出”PleasepressEntertoactivatethisconsole“,等用户输入回车后才启动子进程

oshutdown:

当系统关机时

orestart:

Busybox中配置了CONFIG_FEATURE_USE_INITAB,并且init进程接收到SIGUP信号时执行,先重新读取、解析/etc/inittab文件,再执行restart程序

octrlaltdel:

按下ctrl+alt+del键时执行,不过在串口控制台中无法输入它

表示进程对应的二进制文件。

如果前面有-号,表示该程序是“可以与用户进行交互的”

我们制作最简单的/etc/inittab文件,其内容如下:

:

:

sysinit:

/etc/init.d/rcS

:

:

askfirst:

-/bin/sh

:

:

ctrlaltdel:

/sbin/reboot

:

:

shutdown:

/bin/umount-a–r

制作最简单的脚本程序文件/etc/init.d/rcS,其内容如下:

#!

/bin/sh

ifconfigeth0192.168.2.17

修改shell脚本文件/etc/init.d/rcS的权限,以使其可被执行:

#chmoda+x/etc/init.d/rcS

五、手工构建最简化的/dev目录

在linux机器上,执行ls   /dev可看到几百个设备文件,我需要手工创建它们吗?

maybe,我只需要手工创建几个设备文件!

我怎么知道我应该创建哪几个设备文件呢?

管它呢,先看看开发板上可爱的linux的反应再说。

启动Linux操作系统,显示:

VFS:

Mountedroot(nfsfilesystem).

Freeinginitmemory:

112K

Warning:

unabletoopenaninitialconsole.

这说明,内核已经成功挂载根文件系统,但却未能成功启动第1个用户进程init。

通过错误消息“unabletoopenaninitialconsole”搜索内核源代码,找到init/main.c文件。

748staticintnoinlineinit_post(void)

749{

750        free_initmem();

751        unlock_kernel();

752        mark_rodata_ro();

753        system_state=SYSTEM_RUNNING;

754        numa_default_policy();

755

756        if(sys_open((constchar__user*)"/dev/console",O_RDWR,0)<0)

757                printk(KERN_WARNING"Warning:

unabletoopenaninitialconsole.\n");

758

759        (void)sys_dup(0);

760        (void)sys_dup(0);

761

762        if(ramdisk_execute_command){

763                run_init_process(ramdisk_execute_command);

764                printk(KERN_WARNING"Failedtoexecute%s\n",

765                                ramdisk_execute_command);

766        }

767

768        /*

769         *Wetryeachoftheseuntilonesucceeds.

770         *

771         *TheBourneshellcanbeusedinsteadofinitifweare

772         *tryingtorecoverareallybrokenmachine.

773         */

774        if(execute_command){

775                run_init_process(execute_command);

776                printk(KERN_WARNING"Failedtoexecute%s. Attempting"

777                                        "defaults...\n",execute_command);

778        }

779        run_init_proces

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机软件及应用

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1