Linux中的Ramdisk和Initrd

Ramdisk简介
先简单介绍一下ramdisk,Ramdisk是虚拟于RAM中的盘(Disk)。对于用户来说,能把RAM disk和通常的硬盘分区(如/dev/hda1)同等对待来使用,例如:
redice # mkfs.ext2 /dev/ram0
mke2fs 1.38 (30-Jun-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2048 inodes, 8192 blocks
409 blocks (4.99%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
2048 inodes per group
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
redice # mount /dev/ram0 /mnt/rd
redice # ls /mnt/rd
lost+found
redice # mount
/dev/hda2 on / type ext3
proc on /proc type proc (rw)
/dev/ram0 on /tmp/xxx type ext2 (rw)
当然,Ramdisk和硬盘分区有其不同的地方,例如RAM disk不适合作为长期保存文件的介质,掉电后Ramdisk的内容会随内存内容的消失而消失。Ramdisk的其中一个优势是他的读写速度高,能被用作需要高速读写的文件。但在2.6版本后,Ramdisk的这一作用开始被tmpfs(Virtual memory file system support)取代。
回到上面的例子,我们格式化了一个ramdisk(/dev/ram0)并且将其mount到/mnt/rd目录下,那么这个Ramdisk有多大呢?先看一下:
redice # df -h /dev/ram2
Filesystem            容量  已用 可用 已用% 挂载点
/dev/ram0             7.8M  1.0K  7.4M   1% /mnt/rd
从上面的信息看出,ramdisk有大约7.8M的可用空间。我们再试一下另外的文件系统,重新格式化成minix分区并挂接试一下:
redice # umount /mnt/rd
redice # mkfs.minix /dev/ram0
2752 inodes
8192 blocks
Firstdatazone=90 (90)
Zonesize=1024
Maxsize=268966912
redice # mount /dev/ram0 /mnt/rd
redice # df -h /dev/ram0
Filesystem            容量  已用 可用 已用% 挂载点
/dev/ram0             8.0M  1.0K  8.0M   1% /mnt/rd
目前看出来了,的确是8M(这同时说明,EXT2文件系统本身要占用一定的存储空间,相比之下minix文件系统要少些),这个空间是在编译核心时就确定下来了,在设置Ramdisk时,有一个叫 Default RAM disk size 的参数决定默认情况下Ramdisk的大小。能通过核心命令行参数(ramdisk_size)来改动这个值,例如要设置Ramdisk的大小为16M,在grub中能用:
# grub.conf -
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Redice Linux
        root (hd0,0)
        kernel /vmlinuz ro root=LABEL=/ hdc=ide-scsi ramdisk_size=16384
        initrd /initrd
这样,Ramdisk的大小就变成16M了。这个参数是Ramdisk直接编译到核心时才能使用的,如果Ramdisk编译为模块,则应该使用模块参数来设置Ramdisk的大小:
redice # insmod rd rd_size=16384


编译到核心时,能通过下面的一些核心命令行参数来设置Ramdisk:


  • ramdisk_size - ramdisk的大小(Kbytes);

  • ramdisk - 和ramdisk_size的作用相同;

  • ramdisk_blocksize - ramdisk的块大小,默认情况为1024;


当以模块的形式译时,模块支持以下几个加载参数:


  • rd_size - 同上面的ramdisk_size或ramdisk参数;

  • rd_blocksize - 同上面的ramdisk_blocksize;


initrd
上面已提到,Ramdisk需要先格式化然后理能使用。那么,如果核心希望使用ramdisk该怎么做呢?于是initrd产生了,initrd全称是 initial RAM disk ,他提供一种让核心能简单使用Ramdisk的能力,简单的说,这些能力包括:


  • 格式化一个 Ramdisk;

  • 加载文件系统内容到Ramdisk;

  • 将Ramdisk作为根文件系统;
    我们能将initrd形像的比作
    Norton Ghost
    备份的硬盘分区,而Linux启动阶段的Ramdisk相当于一个未格式化的硬盘分区,核心能直接将initrd的内容释放到一个未初始化的Ramdisk里,这个过程和Ghost恢复一个分区的过程十分相似。于是,相应的内容被加载到相应的Ramdisk中,同时,这个Ramdisk也被格式化成某种由initrd格式所表达的分区格式。
    initrd和Ghost备份的分区有许多相似之处,例如,他有一定的大小,包含分区上的文件系统格式等。initrd支持的格式包括:

  • Ext2文件系统;

  • Romfs文件系统;

  • cramfs文件系统;

  • minix文件系统;


如果核心选择了Gzip支持(通常这是默认的,在init/do_mounts_rd.c中定义的BUILD_CRAMDISK宏)还能使用Gzip压缩的initrd。相关的代码能在核心源码 drivers/block/rd.c:identify_ramdisk_image 中找到。
制作initrd
制作initrd传统的作法是通过软盘(显然过时了,不介绍了)、ramdisk或loop设备(/dev/loop)。通过ramdisk来制作的方法比较简单(以ext2文件系统为例):
redice # mkfs.ext2 /dev/ram0
redice # mount /dev/ram0 /mnt/rd
redice # cp _what_you_like_  /mnt/rd    # 把需要的文件复制过去
redice # dd if=/dev/ram0 of=/tmp/initrd
redice # gzip -9 /tmp/initrd
这个过程也最能够解释initrd的本质,对于Linux来说,Ramdisk的一个块设备,而initrd是这个块设备上所有内容的“克隆”(由命令dd来完成)而生成的文件。核心中加载initrd相关的代码则用于完成将相反的过程,即将这一个文件恢复到Ramdisk中去。
通过loop设备来制作initrd的过程:
redice # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件
redice # losetup /dev/loop0 /tmp/initrd                    # 映射到loop设备上;
redice # mkfs.ext2 /dev/loop0                              # 创建文件系统;
redice # mount /dev/loop0 /mnt/rd
redice # cp _what_you_like_ /mnt/rd                        # 复制需要的文件;
redice # umount /mnt/rd
redice # losetup -d /dev/loop0
redice # gzip -9 /tmp/initrd
不过,目前已有了一些更好的工具来完成这些工作,包括genromfs(uClinux里常用的工具),genext2fs,mkcramfs等。这些工具提供了一些方便研发的新特性,例如,不必上面烦索的过程,只要将文件复制到某个目录中,将其作为根目录,即可生成initrd;另一个重要的改进是,这些工具都能以普通用户的身份来生成initrd。
未完,待续…(补充有关怎么加载|ARM中怎么使用initrd作为根文件系统等)
链接和参考文件
文件

 

原文:http://czdj2000.yo2.cn/articles/linux%E4%B8%AD%E7%9A%84ramdisk%E4%B8%8Einitrd.html

转载于:https://www.cnblogs.com/hicjiajia/archive/2012/07/10/2582634.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

slab下kmalloc内核函数实现

文章目录kmalloc的整体实现获取高速缓存高速缓存获取index总结https://blog.csdn.net/qq_41683305/article/details/124554490,在这篇文章中,我们介绍了伙伴算法、slab机制和常见的内存管理函数,接下来,我们看看kmalloc内核函数的…

PHP array_merge_recursive()函数与示例

PHP array_merge_recursive()函数 (PHP array_merge_recursive() function) array_merge_recursive() function is used to merge two or more arrays, it returns a new array with merged elements. The only difference between array_merge() and array_merge_recursive() …

标题:三羊献瑞

标题:观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。 请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。 思路分析: 首先…

hdu 1069

地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1069 题意&#xff1a;给定若干个木块长宽高&#xff0c;长宽高可以自己调整&#xff0c;求堆积起来最高的高度。 mark&#xff1a;枚举所有木块长宽高可能情况&#xff0c;简单dp。 代码&#xff1a; #include <…

简明 Python 编程规范

简明 Python 编程规范编码 所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- 。设置编辑器&#xff0c;默认保存为 utf-8 格式。注释 业界普遍认同 Python 的注释分为两种的概念&#xff0c;一种是由 # 开头的“真正的”注释&#xff0c;另一种是 docstri…

进程虚拟地址管理

文章目录1 地址分布实际使用中的内存区域2 进程的虚拟地址描述用户空间mmap线程之间共享内存地址的实现机制1 地址分布 现在采用虚拟内存的操作系统通常都使用平坦地址空间&#xff0c;平坦地址空间是指地址空间范围是一个独立的连续空间&#xff08;比如&#xff0c;地址从0扩…

java两个文件夹比较路径_比较Java中两个文件的路径

java两个文件夹比较路径Given the paths of the two files and we have two compare the paths of the files in Java. 给定两个文件的路径&#xff0c;我们有两个比较Java中文件的路径。 Comparing paths of two files 比较两个文件的路径 To compare the paths of two file…

标题:加法变乘法

标题&#xff1a;我们都知道&#xff1a;123 … 49 1225 现在要求你把其中两个不相邻的加号变成乘号&#xff0c;使得结果为2015 比如&#xff1a; 123…10*1112…27*2829…49 2015 就是符合要求的答案。 请你寻找另外一个可能的答案&#xff0c;并把位置靠前的那个乘号左…

C# winform对话框用法大全收藏

对话框中我们常用了以下几种&#xff1a; 1、文件对话框(FileDialog) 它又常用到两个&#xff1a; 打开文件对话框(OpenFileDialog) 保存文件对话(SaveFileDialog) 2、字体对话框(FontDialog) 3、颜色对话框(&#xff23;olorDialog) 4、打印预浏对话框(PrintPreviewDialog) 5、…

【翻译】eXpressAppFramework QuickStart 业务模型设计(四)—— 实现自定义业务类...

这一讲&#xff0c;你将学到如何从头开始实现业务类。为此&#xff0c;将要实现Department和Position业务类。这些类将被应用到之前实现的Contact类中。你将学到引用对象自动生成用户界面的基本要素。 在此之前&#xff0c;我建议你去阅读一下 【翻译】eXpressAppFramework Qui…

内存重映射

文章目录1 kmap2 映射内核内存到用户空间使用remap_pfn_range使用io_remap_pfn_rangemmap文件操作建立VMA和实际物理地址的映射mmap 之前分配 一次性映射mmap 之前分配 Page FaultPage Fault 中分配 映射内核内存有时需要重新映射&#xff0c;无论是从内核到用户空间还是从内…

math.sqrt 有问题_JavaScript中带有示例的Math.sqrt()方法

math.sqrt 有问题JavaScript | Math.sqrt()方法 (JavaScript | Math.sqrt() Method) The Math.sqrt() method is inbuilt in JavaScript to find the square root of a number. In this tutorial, we will learn about the sqrt() method with examples. JavaScript中内置了Mat…

标题:移动距离

标题&#xff1a;移动距离 X星球居民小区的楼房全是一样的&#xff0c;并且按矩阵样式排列。其楼房的编号为1,2,3… 当排满一行时&#xff0c;从下一行相邻的楼往反方向排号。 比如&#xff1a;当小区排号宽度为6时&#xff0c;开始情形如下&#xff1a; 1 2 3 4 5 6 12 11 1…

ISAPI Rewrite 实现简单url重写、二级域名重写

实现步骤&#xff1a; 第一步&#xff1a;下载ISAPI_Rewrite.rar&#xff0c;将Rewrite文件夹和httpd.ini直接放在项目根目录下面。 第二步&#xff1a;IIS配置&#xff0c;筛选Rewrite文件夹里面的Rewrite.dll文件&#xff0c;如图&#xff1a; 第三步&#xff1a;在httpd.ini…

用户登录

用户登录 代码namespace 用户登录 {public partial class Form1 : Form{public Form1(){InitializeComponent();}bool b1, b2, b3, b4, b5, b6;private void button1_Click(object sender, EventArgs e){try{if (b1 && b2 && b3 && b4 && b5 &…

进程上下文和中断上下文

文章目录进程的preempt_count变量thread_infopreempt_counthardirq相关softirq相关上下文原文链接&#xff1a; https://zhuanlan.zhihu.com/p/88883239进程的preempt_count变量 thread_info 在内核中&#xff0c;上下文的设置和判断接口可以参考 include/linux/preempt.h 文…

标题:凑算式

标题&#xff1a;凑算式 这个算式中AI代表19的数字&#xff0c;不同的字母代表不同的数字。 比如&#xff1a; 68/3952/714 就是一种解法&#xff0c; 53/1972/486 是另一种解法。 这个算式一共有多少种解法&#xff1f; 注意&#xff1a;你提交应该是个整数&#xff0c;不要…

汇编中imul_JavaScript中带有示例的Math.imul()方法

汇编中imulJavaScript | Math.imul()方法 (JavaScript | Math.imul() Method) Math.imul() is a function in math library of JavaScript that is used to the 32-bit multiplication of the two values passed to it. It uses C-like semantics to find the multiplication. …

AFTER触发器与INSTEAD OF触发器的区别

INSTEAD OF 触发器用来代替通常的触发动作&#xff0c;即当对表进行INSERT、UPDATE 或 DELETE 操作时&#xff0c;系统不是直接对表执行这些操作&#xff0c;而是把操作内容交给触发器&#xff0c;让触发器检查所进行的操作是否正确。如正确才进行相应的操作。因此&#xff0c;…

Linux内存地址管理

文章目录系统内存布局内核地址的低端和高端内存概念低端内存高端内存地址转换和MMULinux中的四级分页模型虚拟地址字段页表处理将虚拟地址转换物理地址Linux系统中的每个内存地址都是虚拟的&#xff0c;它们不直接指向任何物理内存地址。每当访问内存位置时&#xff0c;可以执行…