首页 > 编程知识 正文

docker的技术特性是什么,docker底层原理

时间:2023-05-03 13:20:05 阅读:39416 作者:1755

0x10 initramfs概述在Linux上,部分内存可用作“块设备支持”。 这通常出现在完全在内存中运行的Linux实时发行版中。 由于Linux的live发行版在卸载光盘后才加载到内存中,因此在尝试新操作系统或修复其他系统时不会损坏已安装的系统。

initrd是内存中的磁盘结构(ramdisk ),其中包含在将控制权交给根文件系统上的init APP应用程序之前装载所需的文件系统所需的工具和脚本。 Linux内核在此根磁盘上启动安装脚本(通常称为linuxrc,但不需要此名称)。 此脚本的工作是准备系统,切换到真正的根文件系统,然后调用init。

initrd有几个缺点

是一个完整的块设备,需要整个文件系统的开销,并且有一定的大小。 选择initrd太小,无法应用所需的脚本。 如果太大,就会浪费内存。 由于这是一个真实、静态的设备,因此它会占用Linux内核中的缓存内存和易于使用的文件(如分页),从而增加initrd的内存消耗。 因此,作为initrd的实现或替代品,出现了能够更好地解决initrd所存在的弊端,实现适当功能的initramfs。

0x 11什么是init ramfs? initramfsfs,即initram文件系统。 翻译成中文为初始 ram 文件系统。 基于tmpfs,大小灵活,直接作用于内存的文件系统。 initramfs中包含的工具和脚本将在正式根文件系统初始化脚本init启动之前装载。 initramfs是可选的,内核编译选项默认情况下启用initramfs(initrd )。 那么,在什么情况下考虑使用initramfs呢?

虽然不能通过加载模块(如第三方自定义引导系统)来创建较小的rescue shell内核,但可以在用户状态下完成的命令initramfs 在内核启动的早期提供用一个户态环境,用于完成在内核启动阶段不易完成的工作initramfs包含抽象层

/initramfs至少包含一个名为/init的文件,内核将运行此文件的进程设置为主init进程,并将其设置为pid=1。 内核挂载initramfs时,文件系统的根分区未挂载,因此无法访问文件系统中的文件。 如果大多数嵌入式设备需要shell,它将在initramfs中打包到shell中。 如果需要其他工具或脚本,也可以将其打包到initramfs中,但请参阅initramfs 是一个能够独立运行的 ram 文件系统

0x12 initramfs的工作方式类似于典型的文件系统,可能存在/usr、/繁荣芝麻等目录。 包括我们的工具和脚本。initramfs 需要使用 cpio 来归档,cpio是一个历史悠久的文件归档解决方案,如linux上常见的tar和windows zip,其主要作用是将多个文件打包为一个文件之所以使用cpio,是因为代码容易实现,并且与更多设备兼容。

归档后,必须考虑initramfs文件的体积。 必须进一步压缩以减少内存和磁盘的使用量。 在将所有文件、工具、库、配置设置(如果适用)等放入cpio归档文件之后,引导加载程序(通常为grub或uboot )将在引导时提供给内核,而karka

内核检测到initramfs时,将创建tmpfs文件系统,提取归档在gzip中的initramfs,并将其存储在tmpfs中。 内核启动tmpfs文件系统中的init脚本。 该脚本用于装载实际的根文件系统,根文件系统和其他重要文件系统安装完成后,init脚本将切换到实际的根文件系统,/s正在蓬勃发展

0x20 initramfs的实用化为了更好地理解initramfs的概念和实现,使用qemu创建和启动实际的initramfs。 如果您还不熟悉qemu引导内核,请参见为qemu ARM仿真器编译Linux内核QEMU模拟ARM环境

0x21内核配置和编译交叉编译器下载

sudo apt-getinstallgcc-arm-Linux-gnueabi自主选择某个版本的内核,下载后进行配置,配置完成后进行编译。 以下是两个内核源代码的镜像站点,可以加快源代码下载速度

3359 mirrors.edge.kernel.org/pub/Linux/ker

nel/
http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/

编译内核,需要注意的是,最后的编译命令是需要 root 权限的,并且编译内核可能需要一些依赖

# 内核配置make distcleanmake ARCH=arm vexpress_defconfigmake ARCH=arm menuconfig # 内核配置如下面的截图# 以下是正式编译sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all

因为编译内核默认使用单核,为了加快编译速度,可在编译命令上加上参数 -j,用于多核加速

sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all -j 4 # 4核 0x22 有关 initramfs 的内核编译配置 选项一(内核默认开启)

General setup 中的 Initial 用于对 initramfs 的支持。初始 RAM 的文件和 RAM 磁盘( initramfs /initrd)支持(如果要采用 initrd 启动则要选择,否则可以不选),对于默认的 Linux 内核配置,该选项默认开启

选项二(vexpress 未开启)

Linux 允许将一部分内存作为块设备 (RAM block device support),即 ramdisk。对于 vexpress 开发板的默认配置,是没有开启 ramdisk 选项的,也就是说,如果使用 vexpress_defonfig 配置,块设备中,只有 mtdblock,没有 ram,而 initramfs 是需要加载到 ram 的块设备中,因此,在内核的图形化配置菜单中,选择 Device Drivers -> Blocks devices -> RAM block device support

大家可能对上述两个配置的区别还不是很有体会,看完整个例子相信你会有更深的认识。

0x23 制作 initramfs

像所有编程语言的牙牙学语的阶段一样,为了简便起见,我们只编写一个简单的 C 程序

/* hello.c */#include <stdio.h>void main(){ printf("Hello Worldn"); fflush(stdout); /* 让程序打印完后继续维持在用户态 */ while(1);}

编译程序,因为我们在 0x21 节使用交叉编译器来编译内核,即该内核支持 arm32 平台的程序,因此在这里,也需要使用交叉编译器编译该 C 代码,为了避免还要拷贝库文件,这里使用静态编译

arm-linux-gnueabi-gcc -static hello.c -o hello

查看文件属性,检查是否生成目标平台程序

lys@kali:~/Documents/test$ file hellohello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=997821ab3ea778fd33cfea6dae5c36f5ab3c6104, for GNU/Linux 3.2.0, not stripped

使用 cipo 归档程序

echo hello| cpio -o --format=newc > helloinitramfs 0x24 qemu 启动 initramfs

使用 qemu 启动编译好的内核,并且指定 initrd 为生成的 initramfs,rdinit 指名要启动的脚本

qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-5.6.6/arch/arm/boot/zImage -dtb linux-5.6.6/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append "rdinit=hello console=ttyAMA0" -initrd test/helloinitramfs -serial stdio

成功启动

这个时候,我们再回过头来看看 0x22 节的两个内核配置选项

选项一是内核默认开启的,Initial Ram filesystem and Ramdisk support 选项就是用来支持 initramfs / initrd 的,如果关闭此选项,则不能使用 -initrd 参数启动内核;选项二对于不同的开发板,默认会有不同的设置,RAM block device support,如果关闭,则不能在 -append 参数中,添加 root=/dev/ram,即将 initramfs 挂载到 /dev/ram 中启动

使用 initrd 的内核配置参数:initrd=addr root=/dev/ram **而 /dev/ram 这个设备(ramdisk 的设备节点)**是需要开启内核的选项二配置

0x30 总结

initramfs 作为根文件系统一个重要补充,在特定条件下弥补了内核启动时,没有用户态的缺陷。很多 Linux 发行版都使用了 initramfs,当然也有一些并没有使用,该 ram 文件系统并非必须,但在很多场景下又不可或缺。例如 Kali Linux 系统,就使用了 initramfs

Debian 系的 Linux 发行版,initrd/initramfs 映象文件一般在 /boot 目录下,initramfs 与根分区文件系统的雏形很像,只是它的大小不大,少了很多工具和库。

本文首先讲述了 initramfs 的由来和工作过程,然后举了一个实际的例子,以将抽象的过程具体化,最后使用 qemu 启动了我们制作的 initramfs,相信通过此文,你一定能够对 initramfs 有一个更加清晰的认识。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。