您的位置:首页 > 运维架构 > Linux

linux启动根文件系统

2015-12-28 10:11 519 查看

linux根文件系统启动方式

linux目前我所知道有3种启动文件系统的方式

1、从ramdisk根文件系统启动

这种方法需要

1) 制作ramdisk文件系统压缩包

2) 然后将这个文件压缩包通过bootloader下载到内存中

3) 当系统启动的时候

a) 通过uboot的bootargs环境变量来传递启动参数,修改为bootargs=initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64,以此指定从ramdisk启动,ramdisk压缩文件起始地址在内存地址0x31000000处,文件大小为0x200000。

b) 或者不通过uboot传递启动参数,也可以通过修改内核配置Default kernel command string为”initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64”

2、文件系统已经存在于硬盘或者flash

kernel根据启动的命令行参数(root=/dev/xxx),直接进行mount。 这里有一个问题,在root文件系统本身还不存在的情况下,kernel如何根据/dev/xxx来找到对应的设备呢?注意:根文件系统和其他文件系统的mount方式是不一样的,kernel通过直接解析设备的名称来获得设备的主、从设备号,然后就可以访问对应的设备驱动了。所以在init/main.c中有很长一串的root_dev_names(如hda,hdab,sda,sdb,nfs,ram,mtdblock……),通过这个表就可以根据设备名称得到设备号。注意,bootloader或内核中设定的启动参数(root=/dev/xxx)只是一个代号,实际的根文件系统中不一定存在这个设备文件!

3、通过initramfs将根目录直接编译到linux内核镜像中

这种方法不同于前面两种方法需要在uboot启动参数中指定ramdisk加载到内存的地址或者文件系统在flash中的分区,由于已经将根目录编译到linux的.init.ramfs段中了,所以启动的时候直接将linux内核镜像的.init.ramfs段的内容解压到系统的rootfs中。

方法1在前面已经有说明,从ramdisk根文件系统启动Linux

下面具体来说说方法3是如何实现的

initramfs文件系统制作

本小节参考自:http://blog.csdn.net/pengrui18/article/details/14389233

1、制作根目录

mkdir rootfs

cd rootfs

mkdir bin dev etc lib proc sbin sys usr mnt tmp var

mknod -m 666 /dev/console c 5 1

2、配置busybox

进入Busybox Setting->

build options->

[]”Build busybox as a static binary”//动态链接

Cross Compile prefix(arm-linux-)

Installation Option->

[*]Don’t usr/usr//避免busybox安装至宿主系统的usr,目录下

Busybox Installation Prefix(/xxx/rootfs)//安装位置

其他选项默认

make & make install

将busybox生成的文件拷贝到rootfs根目录中,也要将交叉编译工具下的/lib目录下的库文件拷贝过去。

3、建立initramfs文件系统启动时所需文件init (initramfs文件系统启动时会在根文件系统中执行第一个init程序,它对uboot传过来的参数init=/linuxrc不予理睬,所以需要在制作的根文件系统里的根目录加入init程序,否则无法启动。init程序和linuxrc程序一样都是符号链接文件,它们都是指向/bin/busybox程序)

cd rootfs

mv linuxrc init

4、添加内核对initramfs文件系统支持

make menuconfig

General setup —>

[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

(/xxx/rootfs) Initramfs source file(s) #输入根文件系统的所在目录

另外initramfs source files除了可以指定根目录还可以指定一个或者多个romfs.txt文件,文件的内容大概如下:

dir /dev 755 0 0

nod /dev/console 644 0 0 c 5 1

dir /sys 755 0 0

5、接下来,当系统启动的时候,会自动加载linux内核镜像中的.init.ramfs中的内容到rootfs中,以此作为根目录

ramdisk与initramfs区别

本小节参考自:/article/9092569.html

配置ramdisk需要设置

a. General Setup —> 选择init RAM filesystem and RAM disk

b. Device Drivers —> Block devices —> RAM block device support

c. (4096)Default RAM disk size kbytes等相关选项保持默认

d. File systems选择Second extended fs support

配置initramfs

initramfs不像ramdisk需要在内存中模拟一个磁盘,他所需的配置很少。

a. General Setup —> 选择init RAM filesystem and RAM disk

b. 指定Initramfs source file(s)

因为initramfs根文件系统启动时执行的第一个程序是init,而不是linuxrc,所以在此,我们制作的根文件系统需要添加一个init文件,相应的linuxrc文件就不再需要了。按照如下方式修改根文件系统

ln -s bin/busybox init

这样就为busybox创建了一个软链接init,这个文件就是我们要创建的init文件。

另外就是我们制作ramdisk根文件系统镜像的时候使用的是genext2fs工具,在此我们制作initramfs根文件系统镜像时,并不需要额外的步骤,而是在你编译Linux内核的时候就自动生成了。自动生成的initramfs根文件系统镜像在Linux源码树的usr目录下。名字叫initramfs_data.cpio.gz,它是gz格式的压缩文件。

initramfs制作方式将根文件系统直接编译到内核镜像中了,这样合二为一的镜像就不用单独烧写根文件系统镜像了,并且,在启动内核时的参数也就不用像ramdisk那样需要添加initrd=…来指定initramfs的位置了。

如果你不想将initramfs合并到内核中,直接用配置ramdisk的内核来启动即可,不过这时必须用initrd=…来指定initramfs的位置,并且第二个参数initranfs根文件系统镜像的大小必须指定为实际大小,否则提示镜像校验错误,无法启动内核。将uImage和initramfs_data.cpio.gz下载到内存,设置启动参数initrd=bufptr,size,就可以像ramdisk一样启动initramfs的根目录了。

initramfs原理

本小节参考自:/article/9092570.html

initramfs与initrd类似,也是初始化好了且存在于ram中的,可以压缩也可以不压缩。但是目前initramfs只支持cpio包格式,它会被populate_rootfs()->unpack_to_rootfs(&_initramfs start, &__initramfs_end - &__initramfs_start, 0)函数(解压缩、)解析、安装。

initramfs与initrd的区别

1)Linux内核只认cpio格式的initramfs文件包(因为unpack_to_rootfs只能解析cpio格式文件),非cpio格式的initramfs文件包将被系统抛弃,而initrd可以是cpio包也可以是传统的印象(image)文件,实际使用中initrd都是传统印象文件。

2)initramfs在编译内核的同时被编译并与内核连接成一个文件,它被链接到地址__initramfs_star处,与内核同时被bootloader加载到ram中,而initrd是另外单独编译生成的,是一个独立的文件,它由bootloader单独加载到ram中内核空间外的地址,比如加载的地址为addr(是物理地址而非虚拟地址),大小为8MB,那么只要在命令行中加入“initrd=addr,8M”命令系统就可以找到initrd(当然通过适当修改Linux的目录架构、makefile文件和相关代码,以上两种情况都是可以相通的)。

3)initramfs被解析处理后其原始的cpio包(压缩或非压缩)所占的空间(&__initramfs_start~&__initramfs_end)是作为系统的一部分一直保留在系统中,不会被释放掉,而对于initrd的印象(image)文件,如果没有在命令行中设置“keepinitrd”命令,即keep_initrd全局变量等于0,那么initrd印象文件被处理后其原始文件(压缩或非压缩)所占的空间(initrd_start~initrd_end)将被释放掉。

4)initramfs可以独立于ram disk单独存在,而要支持initrd必须首先支持ramdisk,即要配置CONFIG_BLK_DEV_INITRD选项首先必须配置CONFIG_BLK_DEV_RAM,因为initrd image实际就是初始化好了的ram disk印象文件,最后都要解析、写入到ram disk设备/dev/ram或/dev/ram0中。

initramfs相关全局变量

__initramfs_start

char数据类型,&__initramfs_start就是initramfs的cpio包起始虚拟地址。

__initramfs_end

char数据类型,&__initramfs_end就是initramfs的cpio包结束虚拟地址。

initramfs被编译链接的位置

initramfs被链接到&__initramfs_start虚拟地址处,属于.init.ramfs区,&__initramfs_start和&__initramfs_end在链接文件arch/arm/kernel/vmlinux.lds.S中定义如下:

__initramfs_start = .;

usr/built-in.o(.init.ramfs);所以initramfs文件实际就是usr目录下的built-in.o文件

__initramfs_end = .;

.init.ramfs在Linux2.6.10/usr/initramfs_data.S中定义,编译内核时会先编译Linux2.6.10\usr\gen_init_cpio.c生成应用程序gen_init_cpio;然后用gen_init_cpio生成Linux2.6.10\usr\ initramfs_data.cpio(.gz),它就是保存在&__initramfs_start与&__initramfs_end之间的.init.ramfs;可以通过修改Linux2.6.10\usr\Makefile文件将来使得编译链接时是否压缩initramfs。

initramfs文件的生成过程

1)cpio包格式二进制initramfs文件是由gen_init_cpio命令生成的,gen_init_cpio应用程序是由Linux2.6.10/gen_init_cpio.c文件编译而来,gen_init_cpio命令格式和用法说明如下。

gen_init_cpio命令格式:

# ./gen_init_cpio

Usage:

./gen_init_cpio

文件格式:

# a comment ;注释行;

file ;描述initramfs中的一个文件

dir ;描述initramfs中的一个目录

nod ;描述initramfs中的一个节点

文件每一行各字段说明:

:该文件/目录/节点在initramfs中的名字,包含绝对路径

:该文件/目录/节点在当前开发主机上的位置

:该文件/目录/节点的模式字

:该文件/目录/节点的用户id,0表示root用户

:该文件/目录/节点的组id,0表示root组

:该设备节点对应设备的类型,b表示块设备,c表示字符设备

:设备节点对应设备的主设备号

:设备节点对应设备的次设备号

文件示例:

# Last modified: 1206050528

dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /root 0700 0 0
dir //lost+found 700 0 0
dir //bin 755 0 0
file //bin/addgroup /home/whh/tmp/bin/addgroup 777 0 0
file //bin/adduser /home/whh/tmp/bin/adduser 777 0 0


2)文件生成方式

方法一:根据上述文件格式说明自行编写。

方法二:写一个脚本文件一次性为指定目录下的每个文件/目录/节点生成一行描述符,并将它们全部写入一个指定的文件中。在Linux2.6.10原始目录下的scripts\gen_initramfs_list.sh就是这样的脚本文件。它的使用方法如下:

# . ./gen_initramfs_list.sh

参考文章

1\ 制作initramfs根文件系统

/article/9092569.html

http://blog.csdn.net/pengrui18/article/details/14389233

2\ initramfs的原理

/article/9092570.html

3\ 其他

http://womendu.iteye.com/blog/1069948
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: