Ramdisk根文件系统启动Linux(使用initramfs启动Linux)
前天做了个从ramdisk根文件系统启动Linux的实验,写了个帖子。经总版主kasim大侠的提携,得知现在基于Linux的发行版通常采用initramfs代替initrd,架构更简单,应用也更灵活一些。正好今天晚上没事,就做了一下使用initramfs启动Linux,写个帖子总结一下。
这个帖子不会详述具体的每一个步骤,仅仅说明它和使用ramdisk启动系统时所需要做的步骤的区别。事实上我也是在前天配置编译内核使用ramdisk启动系统的步骤的基础上改的。这里只总结使用initramfs和使用ramdisk各自配置内核选项的主要区别和遇到的一些问题。
参照我的另一个帖子 《从ramdisk根文件系统启动Linux成功,总结一下》
http://www.arm9home.net/read.php?tid-5610.html
开发环境:Fedora 9
交叉编译工具链:arm-linux-gcc 4.3.2 with EABI
嵌入式Linux内核版本:2.6.29.4-FriendlyARM。本文就是友善之臂的2.6.29.4-FriendlyARM的那个版本config_mini2440_t35的内核的基础上改的。其它版本的应该也类似,仅供参考。
开发板:mini2440-128M Nand Flash
Bootloader:u-boot-2009.11
主要的不同点:
步骤2.修改内核配置选项
进入内核源码目录linux-2.6.29目录
#cp config_mini2440_t35 .config
#make menuconfig ARCH=arm
打开配置菜单,配置使用ramdisk启动系统时需要设置两个选项, 这里只需要配置一个配置项:
General setup-->选择 Initial RAM filesystem and RAM disk...... 项
原因很简单,我们使用的是initramfs,而不是ramdisk,所以不用配置ramdisk的驱动支持项Device Drivers-->Block devices-->RAM block device support 项。相应的之后的(4096)Default RAM disk size kbytes等相关默认配置选项就不会再出现了。
另外initramfs技术和ramdisk技术的另一个重要的区别就是initramfs并不是在内存中模拟出一个磁盘,所以也就不在需要ramdisk中所需的ext2驱动支持。所以,File systems菜单下的ext2文件系统支持< > Second extended fs support选项就可以取消了。
在这一步 还有一个重要的区别就是需要在General setup-->Initial RAM filesystem and RAM disk...... 项的相关项(/work/rootfs) Initramfs source file(s)中填写你要制作成initramfs格式的根文件系统目录 ,在这里我要做的根文件系统的目录是/work/rootfs。
步骤6.制作initramfs根文件系统
h)制作initramfs根文件系统镜像
制作最小系统根文件系统的步骤和以前制作ramdisk根文件系统的步骤基本一致,这里只说明最后一步有何不同。
因为initramfs根文件系统启动时执行的第一个程序是init,而不是linuxrc,所以在此,我们制作的根文件系统需要 添加一个init文件 ,相应的linuxrc文件就不再需要了。
按照如下方式修改根文件系统
#cd /work/rootfs
#ln -s bin/busybox init
这样就为busybox创建了一个软链接init,这个文件就是我们要创建的init文件。
另外就是我们制作ramdisk根文件系统镜像的时候使用的是genext2fs工具,在此我们制作initramfs根文件系统镜像时,并不需要额外的步骤,而是在你编译Linux内核的时候就自动生成了。 自动生成的initramfs根文件系统镜像在Linux源码树的usr目录下。名字叫initramfs_data.cpio.gz ,它是gz格式的压缩文件。
这样就有一个问题,在 编译可以使用initramfs启动的内核的时候,它的配置选项有一个相关项,就是要在(/work/rootfs) Initramfs source file(s)中填写你要制作成initramfs格式的根文件系统目录。这样就要求我们在编译内核的时候,首先先把根文件系统做好。值得注意的是我们按照这个方法制作出来的内核镜像实际上比原来的大了许多,这是因为我们在做这一步的时候,实际上是将initramfs根文件系统直接合并到内核镜像里边了。这样,合二为一的镜像就不再需要单独烧写根文件系统镜像了,相应的,启动内核时的参数就不需要添加initrd=……来指定initramfs的位置了。当然如果你不想将initramfs合并到内核中,直接用配置ramdisk的内核来启动系统即可,不过这时你就必须使用initrd=……来指定initramfs的位置了,并且第二个参数initramfs根文件系统映像的大小必须指定为实际大小,否则提示映像校验错误,无法启动系统。
其它的就没有区别了。
-------------------------------------------------------------------
一切工作做好了,uImage和initramfs_data.cpio.gz都已经编译出来了。
用u-boot下载内核镜像和initramfs根文件系统镜像,此时启动系统,最终内核恐慌kernel panic启动失败。
在超级终端的最后一行显示错误如下:
Unpacking initramfs...<0>Kernel panic - not syncing: bad gzip magic numbers
上网查阅了相关的错误,解决方案如下:
“这个问题已经解决;
是因为,我在u-boot传递给内核的initrd=bufptr,size;
size这个参数中,大小比实际的initramfs的大小还大;
导致unpack_to_rootfs在调用gunzip进行initramfs压缩包进行解压时,gunzip无法判断到initramfs压缩包的结束地址;进行重复的解 压导致的;(gunzip这个东东真不智能啊,呵呵)
将size设置和initramfs压缩包的大小一致就OK了;”
如法炮制,系统启动成功 。
这是一篇关于比较initramfs和initrd的文章
http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/Introducing-initramfs-a-new-model-for-initial-RAM-disks/