Discussion:
Questions about grub_video_set_mode()
(too old to reply)
Dexuan Cui
2018-08-08 00:23:42 UTC
Permalink
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
Paul Menzel
2018-08-09 07:29:55 UTC
Permalink
Dear Dexuan,
Post by Dexuan Cui
I'm debugging a strange grub2 issue in a Linux Virtual Machine
running on Hyper-V.
[
]
Post by Dexuan Cui
4. What's the best way to debug grub_video_set_mode()?
grub_dprintf() can't output anything in this function.
Why? Because the display is not working?
Post by Dexuan Cui
Does grub support remote debugging via network?
I know gdb can debug grub in Qemu, but here the issue looks like Hyper-V specific.
If Hyper-V can emulate a serial port, then this should be one way to
go. Something like below for `/etc/default/grub`.

GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"


Thanks,

Paul
Dexuan Cui
2018-08-11 01:14:19 UTC
Permalink
Sent: Thursday, August 9, 2018 12:30 AM
...
Post by Dexuan Cui
4. What's the best way to debug grub_video_set_mode()?
grub_dprintf() can't output anything in this function.
Why? Because the display is not working?
Hi Paul,
Actually it works -- it looks somehow I was careless... I'm sorry!
Post by Dexuan Cui
Does grub support remote debugging via network?
I know gdb can debug grub in Qemu, but here the issue looks like Hyper-V specific.
If Hyper-V can emulate a serial port, then this should be one way to
go. Something like below for `/etc/default/grub`.
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"
This serial port works very well for me. Thanks for sharing the trick!
Paul
About my original questions, it looks grub is doing right here: sometimes
the VM can have "linux_gfx_mode=text", and if this happens, it looks correct
for grub to set grub_video_adapter_active to NULL.

However, I believe the line
grub_memset (&mode_info, 0, sizeof (mode_info));
is unnecessary, and the commnt before the line
grub_video_adapter_active = NULL;
may seem incorrect. Of course, this is harmless.

Thanks,
-- Dexuan

Continue reading on narkive:
Loading...