zoukankan      html  css  js  c++  java
  • [转]定制 Ubuntu 18.04 UEFI 启动盘初探(1)

    出自https://blog.csdn.net/tonyfield2015/article/details/97530637

    工作中需要制作定制化的Ubuntu启动盘,之前有用 buildroot 做过,但是在安装工具方面还是没有Ubuntu灵活方便,所以还是准备基于Ubuntu来制作。

      网上的文章大部分是基于Ubuntu 安装盘来制作,server版本约1GB大小,desktop版本约需要1.9GB。它有以下优点和缺点,即修改目标。

    优点:

    • 使用 squash 文件系统,和initramrd相比,不需要全部加载进内存,对内存需求较低
    • 有完整的启动脚本,很多改动需求只要修改这些脚本的配置参数就可以达成

    缺点:

    • 镜像太大无法满足频繁改动升级的需要
    • 不需要安装功能,考虑剪除
    • 不是所有应用都需要安装,考虑剪除
    • 需要为不同项目灵活更换配套驱动及工具,需要另行安装
    • 启动界面应按项目内容显示提示菜单

    首先研究 boot/grub/grub.cfg中的启动参数,其中 boot=casper 将影响 init脚本中的 BOOT参数值。

    menuentry "Try Ubuntu without installing" {
        set gfxpayload=keep
        linux    /casper/vmlinuz  file=/cdrom/preseed/ubuntu.seed boot=casper quiet splash ---
        initrd    /casper/initrd.lz

    然后研究 casper/initrd.lz,它负责加载squash文件系统。注意“. /scripts/${BOOT}”会提供“mountroot()”函数。

    . /scripts/local
    . /scripts/nfs
    . /scripts/${BOOT}
    parse_numeric ${ROOT}
    maybe_break mountroot
    mount_top
    mount_premount
    mountroot

     以下是“mountroot()”函数及其注释,看得出来,大部分casper启动功能都在这里完成。

    执行下面3个脚本,都可不予支持

        run_scripts /scripts/casper-premount
    10driver_updates
    只有带启动参数 debian-installer/driver-update=*
    才会真正执行(去找启动盘上的 /cdrom/ubuntu-drivers/$(uname -r)下的驱动更新)
     
    20iso_scan
    只有带启动参数 iso-scan/filename=* 才会真正执行
     
    30custom_installation
    只有带启动参数 debian-installer/custom-installation=* 才会真正执行
     
          if [ ! -z "${NETBOOT}" ]; then

    如果网络引导,可不予支持,不过支持这个功能调试比较方便

            if do_netmount ; then
                  livefs_root="${mountpoint}"
              else
                  panic "Unable to find a live file system on the network"
              fi
          else
    本地引导         # Scan local devices for the image
              i=0

    尝试60次,每次间隔1秒

            while [ "$i" -lt 60 ]; do
     》参考 find_livefs 的实现《             livefs_root=$(find_livefs $i)
    搜索启动盘,优先搜启动参数live-media=*指定的设备,
    如果没有指定或没能搜到,会在合适时机遍历所有设备搜索
                if [ "${livefs_root}" ]; then
    其中 /bin/fstype 查看磁盘文件格式的功能不错,值得注意                 break
                  fi
                  sleep 1
                  i="$(($i + 1))"
              done
          fi
       
          if [ -z "${livefs_root}" ]; then
              panic "Unable to find a medium containing a live file system"
          fi
       
    如果启动参数指定 toram     if [ "${TORAM}" ]; then
      则将文件系统加载在内存         live_dest="ram"
    如果启动参数指定 todisk=*     elif [ "${TODISK}" ]; then
      则将文件系统加载在磁盘         live_dest="${TODISK}"
          fi
          if [ "${live_dest}" ]; then
              log_begin_msg "Copying live_media to ${live_dest}"
     》参考 copy_live_to 的实现《         copy_live_to "${livefs_root}" "${live_dest}"
              log_end_msg
          fi
       
    挂载镜像到目录,会调用setup_unionfs()
     会从/cdrom/casper/下匹配 "ext2" "squashfs" "dir" 后缀的文件或文件夹,并挂载
        mount_images_in_directory "${livefs_root}" "${rootmnt}"
       
          # initialize the /var/crash directory in overlayfs so that inotify for
    crash处理机制,并不理解实际工作机制。     # /var/crash works and update-notifier will notify of crashes
          touch /root/var/crash/crash.init
          rm /root/var/crash/crash.init
       
          log_end_msg
       
          # Allow to override USERNAME and HOST based on media information
    从initrd的/etc/casper.conf提取到FLAVOUR变量     # make it skipable by setting FLAVOUR= in casper.conf
    如果FLAVOUR为空,从启动盘的/.disk/info提取     if [ -f /cdrom/.disk/info ] && [ -z "$FLAVOUR" ]; then
    它将影响 HOST,USERNAME,USERFULLNAME,BUILD_SYSTEM         FLAVOUR="$(cut -d' ' -f1 "/cdrom/.disk/info" 2>/dev/null | tr '[A-Z]' '[a-z]')" || FLAVOUR=
    /etc/casper.conf里的值是         if [ -n "$FLAVOUR" ]; then
    export USERNAME="ubuntu"             HOST=$FLAVOUR
    export USERFULLNAME="Live session user"             USERNAME=$FLAVOUR
    export HOST="ubuntu"             export HOST USERNAME
    export BUILD_SYSTEM="Ubuntu"             sed -i "s,USERNAME=.*,USERNAME="$FLAVOUR",g; s,HOST=.*,HOST="$FLAVOUR",g" /etc/casper.conf
              fi
          fi
       
          # Apply command lines override of HOST, USERNAME and USERFULLNAME
    如果命令行有传参设置,
    则优先使用其设置 HOST,USERNAME,USERFULLNAME
        [ -n "$CMD_HOST" ] && HOST=$CMD_HOST && export HOST
          [ -n "$CMD_USERNAME" ] && USERNAME=$CMD_USERNAME && export USERNAME
          [ -n "$CMD_USERFULLNAME" ] && USERFULLNAME=$CMD_USERFULLNAME && export USERFULLNAME
          if [ -n "$CMD_HOST" ] || [ -n "$CMD_USERNAME" ] || [ -n "$CMD_USERFULLNAME" ]; then
              sed -i "s,USERNAME=.*,USERNAME="$USERNAME",g; s,USERFULLNAME=.*,USERFULLNAME="$USERFULLNAME",g; s,HOST=.*,HOST="$HOST",g" /etc/casper.conf
          fi
       
          # unionfs-fuse needs /dev to be bind-mounted for the duration of
          # casper-bottom; udev's init script will take care of things after that
    如果是unionfs-fuse文件系统,     if [ "${UNIONFS}" = unionfs-fuse ]; then
    用“mount -n -o bind ...”挂载/dev设备目录         mount -n -o bind /dev "${rootmnt}/dev"
          fi
       
          # Open up two fifo's fd's for debconf-communicate to use. Speeds up
          # the Casper process considerably.
          log_begin_msg "Creating debconf-communicate fifo mechanism"
    用 fifo 加速casper过程     mkfifo /tmp/debconf-in.fifo
    结束前这些fifo会被释放删除     mkfifo /tmp/debconf-out.fifo
       
          # Make the template database read-only, so that passthrough debconf
          # instances can write to it directly; otherwise templates are only
          # passed through when necessary.  Use temporary config databases as
          # well; we'll copy their contents back at the end.
          DEBCONF_TMPDIR="$(chroot /root mktemp -dt debconf.XXXXXX)"
          cp -a /root/var/cache/debconf/config.dat "/root$DEBCONF_TMPDIR/"
          cp -a /root/var/cache/debconf/passwords.dat "/root$DEBCONF_TMPDIR/"
          sed "s,^Filename: /var/cache/debconf/configpasswords
    .dat$,Filename: $DEBCONF_TMPDIR/1.dat,; /^Name: templatedb/a
      Readonly: true" /root/etc/debconf.conf >"/root$DEBCONF_TMPDIR/debconf.conf"
       
          DEBCONF_SYSTEMRC="$DEBCONF_TMPDIR/debconf.conf" chroot /root debconf-communicate -fnoninteractive casper > /tmp/debconf-out.fifo < /tmp/debconf-in.fifo &
          debconfpid="$!"
       
          if [ ! -p /tmp/debconf-in.fifo ] || [ ! -p /tmp/debconf-out.fifo ]; then
              log_warning_msg "failed to setup debconf-communicate channel"
          fi
          log_end_msg
       
          # Order matters!
          # These file descriptors must stay open until we're finished with
          # debconf-communicate.
          exec 4</tmp/debconf-out.fifo 3>/tmp/debconf-in.fifo
       
          maybe_break casper-bottom
          [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-bottom"
       
    》参考对应脚本《     run_scripts /scripts/casper-bottom
          [ "$quiet" != "y" ] && log_end_msg
       
          if [ "${UNIONFS}" = unionfs-fuse ]; then
              umount "${rootmnt}/dev"
          fi
       
          # Close the fd's associated with debconf-communicate.
          exec 3>&- 4<&-
          rm -f /tmp/debconf-in.fifo
          rm -f /tmp/debconf-out.fifo
          wait $debconfpid
       
          # Copy config database changes back to the master files.
          chroot /root debconf-copydb tmpdb config
              --config=Name:tmpdb --config=Driver:File
              --config="Filename:$DEBCONF_TMPDIR/config.dat"
          chroot /root debconf-copydb tmpdb passwords
              --config=Name:tmpdb --config=Driver:File
              --config="Filename:$DEBCONF_TMPDIR/passwords.dat"
          rm -rf "$DEBCONF_TMPDIR"
       
          exec 1>&6 6>&-
          exec 2>&7 7>&-
          kill "$tailpid"
          cp casper.log "${rootmnt}/var/log/"
          if [ -f /etc/casper.conf ]; then
              cp /etc/casper.conf "${rootmnt}/etc/"
          fi

    要修改 casper/initrd.lz, 先了解怎么解压和重新打包

    # 解压 initrd.lz

    mkdir initrd-dir
    cd initrd-dir
    cp  ../initrd.lz initrd.lzma
    unlzma -d initrd.lzma
    cpio -id < initrd
    rm  initrd

    # 重新打包为 initrd2.lz
    cd initrd-dir
    find . | cpio --quiet --dereference -o -H newc > ../initrd2
    cd ..
    lzma -7 initrd2
    mv initrd2.lzma  initrd2.lz

    这样我们可以做一些改动,比如升级busybox。

    /scripts/casper会解析启动参数 live-media-path,我们可以通过指定该值来改变 squashfs文件的搜索路径$LIVE_MEDIA_PATH。

                live-media-path=*)
                    LIVE_MEDIA_PATH="${x#live-media-path=}"
                    export LIVE_MEDIA_PATH
                    echo "export LIVE_MEDIA_PATH="$LIVE_MEDIA_PATH"" >> /etc/casper.conf ;;

    下一节尝试 用cubic 工具定制启动盘,因为使用这个工具可以将注意力集中在配置软件上。

  • 相关阅读:
    CSS优化压缩
    CSS clear both清除浮动总结
    jQuery下拉列表二级联动插件
    网站靠什么赚钱?
    程序员到高级程序员的职业生涯
    ie数组不支持indexOf 方法解决
    jquery中的each方法,$.each this.each $.fn.each
    css3写出0.5px的边框
    js 自己创建ready多个可以依次加载
    javascript中的removeEventListener失效问题
  • 原文地址:https://www.cnblogs.com/libra13179/p/13902586.html
Copyright © 2011-2022 走看看