Linux根文件之系统制作流程

来源:互联网 发布:python绝技用的2还是3 编辑:程序博客网 时间:2024/05/21 18:43

20160316

如何制作最小根文件系统

 

1概述

如何制作一个最小的根文件系统,能让内核在该文件系统中运行?该文章是读《嵌入式Linux应用开发完全手册》韦东山 书籍简要总结。
    制作最小的根文件系统的主要分为五个部分:
    ① 编译Busybox得到常用命令与工具集(生成bin,sbin,usr,linuxrc);

② 构建etc目录(/etc/inittab,/etc/fstab,/etc/init.d/rcS等);
    ③ 构建dev目录(/dev/console,/dev/null等设备节点);
    ④ 构建lib目录(C库函数uclibc,glibc);
    ⑤ 创建其他空目录(/proc、/sys等目录),配置需求相关文件程序;

⑥ 制作根文件系统的镜像文件;


2构造bin/sbin/usr目录

2.1配置编译Busybox

#make defconfig   

#make menuconfig

Busybox Setting -->

Build Options -->

[*]Build BusyBox as a static binary (no shared libs)

/*选择busybox静态链接共享库,则lib目录不用建立即可执行/sbin/init */

(/usr/local/arm/4.3.2/bin/arm-linux-)Cross Compiler prefix

/*指定交叉编译器为*/

Installation Options  /*选择生成的文件存放目录*/

Busybox Library Tuning--->

    [*]Username completion

    [*]Fancy shell prompts

    [*]Query cursor position from terminal

/*编译出的busybox的shell命令解释器支持显示当前路径及主机信息*/

#make   

 

2.2安装Busybox

#make install

#cp  bin/ sbin/ usr/ linuxrc  / home/rootfs  -r

切记一定要带上-a的参数,因为bin目录里大部分都是链接,如果不带-a的参数,拷过去之后会做相应的复制,不再是链接的形式

查看busybox安装版本

root@am57xx-evm:/bin# busybox --help

BusyBox v1.23.1 (2016-01-28 14:01:20 EST) multi-call binary.

注】编译的时候如果遇到有错误的地方,可以根据提示进行修改,一般的情况下,是某个命令的配置上有错误,这个时候可以选择重新执行make menuconfig进行重新配置,去掉出错的命令,重新编译即可。也可以BusyBox 中添加自己编写的新命令

查看一个程序(busybox)依赖的共享链接库

1. 使用编译工具readelf

#arm-linux-gnueabihf-readelf  -a  /bin/busybox | grep 'Shared'

=>如果编译配置不选用静态链接共享库,busybox需要依赖动态链接库,则需要在/lib目录中加入相应的动态链接库。

2. 使用ldd命令

#cd uClibc-0.9.28/utils

#make ldd.host  /*制作对应ldd命令,放到主机/usr/local/bin目录即可使用*/

#ldd.host  busybox  /*查看busybox的依赖的动态链接库关系*/

 

3构建etc目录

etc目录取决于要运行的程序,一般最小创建文件/etc/inittab,/etc/init.d/rcS,/etc/fstab。

3.1 /etc/inittab

#/etc/inittab

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

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount  -a  -r  

::restart:/sbin/init

ttySAC0::askfirst:-/bin/sh  /*根据情况需要修改,‘-’表示与用户可交互的。特别注意:如果/dev目录中没有创建ttySAC0串口设备,则内核启动不能进入串口交互界面。*/

inittab文件中条目格式为<id>:<runlevel>:<action>:<process>。特别注意action字段表示init进程如何控制这个子进程,action字段可使用关键字:sysinit、wait、once、respawn、askfirst、shutdown、restart、ctrlaltdel。

3.2 /etc/init.d/rcS

#!/bin/sh

mount -a     /*挂接/etc/fstab文件指定的所有文件系统 */

echo /sbin/mdev> /proc/sys/kernel/hotplug 

/*设置内核,当有设备拔插时调用/sbin/mdev程序 */

mdev -s      /*在/dev目录下生成内核支持的所有设备的结点 */

修改文件属性,使之能执行chmod +x /etc/init.d/rcS

3.3 /etc/fstab

fstab的格式如下:

#device  mount-point  type  options dump fsck oder

proc       /proc        proc    defaults  0  0

tmpfs      /tmp        tmpfs    defaults   0   0

sysfs       /sys         sysfs     defaults   0   0

tmpfs      /dev        tmpfs     defaults   0   0

将/dev、/tmp、/var三个目录挂载为tmpfs文件系统,可以延长Nand Flash的擦写寿命

 

4构建dev目录

/dev目录下存放的跟设备有关的文件,一些驱动程序的设备节点文件就在此目录下。

4.1静态创建设备文件

从系统启动过程中可知,涉及的设备有:创建/dev/mtdblock*(块设备), /dev/ttySAC*(串口设备), /dev/console,/dev/null,即可启动系统。

sudo mknod console c 5 1 (安装好的linux机器/dev/console文件得知)

sudo mknod null c 1 3

其他设备文件可以等到系统启动后,使用“cat /proc/devices”命令查看内核中注册了哪些设备,再一一创建。

实际上,各个Linux系统中dev目录的内容很相似,故可以从其他系统中复制过来,调整部分。

4.2 mdev动态更新设备文件

mdev是通过init进程来启动的,在使用mdev构造/dev目录前,init进程至少要建立设备文件/dev/console、/dev/null

mdev是通过读取内核信息来初始化并动态更新/dev目录。mdev需要设置内核支持sysfs文件系统,还有支持tmpfs文件系统(从”.config”文件确认内核已经设置了CONFIG_SYSFS、CONFIG_TMPFS配置项。mdev的用法请参考busybox/dox/mdev.txt文件。使用mdev构建dev目录,加入语句3.2、3.3节内容。

总结:如果完成第2/3/4节步骤(busybox选用静态链接库)和创建了/sys、/proc目录,则内核加载已经可以进入串口交互界面,但是编写一个简单hello程序还不能运行,需要将c库加入到lib目录。init已经设置PATH=/sbin:/usr/sbin:/bin:/usr/bin


5构建lib目录

拷贝编译工具下的动态库文件。具体操作:执行arm-linux-gcc -v命令,参看交叉编译工具安装在什么目录下,然后拷贝该编译工具的arm-linux目录的lib库下的所有动态文件。或者自己编译glibc源码、uclibc源码制作c库。

例如:我的交叉编译工具安装在opt/tools目录下。在自己做的根文件系统下,建立lib目录。

mkdir lib
cd /opt/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib
ls -l
cp *so* /opt/first_fs/lib –d

-d的作用,原来是一个链接文件的还拷贝成一个链接文件。到目前为止一个最小的根文件系统已经制作好了。

关于C库制作详细步骤,请查看我编写的文档《Linux根文件之lib库制作详解》。

 

6构建其他空目录

其他目录可以为空目录,创建:proc、mnt、tmp、sys、root等。

此时即可作为网络根文件系统直接启动,烧写到开发板还需要制作为镜像文件(例如yaffs文件系统镜像文件、jffs2、ubi等)。


附录1.问题集

1.内核启动之后,执行的第一个脚本文件是哪一个?

答:在嵌入式系统(ubuntu9.04之前),内核启动的第一个(也是唯一的一个)用户进程init进程,init进程的执行程序通常是/sbin/init。/sbin/init解析inittab文件,inittab文件中sysinit指定的脚本为第一个执行脚本文件。嵌入式系统中通常命名它为rcS。

 

2.内核启动的第一个用户进程init进程,该进程执行的程序一定是/sbin/init吗?如果不一定,有哪些可能是被执行的程序?

 

3.Busybox中init程序执行流程简单描述一下?

 

4.Nand Flash的擦写寿命是有限的,如何延长Nand使用寿命?

答:将/dev、/tmp、/var三个目录挂载为tmpfs文件系统。

 

5.如何让linux中dev目录支持热插拔U盘,插拔U盘时自动创建或删除设备节点文件/dev/sda文件?

 

6.在产品研发阶段,所有根文件系统采用NFS挂载以方便开发,由于在u-boot中我们指定了开发板的IP地址为192.168.1.17,所以我们必须在rcS中指定相同的IP地址,否则在启动过程中,会因为IP地址的缘故,在执行rcS后,导致开发板无法和NFS服务器通信,也就无法进入shell。但在最终产品的根文件系统中,也许要求开发板的IP地址是别的IP,而不是192.168.1.17。应该如何做,才能做出一个即可以用于开发阶段,又可以用于最终产品的统一的根文件系统呢?

答案:提示查看/proc/mounts(深入浅出嵌入式底层软件开发有具体答案)。

 

7.在linux终端输入ps看不到任何进程的存在原因分析?

答:ps机制是通过查看/proc中的内容来获得进程信息的,如果/proc目录为空则ps显示看不到任何进程。/proc是用来提供内核和进程信息的虚拟文件系统,由内核自动生成的。我们需要挂载执行mount -t proc none /proc命令。

 

8.bin、sbin、usr/bin、usr/sbin目录存放文件区别?

答:如果是用户和管理员必备的二进制文件,就会放在/bin。如果是系统管理员必备,但是一般用户根本不会用到的二进制文件,就会放在/sbin。相对而言。如果不是用户必备的二进制文件,多半会放在/usr/bin;如果不是系统管理员必备的工具,多半会放在/usr/sbin。

 

附录2.参考文案

1.《嵌入式Linux应用开发完全手册》韦东山 编著

2. 构建嵌入式Linux根文件系统

http://blog.chinaunix.net/uid-8363656-id-2031653.html

3. ubuntu 10.04 启动过程

http://blog.sina.com.cn/s/blog_66fb0c830100xms2.html

4.《深入浅出嵌入式底层软件开发》扬铸 编著


0 0
原创粉丝点击