LiveOS 网络启动

 

通过 dracut 生成的 LiveOS 系统,如何指定用于下载 squashfs 根文件系统的网口的?

通过 dracut 生成的 LiveOS 系统,如何指定用于下载 squashfs 根文件系统的网口的?

dracut 阅读笔记

我从 dracut 官方网站下载了 dracut5.6 版本的源代码,以此作为分析的基础。在官方源码的 dracut.htmlcmdlinChapter 8. DRACUT.CMDLINE(7).Network 提到了 可预测的网络接口

  • 可预测的网络接口
    • 内核使用的网络接口经典命名是 eth0/eth1,当多个网络接口可用时,eth0/eth1指代的就不是固定的接口了,导致安全隐患
    • 一个解决方案是 biosdevname,从固件接口中找到固定槽拓扑信息,用它们为接口分配固定名称
  • 在 systemd 197中,为 systemd/udev 增加了不同命名策略的支持
    1. 包含 Firmware/BIOS 的名称为板载设备提供了索引号(例如: eno1)
    2. 包含 Firmware/BIOS 的名称提供了 PCI Express 热插拔插槽索(slot)引号(例如: ens1)
    3. 包含硬件连接器的物理/装置位置的名称(例如: enp2s0: ethernet PCI bus 2, slot 3)
    4. 包含接口 MAC 地址的名称(例如: enx78e7d1ea46da)
    5. 经典的、不可预测的内核本机 ethX 命名(例如: eth0)
  • 支持顺序:1, 2, 3, 5, 4

《redhat 8 配置和管理网络》

引言

什么是 dracut

Dracut 是用于生成 initramfs/initrd 镜像的底层工具。方法是从已安装的系统中复制工具和文件,并将其与通常位于 /usr/lib/dracut/modules.d 中的 dracut 框架结合起来。

dracut 的 initramfs 不是硬编码的脚本来做各种事情,而是依赖 udev 来创建到设备节点的符号链接,然后当 rootfs 的设备节点出现时,它被挂载,root 被切换到它。

Dracut 中的大多数 initramfs 生成功能由一组生成器模块提供,这些模块由主 dracut 工具提供,用于将特定功能安装到 initramfs 中。它们位于 module 子目录中,并使用 dracut-function 提供的功能来完成它们的工作。

第一章定义

initial ramdisk 是 Linux 内核引导过程中使用的临时文件系统。initrd 和 initramfs 将这个文件系统加载进内存稍有不同。但这两种方法通常用于在挂载真正的根文件系统之前进行准备。

第二章 基本原理

linux 发行版都提供了一个单一、通用的内核映像,用于引导尽可能多的硬件。这个通用内核映像的多个设备驱动作为可加载模块包含在内,因为不可能静态地将它们全部编译到一个内核中。否则内核映像就太大了,无法从内存有限的计算机或者低容量的磁盘启动,根文件系统可能位于软件 RAID 卷、 LVM、 NFS (无磁盘工作站)或加密分区上。所有这些都需要特别的准备来安装。

为了避免对内核中的许多特殊情况进行硬编码处理,使用了带有临时根文件系统(现在称为早期用户空间)的初始引导阶段。这个根文件系统将包含用户空间助手,用于执行硬件检测、模块加载和设备发现,这些都是安装真正的根文件系统所必需的。

第三章 实现

初始根文件系统的映像存储在 linux bootloader 或者 boot 固件可以访问的地方,比如tftp服务器,本地启动分区。bootloader把内核和初始根文件系统镜像加载到内核中,然后启动内核,传入镜像的内存地址。

第四章 挂载准备

Dracut 可以生成定制的 initramfs 镜像,也可以生成通用的 initramfs 镜像。Dracut 的 initramfs 只能以根文件系统的设备名(或其 UUID)启动,并且必须在 boot 阶段发现下面所有的其他内容:

  1. boot 阶段依赖的任何硬件驱动程序必须加载

    所有用于普通存储设备的内核模块都打包到 initramfs 中,然后 udev 将与计算机检测到的硬件匹配的模块引入

  2. 在显示 boot rd.splash 屏幕的系统上,必须初始化视频硬件
  3. 根据根文件系统出现的位置,有不同的操作流程
    • NFS
      • 打开主网络接口(primary network interface)
      • 调用 DHCP 客户端,获取 DHCP 租约
      • 从租约中提取 NFS 共享的名称和 NFS 服务器的地址
    • 软件 RAID
      • 根文件系统出现在软件 RAID 设备上,就没有办法知道 RAID 卷跨越哪个设备
      • 必须调用标准的 MD 实用程序来扫描所有可用的 raid 签名的块设备,并使所需的设备上线
    • 逻辑卷
      • 根文件系统出现在逻辑卷上,则必须调用 LVM 实用程序来扫描并激活包含它的卷组

udev 是一个事件驱动的热插拔代理,当硬件设备、磁盘分区和符合特定规则的存储卷上线时,它会调用辅助程序。

当根文件系统最终可见时:

  • 根文件系统是以只读方式挂载的
  • 最终的根文件系统不能简单地挂载在 / 上,因为这会使初始根文件系统上的脚本和工具无法访问,无法执行任何最终的清理任务。
  • 在 initramfs 上,不能将初始根文件系统替换。相反,它只是被清空,最终的根文件系统挂载在顶部
  • 如果在 initramfs 中使用了 systemd 模块,那么服务启动的顺序类似于第12章 DRACUT.BOOTUP (7)

第五章 关闭 dracut

在 systemd 驱动的系统中,也使用 initramfs 进行关闭流程。shutdown 关闭流程

第二部分 使用

dracut 创建一个初始镜像,用于内核预加载块设备模块(如IDE、SCSI、RAID),这些设备是访问、挂载根文件系统,引导进入真实系统所必须的。

在 boot 阶段,内核将存档到 RAM 磁盘中的文件解包,挂载并使用它作为初始根文件系统。根设备的所有发现都发生在这个早期用户空间中。(initramfs 镜像也称为 initrd)。

有关内核命令行选项的完整列表,请参见 dracut.cmdline (7)。 如果您在启动 initramfs 时进入紧急 shell 中,就会创建文件 /run/initramfs/rdsosreport.txt。 将 rd.debug 添加到内核命令行,可以产生额外的调试信息。 /run/initramfs/rdsosreport.txt 包含所有日志和一些工具的输出。它应该附在任何关于 dracut 问题的报告。

创建镜像

要创建 initramfs 映像,最简单的命令是: dracut。生成一个通用的 initramfs 映像,所有可能的功能都是由已安装的 dracut 模块和系统工具组合而成的, 镜像在 /boot/initramfs-<kernel version>

  • 指定名

      dracut foobar.img
    
  • 为特定的内核版本生成镜像

      dracut --kver 2.6.40-1.rc5.f20
    

查阅内容

  • 查看

    lsinitrd | less
    
  • 显示文件内容

    lsinitrd -f /etc/ld.so.conf
    

增加 dracut 模块

一些 dracut 模块在默认情况下是关闭的,必须手动激活。把模块加到 /etc/dracut.conf 或者 /etc/dracut.conf.d/myconf.conf, 参考dracut.conf(5)。或者

dracut --add module initramfs-module.img

增加模块。可用的 dracut 模块通过

dracut --list-modules

查询

删除模块

  1. dracut.conf/etc/dracut.conf/myconf 配置文件中指定 omit_dracutmodules 变量
  2. 命令行
  dracut -o "multipath lvm" no-multipath-lvm.img

添加内核模块

  1. dracut.conf/etc/dracut.conf.d/myconf.conf 配置文件中指定 drivers 变量
  2. 命令行
  dracut -o "multipath lvm" no-multipath-lvm.img
dracut --add-drivers mymod initramfs-with-mymod.img

boot 参数

不使用“hostonly”模式生成的 initramfs 不包含任何系统配置文件(除了一些特殊的异常) ,因此配置必须在内核命令行上完成。这样不需要重新编译 initramfs 映像,就可以轻松地更改启动的根分区。只要您在根设备的内核命令行上指定了正确的文件系统 LABEL 或 UUID,dracut 就会找到它并从它启动。

DHCP 服务器还可以用 root-path 选项提供内核命令行。请参阅网络引导 所有内核命令行参数,参见 dracut.cmdline (5)

内核命令行参数:

dracut --print-cmdline

指定 root 设备

这是dracut从根分区引导时真正需要的唯一选项,因为根分区可以存在于各种环境中,所以 root= 选项有很多格式,最基本的是 root = < path to device node >root=/dev/sda2),因为设备节点名称可以根据驱动器顺序更改,所以建议使用文件系统标识符(UUID)或文件系统标签(LABEL)来指定根分区:

root=UUID=19e9dda3-5a38-484d-a9b0-fa6b067d0331
root=LABEL=myrootpartitionlabel

查看系统上的所有 UUID 或标签

ls -l /dev/disk/by-uuid
ls -l /dev/disk/by-label

黑名单内核模块

防止特定内核模块的自动内核模块加载,添加内核命令行 rd.blacklist = <kernel module name>,不用包含 .ko后缀

rd.driver.blacklist=mptsas rd.driver.blacklist=nouveau

加速 boot 过程

可以在内核命令上为 dracut 指定尽可能多的信息,以加快引导过程。比如可以告诉 dracut,您的根分区不在 LVM 卷上,或者不在 RAID 分区上,或者它位于特定的加密 LUKS 加密卷内。缺省情况下,dracut 搜索所有地方。典型的 dracut 内核命令行应该包含:

rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0

这将关闭 LVM、 MD raids、 DM radis和加密 LUKS 的所有自动组装

注入自定义文件

将您自己的文件添加到 initramfs 映像中:

  • --include (只能指定一次)
    • 选项指定源路径和目标路径

      dracut --include cmdline-preset /etc/cmdline.d/mycmdline.conf initramfs-cmdline-pre.img
      

      创建一个 initramfs 映像,其中 cmdline-preset 文件将在 initramfs 中复制到 /etc/cmdline.d/mycmdline.conf

    • 加入目录

      etc
      |-- cmdline.d
      |-- mycmdline.conf
      conf.d
      testvar.conf
      

      使用 --include 选项

      dracut --include rd.live.overlay / initramfs-rd.live.overlay.img
      

      把 rd.live.overlay 目录的内容放到 initramfs 映像的根目录中

  • --install(可多次指定此选项)
    • Install 选项允许指定几个文件,这些文件将安装在 initramfs 映像的同一位置

      dracut --install 'strace fsck.ext3 ssh' initramfs-dbg.img
      

      创建一个 initramfs,其中包含 strace、 fsck.ext3和 ssh 可执行文件,以及启动这些文件所需的库

网络 boot

根分区位于网络驱动器上,则必须安装网络 dracut 模块,以创建支持网络的 initramfs 映像。

如果在内核命令行上指定 ip=dhcp,那么 dracut 会向 dhcp 服务器询问机器的 ip 地址。Dhcp 服务器还可以提供额外的根路径,为 dracut 设置根设备。

通过这种机制,您在客户机上具有静态配置,在 TFTP/DHCP 服务器上具有集中式引导配置。如果无法传递内核命令行,那么可以使用“注入自定义文件”一节中描述的方法注入 /etc/cmdline.d/mycmdline.conf

减小镜像大小

可以通过省略(omitting) dracut 模块减小 initramfs 的大小,也可以指定具体的 dracut 和 kernel 模块来生成小的 initramfs 镜像。例如,对于一个 NFS 映像,您可以这样做:

dracut -m "nfs network base" initramfs-nfs-only.img

然后在目标机中用这个映像引导,之后再次在目标机上使用 --host-only 选项创建映像,这将显著减小 initramfs 镜像的大小:

dracut -m "nfs network base" --host-only initramfs-nfs-host-only.img

故障排除

引导过程未能成功,您可以使用多个选项来调试这种情况。更多资料,查看内核的dracut

  1. rd.shell 添加到内核命令行。如果 dracut 无法定位您的根设备,这将显示一个 shell
  2. rd.shell rd.debug log_buf_len=1M 添加到内核命令行,以便在执行 dracut shell 命令时打印它们
  3. /run/initramfs/rdsosreport.txt中包含所有日志和所有重要工具的输出
  4. 手动安装/启动或插入一个 U 盘并安装。然后您可以存储输出以供以后检查。

包括在 bug 报告中的信息

以下内容应该被提及并附在你的错误报告中

  • 使用的内核命令行
    • 通常来自引导加载程序配置文件(例如 /boot/grub2/grub.cfg )或 /proc/cmdline
  • /etc/fstab 获得的磁盘分区信息的副本
    • 从可引导的旧的 initramfs 或救援介质(rescue medium)中获得
  • 打开 dracut 调试(参见调试 dracut 部分) ,并附加文件 /run/initramfs/rdsosreport.txt
  • 网络根设备相关问题还要包括:

    /sbin/ifup <interfacename>
    ip addr show
    

dracut 的调试

配置串口

  • 为内核和 bootloader 启用串口输出
  • 打开文件 /boot/grub2/grub.cfg,在 timeout=5下面加上

    serial --unit=0 --speed=9600
    terminal --timeout=5 serial console
    
  • /boot/grub2/grub.cfg 中,将引导参数添加到‘kernel’行:

    console=tty0 console=ttyS0,9600
    
  • /boot/grub2/grub.cfg 应该类似于下面的示例

    default=0
    timeout=5
    serial --unit=0 --speed=9600
    terminal --timeout=5 serial console
    title Fedora (2.6.29.5-191.fc11.x86_64)
      root (hd0,0)
      kernel /vmlinuz-2.6.29.5-191.fc11.x86_64 ro root=/dev/mapper/vg_uc1-lv_root console=tty0 console=ttyS0,9600
      initrd /dracut-2.6.29.5-191.fc11.x86_64.img
    
  • 重定向非交互输出
    • 将所有非交互输出重定向到 /dev/kmsg,内核将通过下面的方式输出到串口

      exec >/dev/kmsg 2>&1 </dev/console
      

更多关于如何为控制台输出配置内核的详细信息

使用 dracut shell

shell 用于交互式调试,启用 shell

  • 将 boot 参数 rd.shell 添加到引导加载程序(bootloader)配置文件(例如 /boot/grub2/grub.cfg)
  • 删除 boot 参数 rhgbstatic
  • 示例

    default=0
    timeout=5
    serial --unit=0 --speed=9600
    terminal --timeout=5 serial console
    title Fedora (2.6.29.5-191.fc11.x86_64)
      root (hd0,0)
      kernel /vmlinuz-2.6.29.5-191.fc11.x86_64 ro root=/dev/mapper/vg_uc1-lv_root console=tty0 rd.shell
      initrd /dracut-2.6.29.5-191.fc11.x86_64.img
    

从 dracut shell 访问根卷

root volumn 所在的设备可能是:

  • 块设备 (/dev/sda7)
  • LVM 逻辑卷 (/dev/VolGroup00/LogVol00)
  • 加密设备 (/dev/mapper/luks-4d5972ea-901c-4584-bd75-1da802417d83)
  • 网络设备 (netroot=iscsi:@192.168.0.4::3260::iqn.2009-02.org.example:for.all)

要成功引导,必须找到根卷并创建指向文件系统的符号连接 /dev/root,比如访问和引导加密的 LVM 逻辑卷的根卷:

  • 检查您的分区

    >>> parted /dev/sda -s p
    
    Model: ATA HTS541060G9AT00 (scsi)
    Disk /dev/sda: 60.0GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Number  Start   End     Size    Type      File system  Flags
    1      32.3kB  10.8GB  107MB   primary   ext4         boot
    2      10.8GB  55.6GB  44.7GB  logical                lvm
    
  • 您记得您的根卷是 LVM 逻辑卷。请扫描并激活任何逻辑卷。

    >>> lvm vgscan
    >>> lvm vgchange -ay
    
  • 查到使用 blkid 命令的逻辑卷

    >>> blkid
    
    /dev/sda1: UUID="3de247f3-5de4-4a44-afc5-1fe179750cf7" TYPE="ext4"
    /dev/sda2: UUID="Ek4dQw-cOtq-5MJu-OGRF-xz5k-O2l8-wdDj0I" TYPE="LVM2_member"
    /dev/mapper/linux-root: UUID="def0269e-424b-4752-acf3-1077bf96ad2c" TYPE="crypto_LUKS"
    /dev/mapper/linux-home: UUID="c69127c1-f153-4ea2-b58e-4cbfa9257c5e" TYPE="ext3"
    /dev/mapper/linux-swap: UUID="47b4d329-975c-4c08-b218-f9c9bf3635f1" TYPE="swap"
    
  • 根卷存在于加密的块设备上,解锁

    >>> UUID=$(cryptsetup luksUUID /dev/mapper/linux-root)
    >>> cryptsetup luksOpen /dev/mapper/linux-root luks-$UUID
    
    Enter passphrase for /dev/mapper/linux-root:
    Key slot 0 unlocked.
    
  • 创建一个到解锁的根卷的符号链接

    >>> ln -s /dev/mapper/luks-$UUID /dev/root
    
  • 在根卷可用的情况下,您可以通过退出 dracut shell 来继续引导系统

    >>> exit
    

额外的引导参数 dracut.cmdline(7)

shutdown 时调试 dracut

要调试 Systemd 系统上的关闭序列,您可以在预关闭或关闭时使用 rd.break

在已经启动的系统中执行此操作:

>>> mkdir -p /run/initramfs/etc/cmdline.d
>>> echo "rd.debug rd.break=pre-shutdown rd.break=shutdown" > /run/initramfs/etc/cmdline.d/debug.conf
>>> touch /run/initramfs/.need_shutdown

这将在系统转回initramfs后给您一个dracut shell。

dracut.conf(5)

它是用于 dracut 的配置文件,必须有扩展名 .conf,所在路径(优先级从高到低)

/etc/dracut.conf.d/*.conf 
/usr/lib/dracut/dracut.conf.d/*.conf
/etc/dracut.conf 

命令行参数会覆盖它们的值。每一行指定一个属性和一个值。

dracut.cmdline(7)

dracut 内核命令行选项。 内核使用的根设备是在boot配置文件中指定的,而boot配置文件又是在内核命令行指定的。

并不鼓励使用传统的 root=/dev/sda1 样式的设备规范,根设备最好使用 LABEL 或 UUID 标识。

下面是所有由 dracut 处理的内核命令行参数。没有 =rd.* 参数,是布尔型参数。可以通过将它们设置为 {0 | 1} 来打开/关闭它们。如果缺少 = 的赋值,则为 = 1。例如,可以使用 rd.info = 0关闭 rd.info,也可以使用 rd.info = 1rd.info 打开 rd.info。内核命令行中的最后一个值是值,该值是有效的。

Standard

  • init=<path to real init>
    • 指定 initramfs 完成后要启动的 init 程序的路径
  • root=<path to blockdevice>

    root=/dev/sda1
    root=/dev/disk/by-path/pci-0000:00:1f.1-scsi-0:0:1:0-part1
    root=/dev/disk/by-label/Root
    root=LABEL=Root
    root=/dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
    root=UUID=3f5ad593-4546-4a94-a374-bcfb68aa11f7
    root=PARTUUID=3f5ad593-4546-4a94-a374-bcfb68aa11f7
    
    • 指定用作根文件系统的块设备
  • ro
    • 强制安装 //usr (如果是单独的设备)只读。如果没有 ro 和 rw,则按照 /etc/fstab 挂载它们
  • rw
    • 强制安装 //usr (如果它是一个单独的设备)为可读可写
  • rd.retry=<seconds>
    • 指定 dracut 应该重试 initqueue 多长时间以配置设备。默认值是180秒。经过2/3的时间,降级突袭开始强制执行。
    • 如果您有硬件,需要很长时间才能发布它的驱动器,那么您可能需要扩展这个值
  • rd.timeout=<seconds>
    • 指定 dracut 等待设备出现应多长时间,默认为0,意味着永远等待

Debug

当进入紧急 shell 中,就会创建文件 /run/initramfs/rdsosreport.txt

  • rd.shell
    • root 挂载失败会进入 shell
  • rd.debug
    • 如果 systemd 在 initramfs 中处于活动状态,则所有输出都会记录到 systemd 日志,您可以使用journalctl-ab 检查该日志
    • 如果 systemd 不是活动的,日志将写入 dmesg 和 /run/initramfs/init.log
  • rd.break
    • dracut 结束系统时进入 shell
    • rd.break={cmdline|pre-udev|pre-trigger|initqueue|pre-mount|mount|pre-pivot|cleanup}
      • 在指定的断点进入 shell
  • rd.udev.debug
    • 将 udev 设置为 debug 级调试
  • rd.udev.info
    • 将 udev 设置为 loglevel 信息

LVM

  • rd.lvm=0 禁用 LVM 检测

网络

建议使用 ifname 参数将接口绑定到 MAC,或者使用 systemd-udevd 可预测的网络接口名称。可预测的网络接口设备名称基于:

  • 固件/BIOS系统提供的机载设备索引号
  • 固件提供的 pci-Express 热插拔插槽索引号
  • 硬件的物理/地理位置
  • 参考

下面的选项被 network-legacy druct 模块支持。其他网络模块可能支持一组略有不同的选项; 请参考正在使用的特定网络模块的文档。有关 NetworkManager,请参见 nm-initrd-Generator (8)

boot live images

  • 只读文件系统镜像 SquashFS
    • 系统将从 SquashFS 启动只读文件系统,并为只读基本文件系统应用可写的设备映射器快照或 OverlayFS 覆盖挂载。
    • 用户必须小心,避免向快照卷写入太多块。
  • root=live:<url>
    • 需要 dracut livenet 模块

      root=live:http://example.com/liveboot.img
      root=live:ftp://ftp.example.com/liveboot.img
      root=live:torrent://example.com/liveboot.img.torrent
      
  • rd.live.debug=1
    • 启用实时引导进程的调试输出
  • rd.live.ram=1
    • 将完整的映像复制到 RAM 中,并使用它进行引导
  • rd.live.overlay.readonly=1
    • 在只读模式下使用通常的读写持久性覆盖进行引导

drucat.modules(7)

dracut 使用模块化系统来构建和扩展 initramfs 映像。所有模块都位于 /usr/lib/dracut/modules.d<git-src>/modules.d 中。最基本的牵引模块是 99base。在 99base 中定义了初始 shell 脚本 init,它在 initramfs 加载后由内核运行。您可以用自己的99base 版本替换 init,但是不鼓励这样做。如果可能的话,你应该使用牵引钩。所有钩子以及它们执行的时间点都在“引导过程阶段”一节中描述。

创建 initramfs 的主脚本是 dracut 本身。它解析所有参数并设置安装所有内容的目录。然后执行在模块中找到的所有检查、安装和安装内核脚本,这些脚本将被处理。安装完所有内容后,安装目录将被归档并压缩为最终的 initramfs 映像。Check、 install 和 installkernel 使用的所有助手函数都可以在 dracut-function 文件中找到。这些 shell 函数可用于所有模块安装程序(安装、安装内核)脚本,而不需要 source dracut-functions

boot 引导过程

dracut 模块可以在不同的位置插入自定义脚本,以控制引导过程。这些钩子是以 .sh 结尾的 shell 脚本的普通目录,由 init 来引入。通常使用的函数在 dracut-lib.sh 中,它可以由任何脚本通过 source 来引入。

Hook: cmdline

cmdline 钩子是插入脚本以解析内核命令行并准备后续操作的地方(如设置 udev 规则和配置文件)

如何解决下载失败的问题

修改 dracut 的 url-lib.sh 文件的 curl_fetch_url() 函数

curl_fetch_url() {
    local url="$1" outloc="$2"
    echo "$url" > /proc/self/fd/0
    if [ -n "$outloc" ]; then
        curl $curl_args --output - -- "$url" > "$outloc" || return $?
    else
        # 跑的是这个分支
        local outdir="$(mkuniqdir /tmp curl_fetch_url)"
        # 获取断开就不会再获取了,这里要改成获取文件之后,再判断文件的大小
        # 如果不一致,就需要再取
        # || 前面执行完且为错误($? != 0)则执行后面
        ( cd "$outdir"; curl $curl_args --remote-name "$url" || return $? )
        outloc="$outdir/$(ls -A $outdir)"
    fi
    if ! [ -f "$outloc" ]; then
	    warn "Downloading '$url' failed!"
	    return 253
    fi
    if [ -z "$2" ]; then echo "$outloc" ; fi
}

( cd "$outdir"; curl $curl_args --remote-name "$url" || return $? ) 修改如下

# 修改流程,当下载镜像失败后,自动重新下载
( 
    cd "$outdir"
    sroot_log=/tmp/sroot_down.log
    touch ${sroot_log}
    echo ">>> outdir: " $outdir >> ${sroot_log}
    img_name=$(basename "$url")
    echo "img_name" ${img_name} >> ${sroot_log}
    img_size_url=${url}.size
    echo "img_size_url" ${img_size_url} >> ${sroot_log}
    size_name=/tmp/$(basename ${img_size_url})
    echo "size_name" ${size_name} >> ${sroot_log}
    curl $curl_args ${img_size_url} -o ${size_name} || return $?
    echo curl $curl_args ${img_size_url} -o ${size_name}  >> ${sroot_log}

    count=1
    read img_size < ${size_name}
    echo "img_size" ${img_size} >> ${sroot_log}
    while ((count <= 3)); do
        curl $curl_args --remote-name "$url"
        echo curl $curl_args --remote-name "$url" >> ${sroot_log}
        down_size=$(ls -l ${img_name} | awk '{print $5}')
        echo "down_size:" ${down_size} >> ${sroot_log}
        if [[ ${img_size} == ${down_size} ]]; then
            echo "size equel" >> ${sroot_log}
            break
        eles
            echo ">>>>>>>" img_size: ${img_size}, down_size: ${down_size}, img_name: ${img_name} >> ${sroot_log}
            echo "count:" ${count} >> ${sroot_log}
        fi
        ((count++))
    done
    echo "while break, count:" ${count} >> ${sroot_log}
    if [[ $count == 3 ]]; then
        echo "error>>>, ? = $?" >> ${sroot_log}
        return $?
    fi
    echo "=== exec finish ===" >> ${sroot_log}
)
  • 实验脚本

      read i < len.txt
      echo i = $i
    
      j=1
      while ((j <= 3)); do
              if [ $i == "12345" ]; then
                      break
              fi
              ((j++))
      done
    
      curl_fetch() {
          url=http://10.0.0.22/sroot.img
          echo url_size = "${url}_size"
          echo "test over $j"
    
          curl_args="-L -O"
          (
              img_name=$(basename ${url})
              echo ${img_name}
              size_name=$(basename ${img_name}.size)
              echo curl $curl_args --remote-name ${size_name}
              count=1
              read img_size < ${size_name}
              while ((count <= 20)); do
                  echo $curl_args --remote-name "$url"
                  down_size=$(ls -l ${img_name} | awk '{print $5}')
                  if [[ $img_size == $down_size ]]; then
                          break
                  fi
                  ((count++))
              done
              if [ $count==20 ]; then
                      return $?
              fi
          )
      }
    
      curl_fetch
      echo ? = $?
      ~
    
  • 解压 initrd.img

    • 方式1

      mkdir initrd
      mv initrd.img initrd
      cd initrd
      xz -dc < ../initrd.img | cpio -idmv
      
    • 方式2

      mkdir /tmp/initrd; cd /tmp/initrd
      
      /usr/lib/dracut/skipcpio /boot/initramfs-$(uname -r).img | gunzip -c | cpio -idmv
      /usr/lib/dracut/skipcpio /boot/initramfs-$(uname -r).img | xz -dc | cpio -idmv
      
  • 重新制作 initrd.img

    find . 2>/dev/null | cpio -c -o | xz -9 --format=xz > /tmp/new.img
    find . 2>/dev/null | cpio -o -c -R root:root | xz -9 --format=xz > /boot/new.img
    find . 2>/dev/null | cpio -o -H newc -R root:root | xz -9 --format=xz > initrd.img.xz
    find . 2>/dev/null | cpio -o -H newc -R | xz -9 --format=xz > initrd.img.xz
    

    ‘newc’: The new (SVR4) portable format, which supports file systems having more than 65536 i-nodes. (4294967295 bytes)

版本制作实验

dracut(失败)

直接在服务器上使用

curl -L -O http://129.0.0.22/post/url-lib.sh
chmod 755 url-lib.sh
dracut --include url-lib.sh /lib/url-lib.sh initrd.img.new

得到的是 gzip 的压缩格式,并且没有很多模块,应该是 dracut 使用本机安装的模块制作的 initrd.img

dracut dracut

cpio

  • -i–extract  执行copy-in模式,还原备份档
  • -d–make-directories  如有需要cpio会自行建立目录
  • -mpreserve-modification-time  不去更换文件的更改时间。
  • -v–verbose  详细显示指令的执行过程
  • -t–list  将输入的内容呈现出来
  • -u–unconditional  置换所有文件,不论日期时间的新旧与否,皆不予询问而直接覆盖

参考网站

xz

-z, --compress      强制压缩
-d, --decompress    强制解压
-t, --test          测试压缩文件完整性
-l, --list          列出有关文件的信息
-k, --keep          保留(不删除)输入文件
-f, --force         强制覆盖输出文件和(取消)压缩链接
-c, --stdout        写入标准输出,不删除输入文件
-0 .. -9            压缩预设;0-2快速压缩,3-5良好
                    压缩,6-9极好的压缩;默认值为6
-e, --extreme       编码时使用更多的CPU时间来增加压缩
                    不增加解码器内存使用率的比率
-q, --quiet         取消警告;指定两次也可以取消错误
-v, --verbose       详细;为更详细的内容指定两次
-h, --help          显示此简短帮助
-H, --long-help     显示长帮助(同时列出高级选项)
-V, --version       显示版本号

解压方法1(失败)

mkdir initrd
mv initrd.img initrd
cd initrd
xz -dc < ../initrd.img.origin | cpio -idm

# 做镜像 
find . 2>/dev/null | cpio -c -o | xz -9 --format=xz > ../initrd.img
lsinitrd ../initrd.img

failed

尝试2 (失败)

/usr/lib/dracut/skipcpio ../initrd.img.origin| xz -dc | cpio -idm
find . | sudo cpio -H newc -o | xz -9 --format=xz > ../initrd.img

尝试3 (无效 )

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
find . | sudo cpio -H newc -o | xz -9 --format=xz > ../initrd.img

尝试4 (成功)

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
find . 2>/dev/null | cpio -c -o | xz -9 --check=crc32 > ../initrd.img

【问题】mount: only root can use “–no-mtab” option

尝试5 (失败)

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
find . 2>/dev/null | cpio -c -o | xz -9 > ../initrd.img

尝试6 (失败,与4同)

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
find . 2>/dev/null | cpio -H newc -o | xz -9 --check=crc32 > ../initrd.img

尝试7 (成功)

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
find . 2>/dev/null | cpio -H newc -o -R root:root | xz -9 --check=crc32 > ../initrd.img

【解决】mount: only root can use …. 【问题】IBMC_HOST掉电测试_固件升级测试失败,返回【没有收到主机的应答】

尝试8 (失败)

/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1
sudo find . | sudo cpio -H newc -o -R root:root | sudo xz -9 --format=xz > ../initrd.img

新问题

制作的initrd.img无法引导系统启动,出现内核崩溃,找不到 rootfs 的问题

kernel

看看是不是用 initramfs 的方式做镜像可以解决

查看 initramfs 的内容

先尝试下面指令,失败

cat initramfs.img | cpio -imd
再尝试使用 dracut 软件包中提供的 lsinitrd 工具可以查看 initramfs 中的内容,发现它需要用到一个 skipcpio 程序,跳过 initramfs 文件的头部后,再将剩下的部分当成压缩的 CPIO 文件进行解包。最后使用 sudo /usr/lib/dracut/skipcpio initramfs.img zcat cpio -imd 指令完成解压

都没用

试试用 drauct 增加文件的文件

  • 增加文件

    dracut --include cmdline-preset /etc/cmdline.d/mycmdline.conf initramfs-cmdline-pre.img
    

    将创建一个 initramfs 映像,其中 cmdline-preset 文件将在 initramfs 中复制到 /etc/cmdline.d/mycmdline.conf。include 只能指定一次。

  • 查看模块

    dracut --list-modules
    
  • 增加网络模块

    dracut --add <module> initramfs-module.img
    
  • 读取 initramfs 的内容,包括参数

    lsinitrd initrd.img | more
    

    发现它的参数为

    --nomdadmconf --nolvmconf --xz --install '/.buildstamp' --no-early-microcode --add 'fips' --add 'anaconda pollcdrom qemu qemu-net prefixdevname-tools' --force
    

解决 ramOS 下载断链问题

  1. 解压 initrd.img 镜像
  2. 修改下载流程
  3. 重新制作 initrd.img 镜像

解压 initrd.img 镜像

mkdir initrd
cd initrd
/usr/lib/dracut/skipcpio ../initrd.img.origin | xzcat 2> /dev/null | cpio -id --no-absolute-filenames --quiet > /dev/null 2>&1

修改 ramOS 的下载流程

修改 dracut 的 url-lib.sh 文件的 curl_fetch_url() 函数如下:

curl_fetch_url() {
    local url="$1" outloc="$2"
    echo "$url" > /proc/self/fd/0
    if [ -n "$outloc" ]; then
        curl $curl_args --output - -- "$url" > "$outloc" || return $?
    else
        local outdir="$(mkuniqdir /tmp curl_fetch_url)"
        # ( cd "$outdir"; curl $curl_args --remote-name "$url" || return $? )
        # 修改流程,当下载镜像失败后,自动重新下载
        ( 
            cd "$outdir"
            sroot_log=/tmp/sroot_download.log
            touch ${sroot_log}
            echo ">>> outdir: " $outdir >> ${sroot_log}
            img_name=$(basename "$url")
            echo "img_name" ${img_name} >> ${sroot_log}
            img_size_url=${url}.size
            echo "img_size_url" ${img_size_url} >> ${sroot_log}
            size_name=/tmp/$(basename ${img_size_url})
            echo "size_name" ${size_name} >> ${sroot_log}
            curl $curl_args ${img_size_url} -o ${size_name} || return $?
            echo curl $curl_args ${img_size_url} -o ${size_name}  >> ${sroot_log}

            count=1
            read img_size < ${size_name}
            echo "img_size" ${img_size} >> ${sroot_log}
            while ((count <= 20)); do
                curl $curl_args --remote-name "$url"
                echo curl $curl_args --remote-name "$url" >> ${sroot_log}
                down_size=$(ls -l ${img_name} | awk '{print $5}')
                echo "down_size:" ${down_size} >> ${sroot_log}
                if [[ ${img_size} == ${down_size} ]]; then
                    echo "size equel" >> ${sroot_log}
                    break
                eles
                    echo ">>>>>>>" img_size: ${img_size}, down_size: ${down_size}, img_name: ${img_name} >> ${sroot_log}
                    echo "count:" ${count} >> ${sroot_log}
                fi

                sleep 10 
                ((count++))
            done
            echo "while break, count:" ${count} >> ${sroot_log}
            if [[ $count == 20 ]]; then
                echo "error>>>, ? = $?" >> ${sroot_log}
                return $?
            fi
            echo "=== exec finish ===" >> ${sroot_log}
        )
        outloc="$outdir/$(ls -A $outdir)"
    fi
    if ! [ -f "$outloc" ]; then
	    warn "Downloading '$url' failed!"
	    return 253
    fi
    if [ -z "$2" ]; then echo "$outloc" ; fi
}

重新制作 initrd.img 镜像

# 在 initrd/ 目录中
find . 2>/dev/null | cpio -H newc -o -R root:root | xz -9 --check=crc32 > ../initrd.img

draut 流程

当引入新参数 ip=usb:dhcp 之后,出现 dracut-initqueue timeout - starting timeout scripts 的异常,之后进入 shell,但在 shell 中输入 exit 之后,还是可以继续跑 ramOS。所以需要看看是哪里出现了异常

dracut-initqueue

这段打印在 dracut-initqueue 文件中,"$hookdir 的内容是:

lib/dracut/hooks/
  • 我在 lib/dracut/hooks/cmdline/29-parse-livenet.sh 里找到 url-lib.sh
  • sbin/livenetroot 中也找到了 url-lib.sh它的说明是 livenetroot - fetch a live image from the network and run it
  • 但是从结果来看,是进入了 debug.shell,是有一个初始化失败了,exit 退出 shell 之后才继续加载 liveroot,这说明问题在前面

加电到执行main

开机到main的执行

  • 启动 BIOS,准备中断向量表和中断服务程序
    • 上电时RAM空,只能由BIOS加载OS
  • 从启动盘加载 OS 到内存,用到了中断服务程序
    • CPU 只能运行内存中的程序
  • 为执行 main 做过渡过程

BIOS 启动原理

  • CPU上电强行将 CS = 0xF000IP = 0xFFF0,所以 CS:IP = 0xFFFF0地址,它就是BIOS的地址。
  • BIOS 固化在计算机主板的上ROM中,BIOS执行会在屏幕上显示显卡信息、内存信息……
  • BIOS在内存中建立中断向量表和中断服务程序,在内存的 0x00000 ~ 0x003FF 构建中断向量表,在后面256字节内存空间构建 BIOS 数据区(0x00400 ~ 0x004FF),在后面57KB加载8KB的中断服务程序

    bios

加载第一段引导程序

  • BIOS 经过自检后,让 CPU 接收到 int 0x19 中断,这个中断程序就是加载硬盘0磁道1扇区内容得到到内存 0x7C00处,这个扇区也称启动扇区(bootsect)
    • 启动扇区中的代码,负责把 OS 搬到内存

加载第二部分内核代码

  • bootsect 引导程序已经载入内存,它首先规划内存
    • bootsect 会指定启动扇区被BIOS加载的位置(BOOTSEG)以及要搬到的新位置(INITSEG)
    • 内核加载的位置(SYSSEG),内核的末尾位置(ENDSEG)
  • bootsect 运行后
    • 首先把自己从BOOTSEG搬到INITSEG
    • 设置 SS(栈底) 和 SP(栈顶) 寄存器,它们是栈指针
    • 再跑到 INITSEG
    • 现在OS已经完全摆脱 BIOS,进入自己想要的位置了
  • 将setup程序加载到内存
    • 借助BIOS的 int 0x13 中断服务程序完成
    • init 0x19由BIOS执行,把第1扇区代码加载到 0x7C00 位置
    • init 0x13由linux OS 执行,根据设计者要求把扇区代码加载到内存指定位置

RHEL 启动流程

基本流程

步骤 硬盘启动 ramOS 启动
1 上电 BIOS 自检 上电 BIOS 自检
2 MBR 引导 PXE 引导
3 启动内核 启动内核
4 启动第一个进程 systemd 启动第一个进程 systemd

BIOS 开机自检

上电

  • 上电给 CPU 复位指令
  • CPU 给所有寄存器复位
  • 跳转到 BIOS 所在的 ROM 中
    • BIOS 是固化在主板ROM中的一段程序

BIOS

  • BIOS 读取 CMOS 数据,获取主机各硬件信息
    • COMS 是可读写的 RAM,保存了 BIOS 设置的硬件信息,开机密码
  • 自检硬件(Power-On Self Test)
    • 此阶段硬件信息出错蜂鸣器会报警
  • BIOS 对硬件初始化
  • 把自身复制到内存RAM中
  • BIOS 找可引导的存储设置
    • 对于磁盘启动
      • 读取磁盘需要文件系统,BIOS小程序没有这个功能
      • 不依赖于文件系统的方法是,让 BIOS 读取磁盘的 MBR 扇区
        • MBR 磁盘0扇区,512字节尾是 55AA 的扇区
        • MBR 中包含包含了最简单的 bootloader(BL1)
        • 把 BL1 加载到内存
    • 对于网络启动,通过网络下载 pxeboot(BL1)
      • 把 pxeboot 加载进内存执行

BL1

  • MBR 引导
    • MBR 结构

      MBR

      • MBR 中的 BL1 读取所在磁盘 OS 的内核
      • 446B 的BL1太小,完整功能在 OS 的内核(BL2)中
      • 16B x 4 是磁盘主分区表所在位置,每个分区表占16B
      • 2B 是 MBR 标志位
      • MBR 放在磁盘的 sec0
    • 磁盘分区

      disk

      • 分区的 sec0 放置 OS 的 BL2
      • Windows 会自动把自己的 BL2 复制到 MBR 导致先安装的 Linux 会找不到
    • BL1 过程

      • BL1 有 OS 选项表
      • 选择好后,BL1读取对应OS的BL2
      • 控制权交给 BL2
  • pxeboot 引导
    • 通过 BIOS 指定 pxe 启动
    • 从网卡的ROM中读取 BL1
    • BL1 通过 tftp从 服务器下载 pxeboot(grubx64.efi: BL2)

BL2

  • linux 的 BL2 是 stage1(grub) + stage2(内核) 的组合
  • stage1 用于从配置文件

debian live-build

What is a live system?

A live system usually means an operating system booted on a computer from a removable medium, such as a CD-ROM or USB stick, or from a network, ready to use without any installation on the usual drive(s), with auto-configuration done at run time (see Terms).

即时系统通常意味着从可移动介质(如 CD-ROM 或 USB 盘)或从网络启动的操作系统,可以在不安装任何驱动器的情况下使用,并在运行时自动配置(参见术语)。

Live system: An operating system that can boot without installation to a hard drive. Live systems do not alter local operating system(s) or file(s) already installed on the computer hard drive unless instructed to do so. Live systems are typically booted from media such as CDs, DVDs or USB sticks. Some may also boot over the network (via netboot images, see Building a netboot image), and over the Internet (via the boot parameter fetch=URL, see Webbooting).

实时系统:一种不需要安装就可以引导到硬盘驱动器的操作系统。除非有指示,活动系统不会更改已安装在计算机硬盘驱动器上的本地操作系统或文件。实时系统通常从cd、dvd或u盘等媒体启动。有些还可以通过网络引导(通过 netboot 映像,参见构建 netboot 映像),或者通过Internet引导(通过引导参数fetch=URL,参见Webbooting)。

live system 由以下部分组成:

  • Linux kernel image
    • usually named vmlinuz*
  • Initial RAM disk image (initrd)
    • 为 Linux boot 设置的 RAM 磁盘,包含可能需要挂载 System 映像的模块和一些脚本
  • System image
    • 操作系统的文件系统映像
    • 通常,使用 SquashFS 压缩文件系统来最小化活动系统映像的大小。注意,它是只读的
  • Bootloader
    • 一小段精心制作的 boot 代码,可能提供一个提示或菜单,允许选择选项/配置
    • 它加载 Linux 内核及其 initrd,以便与关联的系统文件系统一起运行

4.2 First steps: building an ISO hybrid image

作为第一个示例,创建一个 build 目录,切换到该目录,然后执行一系列 live-build 命令,以创建一个基本的 ISO 混合映像,其中包含一个缺省的 live 系统(不包含 X.org)。它适用于刻录到 CD 或 DVD 媒体上,也适用于复制到 U 盘上。

$ mkdir live-default && cd live-default

运行 ld config 命令,在工作目录中创建一个“config/”层次结构,供其他命令使用:

$ lb build

完成后,应该有一个实时图像 live-image-i386.hybrid.iso 镜像文件,可以在工作目录中使用。

4.3 Using an ISO hybrid live image

4.3.1 Burning an ISO image to a physical medium

# apt-get install xorriso
$ xorriso -as cdrecord -v dev=/dev/sr0 blank=as_needed live-image-i386.hybrid.iso

4.3.2 Copying an ISO hybrid image to a USB stick

$ cp live-image-i386.hybrid.iso ${USBSTICK}
$ sync

4.3.3 Using the space left on a USB stick

在复制了 live-image-i386.hybrid.iso 后,设备上的第一个分区将被 live 系统填满。要使用剩余的可用空间,请使用分区工具(例如分区或分区)在工具条上创建一个新的分区。

gparted ${USBSTICK}
mkfs.ext4 ${PARTITION}

4.3.4 Booting the live medium

在 BIOS 中设置,让它可以从 CD、PXE、USB等介质启动

4.6 Building a netboot image

  • 一个基本的 netboot 映像,其中包含一个不带 X.org 的默认活动系统。它适合于通过网络引导。
  • 清理您的工作目录

      lb clean
    
    • 在 netboot 设置中,需要使用不同的 initramfs 配置,live-build 在构建 netboot 映像时会自动执行该配置
    • 由于 initramfs 的创建属于 chroot 阶段,因此切换到现有构建目录中的 netboot 也意味着重新构建 chroot 阶段。因此,需要使用 lb clean (它也将删除 chroot 阶段)。
  • 运行命令配置映像进行网络引导

      $ lb config -b netboot --net-root-path "/srv/debian-live" --net-root-server "192.168.0.2"
    
    • netbooting 本身并不向客户机提供文件系统映像,因此必须通过 NFS 提供文件
    • 可以通过 --net-root-path--net-root-server 指定地址和服务器。这样在 boot 过程中,可以找到 NFS 服务器和 img 文件
  • 再使用构建命令

      $ lb build
    

在网络引导中,客户端运行一小段通常位于以太网卡 EPROM 上的软件。这个程序发送一个 DHCP 请求来获得一个 IP 地址和下一步要做什么的信息。通常,下一步是通过 TFTP 协议获得更高级别的引导加载程序。它可以是 pxelinux、 GRUB,甚至可以直接引导到像 Linux 这样的操作系统。

现在,我们必须在服务器上配置三个服务以启用 netbooting: DHCP 服务器、 TFTP 服务器和 NFS 服务器。

4.6.1 DHCP 服务器

  • DHCP 服务器确保向 netbooting 客户机系统提供 IP 地址,并公布 PXE 引导加载程序的位置
  • 下面是为 isc-dhcp-server 编写的配置文件

      # /etc/dhcp/dhcpd.conf - configuration file for isc-dhcp-server
    
      ddns-update-style none;
    
      option domain-name "example.org";
      option domain-name-servers ns1.example.org, ns2.example.org;
    
      default-lease-time 600;
      max-lease-time 7200;
    
      log-facility local7;
    
      subnet 192.168.0.0 netmask 255.255.255.0 {
          range 192.168.0.1 192.168.0.254;
          filename "pxelinux.0";
          next-server 192.168.0.2;
          option subnet-mask 255.255.255.0;
          option broadcast-address 192.168.0.255;
          option routers 192.168.0.1;
      }
    

4.6.2 TFTP 服务器

  • tftp 在运行时为系统提供内核和初始 ramdisk
  • 安装 tftpd-hpa 包,它可以把根目录中的所有文件包装在 tftpd 服务器中,通常是 /srv/tftp
    • 要让它为/srv/debian-live/tftpboot 中的文件提供服务,以 root 身份运行以下命令,并在被问及时填写新的 tftp 服务器目录

      $ dpkg-reconfigure -plow tftpd-hpa
      

      4.6.3 NFS 服务器

  • 一旦客户机下载并引导了 Linux 内核并加载了其 initrd,它将尝试通过 NFS 服务器挂载 Live 文件系统映像
  • 您需要安装 nfs-kernel-server 包
  • /etc/export 中添加以下代码行,使文件系统映像可以通过 NFS 使用

      /srv/debian-live *(ro,async,no_root_squash,no_subtree_check)
    
  • 并使用以下命令告诉 NFS 服务器这个新导出:

      $ exportfs -rv
    

4.7 Webbooting

  • Webbooting 是一种使用 Internet 作为手段检索和引导实时系统的方便方法
  • 一方面,您需要一个具有引导加载程序、初始内存磁盘和内核的媒介
  • 另一方面,Web 服务器存储包含文件系统的 squashfs 文件

4.7.1获取 webboot 文件

5. 工具概述

lb 工具手册

5.1 The live-build package

  • live-build 是构建 live 系统的一组脚本。这些脚本也被称为“命令”
  • 它使用一个配置目录来完全自动化和定制构建 Live 映像的所有方面
  • live-build 将其配置完全存储在 config/ 子目录下
  • 前面的 lb 是动态生成命令的通用包装器

5.1.1 The lb config command

  • 构成 live-build 的脚本使用 source 命令从名为 config/ 的单个目录读取它们的配置
  • 由于手工构造这个目录会非常耗时且容易出错,因此可以使用 lb config 命令创建初始的骨架配置树
  • 可以指定多个选项

      $ lb config --binary-images netboot --bootappend-live "boot=live components hostname=live-host username=live-user" ...
    
  • 选项可以在 lb_config 手册中查找到

5.1.2 lb build 命令

  • lb buildconfig/ 目录读入您的配置。然后它运行构建 Live 系统所需的较低级别命令
  • lb_build

5.1.3 lb clean

  • lb clean 命令的工作是删除构建的各个部分,以便后续的构建可以从干净状态开始
  • lb clean --binary 只影响二进制阶段
  • lb clean --purge 删除所有内容

5.2 The live-boot package

  • Live-boot 是为 initramfs-tools 提供钩子的脚本集合,用于生成能够引导 live 系统的 initramfs
    • 例如由live-helper(7)创建的系统
    • 这包括live系统 ISO、 netboot tarball 和 USB 盘映像
  • 在引导时
    • 它将查找包含存储根文件系统(通常是压缩文件系统映像,如 squashfs,是只读媒体)的 /live/ 目录
    • 如果找到,它将使用 aufs 创建一个可写环境,以便类似 Debian 的系统从中启动
  • 更多关于 Debian 中初始 ramfs 的信息可以在 Debian Linux 内核手册的 initramfs 章节

5.3 live-config 包

Live-config 由在 live-boot 之后启动时运行的脚本组成,用于自动配置 live 系统。它处理诸如设置主机名、地区和时区、创建活动用户、抑制 cron 作业和执行活动用户的自动登录等任务。

6. Managing a configuration

6.1处理配置更改

  • ld config 命令把你传递给它的参数以及默认参数都保存到 config/* 文件中
  • 再次运行 lb config 命令不会重新设置选项
    • 比如 lb config --binary-images 命令不会修改它依赖的其他选项

6.1.2 使用示例自动脚本

  • live-build 自带了用于复制和编辑的自动 shell 脚本示例

      $ mkdir mylive && cd mylive && lb config
      $ mkdir auto
      $ cp /usr/share/doc/live-build/examples/auto/* auto/
    
  • 编辑 auto/config, 根据需要添加任何选项

      #!/bin/sh
      lb config noauto \
          --architectures i386 \
          --linux-flavours 686-pae \
          --binary-images hdd \
          --mirror-bootstrap http://ftp.ch.debian.org/debian/ \
          --mirror-binary http://ftp.ch.debian.org/debian/ \
          "${@}"
    
  • 每次使用 lb config 时,auto/config 都会根据这些选项重置配置
  • 当您要对它们进行更改时,编辑此文件中的选项,而不是将它们传递给 lb config
  • noauto 参数抑制对 auto/config 的另一个调用,从而防止无限递归

6.2 克隆一个通过 Git 发布的配置

  • 使用 lb config --config 选项克隆一个包含 live 系统配置的 Git 存储库
  • 要构建一个标准映像,使用 live-images 存储库如下

      $ mkdir live-images && cd live-images
      $ lb config --config https://salsa.debian.org/live-team/live-images.git::debian
      $ cd images/standard
    
  • 然后编辑 auto/config
  • 可以在 ${HOME}/.gitconfig 中添加以下内容来定义 Git 配置中的快捷方式

      # ~/.gitconfig
      [url "https://salsa.debian.org/live-team/"]
              insteadOf = lso:
    
    • 使用时还可以删除 .git 后缀
  • lb config --config 变成

      $ lb config --config lso:live-images::debian
    
  • 注意使用超级用户执行 lb build

7. 定制

7.1 构建时间与启动时间配置

  • Live 系统配置选项分为构建时(build-time)选项(构建时应用的选项)和引导时(boot-time)选项(引导时应用的选项)
  • 引导时选项进一步划分为在引导早期出现的选项(由实时引导包 live-boot packages 应用)和在引导后期出现的选项(由实时配置 live-config 应用)
  • boot-time 的选项,用户可以在 boot 提示符下输入
  • lb config 手册描述了 build-time 的选项
  • lb config/boot 手册描述了 boot-time 的选项
  • 虽然 live-bootlive-config 安装在正构建的 live 系统中,但也建议把它们安装在 build 系统中,这样三分钟配置时方便引用

7.2 build 阶段

构建过程分成多个阶段

  • bootstrap boot 阶段
    • 初始阶段,用packages包填充 chroot 目录,以构建基本的 debian 系统
  • chroot 阶段
    • 完成 chroot 目录的构建
    • 用 configuration 中列出的所有包还有其他文件填充它(大多数定制化的内容都在这个阶段)
  • binary 二进制阶段
    • 构建一个 bootable 镜像
    • 用 chroot 目录的内容为 live 系统构建根文件系统
    • 还会包含其他安装程序、以及live文件系统之外的在目标媒体(medium)上的任何其他材料
  • source 阶段
    • 如果启用打包功能,在 live 镜像构建完成后,会在这个阶段构建 source tarball

7.3 用文件补充 lb config

  • lb configconfig/ 中创建了一个配置框架
  • 可能还要在 config/ 的子目录中给出其他文件
  • 根据文件在 configuration 中的位置,它会被复制到 live 的文件系统或者二进制镜像文件系统中
  • 或者人家我去系统的构建时build-time配置
  • 可以包含自定义包列表、自定义图稿或钩子脚本之类的东西,以便在构建时或引导时运行

7.4 自定义任务

  • 自定义包安装
  • 自定义内容
  • 自定义地区和语言

8. 自定义软件包安装

  • live 系统最基本的定制是选择要包含在镜像中的包

8.1 Package sources

8.1.1 Distribution, archive areas and mode

  • 分发、存档区域和模式
  • 存档中的任何当前发行版都可以在这里用代号(codename)指定
    • 该代号名对于 live-build 的 Buster 版本默认为 Buster
    • 发行版选项不仅影响归档文件中包的源,而且还指示 live-build 根据需要进行构建每个受支持的发行版

        $ lb config --distribution sid
      
      • 针对不稳定的版本 sid 进行构建
  • 在发行存档中(distribution archive),存档区是档案的主要分区(archive areas are major divisions of the archive)
    • 存档区是 main, contrib, non-free
    • 只有 main 存档区包含作为 Debian 发行版一部分的软件
    • 可以指定一个或多个

        $ lb config --archive-areas "main contrib non-free"
      
  • 一些 Debian 衍生产品可以通过 --mode 选项获得实验支持
    • 在 debian 中参数为 debian
    • 在衍生系统(ubuntu)中使用 lb config, 支持指定衍生版本的发行版名称和归档区域

8.1.2 Distribution mirrors

  • Debian 存档通过遍布世界各地的大型镜像网络进行复制
  • 每个 --mirror-* 选项控制在构建的不同阶段使用哪个分布镜像
    • bootstrap 阶段是由带有最小系统的 debootstrap 工具填充 chroot 目录的阶段
    • chroot 阶段是live文件系统chroot被构建的阶段
    • 在后面的二进制阶段中,使用 --mirror-binary--mirror-binary-security 取代前一阶段中使用的镜像

8.1.3 Distribution mirrors used at build time

  • 构建时指定使用的发行版镜像,只需按以下方式设置 --mirror-bootstrap--mirror-chroot-security

      $ lb config --mirror-bootstrap http://localhost/debian/ \
              --mirror-chroot-security http://localhost/debian-security/
    
  • chroot 镜像由 --mirror-chroot 指定,默认是 --mirror-bootstrap 的值

8.1.4 Distribution mirrors used at run time

  • 运行时使用的发行版镜像
  • --mirror-binary* 选项控制放置在二进制镜像中的发行版镜像
    • 用于在运行 live 系统时安装其他软件包
    • 默认是 deb.debian.org,它会自适应地理上相近的镜像

        $ lb config --mirror-binary http://mirror/debian/ \
          --mirror-binary-security http://mirror/debian-security/ \
          --mirror-binary-backports http://mirror/debian-backports/
      

8.1.5 Additional repositories

  • 可以加入自定义的软件仓库
  • 创建 config/archives/your-repository.list.chrootconfig/archives/your-repository.list.binary 系列文件,就像 --mirros-* 选项一样,它们控制着软件仓库的地址,在 chroot 阶段、binary 阶段
    • 比如:config/archives/live.list.chroot文件允许你在live系统构建时从 debian-live 快照存储库安装包
    • 在这个文件中写入

        deb http://debian-live.alioth.debian.org/ sid-snapshots main contrib non-free
      
    • 把代码写到 config/archives/live.list.binary 中,那么存储库将被添加到您的livev系统的/etc/apt/sources.list.d/目录中
  • 您还应该将用于签名存储库的 ASCII-armored GPG 密钥放入 config/archives/your-repository.key.{binary,chroot} 文件中

8.2 Choosing packages to install

选择 live-build 将安装在您的映像中的软件包

8.2.1 Package lists

  • 所有本地包列表都存储在 config/package-list/
  • .list.chroot_install 列表中的软件包同时存在于 live 系统和已安装系统中
  • 如果您没有指定 stage 后缀,那么这个列表将同时用于这两个 stage
  • 通常,您需要指定 .list.chroot 以便软件包只安装在 live 系统中而不会把 .deb 拷贝到媒体介质上

8.2.5 生成软件包列表

  • 任何以叹号开头的行都表示构建映像时要在 chroot 中执行的命令

      ! grep-aptavail -n -sPackage -FPriority standard | sort
    
  • 生成具有“优先级: 标准”的可用包的排序列表
  • 使用 grep-aptavail 命令(来自 dctrl-tools 包)选择包非常有用
  • live-build 提供了一个 Packages 帮助脚本封装了它,它有两个参数:fieldpattern

      $ lb config
      $ echo '! Packages Priority standard' > config/package-lists/standard.list.chroot    
    

8.2.6 Using conditionals inside package lists

  • 在包列表中使用条件句
  • 存储在 config/* 中的任何 live-build 配置变量(减去 LB_ 前缀)都可以在包列表中的条件语句中使用
    • 例如,如果指定了 --architecture amd64,则安装 ia32-libs:

        #if ARCHITECTURES amd64
      
        ia32-libs
      
        #endif
      

8.4.2 使用具有代理的 APT

  • 你可以通过 --apt-http-proxy 指定代理

      $ lb config --apt-http-proxy http://proxy/
    

8.4.4 Passing options to apt or aptitude

  • 如果没有 lb config 选项改变 apt 的行为
    • 可以用 --apt-options--aptitude-options 将选项传递到已经配置的apt工具,
    • 可以通过 apt 的手册查看细节

        $ lb config --apt-options "--yes -oAcquire::Check-Valid-Until=false"
      

9. 定制内容

live 系统的微调定制。包括允许在您的live系统映像添加或替换任意文件,钩子允许您执行任意命令在构建的不同阶段和启动时间,预种子允许当安装软件包时配置包,通过给 debconf 问题提供答案

9.1 Includes

  • 虽然在理想情况下,live 系统应该包含完全由未修改的包提供的文件,但是有时候通过文件提供或修改某些内容是很方便的,Live-build 提供了两种使用它们的机制:
    • Chroot local includes:
    • Binary local includes:
      • 这些允许您添加或替换二进制映像中的文件

9.1.1 Live/chroot local includes

  • Chroot local include 可用于添加或替换 Chroot/Live 文件系统中的文件,以便可以在 Live 系统中使用这些文件
  • 一个典型的用法是填充主干用户目录(/etc/skel)
  • 要包含文件,只需将它们添加到 config/include.chroot 目录
    • 此目录对应于 live 系统的根目录 /
    • 例如,要在活动系统中添加文件 /var/www/index.html,请使用:

        $ mkdir -p config/includes.chroot/var/www
        $ cp /path/to/my/index.html config/includes.chroot/var/www
      
  • 然后,您的配置将具有以下布局:

      -- config
          [...]
          |-- includes.chroot
              |-- var
                  |-- www
                      |-- index.html
          [...]
    
  • 在 package 安装完后,chroot local includes 才被安装,以便覆盖由包安装的文件

9.1.2 二进制本地包括

  • 要在媒体文件系统(medium filesystem)中包含文档或视频等内容,以便在插入媒体时可以立即访问,而无需启动 Live 系统,可以使用二进制本地包含
  • 假设文件 ~/video_demo.* 为 HTML 索引页所说明及连结的即时live系统的示范短片。只需将材料复制到 config/include.bin/

      $ cp ~/video_demo.* config/includes.binary/
    
    • 这些文件现在将出现在活动媒体(live medium)的根目录中

什么是媒体 媒体(medium)在计算机领域有两种含义: 指存储信息的实体,如磁盘、光盘、硬盘、磁带、半导体存储器等,中文常译为媒质; 指传递信息的载体,如数字、文字、声音、图形、图像和视频等,中文译作媒介,多媒体技术中的媒体是指后者。

9.2 Hooks

  • Hooks 允许在构建 chroot 和 binary 阶段运行命令,以便自定义映像
  • 根据您构建的是即时映像(live image)还是常规系统映像(regular system image),您必须将挂钩分别放置在 config/hooks/liveconfig/hooks/normal
  • 这些通常被称为本地钩子,因为它们是在构建环境中执行的
  • 还有一些启动时挂钩(boot-time hooks),允许在启动(boot)过程中运行命令

9.2.1 Chroot local hooks

  • 要在 chroot 阶段运行命令
    • 创建一个 .hook.chroot 后缀的脚本,放在 config/hooks/live 或者 config/hooks/normal 目录
    • 钩子将在应用完其余的 chroot 配置之后在 chroot 中运行
  • 请参见 /usr/share/doc/live-build/example/hook 中提供的针对各种常见 chroot 定制任务的 chroot 钩子脚本示例

9.2.2 Binary local hooks

  • 若要在二进制阶段中运行命令
    • 创建一个 .hook.binary 后缀的脚本,放在 config/hooks/live 或者 config/hooks/normal 目录
    • 钩子将在运行所有其他二进制命令之后运行

9.2.3 Boot-time hooks

  • 要在引导时执行命令,您可以提供 live-config 挂钩,如其手册页的“Customization”部分所述
  • live-config 自己的钩子在 /lib/live/config
  • 自己的钩子要有适当的序号,可以放在 config/includes.chroot/lib/live/config/,作为 chroot local includes

9.3 preseeding Debconf questions

  • .chroot.binary 阶段之后的 config/preseed/ 目录中以 .cfg 为后缀的文件,是 debconf preseed 文件
  • 由使用 debconf-set-selections 的 live-build 在相应的阶段安装

10. Customizing run time behaviours

  • 在运行期间完成的所有配置都由 live-config 完成

10.1 Customizing the live user

  • 活动用户(live user)是在引导时通过 live-boot 创建的,而不是在构建时由 live-build 创建
  • 你可以通配置 live-config 来指定活动用户将属于的其他组
    • 将活动用户添加到 fuse 组
    • 可以在 config/includes.chroot/etc/live/config.conf.d/10-user-setup.conf 中添加以下文件

        LIVE_USER_DEFAULT_GROUPS="audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth fuse"
      
    • 或者使用 live-config.user-default-groups=audio,cdrom,dip,floppy,video,plugdev,netdev,powerdev,scanner,bluetooth,fuse 作为 boot 参数
  • 还可以更改默认用户名“ user”和默认密码“ live”,
    • 修改用户名,在你的 config 中指定

        $ lb config --bootappend-live "boot=live components username=live-user"
      
    • 更改默认密码的一种方法是使用引导时钩子boot-time hooks中描述的钩子

      • 您可以使用 /usr/share/doc/live-config/example/hook 中的 passwd 挂钩,给它加上前缀 2000-passwd 加到 config/includes.chroot/lib/live/config/

10.2 定制地区和语言

  • 使用 locales 参数来定义地区

      $ lb config --bootappend-live "boot=live components locales=de_CH.UTF-8 keyboard-layouts=ch"
    

10.3 Persistence

  • live cd 模型是一个预安装(pre-installed)的系统,它从只读媒介(CD-ROM)运行
  • 即时系统(live system)是这种模式的一个泛化,所以除了 CD 之外还支持其他媒介
  • 它们掉电之后数据无法保存
  • “持久性”是不同类型解决方案的通用名称,这些解决方案可以通过重新引导系统的部分或全部运行时来保存
    • 对文件和目录的修改也是写在可写媒体上的
    • 通常是内存磁盘 ram disk(tmpfs),它掉电消失
    • 存储在这个 ramdisk 上的数据应该保存在可写的持久介质上
      • 如本地存储介质、网络共享,甚至是多会话(重写)可写 CD/DVD
    • 所有媒体都需要在引导时指定一个特殊的引导参数: persistence
  • 如果设置了 boot 参数 persistence (并且没有设置 nopersistence) ,那么在引导过程中将探测本地存储介质(例如硬盘、 USB 驱动器)的持久性卷
    • 通过指定 live-boot(7) 的 boot 参数可以限制使用哪些类型的持久性卷

11. Customizing the binary image

11.1 Bootloaders

  • Live-build 默认情况下使用 syslinux 及其一些衍生工具(取决于映像类型)作为引导加载程序 bootloader
  • 为了使用完整的主题,将 /usr/share/live/build/bootloaders 复制到 config/bootloaders 中并编辑其中的文件
  • 如果你不想修改所有支持的引导装载程序配置,只提供其中一个引导装载程序的本地自定义副本就足够了,比如 config/bootloader/solinux 中的 isolinux

  • 要修改默认的 iso-hybrid 镜像的 boot 超时时间,只需编辑一个默认的 isolinux.cfg 文件,指定以1/10秒为单位的超时

12. Customizing Debian Installer

12.1 Types of Debian Installer

  • “Live” Debian Installer
    • 这是一个带有独立内核和 initrd 的live系统映像
    • 它(从适当的引导加载程序 bootloader 中选择)启动到 Debian Installer 的一个实例中
    • 安装将以与上面描述的“正常”安装相同的方式进行
    • 但是在实际的包安装阶段
      • 不使用 debootstrap 来获取和安装包
      • 而是将活动的文件系统映像复制到目标
      • 这是通过一个名为 live-installer 的特殊 udeb 实现的
    • 在此阶段之后,Debian 安装程序继续正常运行,安装和配置项目,如引导加载程序和本地用户等

live-boot 系统引导组件

  • Live-boot 包含在引导过程(早期用户空间)中配置 live 系统的组件
  • Live-boot 是 initramfs-tools 的挂钩,用于生成能够引导 live 系统的 initramfs
    • 这些 live 系统包括 ISO、netboot tarballs、USB 镜像
  • 在 boot 引导阶段,它将寻找一个(只读)媒介,其中包含一个“/live”目录
    • 这个目录存储着根文件系统(通常是一个压缩的文件系统映像,如 squashfs)
    • 如果找到,它将使用 aufs 创建一个可写环境,从中引导系统

CONFIGURATION

  • Live-boot 可以通过boot引导参数或配置文件进行配置
  • 要在 live 镜像中配置默认使用的 live-boot 参数,查看 --bootappend-live 选项

内核参数

  • live-boot 只有在 boot=live 作为内核参数时才激活

配置文件

  • Live-boot 可以通过配置文件进行配置(但不激活)
  • 这些文件位置
    • 自身根文件系统的 /etc/live/boot.conf, /etc/live/boot/*
    • live 媒介的 live/boot.conf, live/boot/*
    • 这些live-boot的环境变量只能在配置文件中设置
  • 环境变量
    • DISABLE_CDROM=[true|false]
      • 禁用从cd-rom引导的支持。
      • 如果设置为’true’, mkinitramfs将构建一个没有内核模块的initramfs来读取cd-rom

选项

Live-boot当前具有以下参数

  • console=TTY,SPEED
    • 设置使用“live-getty”选项的默认控制台。示例: “console=ttyS0,115200”
  • debug=1
    • boot 过程的详细打印
  • fetch=URL
  • httpfs=URL
    • 另一种形式的 netboot,它从给定的URL下载一个 squashfs image
    • fetch方法将映像复制到RAM中,httpfs方法使用FUSE和httpfs2将映像挂载到适当的位置
    • 复制到RAM需要更多内存,而且对于大型 image 可能需要很长时间
    • 然而,它更有可能正确工作,因为它不需要网络之后,系统运行得更快,因为它不需要联系服务器了
    • 您也可以使用 live 的ISO映像来代替squashfs映像
  • ip=[DEVICE]:[CLIENT_IP]:[NETMASK]:[GATEWAY_IP]:[NAMESERVER] [,[DEVICE]:[CLIENT_IP]:[NETMASK]:[GATEWAY_IP]:[NAMESERVER]]
    • 让您指定应该在启动时配置的接口interface(s)的名称和选项
    • 如果您希望使用dhcp(默认),则不要指定此选项
    • ip=10.0.0.1::10.0.0.254:255.255.255.0::eth0,:::::eth1:dhcp
  • ip=[frommedia]
    • 如果设置了这个变量,dhcp 和静态配置将被跳过
    • 系统将使用(必须)media-preconfigured /etc/network/interfaces 来替代
  • {live-media bootfrom}=DEVICE
    • 如果您指定了这两种等效形式之一
    • live-boot 将首先尝试在这个设备中找到“/live”目录,只读根文件系统应该驻留在这个目录中
  • live-media-offset=BYTES
    • 通过这种方式,您可以告诉live-boot您的映像在上述指定的或自动发现的设备中的offset BYTES开始
    • 这可能有助于将live系统ISO或映像隐藏在另一个ISO或映像中,以创建“干净”映像
  • toram
    • 添加此参数后,实时引导将尝试在安装根文件系统之前将整个只读媒体复制到计算机的RAM中
    • 根据只读媒体所使用的空间,这可能需要大量ram

文件(old)

  • old
    • /etc/live.conf
      • 一些变量可以通过这个配置文件(在活动系统内)进行配置
    • live/filesystem.module
      • 这个可选文件(在实时媒体中)包含一个空白或回车分隔的文件名列表,这些文件名与“/live”目录中的磁盘映像相对应。如果该文件存在,则只有这里列出的图像将合并到根 aufs 中,并且它们将按照这里列出的顺序加载。这个文件中的第一个条目将是 aufs 中的“最低”点,而这个列表中的最后一个文件将位于 aufs 的“顶部”,正好在/overlay 的下面。如果没有这个文件,“/live”目录中的任何图像都将按字母数字顺序加载。
  • new
    • /etc/live/boot.conf
    • /etc/live/boot/*
    • live/boot.conf
    • live/boot/*
    • persistence.conf

live-build

Debian Live工具套件

live-build 是一组用于构建即时系统映像的脚本。即时构建背后的思想是一个工具套件,它使用配置目录来完全自动化和自定义构建实时映像的各个方面

常见的live-build选项

  • --color:打开消息颜色
  • --debug:显示 debug 消息
  • --force:强制执行命令,即使阶段文件已经存在
  • --quiet/verbose

We divide live-build into high level (“porcelain”) commands, secondary major build stage (“porcelain”) commands, and low level (“plumbing”) commands.

我们将实时构建分为高级(“瓷器”)命令,次要主要构建阶段(“瓷器”)命令和低级(“管道”)命令

高层命令

  • lb config
    • 为 live-bulid 创建配置文件
  • lb build
    • 执行构建过程,通过按顺序执行所有二级主要构建阶段
  • lb clean
    • 删除系统构建目录
  • lb
    • 通用的live构建脚本执行包装器

SECONDARY-LEVEL BUILD COMMANDS

  • 下面是按照必要的执行顺序执行构建过程的每个主要阶段的命令
  • 通常,用户可能只执行更高级别的lb build(1)命令,而不是单独使用这些命令
  • lb bootstrap
    • 执行第一个构建阶段,创建(引导bootstraping)一个基本Debian根文件系统
  • lb chroot
    • 执行第二个构建阶段,构建 live OS 文件系统
  • lb installer
    • 执行第三个构建阶段,获取安装程序组件(可选)
  • lb binary
    • 执行第四个构建阶段,生成二进制 binary (live) 映像
  • lb source
    • 执行第五个构建阶段,生成相应的源source image(可选)

配置文件

  • 许多live-build命令使用 config/ 目录中的文件来控制它们的工作
  • 除了所有live-build命令使用的公共 config/common 之外
  • 还可以使用一些其他文件来配置特定live-build命令的行为
  • 这些文件通常命名为 config/stage (其中“stage”当然被替换为它们所属的 stage 的名称)。
  • 对于环境变量优先级:高-低
    • 命令行
    • 配置文件
    • shell 上下文
    • live-build 各环境变量默认值
  • 在某些罕见的情况下,您可能希望为不同的体系结构或发行版本提供这些文件的不同版本
    • 如果存在名为 config/stage.archconfig/stage.dist 的文件
      • 其中“arch”与dpkg --print-architecture的输出相同
      • 而“dist”与目标发行版的代码名相同
    • 那么它们将优先于其他更一般的文件使用

文件

  • /etc/live/build.conf
  • /etc/live/build/*

live-config

  • live-config包含在引导过程(后期用户空间)期间配置live系统的组件
  • live-config 可以通过引导参数或配置文件进行配置
  • 如果两个机制都用于某个选项,引导参数优先于配置文件
  • 使用持久性时,实时配置组件只运行一次
  • 如果使用live-build(7)构建实时系统,则默认使用的实时配置参数可以通过--bootappend-live选项设置

boot 参数(组件)

  • 只有当boot=live用作引导参数时,live-config才被激活
  • 此外,live-config需要被告知通过live-config.components参数运行哪些组件
  • 或者通过’live-config.nocomponents’参数不运行哪些组件
  • 两者同时指定,后者为准

  • live-config.components | components
    • 运行所有组件,live images 默认
    • 可以参考 /lib/live/config

boot 参数(可选)

一些单独的组件可以根据boot引导参数改变它们的行为

启动参数(快捷方式)

对于一些需要组合几个单独参数的常见用例,live-build提供了快捷方式。这允许双方在所有选项上都有完整的粒度,并保持事情的简单性。

配置文件

Live-config可以通过配置文件配置(但不能激活)。除了可以配置引导参数的快捷方式之外,还可以通过一个或多个文件进行配置。如果使用配置文件,仍然需要’boot=live’参数来激活live-config。

注意:如果使用配置文件,(最好)所有引导参数都应该放在 LIVE_CONFIG_CMDLINE 变量中,或者可以设置单独的变量。如果使用单个变量,则要求用户确保设置了所有必要的变量以创建有效的配置。

配置文件可以放在根文件系统本身(/etc/live/config.conf, /etc/live/config.conf.d/*.conf),或者在live媒体上(live/config.conf, live/config.conf.d/*.conf).如果这两个位置都用于某个选项,那么来自实时媒体的位置优先于来自根文件系统的位置。

虽然放置在配置目录中的配置文件不需要特定的名称,但出于一致性考虑,建议使用’vendor.conf’或’project.conf’作为命名方案(而’vendor’或’project’将被实际名称取代,从而产生’progress-linux.conf’之类的文件名)。

配置文件的实际内容由以下一个或多个变量组成

定制化

Live-config可以很容易地为下游项目或本地使用定制

下游项目可以将它们的组件放入/lib/live/config 中,不需要做任何其他事情,在引导期间将自动调用这些组件

这些组件最好放在一个自己的 debian 包中。包含示例组件的示例包可以在 /usr/share/doc/live-config/example 中找到

文件

/etc/live/config.conf
/etc/live/config.conf.d/*.conf
live/config.conf
live/config.conf.d/*.conf
/lib/live/config.sh
/lib/live/config/
/var/lib/live/config/
/var/log/live/config.log
/live/config-hooks/*
live/config-hooks/*
/live/config-preseed/*
live/config-preseed/*