grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Questions about grub_video_set_mode()


From: Dexuan Cui
Subject: Questions about grub_video_set_mode()
Date: Wed, 8 Aug 2018 00:23:42 +0000

Hi,
I'm debugging a strange grub2 issue in a Linux Virtual Machine running on 
Hyper-V.

I have used the latest grub code from https://git.savannah.gnu.org/git/grub.git:

commit c79ebcd18cf3e208e9dda5e2ae008f76c92fe451
Date:   Mon Jul 9 19:49:06 2018 +0100
i386: Don't include lib/i386/reset.c in EFI builds

and I can still reproduce the issue.

The issue is that: sometimes, after I reboot the VM, params->lfb_base is
assigned with zero in grub_linux_setup_video(). The issue can't reproduce
when I boot the VM from Powered Off state.

After spending quite some time, I managed to track the issue down to the below 
error:

grub_linux_boot() -> grub_video_set_mode (tmp, 0, 0) -> return GRUB_ERR_NONE;

Please see the end of the mail for the code snippet.

1. When we enter grub_video_set_mode(), grub_video_adapter_active is NOT NULL 
(it
points to grub_video_vbe_adapter), so grub_video_adapter_active->fini () is 
called and
we reset grub_video_adapter_active to 0 (i.e. NULL);

2. Since 'modemask' is 0, we return GRUB_ERR_NONE after resetting
grub_video_adapter_active to NULL again;

3. In grub_linux_setup_video(), grub_video_get_driver_id() returns
GRUB_VIDEO_DRIVER_NONE, and grub_linux_setup_video() returns immediately, so
params->lfb_base remains with the defaule zero value!

Questions:
1. What's the point of "grub_memset (&mode_info, 0, sizeof (mode_info))" here?
It's a local variable and nobody really uses it.

2. After the comment:
  /* Valid mode found from adapter, and it has been activated.
                 Specify it as active adapter.  */
  why do we reset the 'grub_video_adapter_active' to NULL?
  It sounds wrong to reset it to NULL while we "specify it as active adapter".

3. When we enter grub_video_set_mode(), grub_video_adapter_active is NOT
NULL -- how is this possible?
I think grub_video_adapter_active is set to a non-zero value only in a later 
place
in grub_video_set_mode():
   grub_video_adapter_active = p;

Maybe grub_video_set_mode() has been called once, before I check the function?

I assume the grub loader's execution environment doesn't exist any more, after 
grub
hands over the exectuion to Linux kernel, and after Linux VM reboots, the BIOS 
starts
to run first, and then hands over the execution to grub, and grub will 
re-initialize its
exectuion environment from scratch.

Note: here EFI is not involved at all. This is a Linux booting from MBR.

4. What's the best way to debug grub_video_set_mode()?
  grub_dprintf() can't output anything in this function.
  Does grub support remote debugging via network?
  I know gdb can debug grub in Qemu, but here the issue looks like Hyper-V 
specific.

Looking forward to your help! Thanks in advance!!!

grub-core/video/video.c:
grub_video_set_mode (const char *modestring,
                     unsigned int modemask,
                     unsigned int modevalue)
{

  ......

  /* De-activate last set video adapter.  */
  if (grub_video_adapter_active)
    {
      /* Finalize adapter.  */
      grub_video_adapter_active->fini ();
      if (grub_errno != GRUB_ERR_NONE)
        grub_errno = GRUB_ERR_NONE;

      /* Mark active adapter as not set.  */
      grub_video_adapter_active = 0;
    }

  /* Loop until all modes has been tested out.  */
  while (next_mode != NULL)
    {
      ......

      /* XXX: we assume that we're in pure text mode if
         no video mode is initialized. Is it always true? */
      if (grub_strcmp (current_mode, "text") == 0)
        {
          struct grub_video_mode_info mode_info;

          grub_memset (&mode_info, 0, sizeof (mode_info));
          if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) == 0)
              || ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) != 0))
            {
              /* Valid mode found from adapter, and it has been activated.
                 Specify it as active adapter.  */
              grub_video_adapter_active = NULL;

              /* Free memory.  */
              grub_free (modevar);

              return GRUB_ERR_NONE;
            }
        }

      ......
    }

    ......
}

Thanks,
-- Dexuan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]