LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 13563|回复: 28

ram disk 是什么东东?

[复制链接]
发表于 2005-3-22 21:30:41 | 显示全部楼层 |阅读模式
她和 initrd.img 文件的关系是怎样的?
谁能给详细说一下?
 楼主| 发表于 2005-3-22 22:30:38 | 显示全部楼层
或者简单解释一下下面这句话:

grub>kernel (hd0,0)/vmlinuz root=/dev/ram ramdisk_size=512000 devfs=mount,dall
回复 支持 反对

使用道具 举报

发表于 2005-3-22 23:41:32 | 显示全部楼层
Post by rickxbx
她和 initrd.img 文件的关系是怎样的?
谁能给详细说一下?

ramdisk是一种基于内存的虚拟文件系统,通常用于放置内核的中间数据。
而initrd全称为"boot loader initialized RAM disk",也就是由启动加载器所初始化的RamDisk设备,它的作用是完善内核的模块机制,让内核的初始化流程更具弹性;内核以及initrd,都由bootloader在机子启动后被加载至内存的指定位置,主要功能为按需加载模块以及按需改变根文件系统。

更详细的内容,请参阅initrd的man手册,里面阐述了内核开发者对initrd制订的功能标准。
man initrd
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-23 09:08:36 | 显示全部楼层
man initrd 我倒是读过呢,不过还是有些不很明白
她口口声声说 /dev/initrd 设备,而事实上她哪是设备啊.就是一个文件而已,当然,我们可以认为这是一个设备文件,但是这个东西在我的系统里面没有啊,就算有,好,她又说把这个设备上的内容(应该就是文件内容吧?)拷贝到 /dev/ram0, /dev/ram0 这个设备又是哪来的?这个设备,是个ramdisk而已.很明显,在这个时候,真正的文件系统还没有加载,那这个 /dev/ram0 的信息从何处得到?



Post by home_king
ramdisk是一种基于内存的虚拟文件系统,通常用于放置内核的中间数据。
而initrd全称为"boot loader initialized RAM disk",也就是由启动加载器所初始化的RamDisk设备,它的作用是完善内核的模块机制,让内核的初始化流程更具弹性;内核以及initrd,都由bootloader在机子启动后被加载至内存的指定位置,主要功能为按需加载模块以及按需改变根文件系统。

更详细的内容,请参阅initrd的man手册,里面阐述了内核开发者对initrd制订的功能标准。
man initrd
回复 支持 反对

使用道具 举报

发表于 2005-3-23 10:55:57 | 显示全部楼层
Post by rickxbx
man initrd 我倒是读过呢,不过还是有些不很明白
她口口声声说 /dev/initrd 设备,而事实上她哪是设备啊.就是一个文件而已,当然,我们可以认为这是一个设备文件,但是这个东西在我的系统里面没有啊,

这个设备在往常的内核版本中应该是存在过的,注意到,initrd的man手册里提及,可以通过/dev/initrd来访问initrd的数据,但这只是一个调试选项。目前的内核版本没有使用到这个设备,也注意到,initrd的man手册是1997年撰写的。

Post by rickxbx
就算有,好,她又说把这个设备上的内容(应该就是文件内容吧?)拷贝到 /dev/ram0, /dev/ram0 这个设备又是哪来的?这个设备,是个ramdisk而已.很明显,在这个时候,真正的文件系统还没有加载,那这个 /dev/ram0 的信息从何处得到?

文件系统已经被加载,只是没有设置根文件系统,内核的初始化流程还没有进入用户层而已,我们当然不能知道是否有这个设备,但的确是存在的。
所谓文件系统,就是VFS,而根文件系统是其中的一个属性项而已;而每个设备本身是内核数据区里的一个数据结构,经过VFS的映射,才被用户层视为一个文件。所以,内核要创建继而访问一个设备,是可以直接传递"/dev/ram"这样的参数给create_dev函数来实现的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-23 13:13:37 | 显示全部楼层
Post by home_king

文件系统已经被加载,只是没有设置根文件系统,内核的初始化流程还没有进入用户层而已,我们当然不能知道是否有这个设备,但的确是存在的。
所谓文件系统,就是VFS,而根文件系统是其中的一个属性项而已;而每个设备本身是内核数据区里的一个数据结构,经过VFS的映射,才被用户层视为一个文件。所以,内核要创建继而访问一个设备,是可以直接传递"/dev/ram"这样的参数给create_dev函数来实现的。


既然还没有设置根文件系统,那 /dev/ram0 是以什么为根呢?(即到什么地方去找他)

另外,能否讲解一下在 grub 中使用到的 initrd ,是用来做什么的?如何做到?
谢谢
回复 支持 反对

使用道具 举报

发表于 2005-3-23 13:35:09 | 显示全部楼层
Post by rickxbx
既然还没有设置根文件系统,那 /dev/ram0 是以什么为根呢?(即到什么地方去找他)

另外,能否讲解一下在 grub 中使用到的 initrd ,是用来做什么的?如何做到?
谢谢

设置根文件系统,只是C语言里对一个数据结构的成员赋值而已。而所谓目录项,也是内核数据区里的一个数据结构。要创建/dev/ram0,只需赋值根文件系统的值,创建dev目录项,并且创建这个ram设备即可。
要区分内核层以及用户层的区别,可以用一个很简单的逻辑来解释,试想一个,你在用户层删除了/dev里的ram0,那是不是内核就没有了这个设备了呢?再想,如果你删除了你正在使用的硬盘的设备节点/dev/hda,那么是不是内核就不能操作硬盘了呢?答案是很明显的,没有了设备节点,只意味着用户不能操作该设备,并不代表内核不能访问该设备。在最新的设备管理体系中,设备管理的操作逻辑是放在用户层的,那就是udev,默认的规则中没有/dev/eth0设备节点,但你可以照样上网。

GRUB中只是简单地把initrd拷贝在内存中指定的位置而已,没有对它做进一步的操作,只是将initrd的大小放在内核setup.S的头部数据区域,由内核来初始化这段内存区域。

请看内核初始化代码init中的initramfs.c代码片断:

  1. #ifdef CONFIG_BLK_DEV_INITRD
  2.         if (initrd_start) {
  3.                 int fd;
  4.                 printk(KERN_INFO "checking if image is initramfs...");
  5.                 /*这里的initrd_start和initrd_end就是GRUB放置initrd的内存区域的范围*/
  6.                 err = [color=red]unpack_to_rootfs((char *)initrd_start,
  7.                         initrd_end - initrd_start, 1)[/color];
  8.                 if (!err) {
  9.                         printk(" it is\n");
  10.                         unpack_to_rootfs((char *)initrd_start,
  11.                                 initrd_end - initrd_start, 0);
  12.                         free_initrd_mem(initrd_start, initrd_end);
  13.                         return;
  14.                 }
  15.                 printk("it isn't (%s); looks like an initrd\n", err);
  16.                 [color=red]fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 700);[/color]
  17.                 if (fd >= 0) {
  18.                         sys_write(fd, (char *)initrd_start,
  19.                                         initrd_end - initrd_start);
  20.                         sys_close(fd);
  21.                         free_initrd_mem(initrd_start, initrd_end);
  22.                 }
  23.         }
  24. #endif
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-23 13:38:29 | 显示全部楼层
你看是不是这样:grub 中的 initrd 指令告诉 grub 可以从 initrd 指定的文件读取,然后将读到的内容拷贝到 ram disk,然后将该 ram disk 挂载到文件系统的根目录,然后执行/linuxrc(如果存在的话),并将真正的根文件系统挂载到vfs的根

如果是这样的话,现在就有一个问题:这个ram disk 怎么确定?也就是上面说的 /dev/ram0 怎么确定?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-23 13:42:49 | 显示全部楼层
对,就那个 initrd_start 和 initrd_end 如何确定??
回复 支持 反对

使用道具 举报

发表于 2005-3-23 17:39:55 | 显示全部楼层
Post by rickxbx
你看是不是这样:grub 中的 initrd 指令告诉 grub 可以从 initrd 指定的文件读取,然后将读到的内容拷贝到 ram disk,然后将该 ram disk 挂载到文件系统的根目录,然后执行/linuxrc(如果存在的话),并将真正的根文件系统挂载到vfs的根

如果是这样的话,现在就有一个问题:这个ram disk 怎么确定?也就是上面说的 /dev/ram0 怎么确定?

不是的。
GRUB不参与Linux内核的初始化!它是与内核独立的。

记住,GRUB与Linux内核交互的方式遵循一种协议,目前的协议版本为2.02;GRUB通过"setup head"区域与内核交换数据。

假设内核映像为kernel.img,那么这个img文件里就包含着三截代码段(在编译内核的最后阶段生成),第一段是bootsect.S,就是旧的内核内置启动器,它的地位已经被GRUB替代,所以被丢弃不用;第二段是setup.S,由GRUB负责将其放置到物理地址0x90200上,它的头部就是前面提及的所谓head区,GRUB会把需要告诉内核的信息例如initrd的物理起始地址以及大小,放在这个head区;第三段就是真正的压缩内核映像,视乎其体积类型,如果是大内核,就将这段内核映像放至0x100000。

那么,在初始化页表的时候,内核会搬动head区的数据到合适的位置,里面的数据就会被内核初始化所利用,所以内核就得知了initrd的所有信息。明白了吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表