加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 安全 > 正文

深度解析Linux根文件系统的挂载过程

发布时间:2020-12-31 03:08:09 所属栏目:安全 来源:网络整理
导读:副标题#e# 《深度解析Linux根文件系统的挂载过程》要点: 本文介绍了深度解析Linux根文件系统的挂载过程,希望对您有用。如果有疑问,可以联系我们。 在前面的文章中介绍《Linux操作系统启动过程》,而Linux系统的根文件系统(root file system)的挂载过程则

[code lang=”c”]static int __init populate_rootfs(void)
{
char *err = unpack_to_rootfs(__initramfs_start,
__initramfs_end – __initramfs_start,0);
if (err)
panic(err);
if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
int fd;
printk(KERN_INFO "checking if image is initramfs…");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end – initrd_start,1);
if (!err) {
printk(" it isn");
unpack_to_rootfs((char *)initrd_start,
initrd_end – initrd_start,0);
free_initrd();
return 0;
}
printk("it isn’t (%s); looks like an initrdn",err);
fd = sys_open("/initrd.image",O_WRONLY|O_CREAT,0700);
if (fd >= 0) {
sys_write(fd,(char *)initrd_start,
initrd_end – initrd_start);
sys_close(fd);
free_initrd();
}
#else
printk(KERN_INFO "Unpacking initramfs…");
err = unpack_to_rootfs((char *)initrd_start,0);
if (err)
panic(err);
printk(" donen");
free_initrd();
#endif
}
return 0;
}[/code]

unpack_to_rootfs:顾名思义就是解压包,并将其释放至rootfs.它实际上有两个功能,一个是释放包,一个是查看包,看其是否属于cpio结构的包.功能选择是根据最后的一个参数来区分的.
在这个函数里,对应我们之前分析的三种虚拟根文件系统的情况.一种是跟kernel融为一体的initramfs.在编译kernel的时候,通过链接脚本将其存放在__initramfs_start至__initramfs_end的区域.这种情况下,直接调用unpack_to_rootfs将其释放到根目录.如果不是属于这种形式的.也就是__initramfs_start和__initramfs_end的值相等,长度为零.不会做任何处理.退出.

对应后两种情况.从代码中看到,必须要配制CONFIG_BLK_DEV_RAM才会支持image-initrd.否则全当成cpio-initrd的形式处理.
对于是cpio-initrd的情况.直接将其释放到根目录.对于是image-initrd的情况.将其释放到/initrd.image.最后将initrd内存区域归入伙伴系统.这段内存就可以由操作系统来做其它的用途了.
接下来,内核对这几种情况又是怎么处理的呢?不要着急.往下看:

回到kernel_init()这个函数:

[code lang=”c”]static int __init kernel_init(void * unused)
{
…….
…….
do_basic_setup();

/*
* check if there is an early userspace init. If yes,let it do all
* the work
*/

if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";

if (sys_access((const char __user *) ramdisk_execute_command,and
* we’re essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
init_post();
return 0;
}[/code]

ramdisk_execute_command:在kernel解析引导参数的时候使用.如果用户指定了init文件路径,即使用了“init=”,就会将这个参数值存放到这里.
如果没有指定init文件路径.默认为/init
对应于前面一段的分析,我们知道,对于initramdisk和cpio-initrd的情况,都会将虚拟根文件系统释放到根目录.如果这些虚拟文件系统里有/init这个文件.就会转入到init_post().
Init_post()代码如下:

[code lang=”c”]static int noinline init_post(void)
{
free_initmem();
unlock_kernel();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();

if (sys_open((const char __user *) "/dev/console",O_RDWR,0)
(void) sys_dup(0);
(void) sys_dup(0);

if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %sn",
ramdisk_execute_command);
}

/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults…n",execute_command);
}
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found. Try passing init= option to kernel.");
}[/code]

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读