`
音频数据
  • 浏览: 36788 次
文章分类
社区版块
存档分类
最新评论

Linux的INITRAMFS 与 INITRD

 
阅读更多
1. INITRAMFS 和 INITRD(INITRAMDISK) 是什么?

RAMFS 和 RAMDISK 都是内存文件系统,他们有着小巧快速的特点。INIT前缀表示其包含有效“init”可执行文件,可以作为启动的root文件系统。INITRAMDISK出现较早,在使用nor flash和2.4kernel盛行的时期很流行。RAMFS出现也很早,但INITRAMFS是2.6版本kernel添加的新功能,INITRAMFS更象是INITRAMDISK的一个简化版本。如今嵌入式设备大量使用nand flash,像INITRAMFS和INITRAMDISK已经不适合用来管理nand这种大容量并且需要校验机制的存储设备。
但,在某些场合,比如:
l 你需要做一个很简单快速的镜像文件
l 和Kernel编译出一个镜像文件
l 与板载nand文件系统完全无关的镜像文件
在这些情况下,INITRAMFS和INITRAMDISK都是不错的选择。

INITRAMFS 和 INITRAMDISK 有着相似的制作流程:
l 通过某种压缩算法,把目标root目录压缩成一个文件
l 再把压缩文件存储在某个位置,或者直接链接到kernel镜像中

INITRAMFS和INITRAMDISK在Kernel的启动过程中也有着相似的加载流程:
l 通过Command Line找到压缩的文件(initramfs与Command Line无关)
l 把压缩文件解压到内存中,并以指定的文件系统类型加载(mount)
l 如果加载的rootfs文件系统中有init文件,Linux启动进程就能直接跳转到init进程,然后便有了开机启动init脚本的执行,以及最终的shell console。
l 写入内存文件系统的更改,在重启系统后都不复存在,这是内存文件系统的特点。

INITRAMFS和INITRAMDISK之间也有区别。
ramdisk文件是一个块设备文件,文件系统一般为ext2。ramdisk加载后,从文件系统中读取数据,数据流依次通过了Kernel的“块设备管理读写“->”ext2文件系统“->"VFS"->最后传到用户空间。

而ramfs没有ext2文件系统,没有块设备处理,数据的终点就是“VFS Cache”(内存),同样一个读取流程,数据依次通过"VFS Cache(ramfs)”->VFS->用户。

由此可以看出initramfs比initrd更简单快速,而Kernel对initramfs的内部处理也更为简单上面提到的"VFS Cache"在Kernel中,通常以一个加载的rootfs文件系统来管理,此文件系统的类型为RAMFS(实际名称为ROOTFS)。INITRAMFS的处理过程把initramfs文件直接解压到此文件系统中,然后再将此rootfs文件系统直接呈给用户空间(执行用户init进程)。INITRAMDISK的解压加载过程同样要用到这个rootfs,它会把initramdisk文件解压到此文件系统中的'/dev/ram'块设备里,然后再加载'/dev/ram'块设备。

2. Linux 2.6.28对INITRAMFS的处理

以Samsung 6410测试平台(Kernel 2.6.28)为例,来体验initramfs制作、编译、kernel解析、加载、用户init调度的整个过程。

2.1 Initramfs文件的制作、编译过程

首先查看kernel/.config,这里没有看到对INITRAMFS功能的开关。这跟Kernel文档描述一致,因为Kernel处理INITRAMFS的负荷极小,所以Kernel始终包含处理INITRAMFS的功能。通过此文章后续的说明,你可以看到实际上Kernel一直包含一个RAMFS的rootfs,当此rootfs无效(为空或者没有有效的init文件),此rootfs就会被后续command-line所指定的文件系统所覆盖。
在Kernel menuconfig中,唯一需要指定的是‘CONFIG_INITRAMFS_SOURCE’,这里需要指定用于制作initramfs文件的目标root目录的绝对路径。
然后编译(cd Kernel; make V=1),以下是相关的编译日志:
'kernel/scripts/gen_initramfs_list.sh -o usr/initramfs_data.cpio.gz  -u 0  -g 0  /XXX/root
'arm-none-linux-gnueabi-gcc -c -o usr/initramfs_data.o usr/initramfs_data.S'   # initramfs_data.S: Include '.gz' as a global section 'init.ramfs'
'arm-none-linux-gnueabi-ld -EL    -r -o usr/built-in.o usr/initramfs_data.o'
'arm-none-linux-gnueabi-ld -EL  -r -o vmlinux.o -T arch/arm/kernel/vmlinux.lds ... usr/built-in.o ... '
以下是脚本“vmlinux.lds”中的相关内容:
.init : { /* Init code and data            */
*(.init.text) *(.cpuinit.text) *(.meminit.text)
...
  __initramfs_start = .;
usr/built-in.o(.init.ramfs)
__initramfs_end = .;
...
}
编译过程可以归纳成三步:
第一步,gen_initramfs_list.sh脚本以cpio格式对目标root目录压缩生成XXX.cpio.gz文件,这里为什么使用cpio而不是tar, 因为简单,这一点内核文档有说明。
第二步,initramfs_data.S只做一件事情,创建一个Section,包含XXX.cpio.gz文件。
第三步,编译并链接,‘arch/arm/kernel/vmlinux.lds’中,在init section中声明了两个全局变量“__initramfs_start”和"__initramfs_end"用于指向init.ramfs域的开始和结束。实际上,__initramfs_start就是内核空间全局的指针变量,指定XXX.cpio.gz开始地址,__initramfs_end指定结束地址。当然这两个全局变量只在init进程中有效。
编译过程完成,最终形成一个镜像文件zImage,在这个文件中,__initramfs_start和initramfs_end两个变量分别指向XXX.cpio.gz数据的起始和结束地址(结束地址+1)。

2.2 Kernel加载initramfs的过程

initramfs文件生效的过程大致分为四步:
第一步:Kernel首先要注册一个RAMFS文件系统类型(实际注册的类型名称是"ROOTFS",后续我们可以看到它实际上就是"RAMFS");
第二步:然后加载(mount)一个空的rootfs文件系统,类型就是上面提到的RAMFS(ROOTFS);
第三步:寻址initramfs文件“XXX.cpio.gz”并解压到已mount的rootfs文件系统中;
第四步:寻址用户空间的init,并执行init进程;

第一步和第二步的调用堆栈如下:  
init/main.c: start_kernel() -> fs/dcache.c: vfs_caches_init() ->
fs/namespace.c: mnt_init() {
    ...
    // The last 2 lines
    init_rootfs();
    init_mount_tree();
}
在“fs/ramfs/inode.c: init_rootfs()”函数中,注册了"ROOTFS"文件系统类型。通过阅读inode.c源码,发现"ROOTFS"就是"RAMFS",几乎没有区别。
在“fs/namespace.c: init_mount_tree()”函数中,加载了一个类型为ROOTFS的空root:
    mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
    // 第一个rootfs引用文件系统类型ROOTFS,即RAMFS。第二个rootfs为mount entry。
第三步(寻址initramfs文件XXX.cpio.gz,并解压)的调用堆栈如下:
kernel/init/main.c: start_kernel() {
    ...
    vfs_caches_init();
    ...
    // The last line
    rest_init();
}
kernel/init/main.c: rest_init() {
    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
    ...
}
kernel/init/main.c: kernel_init() {
    ...
    do_basic_setup();
    ...
}
kernel/init/main.c: rest_init() {
    ...
    do_initcalls();
}
// OK
kernel/init/initramfs.c:populate_rootfs() {
    // Decompress the .gz into 'rootfs'
}
rootfs_initcall(populate_rootfs);
检查populate_rootfs做了什么,它通过__initramfs_start指针和__initramfs_end指针访问XXX.cpio.gz文件,调用函数unpack_to_rootfs函数把源文件解压到rootfs中。gunzip执行解压过程,do_name()/do_copy/do_symlink/do_XXX为解压过程回调函数,在这些do_XXX回调函数中,看到大量使用sys_open/sys_write/sys_XXX函数创建、读写、更改文件和目录及其权限。sys_open/sys_write/sys_read实际上是用户空间open/write/read函数系统调用的实现。
至此,一个完整的rootfs已在目标系统的内存中。
第四步(寻址并运行用户空间INIT进程)的调用堆栈:
init/main.c: kernel_init() {
    // At the bottom lines
    if (!ramdisk_execute_command)
       ramdisk_execute_command = "/init";
}
kernel/init/main.c: init_post() {
    if (ramdisk_execute_command) {
       run_init_process(ramdisk_execute_command);
    }
}
kernel/init/main.c: run_init_process() {
    kernel_execve(init_filename, argv_init, envp_init);
}
也就是说,只要initramfs文件“XXX.cpio.gz”的根目录下有一个有效的init,或者一个对init有效的链接,Kernel就能启动这个rootfs。那假如说initramfs的rootfs为空(CONFIG_INITRAMFS_SOURCE没有配置或者指向不存在的位置),或者initramfs的rootfs没有有效的“/init”文件。则Kernel会解析commandline,尝试从MTD/UBI之类的NAND分区启动,或者启动INITRAMDISK,或者NFS启动(如果开启了此功能),其调用堆栈如下:
kernel/init/main.c: kernel_init() {
    // ...
    if (!ramdisk_execute_command)
           ramdisk_execute_command = "/init";
    if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
           ramdisk_execute_command = NULL;
           prepare_namespace();
    }
    // ...
}
kernel/init/do_mounts.c: prepare_namespace() {
    // ...
    if (saved_root_name[0]) {
           root_device_name = saved_root_name;
           if (!strncmp(root_device_name, "mtd", 3) ||
               !strncmp(root_device_name, "ubi", 3)) {
                  mount_block_root(root_device_name, root_mountflags);
                  goto out;
           }
           ROOT_DEV = name_to_dev_t(root_device_name);
           if (strncmp(root_device_name, "/dev/", 5) == 0)
                  root_device_name += 5;
    }
    if (initrd_load())
           goto out;
    // ...
    mount_root() {
           // ...
           mount_nfs_root();
           // ...
    }
    // ...
}
再来总结一下INITRAMFS的特点:
l ROOTFS和RAMFS文件系统在同一个源码文件“inode.c”中实现,他们基本一致,通过Kernel文档也能说明这一点。同时,这也应证了配置Kernel的时候为什么只需要配置'CONFIG_INITRAMFS_SOURCE'一个选项足也。
l ROOTFS文件系统类型的注册,以及rootfs的加载,initramfs的解压加载过程,都是Kernel启动过程的默认行为,menuconfig中没有任何选项可以开关。
l 实际上rootfs不仅为INITRAMFS提供服务,它还为INITRAMDISK的加载提供中转服务,这一过程后面会讲到。
l initramfs默认启动“/init”,请确保在那个位置有一个有效的init或者是链接。
l initramfs的处理总是优先于对commandLine中启动参数的处理,因此initramfs和commandline无关。当最终的zImage包含了一个有效的XXX.cpio.gz时,不管bootloader传给kernel什么样的commandline,Kernel都会从initramfs启动,比如:
bootargs=root=/dev/mtdblock5 rootfstype=yaffs2 init=/init console=ttySAC0,115200
// 即使当前mtdblock5有一个完整的yaffs2文件系统并且其'/init'也有效'. 当前Kernel也会尝试优先启动initramfs。
bootargs=console=ttySAC0,115200
    // 即使没有指定root/rootfstype/init选项,当前kernel也会尝试自带的initramfs。
l 当initramfs没有有效的root时,Kernel才会根据commandline的配置,尝试从mtd/ubi等NAND分区,或者是从ramdisk设备文件,或者是从nfs服务器加载root。

3. Kernel 2.4 armnommu 平台对 INITRAMDISK 的处理

在提到INITRAMFS时,提到了ROOTFS类型的文件系统,以及用此类型的文件系统加载(mount)了一个空的rootfs。 此时的rootfs是VFS cache的实现,不对应任何后端设备。rootfs是INITRAMFS的数据终点,但对于INITRAMDISK来说,当前rootfs只是一个中转站。Kernel会在此对INITRAMDISK的gz文件进行解压,然后再判定解压后的文件系统类型并加载,加载完成后,还要对initrd使用过的内存(VFS cache)进行释放。
早期的uCLinux(Linux 2.4.xx)支持armnommu平台,此平台没有内存管理单元,它处理initrd的方法与当前2.6的kernel有区别。以Linux-2.4.22的armnommu平台为例,它支持三种ramdisk文件的寻址方法:
方法一,就像2.6的kernel处理initramfs一样,当前kernel使用__ramdisk_data指针指向ramdisk压缩文件的开头,__ramdisk_data_end指向其结尾。
方法二,通过menuconfig配置选项'CONFIG_SD_INITRD_START'和'CONFIG_SD_INITRD_SIZE'。
方法三,以BOOTP协议启动,initramdisk文件的位置可通过Makefile的环境变量配置,比如-DINITRD_PHYS=XXX。

所有方法寻址的结果,都是以"initrd_start"变量指向源文件的起始虚拟地址,"initrd_end"变量指向源文件的结束虚拟地址。后面两种方法不再此文章范围内讨论。

3.1 通过__ramdisk_data指针寻址initramdisk文件的方法

方法一的调用堆栈:
【ramdisk文件的制作过程】
genext2fs -i 607  -b 5896 -d Host_Root_Directory -q -D device_table.txt XXX.ext2
// 'Host_Root_Directory' 为主机root目录, 'device_table.txt'为设备配置文件,'XXX.ext2'为生成的目标文件
gzip -c XXX.ext2 > initrd.bin
// 使用gzip压缩生成initrd.bin文件
arm-elf-ld -r -o initrd.o -b binary initrd.bin
// 链接生成initrd.o文件
arm-elf-ld -p -X -T arch/armnommu/vmlinux.lds arch/armnommu/kernel/head-armv.o arch/armnommu/kernel/init_task.o init/main.o init/version.o init/do_mounts.o \
--start-group \
arch/armnommu/kernel/kernel.o arch/armnommu/mm/mm.o arch/armnommu/mach-em86xx/em86xx.o kernel/kernel.o mmnommu/mmnommu.o fs/fs.o ipc/ipc.o \
drivers/char/char.o drivers/block/block.o drivers/misc/misc.o drivers/net/net.o drivers/scsi/scsidrv.o drivers/pci/driver.o drivers/video/video.o drivers/usb/usbdrv.o drivers/media/media.o \
net/network.o \
arch/armnommu/lib/lib.a lib/lib.a toolchain/lib/gcc-lib/arm-elf/2.95.3/libgcc.a \
--end-group \
-o linux
// 与Kernel一起链接生成Linux镜像文件
vmlinux.lds内容:
__ramdisk_data = .;
    initrd.o
__ramdisk_data_end = .;
【Kernel启动寻址initrd文件的过程】
kernel/arch/armnommu/kernel/setup.c: setup_arch() {
#ifdef CONFIG_BLK_DEV_INITRD
// let the kernel know where the initrd exists
#ifdef CONFIG_SD_INITRD_EMBED
{
    extern int __ramdisk_data, __ramdisk_data_end;
    initrd_start = (unsigned long) &__ramdisk_data;
    initrd_end = (unsigned long) &__ramdisk_data_end - (unsigned long) &__ramdisk_data;
}
#else
initrd_start = CONFIG_SD_INITRD_START;
initrd_end = CONFIG_SD_INITRD_START + CONFIG_SD_INITRD_SIZE;
#endif  
#endif
寻址的结果就是变量“initrd_start”和变量“initrd_end”,他们指向实际initrd文件的起始和结束地址,后面的加载过程将会用到这两个变量。

3.2 Kernel加载initramdisk的过程

在前面讲到Kernel处理INITRAMFS时,首先加载的文件系统rootfs要为INITRAMDISK提供中转服务。数据中转服务要用到rootfs下的两个RAMDISK设备文件。
/dev/ram       -> Ramdisk文件解压的目标设备,可以被rootfs或者上层直接mount的ramdisk设备。
/dev/initrd    -> 加载ramdisk文件的源设备,封装对ramdisk文件的读操作,所有对此文件的读操作,都会定位到对initrd_start指针的读操作。

[解压initrd的调用堆栈]
init/main.c: init() -> init/do_mounts.c: prepare_namespace() -> initrd_load() -> handle_initrd()
init/do_mounts.c: initrd_load() {
#ifdef CONFIG_BLK_DEV_RAM
    // ...
    create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
    // 这里"/dev/ram"是initrd加载的目标设备
#endif
    return rd_load_image("/dev/initrd");
    // 这里"/dev/initrd"是initrd加载的源设备
}
init/do_mounts.c: rd_load_image() {
    crd_load(); // means compressed ramdisk load
}
[为什么对设备“/dev/initrd”的读操作,就能定位到对initrd_start的访问]
drivers/block/rd.c:
    rd_init () {
           // ...
#ifdef CONFIG_BLK_DEV_INITRD
           /* We ought to separate initrd operations here */
           register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &rd_bd_op, rd_size<<1);
           devfs_register(devfs_handle, "initrd", DEVFS_FL_DEFAULT, MAJOR_NR,
                  INITRD_MINOR, S_IFBLK | S_IRUSR, &rd_bd_op, NULL);
#endif
           // ...
    }
    // 在随后的open函数中,会重定位read函数到以下函数:
   initrd_read() {

           // ...
           copy_to_user(buf, (char *)initrd_start + *ppos, count);
           // ...
    }
[加载(mount)"/dev/ram"的过程]
前面提到的initrd_load()函数把initrd文件内容读到块设备"/dev/ram"中,此时的块设备“/dev/ram”内容,实际上就是制作过程中提到的XXX.ext2文件内容。
下面要做的就是mount块设备“/dev/ram”。
init/do_mounts.c: prepare_namespace() {
    // ...
    sys_mkdir("/root", 0700);
    // 当前文件系统是'rootfs',目录'/root'是后续mount的Entry
    // ...
    // 然后要判断commandline的‘root=’选项。
    // 如果'root=/dev/ramN'(这是正确的启动选项,N取值0-15,或者直接取值'/dev/ram'),
    // 则,直接加载root
    mount_root();
    // 如果'root!=/dev/ramN'(command line给了其他启动选项)
    handle_initrd();
}
handle_initrd() {
    // 1. 尝试加载initrd到rootfs的/old目录下,并执行其启动脚本'/linuxrc'
    // 2. 尝试加载commandline指定的root设备文件
    mount_root();
    // 3. 在把initrd从/old移动到已经加载的文件系统的'/initrd'目录下。
}
mount_root() {
    // ...
    create_dev("/dev/root", ROOT_DEV, root_device_name);
    // 在当前rootfs下创建设备文件root,指向当前的启动文件
    mount_block_root("/dev/root", root_mountflags);
    // 把'/dev/root' Mount 到 '/root'
}

4. Linux 2.6.28 对 INITRAMDISK 的处理

2.6 与 2.4的Kernel处理INITRAMDISK有一些区别,表现在:
l 寻址initramdisk文件的方式已变,2.6的kernel不再支持init域变量“__ramdisk_data”,转而采用commandLine传递ramdisk文件的物理地址和大小信息。
l 加载initramdisk文件的方式已变,2.6的kernel把ramdisk文件内容直接写入rootfs中的文件“/initrd.image”,再由此文件写入块设备“/dev/ram”。2.6的Kernel不再使用块设备/dev/initrd封装对initramdisk文件的读取操作。
l 2.6的Kernel加入了对initramfs的支持,Kernel在寻址initramdisk地址时,会自动判断当前地址究竟存放的是initramfs还是initramdisk,这种自适应可能会纠正用户的错误使用行为。
其他未提及的部分,比如ramdisk文件的假牙过程,用户INIT寻址过程,与2.4的Kernel一致。

4.1 Kernel 2.6寻址initramdisk的过程

Kernel 2.6通bootloade传递的commandline参数寻址initramdisk内容,这需要bootloader事先读取initramdisk内容到物理地址中,然后在把物理地址和数据长度传递给kernel。
通常的commandline如下:
"console=ttySAC0,115200 mem=16M@0xc0000000 root=/dev/ram initrd=0xc0400000,4M"
其中选项有以下意义:
l "initrd=phy_addr,size",这是向kernel传递initrd内容的物理地址及长度。
l "mem=size@phy_addr",这是在向kernel传递bootmem保留区域的配置,bootmem是Kernel启动初期的内存分配机制,内存区域被保留即意味着告诉bootmem此区域已分配,勿做它用。这里要求当前配置区域完全覆盖initrd所配置区域,commandline中可同时存在多个"mem="选项以适应不同的应用。
l "root=/dev/ram",指定ramdisk设备,跟2.4 Kernel一样。
[Kernel端寻址的堆栈调用]:

1. phys_initrd_start变量和phys_initrd_size变量的赋值:
    arch/arm/mm/init.c: early_initrd() {
           // 解析commandline的"initrd="选项,并复制phys_initrd_start(_size)变量。
    }
2. bootmem的配置:
arch/arm/kernel/setup.c: early_mem() {
    // 解析commandline 的 mem选项
    // 把当前mem装入meminfo全局数组中
    arm_add_memory();
}
arch/arm/kernel/setup.c:setup_arch() -> arch/arm/mm/mmu.c: paging_init() -> bootmem_init()
arch/arm/mm/init.c: bootmem_init() {
    // check_initrd() {
           if (bank_phys_start(bank) <= phys_initrd_start &&
               end <= bank_phys_end(bank))
                  initrd_node = bank->node;
                  // 这里也说明了,为什么"mem="选项配置的内存区域,要完全覆盖"initrd="选项所配置的内存区域
           //...
           return initrd_node;
    }
    for_each_node(node) {
           if (node == initrd_node) {
                 bootmem_reserve_initrd() {
                         res = reserve_bootmem_node(pgdat, phys_initrd_start,
                                   phys_initrd_size, BOOTMEM_EXCLUSIVE);
                         if (res == 0) {
                                initrd_start = __phys_to_virt(phys_initrd_start);
                                initrd_end = initrd_start + phys_initrd_size;
                         }
                  }
           }
    }
}
至此,同2.4的kernel一样,后续的加载initramdisk过程将使用虚拟地址initrd_start和initrd_end访问initramdisk数据。

4.2 Kernel 2.6通过initrd_start加载initramdisk的过程

Initramfs的解压过程: initrd_start -> rootfs:/initrd.image
init/initramfs.c: populate_rootfs() {
    if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
           // 首先判断initrd_start指向的内容是否是initramfs
           err = unpack_to_rootfs((char *)initrd_start,
                  initrd_end - initrd_start, 1);
           if (!err) {
                  // 是,则解压,过程与initramdisk无关。
                  unpack_to_rootfs((char *)initrd_start,
                         initrd_end - initrd_start, 0);
                  free_initrd();
                  return 0;      
           }
           // 否,把initramdisk内容写入rootfs中的文件"/initrd.image"
           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
    // ...
#endif
    }    
}
initramfs的加载过程: rootfs:/initrd.image -> rootfs:/dev/ram -> mount
init/do_mounts.c: prepare_namespace() {
    // ...
    initrd_load();
    // ...
}
init/do_mounts_initrd.c: initrd_load() {
    // 解压的目标块设备
    create_dev("/dev/ram", Root_RAM0);
    // 解压的源文件,2.4 Kernel是“/dev/initrd”块设备
    rd_load_image("/initrd.image");
    //如果ROOT_DEV不是"/dev/ramN"
    handle_initrd() {
           // 内容与2.4Kernel一致,加载别的root并对initrd进行转储
    }
}
init/do_mounts.c: mount_root() {
    // ...
    // 以下过程与2.4 Kernel完全一致。
#ifdef CONFIG_BLOCK
    // 在rootfs下创建设备root,指向有效root设备。
    create_dev("/dev/root", ROOT_DEV);
    // 加载(mount)
    mount_block_root("/dev/root", root_mountflags);
#endif
}
分享到:
评论

相关推荐

    Linux启动流程 initrd与initramfs的区别

    Linux启动流程是操作...在了解了这些基本概念之后,我们可以更加深入地理解Linux启动流程,以及initrd与initramfs之间的差异。这对于系统管理员来说是一个非常重要的知识,它能够帮助他们更好地理解和维护Linux系统。

    initrd 文件系统详解

    为了使用 initrd 文件系统,需要在编译内核时选中 Inital RAM filesystem and RAM disk(initramfs/initrd) support。 initrd 文件系统的优点是能够提供一个快速的启动过程,特别是在大数据量的网络服务器和无盘工作...

    解析Initramfs机制在嵌入式Linux系统中的应用.pdf

    Initramfs机制是Linux 2.6中的一项新机制,它用来取代传统的Initrd机制。在嵌入式Linux系统中,Initramfs机制可以提高系统启动的灵活性和内存的使用效率。下面是Initramfs机制在嵌入式Linux系统中的应用知识点: 1....

    linux中ramdisk和initrd的区别

    Linux中的Ramdisk和Initrd是两种在早期启动过程中利用内存创建临时文件系统的技术。它们都是为了在系统启动时提供一个可操作的文件系统环境,但它们的用途和工作方式有所不同。 ## Ramdisk简介 Ramdisk是一种将...

    vmlinuz.txt与initrd 用于windows中安装linux

    在Linux操作系统中,vmlinuz和initrd(或initramfs)是两个至关重要的组件,它们在Linux系统启动过程中起着核心作用。vmlinuz是一个压缩的内核映像,包含了Linux内核的主要部分,而initrd则是一个临时的根文件系统,...

    i2c-bcm-kona.rar_lz4

    Initramfs和initrd是Linux启动过程中的临时文件系统,它们在内核启动时加载必要的驱动程序和服务,以便访问主文件系统。使用LZ4压缩这些组件可以显著加快系统的启动速度,因为LZ4具有较高的解压速度。 在压缩包内的...

    嵌入式Linux系统初始化分析.pdf

    在嵌入式Linux系统中,initrd/initramfs的使用有很多优点,例如可以提高系统的启动速度、简化系统的配置、提高系统的可靠性等。同时,initrd/initramfs也可以提供一个安全的启动机制,防止系统被未经授权的访问。 ...

    Linux系统内存磁盘初始化技术详细解析

    5. initrd与initramfs的区别: - initramfs是Linux 2.6内核引入的一个新特性,它是内存中直接创建的文件系统,相比于initrd更高效,因为不需要通过loop设备挂载。 - initramfs是内核启动时直接加载的数据结构,而...

    linux 4.8.2内核根目录

    4. **优化与改进**:在Linux 4.8.2中,可能通过调整initrd的大小、选择性地包含驱动或更新脚本来提高启动速度和减少资源占用。 5. **initramfs**:从Linux 2.6.13版本开始,initramfs取代了传统的initrd,成为更...

    gdb + UML调试linux内核

    在生成配置文件时,需要选择合适的配置选项,例如 General Setup-&gt;Initial RAM filesystem and RAM disk(initramfs/initrd) support、Kernel hacking-&gt;Kernel debugging、Kernel hacking-&gt;Compile the kernel with ...

    Gix Linux发行版内存盘打包脚本.

    内存盘,也称为临时根文件系统(initrd 或 initramfs),是Linux启动过程中的一个重要组件。它是一个小型的文件系统,用于在内核加载主要根文件系统之前提供必要的驱动程序和服务。这种技术特别适用于Live CD/USB...

    引导系统启动的MINI initramfs文件

    initrd16 /MINI_initramfs.img } initramfs中的init内容为: [root@zyq test]# cat init #!/bin/bash export PATH=/bin:/usr/bin:/usr/sbin mount -n -t devtmpfs udev /dev mount -t proc none /proc mount -t...

    initramfs-4.18.0-305.12.1.el8_4.x86_64.img

    用于QEMU模拟传入initrd参数

    u-root:具有Linux引导程序的完全Go用户环境! u-root可以创建一个单二进制的根文件系统(initramfs),其中包含用Go语言编写的类似于busybox的一组工具

    一种创建用于Linux内核的initramfs(文件存档)的方法。 使用kexec引导Linux或ESXi,Xen或tboot等多重引导内核的Go引导程序。 它们旨在与一起使用。 这样,用于或解析器将使向LinuxBoot的过渡更加容易。 用法 确保...

    linux-内核编译各个选项的含义

    * Initramfs source file(s):initrd 已经被 initramfs 取代,如果你不明白这是什么意思,请保持空白。 * Optimize for size (Look out for broken compilers!):编译时优化内核尺寸(使用"-Os"而不是"-O2"参数编译...

    linux内核配置文件说明参考

    initrd已经被initramfs取代,如果你不明白这是什么意思,请保持空白 Optimize for size (Look out for broken compilers!) 编译时优化内核尺寸(使用"-Os"而不是"-O2"参数编译),有时会产生错误的二进制代码

    linux系统移植

    - 修改initramfs或initrd,以适应新平台的启动需求,确保引导过程能够正确加载内核和初始化系统环境。 - 调整启动脚本,如`/etc/rc.local`,以执行特定于平台的设置和初始化任务。 5. **文件系统与工具**: - ...

    Linux_linux_

    Linux系统的启动流程通常包括BIOS/UEFI自检、加载GRUB/MBR、运行initrd或initramfs、加载内核、初始化系统服务及运行级别。理解这个过程有助于排查启动故障,优化系统性能。在分析时,会涉及bootlog、syslog、dmesg...

Global site tag (gtag.js) - Google Analytics