linux根文件系统

根文件系统

为什么需要根文件系统? 

1、init进程的应用程序挂在根文件系统上。

2、根文件系统提供了根目录 / 。

3、内核启动后的应用层配置(etc目录)在根文件系统上。(可以认为,发行版 =内核+rootfs)。

4、Shell命令程序在根文件系统上(ls、cd等)。

 (可以说,内核配上rootfs才能工作)

 

根文件系统什么?是特殊用途的文件系统,某种文件系统的格式。rootfstype=

 

根文件系统的形式:

1、镜像文件形式

使用专用工具软件制作可供烧录的镜像文件。

镜像中包含根文件系统中的所有文件。

烧录此镜像类似于相应分区的格式化。

镜像文件系统具有一定的格式,格式是内化的,跟文件名后缀无关。

2、文件夹形式

一个包含特定内容的文件夹。

可由任何一个空文件夹添加必要的文件夹形成。

雏形就是开发主机中构建的文件夹形式。

 

制作ext2格式的根文件系统

mke2fs是一个应用程序,这个应用程序就是用来制作ext2、ext3、ext4等格式的根文件系统的。

1、创建rootfs.ext2文件并且将之挂载到一个目录下方便访问它

dd if=/dev/zero of=rootfs.ext2 bs=1024 count=2048

losetup  /dev/loop1 rootfs.ext2

mke2fs -m 0 /dev/loop1 2048

mount -t ext2 /dev/loop1 ./rootfs/

我们向镜像中写入一个普通文件linuxrc。这个文件就会成为我们制作的镜像中的/linuxrc。内核挂载了这个镜像后就会尝试去执行/linuxrc。然后执行时、挂载成功,执行/linuxrc失败。

 

卸载掉

umount /dev/loop1

losetup -d /dev/loop1

 

nfs方式启动自制简易文件夹形式的rootfs

nfs是一种网络通讯协议,由服务器和客户端构成。使用nfs主要是做rootfs挂载。开发板中运行kernel做nfs客户端,主机ubuntu中搭建nfs服务器。在主机ubuntu的nfs服务器中导出制作的文件夹形式的rootfs目录,则在客户端中就可以去挂载这个文件夹形式的rootfs进而去启动系统。

 

搭建nfs服务器:

安装 NFS
$ sudo apt-get install nfs-kernel-server
$ sudo apt-get install nfs-common
配置 NFS
1 $ sudo dpkg-reconfigure portmap , Should portmap be bound to the
loopback address? N
2 $ sudo vi /etc/default/portmap 末行清除 "-i 127.0.0.1"
配置 hosts.deny
$ sudo vi /etc/hosts.deny
文本末添加
### NFS DAEMONS
portmap: ALL
lockd: ALL
mountd: ALL
rquotad: ALL
statd: ALL
配置 hosts.allow
$ sudo vi /etc/hosts.allow
文本末加入
### NFS DAEMONS
portmap: 192.168.1.
lockd: 192.168.1.
rquotad: 192.168.1.
mountd: 192.168.1.
statd: 192.168.1.
$ sudo /etc/init.d/portmap restart 重启 portmap daemon.
显示如下
Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the restart(8) utility, e.g. restart portmap
portmap start/running, process XXXX
配置/etc/exports
$ sudo vi /etc/exports
文本末添加
/root/rootfs *(rw,sync,no_root_squash)
然后在终端执行 $chmod 777 -R /root/rootfs
$ sudo showmount -e
显示 clnt-create : RPC : Program not registered
$ sudo exportfs -r 更新
$ sudo showmount 192.168.1.116 -e
显示
Export list for 192.168.1.116
/root/rootfs *
启用
$ sudo /etc/init.d/nfs-kernel-server restart 重启 nfs 服务
显示如下
* Stopping NFS kernel daemon
[ OK ]
* Unexporting directories for NFS kernel daemon... [ OK ]
* Exporting directories for NFS kernel daemon...
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for
export "*:/home/work".
Assuming default behaviour ('no_subtree_check').
NOTE: this default has changed since nfs-utils version 1.0.x
* Starting NFS kernel daemon
[ OK ]
挂载测试
$ mount -t nfs localhost:/root/rootfs /mnt
$ mount -t nfs -o nolock localhost:/root/rootfs /mnt

执行后,进入/mnt 目录中,如果可以看到/root/rootfs 中的内容,则说明 nfs 搭建成功! 

 

1、配置网络部分,主要是使能CONFIG_IP_PNP以在2中能够看到Root file system on NFS选项

Networking support

Networking options

TCP/IP networking

IP: kernel level autoconfiguration

[*] IP: DHCP support

[*] IP: BOOTP support

2、配置开启nfs服务

File systems  --->

Network File Systems  --->

<*> NFS client support

[*] NFS client support for NFS version 3                                  [*] NFS client support for the NFSv3 ACL protocol extension

[*] NFS client support for NFS version 4 (EXPERIMENTAL)

[*] NFS client support for NFSv4.1 (DEVELOPER ONLY)

[*] Root file system on NFS  

3、在uboot中设置如下启动参数(IP根据实际使用更改)

setenv bootargs root=/dev/nfs nfsroot=192.168.1.110:/root/porting_x210/rootfs ip=192.168.1.88:192.168.1.110:192.168.1.1:255.255.255.0::eth0:off  init=/linuxrc console=ttySAC2,115200

 

什么是linuxrc?

/linuxrc是一个可执行的应用程序,是应用层的。/linuxrc在开发板当前内核系统下是可执行的。这个应用程序就是用arm-linux-gcc编译链接的;如果是在PC机linux系统下,那么这个程序就是用gcc编译连接的。/linuxrc如果是静态编译连接的那么直接可以运行;如果是动态编译连接的那么我们还必须给他提供必要的库文件才能运行。但是因为我们/linuxrc这个程序是由内核直接调用执行的,因此用户没有机会去导出库文件的路径,因此实际上这个/linuxrc没法动态连接,一般都是静态连接的。

 

/linuxrc执行时引出用户界面

(1)操作系统启动后在一系列的自己运行配置之后,最终会给用户一个操作界面(也许是cmdline,也许是GUI),这个用户操作界面就是由/linuxrc带出来的。

(2)用户界面等很多事并不是在/linuxrc程序中负责的,用户界面有自己专门的应用程序,但是用户界面的应用程序是直接或者间接的被/linuxrc调用执行的。用户界面程序和其他的应用程序就是进程2、3、4·····,这就是我们说的进程1(init进程,也就是/linuxrc)是其他所有应用程序进程的父进程。

 

/linuxrc负责系统启动后的配置

操作系统启动后的应用层的配置(一般叫运行时配置,英文简写etc)是为了让我们的操作系统用起来更方便,更适合我个人的爱好或者实用性。

 

/linuxrc在嵌入式linux中一般就是busybox

(1)busybox是一个C语言写出来的项目,里面包含了很多.c文件和.h文件。这个项目可以被配置编译成各个平台下面可以运行的应用程序。我们如果用arm-linux-gcc来编译busybox就会得到一个可以在我们开发板linux内核上运行的应用程序。

(2)busybox这个程序开发出来就是为了在嵌入式环境下构建rootfs使用的,也就是说他就是专门开发的init进程应用程序。

(3)busybox为当前系统提供了一整套的shell命令程序集。譬如vi、cd、mkdir、ls等。在桌面版的linux发行版(譬如ubuntu、redhat、centOS等)中vi、cd、ls等都是一个一个的单独的应用程序。但是在嵌入式linux中,为了省事我们把vi、cd等所有常用的shell命令集合到一起构成了一个shell命令包,起名叫busybox。

 

 

rootfs中还应该有什么?

 

最重要的就是/linuxrc

 

dev目录下的设备文件。在linux中一切皆是文件,因此一个硬件设备也被虚拟化成一个设备文件来访问,在linux系统中/dev/xxx就表示一个硬件设备,我们要操作这个硬件时就是open打开这个设备文件,然后read/write/ioctl操作这个设备,最后close关闭这个设备。

在最小rootfs中/dev目录也是不可少的,这里面有一两个设备文件是rootfs必须的。

 

sys和proc目录。在最小rootfs中也是不可省略的,但是这两个只要创建了空文件夹即可,里面是没东西的,也不用有东西。这两个目录也是和驱动有关的。属于linux中的虚拟文件系统。

usr是系统的用户所有的一些文件的存放地,这个东西将来busybox安装时会自动生成。

 

/etc目录是很关键很重要的一个,目录中的所有文件全部都是运行时配置文件。/etc目录下的所有配置文件会直接或者间接的被/linuxrc所调用执行,完成操作系统的运行时配置。etc目录是制作rootfs的关键。

 

lib目录也是rootfs中很关键的一个,不能省略的一个。lib目录下放的是当前操作系统中的动态和静态链接库文件。主要是为了其中的动态链接库。

 

 

VFS简介

(1)VFS是linux内核的一种设计理念、设计机制。VFS就是vitrual file system,叫虚拟文件系统。

(2)具体的一些文件系统如FAT、NTFS、ext2、ext3、jffs2、yaffs2、ubi等主要设计目的是为了管理块设备(硬盘、Nand···)

(3)VFS是借鉴了文件系统的设计理念(通过文件系统将底层难以管理的物理磁盘扇区式访问,转换成目录+文件名的方式来访问),将硬件设备的访问也虚拟化成了对目录+文件的访问。所以有了VFS后我们可以通过设备文件(目录+文件名,譬如/dev/mmcblk0p2)的方式来访问系统中的硬件设备。

(4)以上可以初步看出VFS的一些厉害之处,但是VFS不止于此。

 

VFS的意义

(1)对硬件设备的访问,将对硬件设备的访问和对普通文件的访问给接口统一化了(linux中一切届是文件)。

(2)将操作系统上层(应用层)对下层不同文件系统类型的访问细节给屏蔽掉了。因此如果没有VFS那我们写cp命令(其他命令也一样)的时候就不得不去考虑你cp的这个文件在什么文件系统类型下。所以cp命令非常复杂,因此要考虑具体的文件系统类型。有了VFS后情况就不同了。VFS成了一个隔离层,隔离了下层的不同文件系统的差异性,对上层应用提供一个统一的接口。

(3)VFS将不同文件系统和下层硬件设备(块设备)驱动之间的细节也给屏蔽了。不同类型的文件系统在本身设计时是不用考虑各种不同的硬件设备的具体操作差异的,这里有一个类似于VFS的设计理念。

 

VFS和我们学习的关系

(1)VFS机制和rootfs挂载,和其他文件系统的挂载都是有关联的。

(2)内核中有一些sys proc这种虚拟文件系统,这东西也是和VFS机制有关。

(3)/dev/目录下的设备文件都和VFS有关,所以学习驱动绕不开VFS。

 

 

根文件系统构建

 

一、移植busybox生成/linuxrc

1、busybox源码下载地址。www.busybox.net官方网站下载

 

2、修改Makefile

ARCH = arm

CROSS_COMPILE =     /usr/local/mushan_arm/arm-2009q3/bin/arm-none-linux-gnueabi-

 

3、make menuconfig配置

 

(静态编译)

Busybox Settings--->

Build Options--->

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

 

   vi风格命令行)

Busybox Library Tuning--->

[*]vi-style line editing commands

[*]Fancy shell prompts

(模块化设计)

Linux Module Utilities--->

[ ]Simplified modutils

[*]insmod

[*]rmmod

[*]lsmod

[*]modprobe

[*]depmod

 

Linux System Utilities--->[*]mdev

[*]Support /etc/mdev.conf

[*]Support subdirs/symlinks

[*]Support regular expressions substitutions when renaming dev

[*]Support command execution at device addition/removal

[*]Support loading of firmwares

 

4、make 然后make install

   默认装在当前目录的_install目录,需要到make menuconfig指定安装目录。

Busybox Settings--->

Install option-->

 

5、移植busybox后/linuxrc就可以用了,去挂载这个rootfs,应该挂载成功,执行/linuxrc也能成功。

uboot的bootargs设置成:setenv bootargs root=/dev/nfs

nfsroot=192.168.1.110:/root/mushan_root/rootfs ip=192.168.1.88:192.168.1.110:192.168.1.1:255.255.255.0::eth0:off  init=/linuxrc console=ttySAC2,115200 )

 

二、inittab

 

此脚本在/etc/目录下。

#first:run the system script file

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

::askfirst:/bin/login   

#-/bin/sh

::ctrlaltdel:-/sbin/reboot

#umount all filesystem

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

#restart init process

::restart:/sbin/init

 

inittab的工作原理就是被/linuxrc(busybox)执行时所调用起作用。在/etc目录下,所以属于一个运行时配置文件。

 

第一个:#开始的行是注释

第二个:冒号在里面是分隔符,分隔开各个部分。

第三个:inittab内容是以行为单位的,行与行之间没有关联,每行都是一个独立的配置项,每一个配置项表示一个具体的含义。

第四个:每一行的配置项都是由3个冒号分隔开的4个配置值共同确定的。这四个配置值就是id:runlevels:action:process。值得注意得是有些配置值可以空缺,空缺后冒号不能空缺。

第五个:每一行的配置项中4个配置值中最重要的是action和process,action是一个条件/状态,process是一个可被执行的程序的pathname。当满足action的条件时就会执行process这个程序。

 

busybox的执行

 真正的busybox工作时的入口是libbb/appletlib.c中的main函数

 inittab的解析是在busybox/init/init.c/init_main函数中。

(2)执行逻辑是:先通过parse_inittab函数解析/etc/inittab(解析的重点是将inittab中的各个action和process解析出来),然后后面先直接执行sysinit和wait和once(注意这里只执行一遍),然后在while(1)死循环中去执行respwan和askfirst。

 

rcS文件

#!/bin/sh

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

 

runlevel=S

 

prevlevel=N

 

umask 022

 

export PATH runlevel prevlevel

 

mount -a

 

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

mdev -s

 

/bin/hostname -F /etc/sysconfig/HOSTNAME

 

ifconfig eth0 192.168.1.10

 

/etc/init.d/rcS文件是linux的运行时配置文件中最重要的一个,其他的一些配置都是由这个文件引出来的。

 

PATH这个环境变量是linux系统内部定义的一个环境变量,操作系统去执行程序时会默认到PATH指定的各个目录下去寻找。如果找不到就认定这个程序不存在,如果找到了就去执行它。将一个可执行程序的目录导出到PATH,可以让我们不带路径来执行这个程序。

rcS中为什么要先导出PATH?因为在执行ls、cd等程序命令时,需要到可执行程序的路径去执行,PATH环境变量中就有默认的/bin /sbin /usr/bin /usr/sbin 。

 

runlevel=S表示将系统设置为单用户模式

 

umask是linux的一个命令,作用是设置linux系统的umask值,umask值决定当前用户在创建文件时的默认权限。

umask的规律就是:umask值和默认创建文件的权限值加起来是666.

 

mount命令是用来挂载文件系统的,mount -a是挂载所有的应该被挂载的文件系统,在busybox中mount -a时busybox会去查找一个文件/etc/fstab文件,这个文件按照一定的格式列出来所有应该被挂载的文件系统(包括了虚拟文件系统)

 

rcS文件中没有启动mdev的时候,/dev目录下启动后是空的;在rcS文件中添加上mdev有关的2行配置项后,再次启动系统后发现/dev目录下生成了很多的设备驱动文件,/dev目录下的设备驱动文件就是mdev生成的,

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

mdev -s

profile文件添加,显示用户名提示符profile文件放入/etc/目录下。在/etc/sysconfig/HOSTNAME文件中定义。profile文件也是被busybox(init进程)自动调用的

 

如何看到用户登录界面?

inittab中用/bin/login或者/sbin/getty去替代/bin/sh。

::askfirst:-/bin/sh

 

用户密码设置:

复制ubuntu系统中的/etc/passwd和/etc/shadow文件到当前制作的rootfs目录下,修改即可。Passwd  修改密码。

 

自己编写的程序编译后如何能在开发板运行? arm-linux-gcc来交叉编译。

静态链接:arm-linux-gcc hello.c -o hello_satic -static

动态链接:arm-linux-gcc hello.c -o hello_dynamic

动态链接的时候,需要将动态链接库复制到根文件系统的lib目录下。

cp /usr/local/mushan_arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib   /root/mushan_root//rootfs/lib/ -rdf

去掉符号命令:arm-linux-strip *so*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值