当前位置:Linux教程 - Linux资讯 - 分析内核初始化时根内存盘的加载过程(init/main.c)

分析内核初始化时根内存盘的加载过程(init/main.c)

  作者:opera     概述   ====   1)当内核配置了内存盘时, 内核在初始化时可以将软盘加载到内存盘中作为根盘. 当同时配置了初始化内   存盘(Initail RAM Disk)时, 内核在初始化时可以在安装主盘之前, 通过引导程序所加载的initrd文件建   立一个内存初始化盘, 首先将它安装成根文件系统, 然后执行其根目录下的Linuxrc 文件, 可用于在安装   主盘之前加载一些内核模块. 等到linuxrc 程序退出后, 再将主盘安装成根文件系统, 并将内存初始化盘转移安装到其/initrd目录下.   2)当主盘就是initrd所生成的内存初始化盘时, 不再进行重新安装, 在DOS下用loadlin加载的抢救盘就是   这种工作方式.   3)引导程序所加载的initrd为文件系统的映象文件, 可以是gzip压缩的, 也可以是不压缩的. 能够识别的文件系统有minix,ext2,romfs三种.   4)当内核的根盘为软盘时, 内核初始化时会测试软盘的指定部位是否存在文件系统或压缩文件映象, 然后   将之加载或解压到内存盘中作为根盘. 这是单张抢救软盘的工作方式.   有关代码   ========   代码:   ; init/main.c   #ifdef CONFIG_BLK_DEV_INITRD   kdev_t real_root_dev; 启动参数所设定的根盘设备   #endif   asmlinkage void __init start_kernel(void)   {    char * command_line;    unsigned long mempages;    extern char saved_command_line[];    lock_kernel();    printk(linux_banner);    setup_arch(&command_line); arch/i386/kernel/setup.c中,初始化initrd_start和initrd_end两个变量    ...   #ifdef CONFIG_BLK_DEV_INITRD    if (initrd_start && !initrd_below_start_ok &&    initrd_start < min_low_pfn 0)    while (pid != wait(&i)); 等待linuxrc进程退出    if (MAJOR(real_root_dev) != RAMDISK_MAJOR    MINOR(real_root_dev) != 0) {    ; 如果原来的根盘不是0号内存盘,则使用原来的根文件系统,    ; 并且将内存盘转移到其/initrd目录下    error = change_root(real_root_dev,"/initrd");    if (error)    printk(KERN_ERR "Change root to /initrd: "    "error %d\n",error);    }    }   #endif   }   #ifdef CONFIG_BLK_DEV_INITRD   static int do_linuxrc(void * shell)   {    static char *argv[] = { "linuxrc", NULL, };      close(0);close(1);close(2);    setsid(); 设置新的session号    (void) open("/dev/console",O_RDWR,0);    (void) dup(0);    (void) dup(0);    return execve(shell, argv, envp_init);   }   #endif   ; arch/i386/kernel/setup.c   #define RAMDISK_IMAGE_START_MASK 0x07FF   #define RAMDISK_PROMPT_FLAG 0x8000   #define RAMDISK_LOAD_FLAG 0x4000   #define PARAM ((unsigned char *)empty_zero_page)   #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) 可用rdev设置的参数   #define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))   #define INITRD_START (*(unsigned long *) (PARAM+0x218)) 初始化盘映象起始物理地址   #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) 初始化盘字节数     void __init setup_arch(char **cmdline_p)   {    ...   #ifdef CONFIG_BLK_DEV_RAM    rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; 以块为单位    rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);    rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);   #endif    ...   #ifdef CONFIG_BLK_DEV_INITRD    if (LOADER_TYPE && INITRD_START) {    if (INITRD_START + INITRD_SIZE

(出处:http://www.sheup.com)


上一页 [1] [2]