ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:27.60KB ,
资源ID:21645883      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/21645883.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Linux26内核的Initrd机制解析Word文件下载.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Linux26内核的Initrd机制解析Word文件下载.docx

1、3. 制作 Linux usb 启动盘必须使用 initrdusb 设备是启动比较慢的设备,从驱动加载到设备真正可用大概需要几秒钟时间。如果将 usb 驱动编译进内核,内核通常不能成功访问 usb 设备中的文件系统。因为在内核访问 usb 设备时, usb 设备通常没有初始化完毕。所以常规的做法是,在 initrd 中加载 usb 驱动,然后休眠几秒中,等待 usb设备初始化完毕后再挂载 usb 设备中的文件系统。4. 在 linuxrc 脚本中可以很方便地启用个性化 bootsplash。Linux2.4内核对 Initrd 的处理流程为 了使读者清晰的了解Linux2.6内核initrd机

2、制的变化,在重点介绍Linux2.6内核initrd之前,先对linux2.4内核的 initrd进行一个简单的介绍。Linux2.4内核的initrd的格式是文件系统镜像文件,本文将其称为image-initrd,以区别后面介绍 的linux2.6内核的cpio格式的initrd。 linux2.4内核对initrd的处理流程如下:1. boot loader把内核以及/dev/initrd的内容加载到内存,/dev/initrd是由boot loader初始化的设备,存储着initrd。2. 在内核初始化过程中,内核把 /dev/initrd 设备的内容解压缩并拷贝到 /dev/ram0

3、设备上。3. 内核以可读写的方式把 /dev/ram0 设备挂载为原始的根文件系统。4. 如果 /dev/ram0 被指定为真正的根文件系统,那么内核跳至最后一步正常启动。5. 执行 initrd 上的 /linuxrc 文件,linuxrc 通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动, 以及加载根文件系统。6. /linuxrc 执行完毕,真正的根文件系统被挂载。7. 如果真正的根文件系统存在 /initrd 目录,那么 /dev/ram0 将从 / 移动到 /initrd。否则如果 /initrd 目录不存在, /dev/ram0 将被卸载。8. 在真正的根文件系统上进行正常

4、启动过程 ,执行 /sbin/init。 linux2.4 内核的 initrd 的执行是作为内核启动的一个中间阶段,也就是说 initrd 的 /linuxrc 执行以后,内核会继续执行初始化代码,我们后面会看到这是 linux2.4 内核同 2.6 内核的 initrd 处理流程的一个显著区别。3Linux2.6 内核对 Initrd 的处理流程linux2.6 内核支持两种格式的 initrd,一种是前面第 3 部分介绍的 linux2.4 内核那种传统格式的文件系统镜像image-initrd,它的制作方法同 Linux2.4 内核的 initrd 一样,其核心文件就是 /linuxr

5、c。另外一种格式的 initrd 是 cpio 格式的,这种格式的 initrd 从 linux2.5 起开始引入,使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init,本文将这种 initrd 称为 cpio-initrd。尽管 linux2.6 内核对 cpio-initrd和 image-initrd 这两种格式的 initrd 均支持,但对其处理流程有着显著的区别,下面分别介绍 linux2.6 内核对这两种 initrd 的处理流程。cpio-initrd 的处理流程1 boot loader 把内核以及 initrd 文件加载到内存的特定位置。2 内核判断

6、initrd的文件格式,如果是cpio格式。3 将initrd的内容释放到rootfs中。4 执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。image-initrd的处理流程1 boot loader把内核以及initrd文件加载到内存的特定位置。2 内核判断initrd的文件格式,如果不是cpio格式,将其作为image-initrd处理。3 内核将initrd的内容保存在rootfs下的/initrd.image文件中。4 内核将/initrd.image的内容读入/dev/ram0设备中,也就是读入了一个内存盘中。5 接着内核以可读写的

7、方式把/dev/ram0设备挂载为原始的根文件系统。6 .如果/dev/ram0被指定为真正的根文件系统,那么内核跳至最后一步正常启动。7 执行initrd上的/linuxrc文件,linuxrc通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动, 以及加载根文件系统。8 /linuxrc执行完毕,常规根文件系统被挂载9 如果常规根文件系统存在/initrd目录,那么/dev/ram0将从/移动到/initrd。否则如果/initrd目录不存在, /dev/ram0将被卸载。10 在常规根文件系统上进行正常启动过程 ,执行/sbin/init。通 过上面的流程介绍可知,Linux2.6内

8、核对image-initrd的处理流程同linux2.4内核相比并没有显著的变化, cpio-initrd的处理流程相比于image-initrd的处理流程却有很大的区别,流程非常简单,在后面的源代码分析中,读者更能体会到处理的 简捷。4cpio-initrd同image-initrd的区别与优势没有找到正式的关于cpio-initrd同image-initrd对比的文献,根据笔者的使用体验以及内核代码的分析,总结出如下三方面的区别,这些区别也正是cpio-initrd的优势所在:cpio-initrd的制作方法更加简单cpio-initrd的制作非常简单,通过两个命令就可以完成整个制作过程#

9、假设当前目录位于准备好的initrd文件系统的根目录下bash# find . | cpio -c -o ./initrd.imgbash# gzip ./initrd.img而传统initrd的制作过程比较繁琐,需要如下六个步骤bash# dd if=/dev/zero of=./initrd.img bs=512k count=5bash# mkfs.ext2 -F -m0 ./initrd.imgbash# mount -t ext2 -o loop ./initrd.img /mntbash# cp -r * /mntbash# umount /mntbash# gzip -9 ./i

10、nitrd.img本文不对上面命令的含义作细节的解释,因为本文主要介绍的是linux内核对initrd的处理,对上面命令不理解的读者可以参考相关文档。cpio-initrd的内核处理流程更加简化通过上面initrd处理流程的介绍,cpio-initrd的处理流程显得格外简单,通过对比可知cpio-initrd的处理流程在如下两个方面得到了简化:1 cpio-initrd并没有使用额外的ramdisk,而是将其内容输入到rootfs中,其实rootfs本身也是一个基于内存的文件系统。这样就省掉了ramdisk的挂载、卸载等步骤。2 cpio-initrd启动完/init进程,内核的任务就结束了,

11、剩下的工作完全交给/init处理;而对于image-initrd,内核在执行完 /linuxrc进程后,还要进行一些收尾工作,并且要负责执行真正的根文件系统的/sbin/init。通过图1可以更加清晰的看出处理流程的区别:图1内核对cpio-initrd和image-initrd处理流程示意图cpio-initrd的职责更加重要如 图1所示,cpio-initrd不再象image-initrd那样作为linux内核启动的一个中间步骤,而是作为内核启动的终点,内核将控制权交给 cpio-initrd的/init文件后,内核的任务就结束了,所以在/init文件中,我们可以做更多的工作,而不比担心同

12、内核后续处理的衔接问题。 当然目前linux发行版的cpio-initrd的/init文件的内容还没有本质的改变,但是相信initrd职责的增加一定是一个趋势。5linux2.6内核initrd处理的源代码分析上 面简要介绍了Linux2.4内核和2.6内核的initrd的处理流程,为了使读者对于Linux2.6内核的initrd的处理有一个更加深入的认 识,下面将对Linuxe2.6内核初始化部分同initrd密切相关的代码给予一个比较细致的分析,为了讲述方便,进一步明确几个代码分析中使用的概 念:rootfs: 一个基于内存的文件系统,是linux在初始化时加载的第一个文件系统,关于它的进

13、一步介绍可以参考文献4。initramfs: initramfs同本文的主题关系不是很大,但是代码中涉及到了initramfs,为了更好的理解代码,这里对其进行简单的介绍。Initramfs 是在 kernel 2.5中引入的技术,实际上它的含义就是:在内核镜像中附加一个cpio包,这个cpio包中包含了一个小型的文件系统,当内核启动时,内核将这个 cpio包解开,并且将其中包含的文件系统释放到rootfs中,内核中的一部分初始化代码会放到这个文件系统中,作为用户层进程来执行。这样带来的明显 的好处是精简了内核的初始化代码,而且使得内核的初始化过程更容易定制。Linux 2.6.12内核的 i

14、nitramfs还没有什么实质性的东西,一个包含完整功能的initramfs的实现可能还需要一个缓慢的过程。对于initramfs的进一步了解 可以参考文献123。cpio-initrd: 前面已经定义过,指linux2.6内核使用的cpio格式的initrd。image-initrd: 前面已经定义过,专指传统的文件镜像格式的initrd。realfs: 用户最终使用的真正的文件系统。内 核的初始化代码位于 init/main.c 中的 static int init(void * unused)函数中。同initrd的处理相关部分函数调用层次如下图,笔者按照这个层次对每一个函数都给予了比较

15、详细的分析,为了更好的说明,下面列 出的代码中删除了同本文主题不相关的部分:图2 initrd相关代码的调用层次关系图init函数是内核所有初始化代码的入口,代码如下,其中只保留了同initrd相关部分的代码。static int init(void * unused)1 populate_rootfs(); 2 if (sys_access(const char _user *) /init, 0) = 0) execute_command = ; else prepare_namespace();3 if (sys_open(const char _user *) /dev/console

16、, O_RDWR, 0) = 0) sys_write(fd, (char *)initrd_start, initrd_end - initrd_start); sys_close(fd);加载initramfs, initramfs位于地址_initramfs_start处,是内核在编译过程中生成的,initramfs的是作为内核的一部分而存在的,不是 boot loader加载的。前面提到了现在initramfs没有任何实质内容。判断是否加载了initrd。无论哪种格式的initrd,都会被boot loader加载到地址initrd_start处。判断加载的是不是cpio-initrd

17、。实际上 unpack_to_rootfs有两个功能一个是释放cpio包,另一个就是判断是不是cpio包, 这是通过最后一个参数来区分的, 0:释放 1:查看。代码4:如果是cpio-initrd则将其内容释放出来到rootfs中。代码5:如果不是cpio-initrd,则认为是一个image-initrd,将其内容保存到/initrd.image中。在后面的image-initrd的处理代码中会读取/initrd.image。对image-initrd的处理 在prepare_namespace函数里,包含了对image-initrd进行处理的代码,相关代码如下:void _init pre

18、pare_namespace(void)1 if (initrd_load() goto out;out: umount_devfs(/dev2 sys_mount(., /, NULL, MS_MOVE, NULL); sys_chroot( security_sb_post_mountroot(); mount_devfs_fs ();执行initrd_load函数,将initrd载入,如果载入成功的话initrd_load函数会将realfs的根设置为当前目录。将当前目录即realfs的根mount为Linux VFS的根。initrd_load函数执行完后,将真正的文件系统的根设置为当

19、前目录。initrd_load函数负责载入image-initrd,代码如下:int _init initrd_load(void)1 if (mount_initrd) create_dev(/dev/ram, Root_RAM0, NULL);2 if (rd_load_image() & ROOT_DEV != Root_RAM0) sys_unlink( handle_initrd(); return 1; sys_unlink( return 0;如果加载initrd则建立一个ram0设备 /dev/ram。代 码2:/initrd.image文件保存的就是image-initrd,

20、rd_load_image函数执行具体的加载操作,将image- nitrd的文件内容释放到ram0里。判断ROOT_DEV!=Root_RAM0的含义是,如果你在grub或者lilo里配置了 root=/dev/ram0 ,则实际上真正的根设备就是initrd了,所以就不把它作为initrd处理 ,而是作为realfs处理。handle_initrd()函数负责对initrd进行具体的处理,代码如下: static void _init handle_initrd(void)1 real_root_dev = new_encode_dev(ROOT_DEV);2 create_dev(/de

21、v/root.old mount_block_root(, root_mountflags & MS_RDONLY);3 sys_mkdir(/old, 0700); root_fd = sys_open(, 0, 0); old_fd = sys_open( /* move initrd over / and chdir/chroot in initrd root */4 sys_chdir(/root sys_mount( sys_chroot( mount_devfs_fs ();5 pid = kernel_thread(do_linuxrc, /linuxrc, SIGCHLD); if (pid 0) while (pid != sys_wait4(-1, &i, 0, NULL) yield(); /* move initrd to rootfs /old */ sys_fchdir(old_fd); /* switch root and cwd back to / of rootfs */6 sys_fchdir(root_fd); sys_close(old_fd); sys_close(root_fd

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1