Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1039003
  • 博文数量: 836
  • 博客积分: 43880
  • 博客等级: 大将
  • 技术积分: 5485
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-20 17:36
文章分类

全部博文(836)

文章存档

2011年(1)

2008年(835)

我的朋友

分类: LINUX

2008-08-20 18:26:04


linux内存初始化技术(initrd)用于支持两阶段的系统引导过程,是在系统启动过程中被挂载的临时root文件系统(译者注:这里的root文件系统是指的根文件系统)。initrd包含很多可执行程序和驱动,并允许在临时的内存磁盘根文件系统被卸载,内存被释放后挂载真实的root文件系统。在许多嵌入式linux文件系统中,initrd是最终的根文件系统。这篇文章主要讲解了linux2.6内核的initrd技术,包括在内核中的创建及使用。 1什么是内存磁盘初始化?0 initrd挂载优先级高于真实根文件系统,它被邦定在内核上,做为内核启动过程的一部分被加载(load)。然后,做为两阶段引导过程的第一部分,内核挂载(mount)initrd,用于获得并加载真实有效的文件系统。 为了达到这个目的,initrd包含有最起码的目录与程序,例如insmod,来安装内核模块到内核中。 对于桌面或服务器linux,initrd是临时文件系统,它的生存周期很短,仅仅是做为到达真实根文件系统的桥梁。但对于没有存储设备的嵌入式系统来说,它才是永久性的根文件系统。本篇文章对这两方面均有涉及。 2深入分析initrdL initrd包含有必须的程序和系统文件,用于支持系统的启动的第二阶段过程。创建初始化内存的方法,是随着你所使用的系统版本而改变的。从FedoraCore3以后,initrd就由回送设备(loopdevice)建立。什么是回送设备?它是一个设备驱动,允许你将一个文件挂载为块设备,并对其文件系统做出描述。也许loopdevice并不存在与你的内核中,但是你能够通过内核的配置工具(makemenuconfig)打开它。路径是:DeviceDrivers-》BlockDevices-》LoopBackDevicesupport。下面为检查命令: #mkdirtemp;cdtemp #cp/boot/initrd.img.gz. #gunzipinitrd.img.gz #mount-text-oloopinitrd.img/mnt/initrd #ls-la/mnt/initrd # 现在,你可以通过查看/mnt/initrd的子目录来查看initrd的内容。需要注意的是,即使你的initrd镜像文件并不是以.gz做为后缀名,但是你同样可以通过增加此后缀名来让gunzip打开它。 从FedoraCore3开始,默认的initrd镜像就是一个压缩的gpio归档文件。除了用挂载文件的方式以外,你同样可以通过cpio归档的方式来将其挂载成使用了回送设备的压缩镜像。你可以通过以下的指令来检查这个cpio归档文件的内容: #mkdirtemp;cdtemp #cp/boot/initrd-2.6.14.2.imginitrd-2.6.14.2.img.gz #gunzipinitrd-2.6.14.2.img.gz #cpio-i--make-directories你看到的结果将是一个小型根文件系统,如下所示: #ls-la # drwxr-xr-x10rootroot4096May702:48. drwxr-x---15rootroot4096May700:54.. drwxr-xr-x2rootroot4096May702:48bin drwxr-xr-x2rootroot4096May702:48dev drwxr-xr-x4rootroot4096May702:48etc -rwxr-xr-x1rootroot812May702:48init -rw-r--r--1rootroot1723392May702:45initrd-2.6.14.2.img drwxr-xr-x2rootroot4096May702:48lib drwxr-xr-x2rootroot4096May702:48loopfs drwxr-xr-x2rootroot4096May702:48proc lrwxrwxrwx1rootroot3May702:48sbin->bin drwxr-xr-x2rootroot4096May702:48sys drwxr-xr-x2rootroot4096May702:48sysroot # 一些小的,但是很有必要的程序组合能在./bin目录下得到,包括nash(它不是一个shell,而是一个脚本解释工具),用于加载内核模块的insmod,以及lvm等。 上面所示目录中,相对比较有趣的是root目录下的初始化文件。这些文件,和传统的linux启动过程中一样,是在initrd镜像被解压缩到RAM中时生成的。待会我们将继续探讨这个问题。 3创建initrd的工具。 现在,让我们回到一开始的讨论:initrd的镜像是如何被创建的?在传统的linux系统中,initrd是在linuxbuild的时候被创建的。像mkinitrd这样的许许多多的工具,都能够用于通过必须的库和模块来自动构建一个用于过渡到真实根文件系统的initrd。事实上,mkinitrd工具是一个脚本文件,因此,我们能够很清楚得看到,这个过程是如何进行的。同样的,YAIRD(YetAnotherMkinitrd)工具,也允许我们自定制每一个initrd被构建的阶段。 4自己动手,打造自定义的初始化内存盘 由于很多基于linux的嵌入式系统都没有硬盘驱动器,initrd也可以做为永久性的根文件系统。下面我就将告诉你们,如何创建一个initrd镜像。我使用的是标准linux桌面系统,因此大家即使没有嵌入式目标设备也可以照着做。除了交叉编译以外,嵌入式目标文件的构建过程是相同的。 #!/bin/bash #Housekeeping... rm-f/tmp/ramdisk.img rm-f/tmp/ramdisk.img.gz #RamdiskConstants RDSIZE=4000 BLKSIZE=1024 #Createanemptyramdiskimage ddif=/dev/zeroof=/tmp/ramdisk.imgbs=$BLKSIZEcount=$RDSIZE #Makeitanext2mountablefilesystem /sbin/mke2fs-F-m0-b$BLKSIZE/tmp/ramdisk.img$RDSIZE #Mountitsothatwecanpopulate mount/tmp/ramdisk.img/mnt/initrd-text2-oloop=/dev/loop0 #Populatethefilesystem(subdirectories) mkdir/mnt/initrd/bin mkdir/mnt/initrd/sys mkdir/mnt/initrd/dev mkdir/mnt/initrd/proc #Grabbusyboxandcreatethesymboliclinks pushd/mnt/initrd/bin cp/usr/local/src/busybox-1.1.1/busybox. ln-sbusyboxash ln-sbusyboxmount ln-sbusyboxecho ln-sbusyboxls ln-sbusyboxcat ln-sbusyboxps ln-sbusyboxdmesg ln-sbusyboxsysctl popd #Grabthenecessarydevfiles cp-a/dev/console/mnt/initrd/dev cp-a/dev/ramdisk/mnt/initrd/dev cp-a/dev/ram0/mnt/initrd/dev cp-a/dev/null/mnt/initrd/dev cp-a/dev/tty1/mnt/initrd/dev cp-a/dev/tty2/mnt/initrd/dev #Equatesbinwithbin pushd/mnt/initrd ln-sbinsbin popd #Createtheinitfile cat>>/mnt/initrd/linuxrc<#!/bin/ash echo echo"Simpleinitrdisactive" echo mount-tproc/proc/proc mount-tsysfsnone/sys /bin/ash--login EOF chmod x/mnt/initrd/linuxrc #Finishup... umount/mnt/initrd gzip-9/tmp/ramdisk.img cp/tmp/ramdisk.img.gz/boot/ramdisk.img.gz 想创建initrd的话,你需要首先创建一个空文件,将/dev/zero(0字符流)做为ramdisk.img的输入。得到的文件大小大约是4MB(有4000个1K的块组成)。接下来,用mke2fs命令来创建一个使用这个空文件的ext2文件系统。现在,这个文件就是一个ext2文件系统。ok,接下来,以回路设备的形式挂载这个文件到/mnt/initrd,现在,你就在挂载点拥有一个代表着ext2文件系统的目录,并用与存放你的initrd。其他大多数的脚本语句都是用于实现这个功能。 下一步,就是创建一些必须的子目录,用于生成你的根文件系统:/bin,/sys,/dev,和/pro。这里只需要少数几个目录,例如,没有/lib。但是它们已经包含了大部分功能。 如果想让你的根文件系统发挥更大的作用,请使用BusyBox。这个工具是一个包含了许多独立工具的镜像,这些独立的工具你都能在linux中找到(ash,a等等wk,sed,insmod)。BusyBox的优势在于,它把它们集合在了一起,并分享了公用的部分,从而极大缩小了镜像的体积。这对于嵌入式系统来讲,是非常理想的。请将BustBox镜像从它的源目录中复制出来,到你的/bin目录下,这样,很多指向BusyBox工具集的符号链接将被创建,BusyBox能确定哪一个工具将被使用,并自动引用它。这个/bin目录下被创建的链接的小型集合将用于对启动脚本的支持。 再下一步,就是一小部分特殊设备文件的创建。我从我的/dev文件夹中直接拷贝了出来,别忘了加上-a选项来保持它们原有的属性。 倒数第二步,就是生成linuxrc文件。在内核挂载了内存盘之后,它将搜索并执行相关的启动文件,如果没有找到,内核就将linuxrc文件做为其启动脚本。你最好在这个文件中对环境变量做一些基本设置,例如挂载/proc文件系统等。除了/proc外,我还挂载了/sys文件系统,将消息发送给终端。最后,我调用ash并通过它和根文件系统交互。最后记住,用chmod把linuxrc文件的属性改为可执行。 最后,你的根文件系统算是ok了。现在它并没有被挂载,用gzip将它压缩,并将压缩后的文件ramdisk.img.gz拷贝到/boot目录下,这样它就能被GRUB调用。 想要构建你的初始化ram盘的话,你只需要调用mkird,镜像就将自动创建并拷贝到/boot目录下。 1 2 下一页>>


下载本文示例代码
阅读(278) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~