c - 在 Grub 2.02 源代码中查找倒数计时器

标签 c assembly grub

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

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

Grub Boot

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

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

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

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

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

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

最佳答案

变量 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 添加一个新选项,以便可以根据具体情况选择行为。

关于c - 在 Grub 2.02 源代码中查找倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51341871/

相关文章:

c - 64 位计算机如何更改内存中的一个字节?

framebuffer - grub2、grub-mkrescue、BIOS、vbe 帧缓冲区、自定义内核

c - 如何防止一个进程产生更多的 child

c - 等待输入时打印时间

c - 从一个线程切换到另一个出现段错误

c - 汇编到 C 翻译 : Order of Local variables?

linux - 如何在没有x服务器的情况下添加GRUB选项以进行加载

C 宏构建函数

c - 替换 Vim 中的项目而不替换旧的替换项目