在Grub 2.02源代码中找到倒数计时器

时间:2018-07-14 17:39:46

标签: c assembly grub

将Grub的超时更改为1/10秒或1/100秒间隔

在具有AMD64架构的UEFI系统上使用Grub 2.02。我想将grub的超时计数器从1秒间隔更改为1/10秒或1/100秒间隔。原因是使gfxmenu循环进度倒数减少“波动”。下面的启动GIF在循环1秒的“块”中显示了5秒的倒计时:

Grub Boot

成功更改并重新编译源代码后,/etc/default/grub的更改如下:

  • 如果间隔为1/10秒,则GRUB_TIMEOUT=25将为2.5秒倒计时。
  • 如果间隔为1/100秒,则GRUB_TIMEOUT=250的倒数时间为2.5秒。

Grub 2.02来源是1/2百万行

我已经按照以下说明下载了源代码:how to build grub2 bootloader from it's source and test it with qemu emulator,并花了一些时间浏览源文件。但是,有477k行要搜索:

~/src/grub-2.02$ wc -l **/*

      20 asm-tests/arm.S
      18 asm-tests/i386-pc.S
       4 asm-tests/i386.S
      11 asm-tests/mips.S
       8 asm-tests/powerpc.S
            (... SNIP ...)
     115 util/spkmodem-recv.c
  477316 total

我已经在询问Ubuntu 中完成了许多bash项目,但这将是我的第一个C / Assembler Linux项目。作为“新手”,我的想法是:

  • 哪个文件包含倒数计时器源代码?
  • 如何将间隔更改为1/10秒或1/100秒?
  • 将源代码放在我的主目录下是一种常规方法吗?
  • 有关在Virtualbox中进行编译和测试的任何提示都会有所帮助。

请注意仅第一个问题相关。其他问题是作者选择更详细的答案。

2 个答案:

答案 0 :(得分:7)

变量GRUB_TIMEOUTutil/grub.d/00_header.in中求值。

if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
    cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_STYLE_BUTTON}"
echo else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
echo fi
else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
fi

请注意,这是一个生成脚本的脚本,这就是为什么它看起来很奇怪的原因。 make_timeout看起来像这样(同上):

make_timeout ()
{
    if [ "x${3}" != "x" ] ; then
        timeout="${2}"
        style="${3}"
    elif [ "x${1}" != "x" ] && [ "x${1}" != "x0" ] ; then
        # Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
        timeout="${1}"
        if [ "x${2}" != "x0" ] ; then
            grub_warn "$(gettext "Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.")"
        fi
        if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
            style="hidden"
            verbose=
        else
            style="countdown"
            verbose=" --verbose"
        fi
    else
        # No hidden timeout, so treat as GRUB_TIMEOUT_STYLE=menu
        timeout="${2}"
        style="menu"
    fi
    cat << EOF
if [ x\$feature_timeout_style = xy ] ; then
  set timeout_style=${style}
  set timeout=${timeout}
EOF
    if [ "x${style}" = "xmenu" ] ; then
        cat << EOF
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=${timeout}
EOF
    else
        cat << EOF
# Fallback hidden-timeout code in case the timeout_style feature is
# unavailable.
elif sleep${verbose} --interruptible ${timeout} ; then
  set timeout=0
EOF
    fi
    cat << EOF
fi
EOF
}

如您所见,它只调用sleep,并在结尾加上一些选项。此命令在grub-core/commands/sleep.c中定义。尽管sleep命令只能以整秒的增量进入睡眠状态,但基础功能grub_millisleep可以做得更好。

通过将所有grub_millisleep(1000)调用更改为grub_millisleep(100)来修补此功能应该很容易,但是请记住,这会中断sleep的所有使用。一个更干净的选项是向sleep添加一个新选项,以便可以根据具体情况选择行为。

答案 1 :(得分:2)

借助已接受的答案,我能够使用其他方法来实现目标。成功更改和重新编译Grub 2.02源代码后,/etc/default/grub的{​​{1}}倒计时了3.5秒。

请注意,现在在没有“块”的情况下,循环进度如何顺利:

New Grub Boot


要更改的代码:

GRUB_TIMEOUT=35

546行:

/grub-2.02/grub-core/normal/menu.c

更改行:

/* Check whether a second has elapsed since the last tick.  If so, adjust
   the timer and return 1; otherwise, return 0.  */
static int
has_second_elapsed (grub_uint64_t *saved_time)
{
  grub_uint64_t current_time;

  current_time = grub_get_time_ms ();
  /* July 14, 2018 Use deciseconds - change 1000 to 100 */
  if (current_time - *saved_time >= 100)
    {
      *saved_time = current_time;
      return 1;
    }
  else
    return 0;
}

收件人:

if (current_time - *saved_time >= 1000)

Voila!更改一行代码。加上两个注释行,以达到良好的效果。

如何编译if (current_time - *saved_time >= 100)

在遵循有关Grub的website的说明之前:

grub 2.02

然后按照grub的网站说明进行操作:

sudo apt install bison
sudo apt install flex

在Grub网站上运行下一个命令:

cd grub-2.02
./configure

将在make install 目录中创建文件,并与/usr/local/bin目录一起创建。


编译grub的其他问题

我最终将源克隆到VM(Lubuntu 16.04)并在那里重新编译。使用新编译的.../grub-2.02进行了处理,我不得不使用grub-install进行全新安装。然后将新编译的文件手动复制到sudo apt install grub2

我的接线盒歪斜了,所以我必须创建一个新的grub背景图像。在下图中,我将/boot/grub/i386-pc的倒计时更改为3.5秒。


2018年7月16日更新

想出一个参数来获得X86和EFI支持:

GRUB_TIMEOUT=35

但是,在./configure –with-platform=efi ******************************************************* GRUB2 will be compiled with following components: Platform: x86_64-efi With devmapper support: No (need libdevmapper header) With memory debugging: No With disk cache statistics: No With boot time statistics: No efiemu runtime: No (not available on efi) grub-mkfont: No (need freetype2 library) grub-mount: No (need FUSE library) starfield theme: No (No build-time grub-mkfont) With libzfs support: No (need zfs library) Build-time grub-mkfont: No (need freetype2 library) Without unifont (no build-time grub-mkfont) Without liblzma (no support for XZ-compressed mips images) (need lzma library) ******************************************************* 之后出现错误:

make install

我向Grub员工提交了错误报告(2018年7月),但没有听到任何回音。 EFI系统的下一步是使用Ubuntu的存储库而不是Grub的网站说明以全新安装方式下载源代码。