Bug 15329 - Newer kernels make a mess on screen when booting (on x86)
Summary: Newer kernels make a mess on screen when booting (on x86)
Status: RESOLVED CODE_FIX
Alias: None
Product: Platform Specific/Hardware
Classification: Unclassified
Component: i386 (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: H. Peter Anvin
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-16 20:34 UTC by Wim Osterholt
Modified: 2010-02-18 02:40 UTC (History)
1 user (show)

See Also:
Kernel Version: 2.6.31
Subsystem:
Regression: No
Bisected commit-id:


Attachments
Test patch (530 bytes, patch)
2010-02-17 03:45 UTC, H. Peter Anvin
Details | Diff

Description Wim Osterholt 2010-02-16 20:34:37 UTC
Newer kernels make a mess on screen when booting (on x86).

Old behaviour is up to and including kernel 2.6.30-gentoo-r8.
New behaviour is from kernel 2.6.31-gentoo-r6 onward, up to
the latest 2.6.33-rc8.

The uglyfication happens after printing some six lines (from grub).
The cursor jumps up to the SECOND line from the top and starts
overwriting that text with 'Decompressing linux' and the rest.

You cannot read the grub text because the screen got cleared by a
needless 'set video mode'. After that, the screens contents got restored
but immediately overwritten by new text. The new text has no clean
background, so the resulting mess is hardly readable either.
And it happens all very fast.


The Decompressing linux comes from  putstr("\nDecompressing Linux... ")
and that preceding newline makes it appear on the second line.
It appears that the 'get cursor position' call reports a zero instead
of the actual cursor position.

It appears that there hase been a code change in kernel 2.6.31-r6 in
arch/x86/boot/video.c  to get rid of some inline assembler.
The new intcall() seems erroneous in:
static void store_cursor_position(void)
{
        struct biosregs ireg, oreg;

        initregs(&ireg);
        ireg.ah = 0x03;
        intcall(0x10, &ireg, &oreg);

        boot_params.screen_info.orig_x = oreg.dl;
        boot_params.screen_info.orig_y = oreg.dh;

the vertical cursor position here in oreg.dh should not be zero!

If such a simple new function happens to fail here, god knows what goes wrong
in the rest of the kernel!  So it might even be serious!

Next, I fail to see why there should be 'set video mode' to the same mode
we're already in (VIDEO_CURRENT_MODE). It only invokes a needless flicker
and introduces the need to save and restore the cursor position that is in
error now.

Regards,
Wim Osterholt
Comment 1 H. Peter Anvin 2010-02-17 01:32:50 UTC
On 02/16/2010 12:34 PM, bugzilla-daemon@bugzilla.kernel.org wrote:
> It appears that there hase been a code change in kernel 2.6.31-r6 in
> arch/x86/boot/video.c  to get rid of some inline assembler.
> The new intcall() seems erroneous in:
> static void store_cursor_position(void)

I just verified: this is a direct conversion of the old code.

> If such a simple new function happens to fail here, god knows what goes wrong
> in the rest of the kernel!  So it might even be serious!

I suggest taking some Valium.  This is hardly a major emergency.

> Next, I fail to see why there should be 'set video mode' to the same mode
> we're already in (VIDEO_CURRENT_MODE). It only invokes a needless flicker
> and introduces the need to save and restore the cursor position that is in
> error now.

Pass vga=0x0f04 on the kernel command line (some bootloaders support
"vga=current") if that is what you want.

It's a bit hard to figure out what you're seeing (and you seem to be
rather unique in seeing it.)  One possiblity is that your BIOS or boot
loader leaves you on a video page other than video page 0, but the
kernel has *never* tried to handle non-zero video pages during early boot.

	-hpa
Comment 2 Wim Osterholt 2010-02-17 02:39:14 UTC
> 
> --- Comment #1 from H. Peter Anvin <hpa@zytor.com>  2010-02-17 01:32:50 ---
> On 02/16/2010 12:34 PM, bugzilla-daemon@bugzilla.kernel.org wrote:
> > It appears that there hase been a code change in kernel 2.6.31-r6 in
> > arch/x86/boot/video.c  to get rid of some inline assembler.
> > The new intcall() seems erroneous in:
> > static void store_cursor_position(void)
> 
> I just verified: this is a direct conversion of the old code.

But now it doesn't work as well.

> 
> > If such a simple new function happens to fail here, god knows what goes
> wrong
> > in the rest of the kernel!  So it might even be serious!
> 
> I suggest taking some Valium.  This is hardly a major emergency.
> 
> > Next, I fail to see why there should be 'set video mode' to the same mode
> > we're already in (VIDEO_CURRENT_MODE). It only invokes a needless flicker
> > and introduces the need to save and restore the cursor position that is in
> > error now.
> 
> Pass vga=0x0f04 on the kernel command line (some bootloaders support
> "vga=current") if that is what you want.

No, that's not what I want. I don't want to set a video mode, not even the
current. I want it just to continue. That can best be done with vga=ask and
wait the timeout. Then it does NOT tamper with the screen. For conveniene I
would then lower the timeout from 30 to 3 seconds.
My first solution was to add 8 to DH to leave skip over the grub text.
That proved that the set_cursor_position function works fine.
The get_cursor_position function does not.

> It's a bit hard to figure out what you're seeing (and you seem to be
> rather unique in seeing it.)  One possiblity is that your BIOS or boot
> loader leaves you on a video page other than video page 0, but the
> kernel has *never* tried to handle non-zero video pages during early boot.

It's not my BIOS. It happens on _any_ of the different machines around here.
(Some five unrelated machines at least)
Just boot a 2.6.31+ kernel and a 2.6.30- kernel and watch the difference.
You need a monitor that is fast enough to produce image in that early boot
stage. Many modern monitors may need too much time to get in sync before it
produces anything visual. (Some older monitors never even mute.)

What I'm seeing can't be that hard to imagine. 'Decompressing linux' gets
written on the second line while it should under the present text.
I can't rephrase that any clearer I'm afraid.

Wim.
Comment 3 H. Peter Anvin 2010-02-17 02:49:36 UTC
On 02/16/2010 06:39 PM, bugzilla-daemon@bugzilla.kernel.org wrote:
>>
>> Pass vga=0x0f04 on the kernel command line (some bootloaders support
>> "vga=current") if that is what you want.
> 
> No, that's not what I want. I don't want to set a video mode, not even the
> current. I want it just to continue.

That is what vga=current does.

	-hpa
Comment 4 H. Peter Anvin 2010-02-17 03:45:13 UTC
Created attachment 25076 [details]
Test patch

Try this patch.
Comment 5 Wim Osterholt 2010-02-18 02:21:02 UTC
> http://bugzilla.kernel.org/show_bug.cgi?id=15329
> 
> 
> H. Peter Anvin <hpa@zytor.com> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>              Status|NEW                         |ASSIGNED
>          AssignedTo|platform_i386@kernel-bugs.o |hpa@zytor.com
>                    |sdl.org                     |
> 
> 
> --- Comment #4 from H. Peter Anvin <hpa@zytor.com>  2010-02-17 03:45:13 ---
> Created an attachment (id=25076)
>  --> (http://bugzilla.kernel.org/attachment.cgi?id=25076)
> Test patch
> 
> Try this patch.
> 


The line numbers don't exactly match with what I have from www.kernel.org.
I can't quite follow what you change there; especially an extra store_cursor_
position *after* just setting the cursor position.
But the result is a correct text flow when booting.

>>> Pass vga=0x0f04 on the kernel command line (some bootloaders support
>>> "vga=current") if that is what you want.
>>
>> No, that's not what I want. I don't want to set a video mode, not even the
>> current. I want it just to continue.
>
>That is what vga=current does.

No. Everything except vga=ask will enforce setting a video mode by
line 322:	if (!set_mode(mode))
		break;

Furthermore the current video mode as given by
line 310:	u16 mode = boot_params.hdr.vid_mode;
is set to the value of 0xFFFF.  (on my thinkpad 600 that is. not yet
verified on other machines.)
So, I think that something like  if (mode==0xFFFF) break  would be
apropriate in the loop at line 318.
(can't try a reboot during this mail session :)


Regards, Wim.


----- wim@djo.tudelft.nl -----
Comment 6 H. Peter Anvin 2010-02-18 02:27:04 UTC
On 02/17/2010 06:21 PM, bugzilla-daemon@bugzilla.kernel.org wrote:
> 
> No. Everything except vga=ask will enforce setting a video mode by 
> line 322:    if (!set_mode(mode)) break;
> 

Guess what the very first thing in set_mode() is?

>         if (mode == VIDEO_CURRENT_MODE)
>                 return 0;       /* Nothing to do... */

	-hpa
Comment 7 H. Peter Anvin 2010-02-18 02:40:34 UTC
Fixed in -tip, checkin f1f6baf8f1df29be38003089787e378567ce0086

Note You need to log in before you can comment on or make changes to this bug.