主题 : 使用initramfs启动Linux成功,再次总结一下 复制链接 | 浏览器收藏 | 打印
奔跑的蜗牛……
级别: 侠客
UID: 11357
精华: 4
发帖: 69
金钱: 565 两
威望: 125 点
贡献值: 4 点
综合积分: 218 分
注册时间: 2009-12-04
最后登录: 2013-04-05
楼主  发表于: 2010-04-11 23:28

 使用initramfs启动Linux成功,再次总结一下

前天做了个从ramdisk根文件系统启动Linux的实验,写了个帖子。经总版主kasim大侠的提携,得知现在基于Linux的发行版通常采用initramfs代替initrd,架构更简单,应用也更灵活一些。正好今天晚上没事,就做了一下使用initramfs启动Linux,写个帖子总结一下。
这个帖子不会详述具体的每一个步骤,仅仅说明它和使用ramdisk启动系统时所需要做的步骤的区别。事实上我也是在前天配置编译内核使用ramdisk启动系统的步骤的基础上改的。这里只总结使用initramfs和使用ramdisk各自配置内核选项的主要区别和遇到的一些问题。

参照我的另一个帖子《从ramdisk根文件系统启动Linux成功,总结一下》
http://www.aiothome.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了;”

如法炮制,系统启动成功。

再次感谢总版主kasim大侠的提携
[ 此帖被cs2003happy在2010-05-27 12:34重新编辑 ]
附件设置隐藏,需要回复后才能看到
Continue Study of Embedded Linux Development and Application

奔跑的蜗牛……
奔跑的蜗牛……
级别: 侠客
UID: 11357
精华: 4
发帖: 69
金钱: 565 两
威望: 125 点
贡献值: 4 点
综合积分: 218 分
注册时间: 2009-12-04
最后登录: 2013-04-05
1楼  发表于: 2010-04-12 00:34
引用总版主kasim的评论:

“事实上,现在的基于Linux的发行版通常采用initramfs代替initrd,架构更简单,应用也更灵活一些。
参考内核源代码目录下的Documentation/filesystems/ramfs-rootfs-initramfs.txt

这是一篇关于比较initramfs和initrd的文章
http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/Introducing-initramfs-a-new-model-for-initial-RAM-disks/
Continue Study of Embedded Linux Development and Application

奔跑的蜗牛……
级别: 新手上路
UID: 15978
精华: 0
发帖: 5
金钱: 25 两
威望: 5 点
贡献值: 0 点
综合积分: 10 分
注册时间: 2010-03-12
最后登录: 2010-11-09
2楼  发表于: 2010-04-13 22:29
支持一下
级别: 新手上路
UID: 18218
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
贡献值: 0 点
综合积分: 4 分
注册时间: 2010-04-07
最后登录: 2011-05-10
3楼  发表于: 2010-04-15 17:22

 大家救救我,initramfs  boot 不成功

环境:
   1  内核和initramfs分别加载到内存中。
   2 内核缺省命令行:Kernel command line: mem=64M console=ttyS0,115200 initrd=0x20410000,6155776 root
=/dev/ram0 rw
   3 atmel 9261开发板,64M内存。


启动信息如下:
Linux version 2.6.24 (root@scanli) (gcc version 4.4.1 (So
urcery G++ Lite 2009q3-67) ) #125 Thu Apr 15 16:56:05 CST 2010
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
Machine: Atmel AT91SAM9261-EK
Warning: bad configuration page, trying to continue
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 96 MHz, master 96 MHz, main 18.432 MHz
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: mem=64M console=ttyS0,115200 initrd=0x20410000,6155776 root
=/dev/ram0 rw
.
.
.
TCP reno registered
checking if image is initramfs... it is
Freeing initrd memory: 6011K
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) (SUMMARY)  漏 2001-2006 Red Hat, Inc.
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
UDF-fs: No partition found (1)
List of all partitions:
No filesystem could mount root, tried:  ext2 cramfs vfat iso9660 udf
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
级别: 新手上路
UID: 1698
精华: 0
发帖: 12
金钱: 85 两
威望: 12 点
贡献值: 0 点
综合积分: 24 分
注册时间: 2008-09-21
最后登录: 2010-09-13
4楼  发表于: 2010-04-19 16:59
再支持一下,谢谢分享!!
级别: 侠客
UID: 12401
精华: 0
发帖: 96
金钱: 500 两
威望: 100 点
贡献值: 0 点
综合积分: 192 分
注册时间: 2010-01-06
最后登录: 2017-09-13
5楼  发表于: 2010-04-28 09:15
受益菲浅哪~~~~~~~~
For one target!!!!!!
级别: 侠客
UID: 12758
精华: 0
发帖: 77
金钱: 385 两
威望: 77 点
贡献值: 0 点
综合积分: 154 分
注册时间: 2010-01-12
最后登录: 2019-06-05
6楼  发表于: 2010-05-21 19:22
学习下
奔跑的蜗牛……
级别: 侠客
UID: 11357
精华: 4
发帖: 69
金钱: 565 两
威望: 125 点
贡献值: 4 点
综合积分: 218 分
注册时间: 2009-12-04
最后登录: 2013-04-05
7楼  发表于: 2010-05-27 11:36
今天发现内核如果移植好液晶屏驱动的话,如果u-boot不指定
bootargs=initrd=0x31000000,0xF2C4C root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M
并且内核配置中不设置行CONFIG_CMDLINE=""
的话,默认的控制台由开发板相连的LCD输出,默认的终端设备为tty1。

上边结论是由于今天u-boot启动内核时忘了加
bootargs=initrd=0x31000000,0xF2C4C root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64M
结果发现LCD上显示出一大堆启动信息。

[u-boot@MINI2440]# bootm 0x32000000
## Booting kernel from Legacy Image at 32000000 ...
   Image Name:   Linux-2.6.29.4-FriendlyARM
   Created:      2010-04-11  13:53:44 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2881480 Bytes =  2.7 MB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux.............................................................
................................................................................
............. done, booting the kernel.

超级终端显示到这里就停止了。估计是把控制权交给由LCD显示的控制台tty1了。

我分析的不知道是否正确。请大家指正一下。
Continue Study of Embedded Linux Development and Application

奔跑的蜗牛……
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
8楼  发表于: 2010-05-27 12:13

 回 7楼(cs2003happy) 的帖子

是的,tty1就是LCD的framebuffer console。它在初始化时将自己注册为内核的console之一,就像S3C2440的UART驱动一样。当内核启动时没有指定console时,基本上就会用它来作为console。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
奔跑的蜗牛……
级别: 侠客
UID: 11357
精华: 4
发帖: 69
金钱: 565 两
威望: 125 点
贡献值: 4 点
综合积分: 218 分
注册时间: 2009-12-04
最后登录: 2013-04-05
9楼  发表于: 2010-05-27 12:39
谢谢总版主的悉心指教。
Continue Study of Embedded Linux Development and Application

奔跑的蜗牛……